Update ember and ember-data
This commit is contained in:
parent
3eb8e17daa
commit
cd26fc103e
42
assets/javascripts/vendor/ember-data.js
vendored
42
assets/javascripts/vendor/ember-data.js
vendored
|
@ -248,7 +248,7 @@ DS.ManyArrayStateManager = Ember.StateManager.extend({
|
|||
|
||||
|
||||
(function() {
|
||||
var get = Ember.get, set = Ember.set, set = Ember.set;
|
||||
var get = Ember.get, set = Ember.set;
|
||||
|
||||
DS.ManyArray = DS.RecordArray.extend({
|
||||
init: function() {
|
||||
|
@ -3743,31 +3743,35 @@ DS.FixtureAdapter = DS.Adapter.extend({
|
|||
find: function(store, type, id) {
|
||||
var fixtures = this.fixturesForType(type);
|
||||
|
||||
Ember.assert("Unable to find fixtures for model type "+type.toString(), !!fixtures);
|
||||
|
||||
if (fixtures) {
|
||||
fixtures = fixtures.findProperty('id', id);
|
||||
}
|
||||
|
||||
Ember.assert("Unable to find fixtures for model type "+type.toString(), !!fixtures);
|
||||
|
||||
this.simulateRemoteCall(function() {
|
||||
store.load(type, fixtures);
|
||||
}, store, type);
|
||||
if (fixtures) {
|
||||
this.simulateRemoteCall(function() {
|
||||
store.load(type, fixtures);
|
||||
}, store, type);
|
||||
}
|
||||
},
|
||||
|
||||
findMany: function(store, type, ids) {
|
||||
var fixtures = this.fixturesForType(type);
|
||||
|
||||
Ember.assert("Unable to find fixtures for model type "+type.toString(), !!fixtures);
|
||||
|
||||
if (fixtures) {
|
||||
fixtures = fixtures.filter(function(item) {
|
||||
return ids.indexOf(item.id) !== -1;
|
||||
});
|
||||
}
|
||||
|
||||
Ember.assert("Unable to find fixtures for model type "+type.toString(), !!fixtures);
|
||||
|
||||
this.simulateRemoteCall(function() {
|
||||
store.loadMany(type, fixtures);
|
||||
}, store, type);
|
||||
if (fixtures) {
|
||||
this.simulateRemoteCall(function() {
|
||||
store.loadMany(type, fixtures);
|
||||
}, store, type);
|
||||
}
|
||||
},
|
||||
|
||||
findAll: function(store, type) {
|
||||
|
@ -3783,13 +3787,15 @@ DS.FixtureAdapter = DS.Adapter.extend({
|
|||
findQuery: function(store, type, query, array) {
|
||||
var fixtures = this.fixturesForType(type);
|
||||
|
||||
fixtures = this.queryFixtures(fixtures, query);
|
||||
|
||||
Ember.assert("Unable to find fixtures for model type "+type.toString(), !!fixtures);
|
||||
|
||||
this.simulateRemoteCall(function() {
|
||||
array.load(fixtures);
|
||||
}, store, type);
|
||||
fixtures = this.queryFixtures(fixtures, query);
|
||||
|
||||
if (fixtures) {
|
||||
this.simulateRemoteCall(function() {
|
||||
array.load(fixtures);
|
||||
}, store, type);
|
||||
}
|
||||
},
|
||||
|
||||
createRecord: function(store, type, record) {
|
||||
|
@ -4030,7 +4036,9 @@ DS.RESTAdapter = DS.Adapter.extend({
|
|||
data: query,
|
||||
success: function(json) {
|
||||
this.sideload(store, type, json, plural);
|
||||
recordArray.load(json[plural]);
|
||||
setTimeout(function() {
|
||||
recordArray.load(json[plural]);
|
||||
}, 10);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
|
647
assets/javascripts/vendor/ember.js
vendored
647
assets/javascripts/vendor/ember.js
vendored
|
@ -1,5 +1,5 @@
|
|||
// Version: v0.9.8.1-617-g2b213df
|
||||
// Last commit: 2b213df (2012-07-14 16:44:53 -0700)
|
||||
// Version: v0.9.8.1-672-gd7e24ac
|
||||
// Last commit: d7e24ac (2012-07-26 09:35:30 -0700)
|
||||
|
||||
|
||||
(function() {
|
||||
|
@ -142,8 +142,8 @@ window.ember_deprecateFunc = Ember.deprecateFunc("ember_deprecateFunc is deprec
|
|||
|
||||
})();
|
||||
|
||||
// Version: v0.9.8.1-658-gd4a9e46
|
||||
// Last commit: d4a9e46 (2012-07-21 19:16:48 -0700)
|
||||
// Version: v0.9.8.1-672-gd7e24ac
|
||||
// Last commit: d7e24ac (2012-07-26 09:35:30 -0700)
|
||||
|
||||
|
||||
(function() {
|
||||
|
@ -1406,7 +1406,11 @@ set = function set(obj, keyName, value, tolerant) {
|
|||
if (value !== currentValue) {
|
||||
Ember.propertyWillChange(obj, keyName);
|
||||
if (MANDATORY_SETTER) {
|
||||
meta.values[keyName] = value;
|
||||
if (currentValue === undefined && !(keyName in obj)) {
|
||||
Ember.defineProperty(obj, keyName, null, value); // setup mandatory setter
|
||||
} else {
|
||||
meta.values[keyName] = value;
|
||||
}
|
||||
} else {
|
||||
obj[keyName] = value;
|
||||
}
|
||||
|
@ -11377,6 +11381,28 @@ Ember.ControllerMixin.reopen({
|
|||
set(this, outletName, view);
|
||||
|
||||
return view;
|
||||
},
|
||||
|
||||
/**
|
||||
Convenience method to connect controllers. This method makes other controllers
|
||||
available on the controller the method was invoked on.
|
||||
|
||||
For example, to make the `personController` and the `postController` available
|
||||
on the `overviewController`, you would call:
|
||||
|
||||
overviewController.connectControllers('person', 'post');
|
||||
|
||||
@param {String...} controllerNames the controllers to make available
|
||||
*/
|
||||
connectControllers: function() {
|
||||
var controllers = get(this, 'controllers'),
|
||||
controllerNames = Array.prototype.slice.apply(arguments),
|
||||
controllerName;
|
||||
|
||||
for (var i=0, l=controllerNames.length; i<l; i++) {
|
||||
controllerName = controllerNames[i] + 'Controller';
|
||||
set(this, controllerName, get(controllers, controllerName));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -14199,6 +14225,7 @@ Ember.ContainerView = Ember.View.extend({
|
|||
|
||||
if (currentView) {
|
||||
childViews.removeObject(currentView);
|
||||
currentView.destroy();
|
||||
}
|
||||
}, 'currentView'),
|
||||
|
||||
|
@ -14823,7 +14850,14 @@ Ember.State.reopenClass(
|
|||
transitionTo: function(target) {
|
||||
var event = function(stateManager, context) {
|
||||
if (Event && context instanceof Event) {
|
||||
context = context.context;
|
||||
if (context.hasOwnProperty('context')) {
|
||||
context = context.context;
|
||||
} else {
|
||||
// If we received an event and it doesn't contain
|
||||
// a context, don't pass along a superfluous
|
||||
// context to the target of the event.
|
||||
return stateManager.transitionTo(target);
|
||||
}
|
||||
}
|
||||
|
||||
stateManager.transitionTo(target, context);
|
||||
|
@ -14842,6 +14876,167 @@ Ember.State.reopenClass(
|
|||
(function() {
|
||||
var get = Ember.get, set = Ember.set, fmt = Ember.String.fmt;
|
||||
var arrayForEach = Ember.ArrayPolyfills.forEach;
|
||||
/**
|
||||
@private
|
||||
|
||||
A Transition takes the enter, exit and resolve states and normalizes
|
||||
them:
|
||||
|
||||
* takes any passed in contexts into consideration
|
||||
* adds in `initialState`s
|
||||
*/
|
||||
var Transition = function(raw) {
|
||||
this.enterStates = raw.enterStates.slice();
|
||||
this.exitStates = raw.exitStates.slice();
|
||||
this.resolveState = raw.resolveState;
|
||||
|
||||
this.finalState = raw.enterStates[raw.enterStates.length - 1] || raw.resolveState;
|
||||
};
|
||||
|
||||
Transition.prototype = {
|
||||
/**
|
||||
@private
|
||||
|
||||
Normalize the passed in enter, exit and resolve states.
|
||||
|
||||
This process also adds `finalState` and `contexts` to the Transition object.
|
||||
|
||||
@param {Ember.StateManager} manager the state manager running the transition
|
||||
@param {Array} contexts a list of contexts passed into `transitionTo`
|
||||
*/
|
||||
normalize: function(manager, contexts) {
|
||||
this.matchContextsToStates(contexts);
|
||||
this.addInitialStates();
|
||||
this.removeUnchangedContexts(manager);
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
@private
|
||||
|
||||
Match each of the contexts passed to `transitionTo` to a state.
|
||||
This process may also require adding additional enter and exit
|
||||
states if there are more contexts than enter states.
|
||||
|
||||
@param {Array} contexts a list of contexts passed into `transitionTo`
|
||||
*/
|
||||
matchContextsToStates: function(contexts) {
|
||||
var stateIdx = this.enterStates.length - 1,
|
||||
matchedContexts = [],
|
||||
state,
|
||||
context;
|
||||
|
||||
// Next, we will match the passed in contexts to the states they
|
||||
// represent.
|
||||
//
|
||||
// First, assign a context to each enter state in reverse order. If
|
||||
// any contexts are left, add a parent state to the list of states
|
||||
// to enter and exit, and assign a context to the parent state.
|
||||
//
|
||||
// If there are still contexts left when the state manager is
|
||||
// reached, raise an exception.
|
||||
//
|
||||
// This allows the following:
|
||||
//
|
||||
// |- root
|
||||
// | |- post
|
||||
// | | |- comments
|
||||
// | |- about (* current state)
|
||||
//
|
||||
// For `transitionTo('post.comments', post, post.get('comments')`,
|
||||
// the first context (`post`) will be assigned to `root.post`, and
|
||||
// the second context (`post.get('comments')`) will be assigned
|
||||
// to `root.post.comments`.
|
||||
//
|
||||
// For the following:
|
||||
//
|
||||
// |- root
|
||||
// | |- post
|
||||
// | | |- index (* current state)
|
||||
// | | |- comments
|
||||
//
|
||||
// For `transitionTo('post.comments', otherPost, otherPost.get('comments')`,
|
||||
// the `<root.post>` state will be added to the list of enter and exit
|
||||
// states because its context has changed.
|
||||
|
||||
while (contexts.length > 0) {
|
||||
if (stateIdx >= 0) {
|
||||
state = this.enterStates[stateIdx--];
|
||||
} else {
|
||||
if (this.enterStates.length) {
|
||||
state = get(this.enterStates[0], 'parentState');
|
||||
if (!state) { throw "Cannot match all contexts to states"; }
|
||||
} else {
|
||||
// If re-entering the current state with a context, the resolve
|
||||
// state will be the current state.
|
||||
state = this.resolveState;
|
||||
}
|
||||
|
||||
this.enterStates.unshift(state);
|
||||
this.exitStates.unshift(state);
|
||||
}
|
||||
|
||||
// in routers, only states with dynamic segments have a context
|
||||
if (get(state, 'hasContext')) {
|
||||
context = contexts.pop();
|
||||
} else {
|
||||
context = null;
|
||||
}
|
||||
|
||||
matchedContexts.unshift(context);
|
||||
}
|
||||
|
||||
this.contexts = matchedContexts;
|
||||
},
|
||||
|
||||
/**
|
||||
@private
|
||||
|
||||
Add any `initialState`s to the list of enter states.
|
||||
*/
|
||||
addInitialStates: function() {
|
||||
var finalState = this.finalState, initialState;
|
||||
|
||||
while(true) {
|
||||
initialState = get(finalState, 'initialState') || 'start';
|
||||
finalState = get(finalState, 'states.' + initialState);
|
||||
|
||||
if (!finalState) { break; }
|
||||
|
||||
this.finalState = finalState;
|
||||
this.enterStates.push(finalState);
|
||||
this.contexts.push(undefined);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
@private
|
||||
|
||||
Remove any states that were added because the number of contexts
|
||||
exceeded the number of explicit enter states, but the context has
|
||||
not changed since the last time the state was entered.
|
||||
|
||||
@param {Ember.StateManager} manager passed in to look up the last
|
||||
context for a states
|
||||
*/
|
||||
removeUnchangedContexts: function(manager) {
|
||||
// Start from the beginning of the enter states. If the state was added
|
||||
// to the list during the context matching phase, make sure the context
|
||||
// has actually changed since the last time the state was entered.
|
||||
while (this.enterStates.length > 0) {
|
||||
if (this.enterStates[0] !== this.exitStates[0]) { break; }
|
||||
|
||||
if (this.enterStates.length === this.contexts.length) {
|
||||
if (manager.getStateMeta(this.enterStates[0], 'context') !== this.contexts[0]) { break; }
|
||||
this.contexts.shift();
|
||||
}
|
||||
|
||||
this.resolveState = this.enterStates.shift();
|
||||
this.exitStates.shift();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@class
|
||||
|
||||
|
@ -15351,18 +15546,29 @@ Ember.StateManager = Ember.State.extend(
|
|||
return possible;
|
||||
},
|
||||
|
||||
findStatesByPath: function(state, path) {
|
||||
/**
|
||||
@private
|
||||
|
||||
A state stores its child states in its `states` hash.
|
||||
This code takes a path like `posts.show` and looks
|
||||
up `origin.states.posts.states.show`.
|
||||
|
||||
It returns a list of all of the states from the
|
||||
origin, which is the list of states to call `enter`
|
||||
on.
|
||||
*/
|
||||
findStatesByPath: function(origin, path) {
|
||||
if (!path || path === "") { return undefined; }
|
||||
var r = path.split('.'),
|
||||
ret = [];
|
||||
|
||||
for (var i=0, len = r.length; i < len; i++) {
|
||||
var states = get(state, 'states');
|
||||
var states = get(origin, 'states');
|
||||
|
||||
if (!states) { return undefined; }
|
||||
|
||||
var s = get(states, r[i]);
|
||||
if (s) { state = s; ret.push(s); }
|
||||
if (s) { origin = s; ret.push(s); }
|
||||
else { return undefined; }
|
||||
}
|
||||
|
||||
|
@ -15376,122 +15582,130 @@ Ember.StateManager = Ember.State.extend(
|
|||
},
|
||||
|
||||
transitionTo: function(path, context) {
|
||||
// 1. Normalize arguments
|
||||
// 2. Ensure that we are in the correct state
|
||||
// 3. Map provided path to context objects and send
|
||||
// appropriate transitionEvent events
|
||||
|
||||
// XXX When is transitionTo called with no path
|
||||
if (Ember.empty(path)) { return; }
|
||||
|
||||
// The ES6 signature of this function is `path, ...contexts`
|
||||
var contexts = context ? Array.prototype.slice.call(arguments, 1) : [],
|
||||
currentState = get(this, 'currentState') || this,
|
||||
resolveState = currentState,
|
||||
exitStates = [],
|
||||
matchedContexts = [],
|
||||
cachedPath,
|
||||
enterStates,
|
||||
state,
|
||||
initialState,
|
||||
stateIdx,
|
||||
useContext;
|
||||
currentState = get(this, 'currentState') || this;
|
||||
|
||||
if (!context && (cachedPath = currentState.pathsCacheNoContext[path])) {
|
||||
// fast path
|
||||
// First, get the enter, exit and resolve states for the current state
|
||||
// and specified path. If possible, use an existing cache.
|
||||
var hash = this.contextFreeTransition(currentState, path);
|
||||
|
||||
exitStates = cachedPath.exitStates;
|
||||
enterStates = cachedPath.enterStates;
|
||||
resolveState = cachedPath.resolveState;
|
||||
} else {
|
||||
// normal path
|
||||
// Next, process the raw state information for the contexts passed in.
|
||||
var transition = new Transition(hash).normalize(this, contexts);
|
||||
|
||||
if ((cachedPath = currentState.pathsCache[path])) {
|
||||
// cache hit
|
||||
|
||||
exitStates = cachedPath.exitStates;
|
||||
enterStates = cachedPath.enterStates;
|
||||
resolveState = cachedPath.resolveState;
|
||||
} else {
|
||||
// cache miss
|
||||
|
||||
enterStates = this.findStatesByPath(currentState, path);
|
||||
|
||||
while (resolveState && !enterStates) {
|
||||
exitStates.unshift(resolveState);
|
||||
|
||||
resolveState = get(resolveState, 'parentState');
|
||||
if (!resolveState) {
|
||||
enterStates = this.findStatesByPath(this, path);
|
||||
if (!enterStates) {
|
||||
Ember.assert('Could not find state for path: "'+path+'"');
|
||||
return;
|
||||
}
|
||||
}
|
||||
enterStates = this.findStatesByPath(resolveState, path);
|
||||
}
|
||||
|
||||
while (enterStates.length > 0 && enterStates[0] === exitStates[0]) {
|
||||
resolveState = enterStates.shift();
|
||||
exitStates.shift();
|
||||
}
|
||||
|
||||
currentState.pathsCache[path] = {
|
||||
exitStates: exitStates,
|
||||
enterStates: enterStates,
|
||||
resolveState: resolveState
|
||||
};
|
||||
}
|
||||
|
||||
// Don't modify the cached versions
|
||||
enterStates = enterStates.slice();
|
||||
exitStates = exitStates.slice();
|
||||
|
||||
stateIdx = enterStates.length-1;
|
||||
while (contexts.length > 0) {
|
||||
if (stateIdx >= 0) {
|
||||
state = enterStates[stateIdx--];
|
||||
} else {
|
||||
state = enterStates[0] ? get(enterStates[0], 'parentState') : resolveState;
|
||||
if (!state) { throw "Cannot match all contexts to states"; }
|
||||
enterStates.unshift(state);
|
||||
exitStates.unshift(state);
|
||||
}
|
||||
|
||||
useContext = context && get(state, 'hasContext');
|
||||
matchedContexts.unshift(useContext ? contexts.pop() : null);
|
||||
}
|
||||
|
||||
state = enterStates[enterStates.length - 1] || resolveState;
|
||||
while(true) {
|
||||
initialState = get(state, 'initialState') || 'start';
|
||||
state = get(state, 'states.'+initialState);
|
||||
if (!state) { break; }
|
||||
enterStates.push(state);
|
||||
matchedContexts.push(undefined);
|
||||
}
|
||||
|
||||
while (enterStates.length > 0) {
|
||||
if (enterStates[0] !== exitStates[0]) { break; }
|
||||
|
||||
if (enterStates.length === matchedContexts.length) {
|
||||
if (this.getStateMeta(enterStates[0], 'context') !== matchedContexts[0]) { break; }
|
||||
matchedContexts.shift();
|
||||
}
|
||||
|
||||
resolveState = enterStates.shift();
|
||||
exitStates.shift();
|
||||
}
|
||||
}
|
||||
|
||||
this.enterState(exitStates, enterStates, enterStates[enterStates.length-1] || resolveState);
|
||||
this.triggerSetupContext(enterStates, matchedContexts);
|
||||
this.enterState(transition);
|
||||
this.triggerSetupContext(transition);
|
||||
},
|
||||
|
||||
triggerSetupContext: function(enterStates, contexts) {
|
||||
var offset = enterStates.length - contexts.length;
|
||||
contextFreeTransition: function(currentState, path) {
|
||||
var cache = currentState.pathsCache[path];
|
||||
if (cache) { return cache; }
|
||||
|
||||
var enterStates = this.findStatesByPath(currentState, path),
|
||||
exitStates = [],
|
||||
resolveState = currentState;
|
||||
|
||||
// Walk up the states. For each state, check whether a state matching
|
||||
// the `path` is nested underneath. This will find the closest
|
||||
// parent state containing `path`.
|
||||
//
|
||||
// This allows the user to pass in a relative path. For example, for
|
||||
// the following state hierarchy:
|
||||
//
|
||||
// | |root
|
||||
// | |- posts
|
||||
// | | |- show (* current)
|
||||
// | |- comments
|
||||
// | | |- show
|
||||
//
|
||||
// If the current state is `<root.posts.show>`, an attempt to
|
||||
// transition to `comments.show` will match `<root.comments.show>`.
|
||||
//
|
||||
// First, this code will look for root.posts.show.comments.show.
|
||||
// Next, it will look for root.posts.comments.show. Finally,
|
||||
// it will look for `root.comments.show`, and find the state.
|
||||
//
|
||||
// After this process, the following variables will exist:
|
||||
//
|
||||
// * resolveState: a common parent state between the current
|
||||
// and target state. In the above example, `<root>` is the
|
||||
// `resolveState`.
|
||||
// * enterStates: a list of all of the states represented
|
||||
// by the path from the `resolveState`. For example, for
|
||||
// the path `root.comments.show`, `enterStates` would have
|
||||
// `[<root.comments>, <root.comments.show>]`
|
||||
// * exitStates: a list of all of the states from the
|
||||
// `resolveState` to the `currentState`. In the above
|
||||
// example, `exitStates` would have
|
||||
// `[<root.posts>`, `<root.posts.show>]`.
|
||||
while (resolveState && !enterStates) {
|
||||
exitStates.unshift(resolveState);
|
||||
|
||||
resolveState = get(resolveState, 'parentState');
|
||||
if (!resolveState) {
|
||||
enterStates = this.findStatesByPath(this, path);
|
||||
if (!enterStates) {
|
||||
Ember.assert('Could not find state for path: "'+path+'"');
|
||||
return;
|
||||
}
|
||||
}
|
||||
enterStates = this.findStatesByPath(resolveState, path);
|
||||
}
|
||||
|
||||
// If the path contains some states that are parents of both the
|
||||
// current state and the target state, remove them.
|
||||
//
|
||||
// For example, in the following hierarchy:
|
||||
//
|
||||
// |- root
|
||||
// | |- post
|
||||
// | | |- index (* current)
|
||||
// | | |- show
|
||||
//
|
||||
// If the `path` is `root.post.show`, the three variables will
|
||||
// be:
|
||||
//
|
||||
// * resolveState: `<state manager>`
|
||||
// * enterStates: `[<root>, <root.post>, <root.post.show>]`
|
||||
// * exitStates: `[<root>, <root.post>, <root.post.index>]`
|
||||
//
|
||||
// The goal of this code is to remove the common states, so we
|
||||
// have:
|
||||
//
|
||||
// * resolveState: `<root.post>`
|
||||
// * enterStates: `[<root.post.show>]`
|
||||
// * exitStates: `[<root.post.index>]`
|
||||
//
|
||||
// This avoid unnecessary calls to the enter and exit transitions.
|
||||
while (enterStates.length > 0 && enterStates[0] === exitStates[0]) {
|
||||
resolveState = enterStates.shift();
|
||||
exitStates.shift();
|
||||
}
|
||||
|
||||
// Cache the enterStates, exitStates, and resolveState for the
|
||||
// current state and the `path`.
|
||||
var transitions = currentState.pathsCache[path] = {
|
||||
exitStates: exitStates,
|
||||
enterStates: enterStates,
|
||||
resolveState: resolveState
|
||||
};
|
||||
|
||||
return transitions;
|
||||
},
|
||||
|
||||
triggerSetupContext: function(transitions) {
|
||||
var contexts = transitions.contexts,
|
||||
offset = transitions.enterStates.length - contexts.length,
|
||||
enterStates = transitions.enterStates,
|
||||
transitionEvent = get(this, 'transitionEvent');
|
||||
|
||||
Ember.assert("More contexts provided than states", offset >= 0);
|
||||
|
||||
arrayForEach.call(enterStates, function(state, idx) {
|
||||
state.trigger(get(this, 'transitionEvent'), this, contexts[idx-offset]);
|
||||
state.trigger(transitionEvent, this, contexts[idx-offset]);
|
||||
}, this);
|
||||
},
|
||||
|
||||
|
@ -15506,21 +15720,20 @@ Ember.StateManager = Ember.State.extend(
|
|||
}
|
||||
},
|
||||
|
||||
enterState: function(exitStates, enterStates, state) {
|
||||
var log = this.enableLogging,
|
||||
stateManager = this;
|
||||
enterState: function(transition) {
|
||||
var log = this.enableLogging;
|
||||
|
||||
exitStates = exitStates.slice(0).reverse();
|
||||
var exitStates = transition.exitStates.slice(0).reverse();
|
||||
arrayForEach.call(exitStates, function(state) {
|
||||
state.trigger('exit', stateManager);
|
||||
});
|
||||
state.trigger('exit', this);
|
||||
}, this);
|
||||
|
||||
arrayForEach.call(enterStates, function(state) {
|
||||
arrayForEach.call(transition.enterStates, function(state) {
|
||||
if (log) { Ember.Logger.log("STATEMANAGER: Entering " + get(state, 'path')); }
|
||||
state.trigger('enter', stateManager);
|
||||
});
|
||||
state.trigger('enter', this);
|
||||
}, this);
|
||||
|
||||
set(this, 'currentState', state);
|
||||
set(this, 'currentState', transition.finalState);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -16109,9 +16322,9 @@ var get = Ember.get, set = Ember.set;
|
|||
|
||||
## Adding Routes to a Router
|
||||
The `initialState` property of Ember.Router instances is named `root`. The state stored in this
|
||||
property should be a subclass of Ember.Route. The `root` route should itself have states that are
|
||||
also subclasses of Ember.Route and have `route` properties describing the URL pattern you would
|
||||
like to detect.
|
||||
property must be a subclass of Ember.Route. The `root` route acts as the container for the
|
||||
set of routable states but is not routable itself. It should have states that are also subclasses
|
||||
of Ember.Route which each have a `route` property describing the URL pattern you would like to detect.
|
||||
|
||||
App = Ember.Application.create({
|
||||
Router: Ember.Router.extend({
|
||||
|
@ -16153,6 +16366,46 @@ var get = Ember.get, set = Ember.set;
|
|||
'root.bRoute' ('/alphabeta') and transition the router first to the state named 'root' and
|
||||
then to the substate 'bRoute'.
|
||||
|
||||
## Adding Nested Routes to a Router
|
||||
Routes can contain nested subroutes each with their own `route` property describing the nested
|
||||
portion of the URL they would like to detect and handle. Router, like all instances of StateManager,
|
||||
cannot call `transitonTo` with an intermediary state. To avoid transitioning the Router into an
|
||||
intermediary state when detecting URLs, a Route with nested routes must define both a base `route`
|
||||
property for itself and a child Route with a `route` property of `'/'` which will be transitioned
|
||||
to when the base route is detected in the URL:
|
||||
|
||||
Given the following application code:
|
||||
|
||||
App = Ember.Application.create({
|
||||
Router: Ember.Router.extend({
|
||||
root: Ember.Route.extend({
|
||||
aRoute: Ember.Route.extend({
|
||||
route: '/theBaseRouteForThisSet',
|
||||
|
||||
indexSubRoute: Ember.Route.extend({
|
||||
route: '/',
|
||||
}),
|
||||
|
||||
subRouteOne: Ember.Route.extend({
|
||||
route: '/subroute1
|
||||
}),
|
||||
|
||||
subRouteTwo: Ember.Route.extend({
|
||||
route: '/subRoute2'
|
||||
})
|
||||
|
||||
})
|
||||
})
|
||||
})
|
||||
});
|
||||
App.initialize();
|
||||
|
||||
When the application is loaded at '/theBaseRouteForThisSet' the Router will transition to the route
|
||||
at path 'root.aRoute' and then transition to state 'indexSubRoute'.
|
||||
|
||||
When the application is loaded at '/theBaseRouteForThisSet/subRoute1' the Router will transition to
|
||||
the route at path 'root.aRoute' and then transition to state 'subRouteOne'.
|
||||
|
||||
## Route Transition Events
|
||||
Transitioning between Ember.Route instances (including the transition into the detected
|
||||
route when loading the application) triggers the same transition events as state transitions for
|
||||
|
@ -16383,7 +16636,7 @@ var get = Ember.get, set = Ember.set;
|
|||
|
||||
<script type="text/x-handlebars" data-template-name="photos">
|
||||
{{#each photo in controller}}
|
||||
<h1><a {{action showPhoto context="photo"}}>{{title}}</a></h1>
|
||||
<h1><a {{action showPhoto photo}}>{{title}}</a></h1>
|
||||
{{/each}}
|
||||
</script>
|
||||
|
||||
|
@ -19050,27 +19303,39 @@ Ember.Handlebars.registerHelper('template', function(name, options) {
|
|||
|
||||
|
||||
(function() {
|
||||
var EmberHandlebars = Ember.Handlebars, getPath = EmberHandlebars.getPath, get = Ember.get;
|
||||
var EmberHandlebars = Ember.Handlebars,
|
||||
getPath = EmberHandlebars.getPath,
|
||||
get = Ember.get,
|
||||
a_slice = Array.prototype.slice;
|
||||
|
||||
var ActionHelper = EmberHandlebars.ActionHelper = {
|
||||
registeredActions: {}
|
||||
};
|
||||
|
||||
ActionHelper.registerAction = function(actionName, eventName, target, view, context, link) {
|
||||
ActionHelper.registerAction = function(actionName, options) {
|
||||
var actionId = (++Ember.$.uuid).toString();
|
||||
|
||||
ActionHelper.registeredActions[actionId] = {
|
||||
eventName: eventName,
|
||||
eventName: options.eventName,
|
||||
handler: function(event) {
|
||||
if (link && (event.button !== 0 || event.shiftKey || event.metaKey || event.altKey || event.ctrlKey)) {
|
||||
var modifier = event.shiftKey || event.metaKey || event.altKey || event.ctrlKey,
|
||||
secondaryClick = event.which > 1, // IE9 may return undefined
|
||||
nonStandard = modifier || secondaryClick;
|
||||
|
||||
if (options.link && nonStandard) {
|
||||
// Allow the browser to handle special link clicks normally
|
||||
return;
|
||||
}
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
event.view = view;
|
||||
event.context = context;
|
||||
event.view = options.view;
|
||||
|
||||
if (options.hasOwnProperty('context')) {
|
||||
event.context = options.context;
|
||||
}
|
||||
|
||||
var target = options.target;
|
||||
|
||||
// Check for StateManager (or compatible object)
|
||||
if (target.isState && typeof target.send === 'function') {
|
||||
|
@ -19082,7 +19347,7 @@ ActionHelper.registerAction = function(actionName, eventName, target, view, cont
|
|||
}
|
||||
};
|
||||
|
||||
view.on('willRerender', function() {
|
||||
options.view.on('willRerender', function() {
|
||||
delete ActionHelper.registeredActions[actionId];
|
||||
});
|
||||
|
||||
|
@ -19091,14 +19356,16 @@ ActionHelper.registerAction = function(actionName, eventName, target, view, cont
|
|||
|
||||
/**
|
||||
The `{{action}}` helper registers an HTML element within a template for
|
||||
DOM event handling. User interaction with that element will call the method
|
||||
on the template's associated `Ember.View` instance that has the same name
|
||||
as the first provided argument to `{{action}}`:
|
||||
DOM event handling and forwards that interaction to the Application's router,
|
||||
the template's `Ember.View` instance, or supplied `target` option (see 'Specifiying a Target').
|
||||
|
||||
User interaction with that element will invoke the supplied action name on
|
||||
the appropriate target.
|
||||
|
||||
Given the following Handlebars template on the page
|
||||
|
||||
<script type="text/x-handlebars" data-template-name='a-template'>
|
||||
<div {{action "anActionName"}}>
|
||||
<div {{action anActionName}}>
|
||||
click me
|
||||
</div>
|
||||
</script>
|
||||
|
@ -19134,15 +19401,51 @@ ActionHelper.registerAction = function(actionName, eventName, target, view, cont
|
|||
handler.
|
||||
|
||||
If you need the default handler to trigger you should either register your
|
||||
own event handler, or use event methods on your view class.
|
||||
own event handler, or use event methods on your view class. See Ember.View
|
||||
'Responding to Browser Events' for more information.
|
||||
|
||||
### Specifying an Action Target
|
||||
### Specifying DOM event type
|
||||
|
||||
A `target` option can be provided to change which object will receive the
|
||||
method call. This option must be a string representing a path to an object:
|
||||
By default the `{{action}}` helper registers for DOM `click` events. You can
|
||||
supply an `on` option to the helper to specify a different DOM event name:
|
||||
|
||||
<script type="text/x-handlebars" data-template-name='a-template'>
|
||||
<div {{action "anActionName" target="MyApplication.someObject"}}>
|
||||
<div {{action anActionName on="doubleClick"}}>
|
||||
click me
|
||||
</div>
|
||||
</script>
|
||||
|
||||
See Ember.View 'Responding to Browser Events' for a list of
|
||||
acceptable DOM event names.
|
||||
|
||||
Because `{{action}}` depends on Ember's event dispatch system it will only
|
||||
function if an `Ember.EventDispatcher` instance is available. An
|
||||
`Ember.EventDispatcher` instance will be created when a new
|
||||
`Ember.Application` is created. Having an instance of `Ember.Application`
|
||||
will satisfy this requirement.
|
||||
|
||||
|
||||
### Specifying a Target
|
||||
There are several possible target objects for `{{action}}` helpers:
|
||||
|
||||
In a typical `Ember.Router`-backed Application where views are managed
|
||||
through use of the `{{outlet}}` helper, actions will be forwarded to the
|
||||
current state of the Applications's Router. See Ember.Router 'Responding
|
||||
to User-initiated Events' for more information.
|
||||
|
||||
If you manaully set the `target` property on the controller of a template's
|
||||
`Ember.View` instance, the specifed `controller.target` will become the target
|
||||
for any actions. Likely custom values for a controller's `target` are the
|
||||
controller itself or a StateManager other than the Application's Router.
|
||||
|
||||
If the templates's view lacks a controller property the view itself is the target.
|
||||
|
||||
Finally, a `target` option can be provided to the helper to change which object
|
||||
will receive the method call. This option must be a string representing a
|
||||
path to an object:
|
||||
|
||||
<script type="text/x-handlebars" data-template-name='a-template'>
|
||||
<div {{action anActionName target="MyApplication.someObject"}}>
|
||||
click me
|
||||
</div>
|
||||
</script>
|
||||
|
@ -19156,7 +19459,7 @@ ActionHelper.registerAction = function(actionName, eventName, target, view, cont
|
|||
a target:
|
||||
|
||||
<script type="text/x-handlebars" data-template-name='a-template'>
|
||||
<div {{action "anActionName" target="parentView"}}>
|
||||
<div {{action anActionName target="parentView"}}>
|
||||
click me
|
||||
</div>
|
||||
</script>
|
||||
|
@ -19173,7 +19476,7 @@ ActionHelper.registerAction = function(actionName, eventName, target, view, cont
|
|||
action name an error will be thrown.
|
||||
|
||||
<script type="text/x-handlebars" data-template-name='a-template'>
|
||||
<div {{action "aMethodNameThatIsMissing"}}>
|
||||
<div {{action aMethodNameThatIsMissing}}>
|
||||
click me
|
||||
</div>
|
||||
</script>
|
||||
|
@ -19192,34 +19495,15 @@ ActionHelper.registerAction = function(actionName, eventName, target, view, cont
|
|||
Will throw `Uncaught TypeError: Cannot call method 'call' of undefined` when
|
||||
"click me" is clicked.
|
||||
|
||||
### Specifying DOM event type
|
||||
|
||||
By default the `{{action}}` helper registers for DOM `click` events. You can
|
||||
supply an `on` option to the helper to specify a different DOM event name:
|
||||
|
||||
<script type="text/x-handlebars" data-template-name='a-template'>
|
||||
<div {{action "aMethodNameThatIsMissing" on="doubleClick"}}>
|
||||
click me
|
||||
</div>
|
||||
</script>
|
||||
|
||||
See `Ember.EventDispatcher` for a list of acceptable DOM event names.
|
||||
|
||||
Because `{{action}}` depends on Ember's event dispatch system it will only
|
||||
function if an `Ember.EventDispatcher` instance is available. An
|
||||
`Ember.EventDispatcher` instance will be created when a new
|
||||
`Ember.Application` is created. Having an instance of `Ember.Application`
|
||||
will satisfy this requirement.
|
||||
|
||||
### Specifying a context
|
||||
|
||||
By default the `{{action}}` helper passes the current Handlebars context
|
||||
along in the `jQuery.Event` object. You may specify an alternative object to
|
||||
along in the `jQuery.Event` object. You may specify an alternate object to
|
||||
pass as the context by providing a property path:
|
||||
|
||||
<script type="text/x-handlebars" data-template-name='a-template'>
|
||||
{{#each person in people}}
|
||||
<div {{action "edit" context="person"}}>
|
||||
<div {{action edit person}}>
|
||||
click me
|
||||
</div>
|
||||
{{/each}}
|
||||
|
@ -19227,15 +19511,23 @@ ActionHelper.registerAction = function(actionName, eventName, target, view, cont
|
|||
|
||||
@name Handlebars.helpers.action
|
||||
@param {String} actionName
|
||||
@param {Object...} contexts
|
||||
@param {Hash} options
|
||||
*/
|
||||
EmberHandlebars.registerHelper('action', function(actionName, options) {
|
||||
EmberHandlebars.registerHelper('action', function(actionName) {
|
||||
var options = arguments[arguments.length - 1],
|
||||
contexts = a_slice.call(arguments, 1, -1);
|
||||
|
||||
var hash = options.hash,
|
||||
eventName = hash.on || "click",
|
||||
view = options.data.view,
|
||||
target, context, controller, link;
|
||||
|
||||
view = get(view, 'concreteView');
|
||||
// create a hash to pass along to registerAction
|
||||
var action = {
|
||||
eventName: hash.on || "click"
|
||||
};
|
||||
|
||||
action.view = view = get(view, 'concreteView');
|
||||
|
||||
if (hash.target) {
|
||||
target = getPath(this, hash.target, options);
|
||||
|
@ -19243,19 +19535,22 @@ EmberHandlebars.registerHelper('action', function(actionName, options) {
|
|||
target = get(controller, 'target');
|
||||
}
|
||||
|
||||
target = target || view;
|
||||
action.target = target = target || view;
|
||||
|
||||
context = hash.context ? getPath(this, hash.context, options) : options.contexts[0];
|
||||
// TODO: Support multiple contexts
|
||||
if (contexts.length) {
|
||||
action.context = context = getPath(this, contexts[0], options);
|
||||
}
|
||||
|
||||
var output = [], url;
|
||||
|
||||
if (hash.href && target.urlForEvent) {
|
||||
url = target.urlForEvent(actionName, context);
|
||||
output.push('href="' + url + '"');
|
||||
link = true;
|
||||
action.link = true;
|
||||
}
|
||||
|
||||
var actionId = ActionHelper.registerAction(actionName, eventName, target, view, context, link);
|
||||
var actionId = ActionHelper.registerAction(actionName, action);
|
||||
output.push('data-ember-action="' + actionId + '"');
|
||||
|
||||
return new EmberHandlebars.SafeString(output.join(" "));
|
||||
|
@ -20275,8 +20570,8 @@ Ember.onLoad('application', bootstrap);
|
|||
|
||||
})();
|
||||
|
||||
// Version: v0.9.8.1-658-gd4a9e46
|
||||
// Last commit: d4a9e46 (2012-07-21 19:16:48 -0700)
|
||||
// Version: v0.9.8.1-672-gd7e24ac
|
||||
// Last commit: d7e24ac (2012-07-26 09:35:30 -0700)
|
||||
|
||||
|
||||
(function() {
|
||||
|
|
|
@ -1952,8 +1952,8 @@ Handlebars.VM = {
|
|||
|
||||
Handlebars.template = Handlebars.VM.template;
|
||||
;
|
||||
// Version: v0.9.8.1-617-g2b213df
|
||||
// Last commit: 2b213df (2012-07-14 16:44:53 -0700)
|
||||
// Version: v0.9.8.1-672-gd7e24ac
|
||||
// Last commit: d7e24ac (2012-07-26 09:35:30 -0700)
|
||||
|
||||
|
||||
(function() {
|
||||
|
@ -2096,8 +2096,8 @@ window.ember_deprecateFunc = Ember.deprecateFunc("ember_deprecateFunc is deprec
|
|||
|
||||
})();
|
||||
|
||||
// Version: v0.9.8.1-658-gd4a9e46
|
||||
// Last commit: d4a9e46 (2012-07-21 19:16:48 -0700)
|
||||
// Version: v0.9.8.1-672-gd7e24ac
|
||||
// Last commit: d7e24ac (2012-07-26 09:35:30 -0700)
|
||||
|
||||
|
||||
(function() {
|
||||
|
@ -3360,7 +3360,11 @@ set = function set(obj, keyName, value, tolerant) {
|
|||
if (value !== currentValue) {
|
||||
Ember.propertyWillChange(obj, keyName);
|
||||
if (MANDATORY_SETTER) {
|
||||
meta.values[keyName] = value;
|
||||
if (currentValue === undefined && !(keyName in obj)) {
|
||||
Ember.defineProperty(obj, keyName, null, value); // setup mandatory setter
|
||||
} else {
|
||||
meta.values[keyName] = value;
|
||||
}
|
||||
} else {
|
||||
obj[keyName] = value;
|
||||
}
|
||||
|
@ -13331,6 +13335,28 @@ Ember.ControllerMixin.reopen({
|
|||
set(this, outletName, view);
|
||||
|
||||
return view;
|
||||
},
|
||||
|
||||
/**
|
||||
Convenience method to connect controllers. This method makes other controllers
|
||||
available on the controller the method was invoked on.
|
||||
|
||||
For example, to make the `personController` and the `postController` available
|
||||
on the `overviewController`, you would call:
|
||||
|
||||
overviewController.connectControllers('person', 'post');
|
||||
|
||||
@param {String...} controllerNames the controllers to make available
|
||||
*/
|
||||
connectControllers: function() {
|
||||
var controllers = get(this, 'controllers'),
|
||||
controllerNames = Array.prototype.slice.apply(arguments),
|
||||
controllerName;
|
||||
|
||||
for (var i=0, l=controllerNames.length; i<l; i++) {
|
||||
controllerName = controllerNames[i] + 'Controller';
|
||||
set(this, controllerName, get(controllers, controllerName));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -16153,6 +16179,7 @@ Ember.ContainerView = Ember.View.extend({
|
|||
|
||||
if (currentView) {
|
||||
childViews.removeObject(currentView);
|
||||
currentView.destroy();
|
||||
}
|
||||
}, 'currentView'),
|
||||
|
||||
|
@ -16777,7 +16804,14 @@ Ember.State.reopenClass(
|
|||
transitionTo: function(target) {
|
||||
var event = function(stateManager, context) {
|
||||
if (Event && context instanceof Event) {
|
||||
context = context.context;
|
||||
if (context.hasOwnProperty('context')) {
|
||||
context = context.context;
|
||||
} else {
|
||||
// If we received an event and it doesn't contain
|
||||
// a context, don't pass along a superfluous
|
||||
// context to the target of the event.
|
||||
return stateManager.transitionTo(target);
|
||||
}
|
||||
}
|
||||
|
||||
stateManager.transitionTo(target, context);
|
||||
|
@ -16796,6 +16830,167 @@ Ember.State.reopenClass(
|
|||
(function() {
|
||||
var get = Ember.get, set = Ember.set, fmt = Ember.String.fmt;
|
||||
var arrayForEach = Ember.ArrayPolyfills.forEach;
|
||||
/**
|
||||
@private
|
||||
|
||||
A Transition takes the enter, exit and resolve states and normalizes
|
||||
them:
|
||||
|
||||
* takes any passed in contexts into consideration
|
||||
* adds in `initialState`s
|
||||
*/
|
||||
var Transition = function(raw) {
|
||||
this.enterStates = raw.enterStates.slice();
|
||||
this.exitStates = raw.exitStates.slice();
|
||||
this.resolveState = raw.resolveState;
|
||||
|
||||
this.finalState = raw.enterStates[raw.enterStates.length - 1] || raw.resolveState;
|
||||
};
|
||||
|
||||
Transition.prototype = {
|
||||
/**
|
||||
@private
|
||||
|
||||
Normalize the passed in enter, exit and resolve states.
|
||||
|
||||
This process also adds `finalState` and `contexts` to the Transition object.
|
||||
|
||||
@param {Ember.StateManager} manager the state manager running the transition
|
||||
@param {Array} contexts a list of contexts passed into `transitionTo`
|
||||
*/
|
||||
normalize: function(manager, contexts) {
|
||||
this.matchContextsToStates(contexts);
|
||||
this.addInitialStates();
|
||||
this.removeUnchangedContexts(manager);
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
@private
|
||||
|
||||
Match each of the contexts passed to `transitionTo` to a state.
|
||||
This process may also require adding additional enter and exit
|
||||
states if there are more contexts than enter states.
|
||||
|
||||
@param {Array} contexts a list of contexts passed into `transitionTo`
|
||||
*/
|
||||
matchContextsToStates: function(contexts) {
|
||||
var stateIdx = this.enterStates.length - 1,
|
||||
matchedContexts = [],
|
||||
state,
|
||||
context;
|
||||
|
||||
// Next, we will match the passed in contexts to the states they
|
||||
// represent.
|
||||
//
|
||||
// First, assign a context to each enter state in reverse order. If
|
||||
// any contexts are left, add a parent state to the list of states
|
||||
// to enter and exit, and assign a context to the parent state.
|
||||
//
|
||||
// If there are still contexts left when the state manager is
|
||||
// reached, raise an exception.
|
||||
//
|
||||
// This allows the following:
|
||||
//
|
||||
// |- root
|
||||
// | |- post
|
||||
// | | |- comments
|
||||
// | |- about (* current state)
|
||||
//
|
||||
// For `transitionTo('post.comments', post, post.get('comments')`,
|
||||
// the first context (`post`) will be assigned to `root.post`, and
|
||||
// the second context (`post.get('comments')`) will be assigned
|
||||
// to `root.post.comments`.
|
||||
//
|
||||
// For the following:
|
||||
//
|
||||
// |- root
|
||||
// | |- post
|
||||
// | | |- index (* current state)
|
||||
// | | |- comments
|
||||
//
|
||||
// For `transitionTo('post.comments', otherPost, otherPost.get('comments')`,
|
||||
// the `<root.post>` state will be added to the list of enter and exit
|
||||
// states because its context has changed.
|
||||
|
||||
while (contexts.length > 0) {
|
||||
if (stateIdx >= 0) {
|
||||
state = this.enterStates[stateIdx--];
|
||||
} else {
|
||||
if (this.enterStates.length) {
|
||||
state = get(this.enterStates[0], 'parentState');
|
||||
if (!state) { throw "Cannot match all contexts to states"; }
|
||||
} else {
|
||||
// If re-entering the current state with a context, the resolve
|
||||
// state will be the current state.
|
||||
state = this.resolveState;
|
||||
}
|
||||
|
||||
this.enterStates.unshift(state);
|
||||
this.exitStates.unshift(state);
|
||||
}
|
||||
|
||||
// in routers, only states with dynamic segments have a context
|
||||
if (get(state, 'hasContext')) {
|
||||
context = contexts.pop();
|
||||
} else {
|
||||
context = null;
|
||||
}
|
||||
|
||||
matchedContexts.unshift(context);
|
||||
}
|
||||
|
||||
this.contexts = matchedContexts;
|
||||
},
|
||||
|
||||
/**
|
||||
@private
|
||||
|
||||
Add any `initialState`s to the list of enter states.
|
||||
*/
|
||||
addInitialStates: function() {
|
||||
var finalState = this.finalState, initialState;
|
||||
|
||||
while(true) {
|
||||
initialState = get(finalState, 'initialState') || 'start';
|
||||
finalState = get(finalState, 'states.' + initialState);
|
||||
|
||||
if (!finalState) { break; }
|
||||
|
||||
this.finalState = finalState;
|
||||
this.enterStates.push(finalState);
|
||||
this.contexts.push(undefined);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
@private
|
||||
|
||||
Remove any states that were added because the number of contexts
|
||||
exceeded the number of explicit enter states, but the context has
|
||||
not changed since the last time the state was entered.
|
||||
|
||||
@param {Ember.StateManager} manager passed in to look up the last
|
||||
context for a states
|
||||
*/
|
||||
removeUnchangedContexts: function(manager) {
|
||||
// Start from the beginning of the enter states. If the state was added
|
||||
// to the list during the context matching phase, make sure the context
|
||||
// has actually changed since the last time the state was entered.
|
||||
while (this.enterStates.length > 0) {
|
||||
if (this.enterStates[0] !== this.exitStates[0]) { break; }
|
||||
|
||||
if (this.enterStates.length === this.contexts.length) {
|
||||
if (manager.getStateMeta(this.enterStates[0], 'context') !== this.contexts[0]) { break; }
|
||||
this.contexts.shift();
|
||||
}
|
||||
|
||||
this.resolveState = this.enterStates.shift();
|
||||
this.exitStates.shift();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@class
|
||||
|
||||
|
@ -17305,18 +17500,29 @@ Ember.StateManager = Ember.State.extend(
|
|||
return possible;
|
||||
},
|
||||
|
||||
findStatesByPath: function(state, path) {
|
||||
/**
|
||||
@private
|
||||
|
||||
A state stores its child states in its `states` hash.
|
||||
This code takes a path like `posts.show` and looks
|
||||
up `origin.states.posts.states.show`.
|
||||
|
||||
It returns a list of all of the states from the
|
||||
origin, which is the list of states to call `enter`
|
||||
on.
|
||||
*/
|
||||
findStatesByPath: function(origin, path) {
|
||||
if (!path || path === "") { return undefined; }
|
||||
var r = path.split('.'),
|
||||
ret = [];
|
||||
|
||||
for (var i=0, len = r.length; i < len; i++) {
|
||||
var states = get(state, 'states');
|
||||
var states = get(origin, 'states');
|
||||
|
||||
if (!states) { return undefined; }
|
||||
|
||||
var s = get(states, r[i]);
|
||||
if (s) { state = s; ret.push(s); }
|
||||
if (s) { origin = s; ret.push(s); }
|
||||
else { return undefined; }
|
||||
}
|
||||
|
||||
|
@ -17330,122 +17536,130 @@ Ember.StateManager = Ember.State.extend(
|
|||
},
|
||||
|
||||
transitionTo: function(path, context) {
|
||||
// 1. Normalize arguments
|
||||
// 2. Ensure that we are in the correct state
|
||||
// 3. Map provided path to context objects and send
|
||||
// appropriate transitionEvent events
|
||||
|
||||
// XXX When is transitionTo called with no path
|
||||
if (Ember.empty(path)) { return; }
|
||||
|
||||
// The ES6 signature of this function is `path, ...contexts`
|
||||
var contexts = context ? Array.prototype.slice.call(arguments, 1) : [],
|
||||
currentState = get(this, 'currentState') || this,
|
||||
resolveState = currentState,
|
||||
exitStates = [],
|
||||
matchedContexts = [],
|
||||
cachedPath,
|
||||
enterStates,
|
||||
state,
|
||||
initialState,
|
||||
stateIdx,
|
||||
useContext;
|
||||
currentState = get(this, 'currentState') || this;
|
||||
|
||||
if (!context && (cachedPath = currentState.pathsCacheNoContext[path])) {
|
||||
// fast path
|
||||
// First, get the enter, exit and resolve states for the current state
|
||||
// and specified path. If possible, use an existing cache.
|
||||
var hash = this.contextFreeTransition(currentState, path);
|
||||
|
||||
exitStates = cachedPath.exitStates;
|
||||
enterStates = cachedPath.enterStates;
|
||||
resolveState = cachedPath.resolveState;
|
||||
} else {
|
||||
// normal path
|
||||
// Next, process the raw state information for the contexts passed in.
|
||||
var transition = new Transition(hash).normalize(this, contexts);
|
||||
|
||||
if ((cachedPath = currentState.pathsCache[path])) {
|
||||
// cache hit
|
||||
|
||||
exitStates = cachedPath.exitStates;
|
||||
enterStates = cachedPath.enterStates;
|
||||
resolveState = cachedPath.resolveState;
|
||||
} else {
|
||||
// cache miss
|
||||
|
||||
enterStates = this.findStatesByPath(currentState, path);
|
||||
|
||||
while (resolveState && !enterStates) {
|
||||
exitStates.unshift(resolveState);
|
||||
|
||||
resolveState = get(resolveState, 'parentState');
|
||||
if (!resolveState) {
|
||||
enterStates = this.findStatesByPath(this, path);
|
||||
if (!enterStates) {
|
||||
Ember.assert('Could not find state for path: "'+path+'"');
|
||||
return;
|
||||
}
|
||||
}
|
||||
enterStates = this.findStatesByPath(resolveState, path);
|
||||
}
|
||||
|
||||
while (enterStates.length > 0 && enterStates[0] === exitStates[0]) {
|
||||
resolveState = enterStates.shift();
|
||||
exitStates.shift();
|
||||
}
|
||||
|
||||
currentState.pathsCache[path] = {
|
||||
exitStates: exitStates,
|
||||
enterStates: enterStates,
|
||||
resolveState: resolveState
|
||||
};
|
||||
}
|
||||
|
||||
// Don't modify the cached versions
|
||||
enterStates = enterStates.slice();
|
||||
exitStates = exitStates.slice();
|
||||
|
||||
stateIdx = enterStates.length-1;
|
||||
while (contexts.length > 0) {
|
||||
if (stateIdx >= 0) {
|
||||
state = enterStates[stateIdx--];
|
||||
} else {
|
||||
state = enterStates[0] ? get(enterStates[0], 'parentState') : resolveState;
|
||||
if (!state) { throw "Cannot match all contexts to states"; }
|
||||
enterStates.unshift(state);
|
||||
exitStates.unshift(state);
|
||||
}
|
||||
|
||||
useContext = context && get(state, 'hasContext');
|
||||
matchedContexts.unshift(useContext ? contexts.pop() : null);
|
||||
}
|
||||
|
||||
state = enterStates[enterStates.length - 1] || resolveState;
|
||||
while(true) {
|
||||
initialState = get(state, 'initialState') || 'start';
|
||||
state = get(state, 'states.'+initialState);
|
||||
if (!state) { break; }
|
||||
enterStates.push(state);
|
||||
matchedContexts.push(undefined);
|
||||
}
|
||||
|
||||
while (enterStates.length > 0) {
|
||||
if (enterStates[0] !== exitStates[0]) { break; }
|
||||
|
||||
if (enterStates.length === matchedContexts.length) {
|
||||
if (this.getStateMeta(enterStates[0], 'context') !== matchedContexts[0]) { break; }
|
||||
matchedContexts.shift();
|
||||
}
|
||||
|
||||
resolveState = enterStates.shift();
|
||||
exitStates.shift();
|
||||
}
|
||||
}
|
||||
|
||||
this.enterState(exitStates, enterStates, enterStates[enterStates.length-1] || resolveState);
|
||||
this.triggerSetupContext(enterStates, matchedContexts);
|
||||
this.enterState(transition);
|
||||
this.triggerSetupContext(transition);
|
||||
},
|
||||
|
||||
triggerSetupContext: function(enterStates, contexts) {
|
||||
var offset = enterStates.length - contexts.length;
|
||||
contextFreeTransition: function(currentState, path) {
|
||||
var cache = currentState.pathsCache[path];
|
||||
if (cache) { return cache; }
|
||||
|
||||
var enterStates = this.findStatesByPath(currentState, path),
|
||||
exitStates = [],
|
||||
resolveState = currentState;
|
||||
|
||||
// Walk up the states. For each state, check whether a state matching
|
||||
// the `path` is nested underneath. This will find the closest
|
||||
// parent state containing `path`.
|
||||
//
|
||||
// This allows the user to pass in a relative path. For example, for
|
||||
// the following state hierarchy:
|
||||
//
|
||||
// | |root
|
||||
// | |- posts
|
||||
// | | |- show (* current)
|
||||
// | |- comments
|
||||
// | | |- show
|
||||
//
|
||||
// If the current state is `<root.posts.show>`, an attempt to
|
||||
// transition to `comments.show` will match `<root.comments.show>`.
|
||||
//
|
||||
// First, this code will look for root.posts.show.comments.show.
|
||||
// Next, it will look for root.posts.comments.show. Finally,
|
||||
// it will look for `root.comments.show`, and find the state.
|
||||
//
|
||||
// After this process, the following variables will exist:
|
||||
//
|
||||
// * resolveState: a common parent state between the current
|
||||
// and target state. In the above example, `<root>` is the
|
||||
// `resolveState`.
|
||||
// * enterStates: a list of all of the states represented
|
||||
// by the path from the `resolveState`. For example, for
|
||||
// the path `root.comments.show`, `enterStates` would have
|
||||
// `[<root.comments>, <root.comments.show>]`
|
||||
// * exitStates: a list of all of the states from the
|
||||
// `resolveState` to the `currentState`. In the above
|
||||
// example, `exitStates` would have
|
||||
// `[<root.posts>`, `<root.posts.show>]`.
|
||||
while (resolveState && !enterStates) {
|
||||
exitStates.unshift(resolveState);
|
||||
|
||||
resolveState = get(resolveState, 'parentState');
|
||||
if (!resolveState) {
|
||||
enterStates = this.findStatesByPath(this, path);
|
||||
if (!enterStates) {
|
||||
Ember.assert('Could not find state for path: "'+path+'"');
|
||||
return;
|
||||
}
|
||||
}
|
||||
enterStates = this.findStatesByPath(resolveState, path);
|
||||
}
|
||||
|
||||
// If the path contains some states that are parents of both the
|
||||
// current state and the target state, remove them.
|
||||
//
|
||||
// For example, in the following hierarchy:
|
||||
//
|
||||
// |- root
|
||||
// | |- post
|
||||
// | | |- index (* current)
|
||||
// | | |- show
|
||||
//
|
||||
// If the `path` is `root.post.show`, the three variables will
|
||||
// be:
|
||||
//
|
||||
// * resolveState: `<state manager>`
|
||||
// * enterStates: `[<root>, <root.post>, <root.post.show>]`
|
||||
// * exitStates: `[<root>, <root.post>, <root.post.index>]`
|
||||
//
|
||||
// The goal of this code is to remove the common states, so we
|
||||
// have:
|
||||
//
|
||||
// * resolveState: `<root.post>`
|
||||
// * enterStates: `[<root.post.show>]`
|
||||
// * exitStates: `[<root.post.index>]`
|
||||
//
|
||||
// This avoid unnecessary calls to the enter and exit transitions.
|
||||
while (enterStates.length > 0 && enterStates[0] === exitStates[0]) {
|
||||
resolveState = enterStates.shift();
|
||||
exitStates.shift();
|
||||
}
|
||||
|
||||
// Cache the enterStates, exitStates, and resolveState for the
|
||||
// current state and the `path`.
|
||||
var transitions = currentState.pathsCache[path] = {
|
||||
exitStates: exitStates,
|
||||
enterStates: enterStates,
|
||||
resolveState: resolveState
|
||||
};
|
||||
|
||||
return transitions;
|
||||
},
|
||||
|
||||
triggerSetupContext: function(transitions) {
|
||||
var contexts = transitions.contexts,
|
||||
offset = transitions.enterStates.length - contexts.length,
|
||||
enterStates = transitions.enterStates,
|
||||
transitionEvent = get(this, 'transitionEvent');
|
||||
|
||||
Ember.assert("More contexts provided than states", offset >= 0);
|
||||
|
||||
arrayForEach.call(enterStates, function(state, idx) {
|
||||
state.trigger(get(this, 'transitionEvent'), this, contexts[idx-offset]);
|
||||
state.trigger(transitionEvent, this, contexts[idx-offset]);
|
||||
}, this);
|
||||
},
|
||||
|
||||
|
@ -17460,21 +17674,20 @@ Ember.StateManager = Ember.State.extend(
|
|||
}
|
||||
},
|
||||
|
||||
enterState: function(exitStates, enterStates, state) {
|
||||
var log = this.enableLogging,
|
||||
stateManager = this;
|
||||
enterState: function(transition) {
|
||||
var log = this.enableLogging;
|
||||
|
||||
exitStates = exitStates.slice(0).reverse();
|
||||
var exitStates = transition.exitStates.slice(0).reverse();
|
||||
arrayForEach.call(exitStates, function(state) {
|
||||
state.trigger('exit', stateManager);
|
||||
});
|
||||
state.trigger('exit', this);
|
||||
}, this);
|
||||
|
||||
arrayForEach.call(enterStates, function(state) {
|
||||
arrayForEach.call(transition.enterStates, function(state) {
|
||||
if (log) { Ember.Logger.log("STATEMANAGER: Entering " + get(state, 'path')); }
|
||||
state.trigger('enter', stateManager);
|
||||
});
|
||||
state.trigger('enter', this);
|
||||
}, this);
|
||||
|
||||
set(this, 'currentState', state);
|
||||
set(this, 'currentState', transition.finalState);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -18063,9 +18276,9 @@ var get = Ember.get, set = Ember.set;
|
|||
|
||||
## Adding Routes to a Router
|
||||
The `initialState` property of Ember.Router instances is named `root`. The state stored in this
|
||||
property should be a subclass of Ember.Route. The `root` route should itself have states that are
|
||||
also subclasses of Ember.Route and have `route` properties describing the URL pattern you would
|
||||
like to detect.
|
||||
property must be a subclass of Ember.Route. The `root` route acts as the container for the
|
||||
set of routable states but is not routable itself. It should have states that are also subclasses
|
||||
of Ember.Route which each have a `route` property describing the URL pattern you would like to detect.
|
||||
|
||||
App = Ember.Application.create({
|
||||
Router: Ember.Router.extend({
|
||||
|
@ -18107,6 +18320,46 @@ var get = Ember.get, set = Ember.set;
|
|||
'root.bRoute' ('/alphabeta') and transition the router first to the state named 'root' and
|
||||
then to the substate 'bRoute'.
|
||||
|
||||
## Adding Nested Routes to a Router
|
||||
Routes can contain nested subroutes each with their own `route` property describing the nested
|
||||
portion of the URL they would like to detect and handle. Router, like all instances of StateManager,
|
||||
cannot call `transitonTo` with an intermediary state. To avoid transitioning the Router into an
|
||||
intermediary state when detecting URLs, a Route with nested routes must define both a base `route`
|
||||
property for itself and a child Route with a `route` property of `'/'` which will be transitioned
|
||||
to when the base route is detected in the URL:
|
||||
|
||||
Given the following application code:
|
||||
|
||||
App = Ember.Application.create({
|
||||
Router: Ember.Router.extend({
|
||||
root: Ember.Route.extend({
|
||||
aRoute: Ember.Route.extend({
|
||||
route: '/theBaseRouteForThisSet',
|
||||
|
||||
indexSubRoute: Ember.Route.extend({
|
||||
route: '/',
|
||||
}),
|
||||
|
||||
subRouteOne: Ember.Route.extend({
|
||||
route: '/subroute1
|
||||
}),
|
||||
|
||||
subRouteTwo: Ember.Route.extend({
|
||||
route: '/subRoute2'
|
||||
})
|
||||
|
||||
})
|
||||
})
|
||||
})
|
||||
});
|
||||
App.initialize();
|
||||
|
||||
When the application is loaded at '/theBaseRouteForThisSet' the Router will transition to the route
|
||||
at path 'root.aRoute' and then transition to state 'indexSubRoute'.
|
||||
|
||||
When the application is loaded at '/theBaseRouteForThisSet/subRoute1' the Router will transition to
|
||||
the route at path 'root.aRoute' and then transition to state 'subRouteOne'.
|
||||
|
||||
## Route Transition Events
|
||||
Transitioning between Ember.Route instances (including the transition into the detected
|
||||
route when loading the application) triggers the same transition events as state transitions for
|
||||
|
@ -18337,7 +18590,7 @@ var get = Ember.get, set = Ember.set;
|
|||
|
||||
<script type="text/x-handlebars" data-template-name="photos">
|
||||
{{#each photo in controller}}
|
||||
<h1><a {{action showPhoto context="photo"}}>{{title}}</a></h1>
|
||||
<h1><a {{action showPhoto photo}}>{{title}}</a></h1>
|
||||
{{/each}}
|
||||
</script>
|
||||
|
||||
|
@ -21004,27 +21257,39 @@ Ember.Handlebars.registerHelper('template', function(name, options) {
|
|||
|
||||
|
||||
(function() {
|
||||
var EmberHandlebars = Ember.Handlebars, getPath = EmberHandlebars.getPath, get = Ember.get;
|
||||
var EmberHandlebars = Ember.Handlebars,
|
||||
getPath = EmberHandlebars.getPath,
|
||||
get = Ember.get,
|
||||
a_slice = Array.prototype.slice;
|
||||
|
||||
var ActionHelper = EmberHandlebars.ActionHelper = {
|
||||
registeredActions: {}
|
||||
};
|
||||
|
||||
ActionHelper.registerAction = function(actionName, eventName, target, view, context, link) {
|
||||
ActionHelper.registerAction = function(actionName, options) {
|
||||
var actionId = (++Ember.$.uuid).toString();
|
||||
|
||||
ActionHelper.registeredActions[actionId] = {
|
||||
eventName: eventName,
|
||||
eventName: options.eventName,
|
||||
handler: function(event) {
|
||||
if (link && (event.button !== 0 || event.shiftKey || event.metaKey || event.altKey || event.ctrlKey)) {
|
||||
var modifier = event.shiftKey || event.metaKey || event.altKey || event.ctrlKey,
|
||||
secondaryClick = event.which > 1, // IE9 may return undefined
|
||||
nonStandard = modifier || secondaryClick;
|
||||
|
||||
if (options.link && nonStandard) {
|
||||
// Allow the browser to handle special link clicks normally
|
||||
return;
|
||||
}
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
event.view = view;
|
||||
event.context = context;
|
||||
event.view = options.view;
|
||||
|
||||
if (options.hasOwnProperty('context')) {
|
||||
event.context = options.context;
|
||||
}
|
||||
|
||||
var target = options.target;
|
||||
|
||||
// Check for StateManager (or compatible object)
|
||||
if (target.isState && typeof target.send === 'function') {
|
||||
|
@ -21036,7 +21301,7 @@ ActionHelper.registerAction = function(actionName, eventName, target, view, cont
|
|||
}
|
||||
};
|
||||
|
||||
view.on('willRerender', function() {
|
||||
options.view.on('willRerender', function() {
|
||||
delete ActionHelper.registeredActions[actionId];
|
||||
});
|
||||
|
||||
|
@ -21045,14 +21310,16 @@ ActionHelper.registerAction = function(actionName, eventName, target, view, cont
|
|||
|
||||
/**
|
||||
The `{{action}}` helper registers an HTML element within a template for
|
||||
DOM event handling. User interaction with that element will call the method
|
||||
on the template's associated `Ember.View` instance that has the same name
|
||||
as the first provided argument to `{{action}}`:
|
||||
DOM event handling and forwards that interaction to the Application's router,
|
||||
the template's `Ember.View` instance, or supplied `target` option (see 'Specifiying a Target').
|
||||
|
||||
User interaction with that element will invoke the supplied action name on
|
||||
the appropriate target.
|
||||
|
||||
Given the following Handlebars template on the page
|
||||
|
||||
<script type="text/x-handlebars" data-template-name='a-template'>
|
||||
<div {{action "anActionName"}}>
|
||||
<div {{action anActionName}}>
|
||||
click me
|
||||
</div>
|
||||
</script>
|
||||
|
@ -21088,15 +21355,51 @@ ActionHelper.registerAction = function(actionName, eventName, target, view, cont
|
|||
handler.
|
||||
|
||||
If you need the default handler to trigger you should either register your
|
||||
own event handler, or use event methods on your view class.
|
||||
own event handler, or use event methods on your view class. See Ember.View
|
||||
'Responding to Browser Events' for more information.
|
||||
|
||||
### Specifying an Action Target
|
||||
### Specifying DOM event type
|
||||
|
||||
A `target` option can be provided to change which object will receive the
|
||||
method call. This option must be a string representing a path to an object:
|
||||
By default the `{{action}}` helper registers for DOM `click` events. You can
|
||||
supply an `on` option to the helper to specify a different DOM event name:
|
||||
|
||||
<script type="text/x-handlebars" data-template-name='a-template'>
|
||||
<div {{action "anActionName" target="MyApplication.someObject"}}>
|
||||
<div {{action anActionName on="doubleClick"}}>
|
||||
click me
|
||||
</div>
|
||||
</script>
|
||||
|
||||
See Ember.View 'Responding to Browser Events' for a list of
|
||||
acceptable DOM event names.
|
||||
|
||||
Because `{{action}}` depends on Ember's event dispatch system it will only
|
||||
function if an `Ember.EventDispatcher` instance is available. An
|
||||
`Ember.EventDispatcher` instance will be created when a new
|
||||
`Ember.Application` is created. Having an instance of `Ember.Application`
|
||||
will satisfy this requirement.
|
||||
|
||||
|
||||
### Specifying a Target
|
||||
There are several possible target objects for `{{action}}` helpers:
|
||||
|
||||
In a typical `Ember.Router`-backed Application where views are managed
|
||||
through use of the `{{outlet}}` helper, actions will be forwarded to the
|
||||
current state of the Applications's Router. See Ember.Router 'Responding
|
||||
to User-initiated Events' for more information.
|
||||
|
||||
If you manaully set the `target` property on the controller of a template's
|
||||
`Ember.View` instance, the specifed `controller.target` will become the target
|
||||
for any actions. Likely custom values for a controller's `target` are the
|
||||
controller itself or a StateManager other than the Application's Router.
|
||||
|
||||
If the templates's view lacks a controller property the view itself is the target.
|
||||
|
||||
Finally, a `target` option can be provided to the helper to change which object
|
||||
will receive the method call. This option must be a string representing a
|
||||
path to an object:
|
||||
|
||||
<script type="text/x-handlebars" data-template-name='a-template'>
|
||||
<div {{action anActionName target="MyApplication.someObject"}}>
|
||||
click me
|
||||
</div>
|
||||
</script>
|
||||
|
@ -21110,7 +21413,7 @@ ActionHelper.registerAction = function(actionName, eventName, target, view, cont
|
|||
a target:
|
||||
|
||||
<script type="text/x-handlebars" data-template-name='a-template'>
|
||||
<div {{action "anActionName" target="parentView"}}>
|
||||
<div {{action anActionName target="parentView"}}>
|
||||
click me
|
||||
</div>
|
||||
</script>
|
||||
|
@ -21127,7 +21430,7 @@ ActionHelper.registerAction = function(actionName, eventName, target, view, cont
|
|||
action name an error will be thrown.
|
||||
|
||||
<script type="text/x-handlebars" data-template-name='a-template'>
|
||||
<div {{action "aMethodNameThatIsMissing"}}>
|
||||
<div {{action aMethodNameThatIsMissing}}>
|
||||
click me
|
||||
</div>
|
||||
</script>
|
||||
|
@ -21146,34 +21449,15 @@ ActionHelper.registerAction = function(actionName, eventName, target, view, cont
|
|||
Will throw `Uncaught TypeError: Cannot call method 'call' of undefined` when
|
||||
"click me" is clicked.
|
||||
|
||||
### Specifying DOM event type
|
||||
|
||||
By default the `{{action}}` helper registers for DOM `click` events. You can
|
||||
supply an `on` option to the helper to specify a different DOM event name:
|
||||
|
||||
<script type="text/x-handlebars" data-template-name='a-template'>
|
||||
<div {{action "aMethodNameThatIsMissing" on="doubleClick"}}>
|
||||
click me
|
||||
</div>
|
||||
</script>
|
||||
|
||||
See `Ember.EventDispatcher` for a list of acceptable DOM event names.
|
||||
|
||||
Because `{{action}}` depends on Ember's event dispatch system it will only
|
||||
function if an `Ember.EventDispatcher` instance is available. An
|
||||
`Ember.EventDispatcher` instance will be created when a new
|
||||
`Ember.Application` is created. Having an instance of `Ember.Application`
|
||||
will satisfy this requirement.
|
||||
|
||||
### Specifying a context
|
||||
|
||||
By default the `{{action}}` helper passes the current Handlebars context
|
||||
along in the `jQuery.Event` object. You may specify an alternative object to
|
||||
along in the `jQuery.Event` object. You may specify an alternate object to
|
||||
pass as the context by providing a property path:
|
||||
|
||||
<script type="text/x-handlebars" data-template-name='a-template'>
|
||||
{{#each person in people}}
|
||||
<div {{action "edit" context="person"}}>
|
||||
<div {{action edit person}}>
|
||||
click me
|
||||
</div>
|
||||
{{/each}}
|
||||
|
@ -21181,15 +21465,23 @@ ActionHelper.registerAction = function(actionName, eventName, target, view, cont
|
|||
|
||||
@name Handlebars.helpers.action
|
||||
@param {String} actionName
|
||||
@param {Object...} contexts
|
||||
@param {Hash} options
|
||||
*/
|
||||
EmberHandlebars.registerHelper('action', function(actionName, options) {
|
||||
EmberHandlebars.registerHelper('action', function(actionName) {
|
||||
var options = arguments[arguments.length - 1],
|
||||
contexts = a_slice.call(arguments, 1, -1);
|
||||
|
||||
var hash = options.hash,
|
||||
eventName = hash.on || "click",
|
||||
view = options.data.view,
|
||||
target, context, controller, link;
|
||||
|
||||
view = get(view, 'concreteView');
|
||||
// create a hash to pass along to registerAction
|
||||
var action = {
|
||||
eventName: hash.on || "click"
|
||||
};
|
||||
|
||||
action.view = view = get(view, 'concreteView');
|
||||
|
||||
if (hash.target) {
|
||||
target = getPath(this, hash.target, options);
|
||||
|
@ -21197,19 +21489,22 @@ EmberHandlebars.registerHelper('action', function(actionName, options) {
|
|||
target = get(controller, 'target');
|
||||
}
|
||||
|
||||
target = target || view;
|
||||
action.target = target = target || view;
|
||||
|
||||
context = hash.context ? getPath(this, hash.context, options) : options.contexts[0];
|
||||
// TODO: Support multiple contexts
|
||||
if (contexts.length) {
|
||||
action.context = context = getPath(this, contexts[0], options);
|
||||
}
|
||||
|
||||
var output = [], url;
|
||||
|
||||
if (hash.href && target.urlForEvent) {
|
||||
url = target.urlForEvent(actionName, context);
|
||||
output.push('href="' + url + '"');
|
||||
link = true;
|
||||
action.link = true;
|
||||
}
|
||||
|
||||
var actionId = ActionHelper.registerAction(actionName, eventName, target, view, context, link);
|
||||
var actionId = ActionHelper.registerAction(actionName, action);
|
||||
output.push('data-ember-action="' + actionId + '"');
|
||||
|
||||
return new EmberHandlebars.SafeString(output.join(" "));
|
||||
|
@ -22229,8 +22524,8 @@ Ember.onLoad('application', bootstrap);
|
|||
|
||||
})();
|
||||
|
||||
// Version: v0.9.8.1-658-gd4a9e46
|
||||
// Last commit: d4a9e46 (2012-07-21 19:16:48 -0700)
|
||||
// Version: v0.9.8.1-672-gd7e24ac
|
||||
// Last commit: d7e24ac (2012-07-26 09:35:30 -0700)
|
||||
|
||||
|
||||
(function() {
|
||||
|
@ -22492,7 +22787,7 @@ DS.ManyArrayStateManager = Ember.StateManager.extend({
|
|||
|
||||
|
||||
(function() {
|
||||
var get = Ember.get, set = Ember.set, set = Ember.set;
|
||||
var get = Ember.get, set = Ember.set;
|
||||
|
||||
DS.ManyArray = DS.RecordArray.extend({
|
||||
init: function() {
|
||||
|
@ -25987,31 +26282,35 @@ DS.FixtureAdapter = DS.Adapter.extend({
|
|||
find: function(store, type, id) {
|
||||
var fixtures = this.fixturesForType(type);
|
||||
|
||||
Ember.assert("Unable to find fixtures for model type "+type.toString(), !!fixtures);
|
||||
|
||||
if (fixtures) {
|
||||
fixtures = fixtures.findProperty('id', id);
|
||||
}
|
||||
|
||||
Ember.assert("Unable to find fixtures for model type "+type.toString(), !!fixtures);
|
||||
|
||||
this.simulateRemoteCall(function() {
|
||||
store.load(type, fixtures);
|
||||
}, store, type);
|
||||
if (fixtures) {
|
||||
this.simulateRemoteCall(function() {
|
||||
store.load(type, fixtures);
|
||||
}, store, type);
|
||||
}
|
||||
},
|
||||
|
||||
findMany: function(store, type, ids) {
|
||||
var fixtures = this.fixturesForType(type);
|
||||
|
||||
Ember.assert("Unable to find fixtures for model type "+type.toString(), !!fixtures);
|
||||
|
||||
if (fixtures) {
|
||||
fixtures = fixtures.filter(function(item) {
|
||||
return ids.indexOf(item.id) !== -1;
|
||||
});
|
||||
}
|
||||
|
||||
Ember.assert("Unable to find fixtures for model type "+type.toString(), !!fixtures);
|
||||
|
||||
this.simulateRemoteCall(function() {
|
||||
store.loadMany(type, fixtures);
|
||||
}, store, type);
|
||||
if (fixtures) {
|
||||
this.simulateRemoteCall(function() {
|
||||
store.loadMany(type, fixtures);
|
||||
}, store, type);
|
||||
}
|
||||
},
|
||||
|
||||
findAll: function(store, type) {
|
||||
|
@ -26027,13 +26326,15 @@ DS.FixtureAdapter = DS.Adapter.extend({
|
|||
findQuery: function(store, type, query, array) {
|
||||
var fixtures = this.fixturesForType(type);
|
||||
|
||||
fixtures = this.queryFixtures(fixtures, query);
|
||||
|
||||
Ember.assert("Unable to find fixtures for model type "+type.toString(), !!fixtures);
|
||||
|
||||
this.simulateRemoteCall(function() {
|
||||
array.load(fixtures);
|
||||
}, store, type);
|
||||
fixtures = this.queryFixtures(fixtures, query);
|
||||
|
||||
if (fixtures) {
|
||||
this.simulateRemoteCall(function() {
|
||||
array.load(fixtures);
|
||||
}, store, type);
|
||||
}
|
||||
},
|
||||
|
||||
createRecord: function(store, type, record) {
|
||||
|
@ -26274,7 +26575,9 @@ DS.RESTAdapter = DS.Adapter.extend({
|
|||
data: query,
|
||||
success: function(json) {
|
||||
this.sideload(store, type, json, plural);
|
||||
recordArray.load(json[plural]);
|
||||
setTimeout(function() {
|
||||
recordArray.load(json[plural]);
|
||||
}, 10);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue
Block a user