diff --git a/Gemfile b/Gemfile
index 61acfa3d2e1..abf697bb3b9 100644
--- a/Gemfile
+++ b/Gemfile
@@ -48,7 +48,7 @@ gem 'onebox'
gem 'http_accept_language', '~>2.0.5', require: false
gem 'ember-rails', '0.18.5'
-gem 'ember-source', '1.12.2'
+gem 'ember-source', '2.4.6'
gem 'barber'
gem 'babel-transpiler'
diff --git a/Gemfile.lock b/Gemfile.lock
index 9888729c673..153c7d071fc 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -81,9 +81,9 @@ GEM
domain_name (0.5.25)
unf (>= 0.0.5, < 1.0.0)
email_reply_trimmer (0.1.6)
- ember-data-source (1.0.0.beta.16.1)
- ember-source (~> 1.8)
- ember-handlebars-template (0.7.3)
+ ember-data-source (2.2.1)
+ ember-source (>= 1.8, < 3.0)
+ ember-handlebars-template (0.7.4)
barber (>= 0.11.0)
sprockets (>= 3.3, < 4)
ember-rails (0.18.5)
@@ -93,7 +93,7 @@ GEM
ember-source (>= 1.1.0)
jquery-rails (>= 1.0.17)
railties (>= 3.1)
- ember-source (1.12.2)
+ ember-source (2.4.6)
erubis (2.7.0)
eventmachine (1.2.0.1)
excon (0.53.0)
@@ -137,8 +137,8 @@ GEM
image_size (1.4.1)
in_threads (1.3.1)
jmespath (1.3.1)
- jquery-rails (4.0.5)
- rails-dom-testing (~> 1.0)
+ jquery-rails (4.2.1)
+ rails-dom-testing (>= 1, < 3)
railties (>= 4.2.0)
thor (>= 0.14, < 2.0)
json (1.8.3)
@@ -413,7 +413,7 @@ DEPENDENCIES
discourse_fastimage (= 2.0.3)
email_reply_trimmer (= 0.1.6)
ember-rails (= 0.18.5)
- ember-source (= 1.12.2)
+ ember-source (= 2.4.6)
excon
execjs
fabrication (= 2.9.8)
diff --git a/app/assets/javascripts/discourse/helpers/custom-html.js.es6 b/app/assets/javascripts/discourse/helpers/custom-html.js.es6
index 4828ae057ec..29b98c46cf6 100644
--- a/app/assets/javascripts/discourse/helpers/custom-html.js.es6
+++ b/app/assets/javascripts/discourse/helpers/custom-html.js.es6
@@ -1,4 +1,5 @@
-import { registerHelper } from 'discourse-common/lib/helpers';
+const { registerKeyword } = Ember.__loader.require("ember-htmlbars/keywords");
+const { internal } = Ember.__loader.require('htmlbars-runtime');
import PreloadStore from 'preload-store';
let _customizations = {};
@@ -24,15 +25,35 @@ export function setCustomHTML(key, html) {
_customizations[key] = html;
}
-registerHelper('custom-html', function([id, contextString], hash, options, env) {
- const html = getCustomHTML(id);
- if (html) { return html; }
+registerKeyword('custom-html', {
+ setupState(state, env, scope, params) {
+ return { htmlKey: env.hooks.getValue(params[0]) };
+ },
- if (env) {
- const target = (env || contextString);
- const container = target.container || target.data.view.container;
- if (container.lookup('template:' + id)) {
- return env.helpers.partial.helperFunction.apply(this, arguments);
+ render(renderNode, env, scope, params, hash, template, inverse, visitor) {
+ let state = renderNode.getState();
+ if (!state.htmlKey) { return true; }
+
+ const html = getCustomHTML(state.htmlKey);
+ if (html) {
+ const htmlHash = { html };
+ env.hooks.component(renderNode,
+ env,
+ scope,
+ 'custom-html-container',
+ params,
+ htmlHash,
+ { default: template, inverse },
+ visitor);
+ return true;
}
+
+ template = env.owner.lookup(`template:${state.htmlKey}`);
+ if (template) {
+ internal.hostBlock(renderNode, env, scope, template.raw, null, null, visitor, function(options) {
+ options.templates.template.yield();
+ });
+ }
+ return true;
}
});
diff --git a/app/assets/javascripts/discourse/helpers/plugin-outlet.js.es6 b/app/assets/javascripts/discourse/helpers/plugin-outlet.js.es6
index b56ea69f080..3f00baed783 100644
--- a/app/assets/javascripts/discourse/helpers/plugin-outlet.js.es6
+++ b/app/assets/javascripts/discourse/helpers/plugin-outlet.js.es6
@@ -23,24 +23,15 @@
Will insert Hello World at that point in the template.
- Optionally you can also define a view class for the outlet as:
-
- plugins/hello/assets/javascripts/discourse/views/connectors/evil-trout/hello.js.es6
-
- And it will be wired up automatically.
-
## Disabling
If a plugin returns a disabled status, the outlets will not be wired up for it.
The list of disabled plugins is returned via the `Site` singleton.
**/
-import { registerHelper } from 'discourse-common/lib/helpers';
-
-let _connectorCache, _rawCache;
+let _connectorCache, _rawCache, _templateCache;
function findOutlets(collection, callback) {
-
const disabledPlugins = Discourse.Site.currentProp('disabled_plugins') || [];
Object.keys(collection).forEach(function(res) {
@@ -62,6 +53,7 @@ function findOutlets(collection, callback) {
}
export function clearCache() {
+ _templateCache = null;
_connectorCache = null;
_rawCache = null;
}
@@ -69,57 +61,32 @@ export function clearCache() {
function buildConnectorCache() {
_connectorCache = {};
_rawCache = {};
-
- const uniqueViews = {};
- findOutlets(requirejs._eak_seen, function(outletName, resource, uniqueName) {
- _connectorCache[outletName] = _connectorCache[outletName] || [];
-
- const viewClass = require(resource, null, null, true).default;
- uniqueViews[uniqueName] = viewClass;
- _connectorCache[outletName].pushObject(viewClass);
- });
+ _templateCache = [];
findOutlets(Ember.TEMPLATES, function(outletName, resource, uniqueName) {
- const mixin = {templateName: resource.replace('javascripts/', '')};
- let viewClass = uniqueViews[uniqueName];
-
- if (viewClass) {
- // We are going to add it back with the proper template
- _connectorCache[outletName] = _connectorCache[outletName] || [];
- _connectorCache[outletName].removeObject(viewClass);
- } else {
- if (!/\.raw$/.test(uniqueName)) {
- viewClass = Ember.View.extend({ classNames: [outletName + '-outlet', uniqueName] });
- }
- }
-
- if (viewClass) {
- _connectorCache[outletName] = _connectorCache[outletName] || [];
- _connectorCache[outletName].pushObject(viewClass.extend(mixin));
- } else {
- // we have a raw template
+ if (/\.raw$/.test(uniqueName)) {
if (!_rawCache[outletName]) {
_rawCache[outletName] = [];
}
-
_rawCache[outletName].push(Ember.TEMPLATES[resource]);
+ } else {
+ _connectorCache[outletName] = _connectorCache[outletName] || [];
+
+ _connectorCache[outletName].push({
+ templateName: resource.replace('javascripts/', ''),
+ template: Ember.TEMPLATES[resource],
+ classNames: `${outletName}-outlet ${uniqueName}`
+ });
}
});
-}
-
-var _viewInjections;
-function viewInjections(container) {
- if (_viewInjections) { return _viewInjections; }
-
- const injections = container._registry.getTypeInjections('view');
-
- _viewInjections = {};
- injections.forEach(function(i) {
- _viewInjections[i.property] = container.lookup(i.fullName);
+ Object.keys(_connectorCache).forEach(outletName => {
+ const connector = _connectorCache[outletName];
+ (connector || []).forEach(s => {
+ _templateCache.push(s.template);
+ s.templateId = parseInt(_templateCache.length - 1);
+ });
});
-
- return _viewInjections;
}
// unbound version of outlets, only has a template
@@ -136,41 +103,50 @@ Handlebars.registerHelper('plugin-outlet', function(name) {
return new Handlebars.SafeString(output.join(""));
}
-
});
-registerHelper('plugin-outlet', function([connectionName], hash, options, env) {
- if (!_connectorCache) { buildConnectorCache(); }
+const { registerKeyword } = Ember.__loader.require("ember-htmlbars/keywords");
+const { internal } = Ember.__loader.require('htmlbars-runtime');
- if (_connectorCache[connectionName]) {
- const childViews = _connectorCache[connectionName];
+registerKeyword('plugin-outlet', {
+ setupState(state, env, scope, params) {
+ if (!_connectorCache) { buildConnectorCache(); }
+ return { outletName: env.hooks.getValue(params[0]) };
+ },
- // If there is more than one view, create a container. Otherwise
- // just shove it in.
- const viewClass = (childViews.length > 1) ? Ember.ContainerView : childViews[0];
+ render(renderNode, env, scope, params, hash, template, inverse, visitor) {
+ let state = renderNode.getState();
+ if (!state.outletName) { return true; }
+ const connector = _connectorCache[state.outletName];
+ if (!connector || connector.length === 0) { return true; }
- // TODO: Figure out how to do this without a container view
- if (env) {
- const newHash = $.extend({}, viewInjections(env.data.view.container));
- if (hash.tagName) { newHash.tagName = hash.tagName; }
+ const listTemplate = Ember.TEMPLATES['outlet-list'];
+ listTemplate.raw.locals = ['templateId', 'outletClasses', 'tagName'];
- // we don't need the default template since we have a connector
- delete options.fn;
- delete options.template;
- env.helpers.view.helperFunction.call(this, [viewClass], newHash, options, env);
-
- const cvs = env.data.view._childViews;
- if (childViews.length > 1 && cvs && cvs.length) {
- const inserted = cvs[cvs.length-1];
- if (inserted) {
- childViews.forEach(function(cv) {
- inserted.pushObject(cv.create());
- });
- }
- }
- }
+ internal.hostBlock(renderNode, env, scope, listTemplate.raw, null, null, visitor, function(options) {
+ connector.forEach(source => {
+ const tid = source.templateId;
+ options.templates.template.yieldItem(`d-outlet-${tid}`, [
+ tid,
+ source.classNames,
+ hash.tagName || 'div'
+ ]);
+ });
+ });
+ return true;
}
});
-// No longer used
-export function rewire() { }
+registerKeyword('connector', function(morph, env, scope, params, hash, template, inverse, visitor) {
+ template = _templateCache[parseInt(env.hooks.getValue(hash.templateId))];
+
+ env.hooks.component(morph,
+ env,
+ scope,
+ 'connector-container',
+ params,
+ hash,
+ { default: template.raw, inverse },
+ visitor);
+ return true;
+});
diff --git a/app/assets/javascripts/discourse/templates/components/custom-html-container.hbs b/app/assets/javascripts/discourse/templates/components/custom-html-container.hbs
new file mode 100644
index 00000000000..81eb3c4f9b0
--- /dev/null
+++ b/app/assets/javascripts/discourse/templates/components/custom-html-container.hbs
@@ -0,0 +1 @@
+{{html}}
diff --git a/app/assets/javascripts/discourse/templates/outlet-list.hbs b/app/assets/javascripts/discourse/templates/outlet-list.hbs
new file mode 100644
index 00000000000..a58e2acd7e7
--- /dev/null
+++ b/app/assets/javascripts/discourse/templates/outlet-list.hbs
@@ -0,0 +1 @@
+{{connector templateId=(unbound templateId) class=(unbound outletClasses) tagName=(unbound tagName)}}
diff --git a/vendor/assets/javascripts/ember-template-compiler.js b/vendor/assets/javascripts/ember-template-compiler.js
deleted file mode 100644
index cb84221ec07..00000000000
--- a/vendor/assets/javascripts/ember-template-compiler.js
+++ /dev/null
@@ -1,17119 +0,0 @@
-/*!
- * @overview Ember - JavaScript Application Framework
- * @copyright Copyright 2011-2015 Tilde Inc. and contributors
- * Portions Copyright 2006-2011 Strobe Inc.
- * Portions Copyright 2008-2011 Apple Inc. All rights reserved.
- * @license Licensed under MIT license
- * See https://raw.github.com/emberjs/ember.js/master/LICENSE
- * @version 1.12.2
- */
-
-(function() {
-var enifed, requireModule, eriuqer, requirejs, Ember;
-var mainContext = this;
-
-(function() {
-
- Ember = this.Ember = this.Ember || {};
- if (typeof Ember === 'undefined') { Ember = {}; };
-
- if (typeof Ember.__loader === 'undefined') {
- var registry = {};
- var seen = {};
-
- enifed = function(name, deps, callback) {
- var value = { };
-
- if (!callback) {
- value.deps = [];
- value.callback = deps;
- } else {
- value.deps = deps;
- value.callback = callback;
- }
-
- registry[name] = value;
- };
-
- requirejs = eriuqer = requireModule = function(name) {
- return internalRequire(name, null);
- }
-
- function internalRequire(name, referrerName) {
- var exports = seen[name];
-
- if (exports !== undefined) {
- return exports;
- }
-
- exports = seen[name] = {};
-
- if (!registry[name]) {
- if (referrerName) {
- throw new Error('Could not find module ' + name + ' required by: ' + referrerName);
- } else {
- throw new Error('Could not find module ' + name);
- }
- }
-
- var mod = registry[name];
- var deps = mod.deps;
- var callback = mod.callback;
- var reified = [];
- var length = deps.length;
-
- for (var i=0; i\s*\(([^\)]+)\)/gm, '{anonymous}($1)').split('\n');
- stack.shift();
- } else {
- // Firefox
- stack = error.stack.replace(/(?:\n@:0)?\s+$/m, '').replace(/^\(/gm, '{anonymous}(').split('\n');
- }
-
- stackStr = "\n " + stack.slice(2).join("\n ");
- message = message + stackStr;
- }
-
- Logger['default'].warn("DEPRECATION: " + message);
- };
-
- /**
- Alias an old, deprecated method with its new counterpart.
-
- Display a deprecation warning with the provided message and a stack trace
- (Chrome and Firefox only) when the assigned method is called.
-
- Ember build tools will not remove calls to `Ember.deprecateFunc()`, though
- no warnings will be shown in production.
-
- ```javascript
- Ember.oldMethod = Ember.deprecateFunc('Please use the new, updated method', Ember.newMethod);
- ```
-
- @method deprecateFunc
- @param {String} message A description of the deprecation.
- @param {Function} func The new function called to replace its deprecated counterpart.
- @return {Function} a new function that wrapped the original function with a deprecation warning
- */
- Ember['default'].deprecateFunc = function (message, func) {
- return function () {
- Ember['default'].deprecate(message);
- return func.apply(this, arguments);
- };
- };
-
- /**
- Run a function meant for debugging. Ember build tools will remove any calls to
- `Ember.runInDebug()` when doing a production build.
-
- ```javascript
- Ember.runInDebug(function() {
- Ember.Handlebars.EachView.reopen({
- didInsertElement: function() {
- console.log('I\'m happy');
- }
- });
- });
- ```
-
- @method runInDebug
- @param {Function} func The function to be executed.
- @since 1.5.0
- */
- Ember['default'].runInDebug = function (func) {
- func();
- };
-
- /**
- Will call `Ember.warn()` if ENABLE_ALL_FEATURES, ENABLE_OPTIONAL_FEATURES, or
- any specific FEATURES flag is truthy.
-
- This method is called automatically in debug canary builds.
-
- @private
- @method _warnIfUsingStrippedFeatureFlags
- @return {void}
- */
-
- function _warnIfUsingStrippedFeatureFlags(FEATURES, featuresWereStripped) {
- if (featuresWereStripped) {
- Ember['default'].warn('Ember.ENV.ENABLE_ALL_FEATURES is only available in canary builds.', !Ember['default'].ENV.ENABLE_ALL_FEATURES);
- Ember['default'].warn('Ember.ENV.ENABLE_OPTIONAL_FEATURES is only available in canary builds.', !Ember['default'].ENV.ENABLE_OPTIONAL_FEATURES);
-
- for (var key in FEATURES) {
- if (FEATURES.hasOwnProperty(key) && key !== 'isEnabled') {
- Ember['default'].warn('FEATURE["' + key + '"] is set as enabled, but FEATURE flags are only available in canary builds.', !FEATURES[key]);
- }
- }
- }
- }
-
- if (!Ember['default'].testing) {
- // Complain if they're using FEATURE flags in builds other than canary
- Ember['default'].FEATURES['features-stripped-test'] = true;
- var featuresWereStripped = true;
-
-
- delete Ember['default'].FEATURES['features-stripped-test'];
- _warnIfUsingStrippedFeatureFlags(Ember['default'].ENV.FEATURES, featuresWereStripped);
-
- // Inform the developer about the Ember Inspector if not installed.
- var isFirefox = typeof InstallTrigger !== 'undefined';
- var isChrome = environment['default'].isChrome;
-
- if (typeof window !== 'undefined' && (isFirefox || isChrome) && window.addEventListener) {
- window.addEventListener("load", function () {
- if (document.documentElement && document.documentElement.dataset && !document.documentElement.dataset.emberExtension) {
- var downloadURL;
-
- if (isChrome) {
- downloadURL = 'https://chrome.google.com/webstore/detail/ember-inspector/bmdblncegkenkacieihfhpjfppoconhi';
- } else if (isFirefox) {
- downloadURL = 'https://addons.mozilla.org/en-US/firefox/addon/ember-inspector/';
- }
-
- Ember['default'].debug('For more advanced debugging, install the Ember Inspector from ' + downloadURL);
- }
- }, false);
- }
- }
-
- /*
- We are transitioning away from `ember.js` to `ember.debug.js` to make
- it much clearer that it is only for local development purposes.
-
- This flag value is changed by the tooling (by a simple string replacement)
- so that if `ember.js` (which must be output for backwards compat reasons) is
- used a nice helpful warning message will be printed out.
- */
- var runningNonEmberDebugJS = false;
- if (runningNonEmberDebugJS) {
- Ember['default'].warn('Please use `ember.debug.js` instead of `ember.js` for development and debugging.');
- }
-
- exports.runningNonEmberDebugJS = runningNonEmberDebugJS;
-
-});
-enifed('ember-metal', ['exports', 'ember-metal/core', 'ember-metal/merge', 'ember-metal/instrumentation', 'ember-metal/utils', 'ember-metal/error', 'ember-metal/enumerable_utils', 'ember-metal/cache', 'ember-metal/platform/define_property', 'ember-metal/platform/create', 'ember-metal/array', 'ember-metal/logger', 'ember-metal/property_get', 'ember-metal/events', 'ember-metal/observer_set', 'ember-metal/property_events', 'ember-metal/properties', 'ember-metal/property_set', 'ember-metal/map', 'ember-metal/get_properties', 'ember-metal/set_properties', 'ember-metal/watch_key', 'ember-metal/chains', 'ember-metal/watch_path', 'ember-metal/watching', 'ember-metal/expand_properties', 'ember-metal/computed', 'ember-metal/alias', 'ember-metal/computed_macros', 'ember-metal/observer', 'ember-metal/mixin', 'ember-metal/binding', 'ember-metal/run_loop', 'ember-metal/libraries', 'ember-metal/is_none', 'ember-metal/is_empty', 'ember-metal/is_blank', 'ember-metal/is_present', 'ember-metal/keys', 'backburner', 'ember-metal/streams/utils', 'ember-metal/streams/stream'], function (exports, Ember, merge, instrumentation, utils, EmberError, EnumerableUtils, Cache, define_property, create, array, Logger, property_get, events, ObserverSet, property_events, properties, property_set, map, getProperties, setProperties, watch_key, chains, watch_path, watching, expandProperties, computed, alias, computed_macros, observer, mixin, binding, run, Libraries, isNone, isEmpty, isBlank, isPresent, keys, Backburner, streams__utils, Stream) {
-
- 'use strict';
-
- /**
- Ember Metal
-
- @module ember
- @submodule ember-metal
- */
-
- // BEGIN IMPORTS
- computed.computed.empty = computed_macros.empty;
- computed.computed.notEmpty = computed_macros.notEmpty;
- computed.computed.none = computed_macros.none;
- computed.computed.not = computed_macros.not;
- computed.computed.bool = computed_macros.bool;
- computed.computed.match = computed_macros.match;
- computed.computed.equal = computed_macros.equal;
- computed.computed.gt = computed_macros.gt;
- computed.computed.gte = computed_macros.gte;
- computed.computed.lt = computed_macros.lt;
- computed.computed.lte = computed_macros.lte;
- computed.computed.alias = alias['default'];
- computed.computed.oneWay = computed_macros.oneWay;
- computed.computed.reads = computed_macros.oneWay;
- computed.computed.readOnly = computed_macros.readOnly;
- computed.computed.defaultTo = computed_macros.defaultTo;
- computed.computed.deprecatingAlias = computed_macros.deprecatingAlias;
- computed.computed.and = computed_macros.and;
- computed.computed.or = computed_macros.or;
- computed.computed.any = computed_macros.any;
- computed.computed.collect = computed_macros.collect;var EmberInstrumentation = Ember['default'].Instrumentation = {};
- EmberInstrumentation.instrument = instrumentation.instrument;
- EmberInstrumentation.subscribe = instrumentation.subscribe;
- EmberInstrumentation.unsubscribe = instrumentation.unsubscribe;
- EmberInstrumentation.reset = instrumentation.reset;
-
- Ember['default'].instrument = instrumentation.instrument;
- Ember['default'].subscribe = instrumentation.subscribe;
-
- Ember['default']._Cache = Cache['default'];
-
- Ember['default'].generateGuid = utils.generateGuid;
- Ember['default'].GUID_KEY = utils.GUID_KEY;
- Ember['default'].create = create['default'];
- Ember['default'].keys = keys['default'];
- Ember['default'].platform = {
- defineProperty: properties.defineProperty,
- hasPropertyAccessors: define_property.hasPropertyAccessors
- };
-
- var EmberArrayPolyfills = Ember['default'].ArrayPolyfills = {};
-
- EmberArrayPolyfills.map = array.map;
- EmberArrayPolyfills.forEach = array.forEach;
- EmberArrayPolyfills.filter = array.filter;
- EmberArrayPolyfills.indexOf = array.indexOf;
-
- Ember['default'].Error = EmberError['default'];
- Ember['default'].guidFor = utils.guidFor;
- Ember['default'].META_DESC = utils.META_DESC;
- Ember['default'].EMPTY_META = utils.EMPTY_META;
- Ember['default'].meta = utils.meta;
- Ember['default'].getMeta = utils.getMeta;
- Ember['default'].setMeta = utils.setMeta;
- Ember['default'].metaPath = utils.metaPath;
- Ember['default'].inspect = utils.inspect;
- Ember['default'].typeOf = utils.typeOf;
- Ember['default'].tryCatchFinally = utils.deprecatedTryCatchFinally;
- Ember['default'].isArray = utils.isArray;
- Ember['default'].makeArray = utils.makeArray;
- Ember['default'].canInvoke = utils.canInvoke;
- Ember['default'].tryInvoke = utils.tryInvoke;
- Ember['default'].tryFinally = utils.deprecatedTryFinally;
- Ember['default'].wrap = utils.wrap;
- Ember['default'].apply = utils.apply;
- Ember['default'].applyStr = utils.applyStr;
- Ember['default'].uuid = utils.uuid;
-
- Ember['default'].Logger = Logger['default'];
-
- Ember['default'].get = property_get.get;
- Ember['default'].getWithDefault = property_get.getWithDefault;
- Ember['default'].normalizeTuple = property_get.normalizeTuple;
- Ember['default']._getPath = property_get._getPath;
-
- Ember['default'].EnumerableUtils = EnumerableUtils['default'];
-
- Ember['default'].on = events.on;
- Ember['default'].addListener = events.addListener;
- Ember['default'].removeListener = events.removeListener;
- Ember['default']._suspendListener = events.suspendListener;
- Ember['default']._suspendListeners = events.suspendListeners;
- Ember['default'].sendEvent = events.sendEvent;
- Ember['default'].hasListeners = events.hasListeners;
- Ember['default'].watchedEvents = events.watchedEvents;
- Ember['default'].listenersFor = events.listenersFor;
- Ember['default'].accumulateListeners = events.accumulateListeners;
-
- Ember['default']._ObserverSet = ObserverSet['default'];
-
- Ember['default'].propertyWillChange = property_events.propertyWillChange;
- Ember['default'].propertyDidChange = property_events.propertyDidChange;
- Ember['default'].overrideChains = property_events.overrideChains;
- Ember['default'].beginPropertyChanges = property_events.beginPropertyChanges;
- Ember['default'].endPropertyChanges = property_events.endPropertyChanges;
- Ember['default'].changeProperties = property_events.changeProperties;
-
- Ember['default'].defineProperty = properties.defineProperty;
-
- Ember['default'].set = property_set.set;
- Ember['default'].trySet = property_set.trySet;
-
- Ember['default'].OrderedSet = map.OrderedSet;
- Ember['default'].Map = map.Map;
- Ember['default'].MapWithDefault = map.MapWithDefault;
-
- Ember['default'].getProperties = getProperties['default'];
- Ember['default'].setProperties = setProperties['default'];
-
- Ember['default'].watchKey = watch_key.watchKey;
- Ember['default'].unwatchKey = watch_key.unwatchKey;
-
- Ember['default'].flushPendingChains = chains.flushPendingChains;
- Ember['default'].removeChainWatcher = chains.removeChainWatcher;
- Ember['default']._ChainNode = chains.ChainNode;
- Ember['default'].finishChains = chains.finishChains;
-
- Ember['default'].watchPath = watch_path.watchPath;
- Ember['default'].unwatchPath = watch_path.unwatchPath;
-
- Ember['default'].watch = watching.watch;
- Ember['default'].isWatching = watching.isWatching;
- Ember['default'].unwatch = watching.unwatch;
- Ember['default'].rewatch = watching.rewatch;
- Ember['default'].destroy = watching.destroy;
-
- Ember['default'].expandProperties = expandProperties['default'];
-
- Ember['default'].ComputedProperty = computed.ComputedProperty;
- Ember['default'].computed = computed.computed;
- Ember['default'].cacheFor = computed.cacheFor;
-
- Ember['default'].addObserver = observer.addObserver;
- Ember['default'].observersFor = observer.observersFor;
- Ember['default'].removeObserver = observer.removeObserver;
- Ember['default'].addBeforeObserver = observer.addBeforeObserver;
- Ember['default']._suspendBeforeObserver = observer._suspendBeforeObserver;
- Ember['default']._suspendBeforeObservers = observer._suspendBeforeObservers;
- Ember['default']._suspendObserver = observer._suspendObserver;
- Ember['default']._suspendObservers = observer._suspendObservers;
- Ember['default'].beforeObserversFor = observer.beforeObserversFor;
- Ember['default'].removeBeforeObserver = observer.removeBeforeObserver;
-
- Ember['default'].IS_BINDING = mixin.IS_BINDING;
- Ember['default'].required = mixin.required;
- Ember['default'].aliasMethod = mixin.aliasMethod;
- Ember['default'].observer = mixin.observer;
- Ember['default'].immediateObserver = mixin.immediateObserver;
- Ember['default'].beforeObserver = mixin.beforeObserver;
- Ember['default'].mixin = mixin.mixin;
- Ember['default'].Mixin = mixin.Mixin;
-
- Ember['default'].oneWay = binding.oneWay;
- Ember['default'].bind = binding.bind;
- Ember['default'].Binding = binding.Binding;
- Ember['default'].isGlobalPath = binding.isGlobalPath;
-
- Ember['default'].run = run['default'];
-
- /**
- * @class Backburner
- * @for Ember
- * @private
- */
- Ember['default'].Backburner = Backburner['default'];
-
- Ember['default'].libraries = new Libraries['default']();
- Ember['default'].libraries.registerCoreLibrary('Ember', Ember['default'].VERSION);
-
- Ember['default'].isNone = isNone['default'];
- Ember['default'].isEmpty = isEmpty['default'];
- Ember['default'].isBlank = isBlank['default'];
- Ember['default'].isPresent = isPresent['default'];
-
- Ember['default'].merge = merge['default'];
-
-
- /**
- A function may be assigned to `Ember.onerror` to be called when Ember
- internals encounter an error. This is useful for specialized error handling
- and reporting code.
-
- ```javascript
- Ember.onerror = function(error) {
- Em.$.ajax('/report-error', 'POST', {
- stack: error.stack,
- otherInformation: 'whatever app state you want to provide'
- });
- };
- ```
-
- Internally, `Ember.onerror` is used as Backburner's error handler.
-
- @event onerror
- @for Ember
- @param {Exception} error the error object
- */
- Ember['default'].onerror = null;
- // END EXPORTS
-
- // do this for side-effects of updating Ember.assert, warn, etc when
- // ember-debug is present
- if (Ember['default'].__loader.registry['ember-debug']) {
- requireModule('ember-debug');
- }
-
- exports['default'] = Ember['default'];
-
-});
-enifed('ember-metal/alias', ['exports', 'ember-metal/property_get', 'ember-metal/property_set', 'ember-metal/core', 'ember-metal/error', 'ember-metal/properties', 'ember-metal/computed', 'ember-metal/platform/create', 'ember-metal/utils', 'ember-metal/dependent_keys'], function (exports, property_get, property_set, Ember, EmberError, properties, computed, create, utils, dependent_keys) {
-
- 'use strict';
-
- exports.AliasedProperty = AliasedProperty;
-
- exports['default'] = alias;
-
- function alias(altKey) {
- return new AliasedProperty(altKey);
- }
-
- function AliasedProperty(altKey) {
- this.isDescriptor = true;
- this.altKey = altKey;
- this._dependentKeys = [altKey];
- }
-
- AliasedProperty.prototype = create['default'](properties.Descriptor.prototype);
-
- AliasedProperty.prototype.get = function AliasedProperty_get(obj, keyName) {
- return property_get.get(obj, this.altKey);
- };
-
- AliasedProperty.prototype.set = function AliasedProperty_set(obj, keyName, value) {
- return property_set.set(obj, this.altKey, value);
- };
-
- AliasedProperty.prototype.willWatch = function (obj, keyName) {
- dependent_keys.addDependentKeys(this, obj, keyName, utils.meta(obj));
- };
-
- AliasedProperty.prototype.didUnwatch = function (obj, keyName) {
- dependent_keys.removeDependentKeys(this, obj, keyName, utils.meta(obj));
- };
-
- AliasedProperty.prototype.setup = function (obj, keyName) {
- Ember['default'].assert("Setting alias '" + keyName + "' on self", this.altKey !== keyName);
- var m = utils.meta(obj);
- if (m.watching[keyName]) {
- dependent_keys.addDependentKeys(this, obj, keyName, m);
- }
- };
-
- AliasedProperty.prototype.teardown = function (obj, keyName) {
- var m = utils.meta(obj);
- if (m.watching[keyName]) {
- dependent_keys.removeDependentKeys(this, obj, keyName, m);
- }
- };
-
- AliasedProperty.prototype.readOnly = function () {
- this.set = AliasedProperty_readOnlySet;
- return this;
- };
-
- function AliasedProperty_readOnlySet(obj, keyName, value) {
- throw new EmberError['default']("Cannot set read-only property '" + keyName + "' on object: " + utils.inspect(obj));
- }
-
- AliasedProperty.prototype.oneWay = function () {
- this.set = AliasedProperty_oneWaySet;
- return this;
- };
-
- function AliasedProperty_oneWaySet(obj, keyName, value) {
- properties.defineProperty(obj, keyName, null);
- return property_set.set(obj, keyName, value);
- }
-
- // Backwards compatibility with Ember Data
- AliasedProperty.prototype._meta = undefined;
- AliasedProperty.prototype.meta = computed.ComputedProperty.prototype.meta;
-
-});
-enifed('ember-metal/array', ['exports'], function (exports) {
-
- 'use strict';
-
- /**
- @module ember-metal
- */
-
- var ArrayPrototype = Array.prototype;
-
- // Testing this is not ideal, but we want to use native functions
- // if available, but not to use versions created by libraries like Prototype
- var isNativeFunc = function (func) {
- // This should probably work in all browsers likely to have ES5 array methods
- return func && Function.prototype.toString.call(func).indexOf('[native code]') > -1;
- };
-
- var defineNativeShim = function (nativeFunc, shim) {
- if (isNativeFunc(nativeFunc)) {
- return nativeFunc;
- }
- return shim;
- };
-
- // From: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/array/map
- var map = defineNativeShim(ArrayPrototype.map, function (fun) {
- //"use strict";
-
- if (this === void 0 || this === null || typeof fun !== "function") {
- throw new TypeError();
- }
-
- var t = Object(this);
- var len = t.length >>> 0;
- var res = new Array(len);
-
- for (var i = 0; i < len; i++) {
- if (i in t) {
- res[i] = fun.call(arguments[1], t[i], i, t);
- }
- }
-
- return res;
- });
-
- // From: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/array/foreach
- var forEach = defineNativeShim(ArrayPrototype.forEach, function (fun) {
- //"use strict";
-
- if (this === void 0 || this === null || typeof fun !== "function") {
- throw new TypeError();
- }
-
- var t = Object(this);
- var len = t.length >>> 0;
-
- for (var i = 0; i < len; i++) {
- if (i in t) {
- fun.call(arguments[1], t[i], i, t);
- }
- }
- });
-
- var indexOf = defineNativeShim(ArrayPrototype.indexOf, function (obj, fromIndex) {
- if (fromIndex === null || fromIndex === undefined) {
- fromIndex = 0;
- } else if (fromIndex < 0) {
- fromIndex = Math.max(0, this.length + fromIndex);
- }
-
- for (var i = fromIndex, j = this.length; i < j; i++) {
- if (this[i] === obj) {
- return i;
- }
- }
- return -1;
- });
-
- var lastIndexOf = defineNativeShim(ArrayPrototype.lastIndexOf, function (obj, fromIndex) {
- var len = this.length;
- var idx;
-
- if (fromIndex === undefined) {
- fromIndex = len - 1;
- } else {
- fromIndex = fromIndex < 0 ? Math.ceil(fromIndex) : Math.floor(fromIndex);
- }
-
- if (fromIndex < 0) {
- fromIndex += len;
- }
-
- for (idx = fromIndex; idx >= 0; idx--) {
- if (this[idx] === obj) {
- return idx;
- }
- }
- return -1;
- });
-
- var filter = defineNativeShim(ArrayPrototype.filter, function (fn, context) {
- var i, value;
- var result = [];
- var length = this.length;
-
- for (i = 0; i < length; i++) {
- if (this.hasOwnProperty(i)) {
- value = this[i];
- if (fn.call(context, value, i, this)) {
- result.push(value);
- }
- }
- }
- return result;
- });
-
- if (Ember.SHIM_ES5) {
- ArrayPrototype.map = ArrayPrototype.map || map;
- ArrayPrototype.forEach = ArrayPrototype.forEach || forEach;
- ArrayPrototype.filter = ArrayPrototype.filter || filter;
- ArrayPrototype.indexOf = ArrayPrototype.indexOf || indexOf;
- ArrayPrototype.lastIndexOf = ArrayPrototype.lastIndexOf || lastIndexOf;
- }
-
- /**
- Array polyfills to support ES5 features in older browsers.
-
- @namespace Ember
- @property ArrayPolyfills
- */
-
- exports.map = map;
- exports.forEach = forEach;
- exports.filter = filter;
- exports.indexOf = indexOf;
- exports.lastIndexOf = lastIndexOf;
-
-});
-enifed('ember-metal/binding', ['exports', 'ember-metal/core', 'ember-metal/property_get', 'ember-metal/property_set', 'ember-metal/utils', 'ember-metal/observer', 'ember-metal/run_loop', 'ember-metal/path_cache'], function (exports, Ember, property_get, property_set, utils, observer, run, path_cache) {
-
- 'use strict';
-
- exports.bind = bind;
- exports.oneWay = oneWay;
- exports.Binding = Binding;
-
- Ember['default'].LOG_BINDINGS = false || !!Ember['default'].ENV.LOG_BINDINGS;
-
- /**
- Returns true if the provided path is global (e.g., `MyApp.fooController.bar`)
- instead of local (`foo.bar.baz`).
-
- @method isGlobalPath
- @for Ember
- @private
- @param {String} path
- @return Boolean
- */
-
- function getWithGlobals(obj, path) {
- return property_get.get(path_cache.isGlobal(path) ? Ember['default'].lookup : obj, path);
- }
-
- // ..........................................................
- // BINDING
- //
-
- function Binding(toPath, fromPath) {
- this._direction = undefined;
- this._from = fromPath;
- this._to = toPath;
- this._readyToSync = undefined;
- this._oneWay = undefined;
- }
-
- /**
- @class Binding
- @namespace Ember
- */
-
- Binding.prototype = {
- /**
- This copies the Binding so it can be connected to another object.
- @method copy
- @return {Ember.Binding} `this`
- */
- copy: function () {
- var copy = new Binding(this._to, this._from);
- if (this._oneWay) {
- copy._oneWay = true;
- }
- return copy;
- },
-
- // ..........................................................
- // CONFIG
- //
-
- /**
- This will set `from` property path to the specified value. It will not
- attempt to resolve this property path to an actual object until you
- connect the binding.
- The binding will search for the property path starting at the root object
- you pass when you `connect()` the binding. It follows the same rules as
- `get()` - see that method for more information.
- @method from
- @param {String} path the property path to connect to
- @return {Ember.Binding} `this`
- */
- from: function (path) {
- this._from = path;
- return this;
- },
-
- /**
- This will set the `to` property path to the specified value. It will not
- attempt to resolve this property path to an actual object until you
- connect the binding.
- The binding will search for the property path starting at the root object
- you pass when you `connect()` the binding. It follows the same rules as
- `get()` - see that method for more information.
- @method to
- @param {String|Tuple} path A property path or tuple
- @return {Ember.Binding} `this`
- */
- to: function (path) {
- this._to = path;
- return this;
- },
-
- /**
- Configures the binding as one way. A one-way binding will relay changes
- on the `from` side to the `to` side, but not the other way around. This
- means that if you change the `to` side directly, the `from` side may have
- a different value.
- @method oneWay
- @return {Ember.Binding} `this`
- */
- oneWay: function () {
- this._oneWay = true;
- return this;
- },
-
- /**
- @method toString
- @return {String} string representation of binding
- */
- toString: function () {
- var oneWay = this._oneWay ? '[oneWay]' : '';
- return "Ember.Binding<" + utils.guidFor(this) + ">(" + this._from + " -> " + this._to + ")" + oneWay;
- },
-
- // ..........................................................
- // CONNECT AND SYNC
- //
-
- /**
- Attempts to connect this binding instance so that it can receive and relay
- changes. This method will raise an exception if you have not set the
- from/to properties yet.
- @method connect
- @param {Object} obj The root object for this binding.
- @return {Ember.Binding} `this`
- */
- connect: function (obj) {
- Ember['default'].assert('Must pass a valid object to Ember.Binding.connect()', !!obj);
-
- var fromPath = this._from;
- var toPath = this._to;
- property_set.trySet(obj, toPath, getWithGlobals(obj, fromPath));
-
- // add an observer on the object to be notified when the binding should be updated
- observer.addObserver(obj, fromPath, this, this.fromDidChange);
-
- // if the binding is a two-way binding, also set up an observer on the target
- if (!this._oneWay) {
- observer.addObserver(obj, toPath, this, this.toDidChange);
- }
-
- this._readyToSync = true;
-
- return this;
- },
-
- /**
- Disconnects the binding instance. Changes will no longer be relayed. You
- will not usually need to call this method.
- @method disconnect
- @param {Object} obj The root object you passed when connecting the binding.
- @return {Ember.Binding} `this`
- */
- disconnect: function (obj) {
- Ember['default'].assert('Must pass a valid object to Ember.Binding.disconnect()', !!obj);
-
- var twoWay = !this._oneWay;
-
- // remove an observer on the object so we're no longer notified of
- // changes that should update bindings.
- observer.removeObserver(obj, this._from, this, this.fromDidChange);
-
- // if the binding is two-way, remove the observer from the target as well
- if (twoWay) {
- observer.removeObserver(obj, this._to, this, this.toDidChange);
- }
-
- this._readyToSync = false; // disable scheduled syncs...
- return this;
- },
-
- // ..........................................................
- // PRIVATE
- //
-
- /* called when the from side changes */
- fromDidChange: function (target) {
- this._scheduleSync(target, 'fwd');
- },
-
- /* called when the to side changes */
- toDidChange: function (target) {
- this._scheduleSync(target, 'back');
- },
-
- _scheduleSync: function (obj, dir) {
- var existingDir = this._direction;
-
- // if we haven't scheduled the binding yet, schedule it
- if (existingDir === undefined) {
- run['default'].schedule('sync', this, this._sync, obj);
- this._direction = dir;
- }
-
- // If both a 'back' and 'fwd' sync have been scheduled on the same object,
- // default to a 'fwd' sync so that it remains deterministic.
- if (existingDir === 'back' && dir === 'fwd') {
- this._direction = 'fwd';
- }
- },
-
- _sync: function (obj) {
- var log = Ember['default'].LOG_BINDINGS;
-
- // don't synchronize destroyed objects or disconnected bindings
- if (obj.isDestroyed || !this._readyToSync) {
- return;
- }
-
- // get the direction of the binding for the object we are
- // synchronizing from
- var direction = this._direction;
-
- var fromPath = this._from;
- var toPath = this._to;
-
- this._direction = undefined;
-
- // if we're synchronizing from the remote object...
- if (direction === 'fwd') {
- var fromValue = getWithGlobals(obj, this._from);
- if (log) {
- Ember['default'].Logger.log(' ', this.toString(), '->', fromValue, obj);
- }
- if (this._oneWay) {
- property_set.trySet(obj, toPath, fromValue);
- } else {
- observer._suspendObserver(obj, toPath, this, this.toDidChange, function () {
- property_set.trySet(obj, toPath, fromValue);
- });
- }
- // if we're synchronizing *to* the remote object
- } else if (direction === 'back') {
- var toValue = property_get.get(obj, this._to);
- if (log) {
- Ember['default'].Logger.log(' ', this.toString(), '<-', toValue, obj);
- }
- observer._suspendObserver(obj, fromPath, this, this.fromDidChange, function () {
- property_set.trySet(path_cache.isGlobal(fromPath) ? Ember['default'].lookup : obj, fromPath, toValue);
- });
- }
- }
-
- };
-
- function mixinProperties(to, from) {
- for (var key in from) {
- if (from.hasOwnProperty(key)) {
- to[key] = from[key];
- }
- }
- }
-
- mixinProperties(Binding, {
-
- /*
- See `Ember.Binding.from`.
- @method from
- @static
- */
- from: function (from) {
- var C = this;
- return new C(undefined, from);
- },
-
- /*
- See `Ember.Binding.to`.
- @method to
- @static
- */
- to: function (to) {
- var C = this;
- return new C(to, undefined);
- },
-
- /**
- Creates a new Binding instance and makes it apply in a single direction.
- A one-way binding will relay changes on the `from` side object (supplied
- as the `from` argument) the `to` side, but not the other way around.
- This means that if you change the "to" side directly, the "from" side may have
- a different value.
- See `Binding.oneWay`.
- @method oneWay
- @param {String} from from path.
- @param {Boolean} [flag] (Optional) passing nothing here will make the
- binding `oneWay`. You can instead pass `false` to disable `oneWay`, making the
- binding two way again.
- @return {Ember.Binding} `this`
- */
- oneWay: function (from, flag) {
- var C = this;
- return new C(undefined, from).oneWay(flag);
- }
-
- });
- /**
- An `Ember.Binding` connects the properties of two objects so that whenever
- the value of one property changes, the other property will be changed also.
-
- ## Automatic Creation of Bindings with `/^*Binding/`-named Properties
-
- You do not usually create Binding objects directly but instead describe
- bindings in your class or object definition using automatic binding
- detection.
-
- Properties ending in a `Binding` suffix will be converted to `Ember.Binding`
- instances. The value of this property should be a string representing a path
- to another object or a custom binding instance created using Binding helpers
- (see "One Way Bindings"):
-
- ```
- valueBinding: "MyApp.someController.title"
- ```
-
- This will create a binding from `MyApp.someController.title` to the `value`
- property of your object instance automatically. Now the two values will be
- kept in sync.
-
- ## One Way Bindings
-
- One especially useful binding customization you can use is the `oneWay()`
- helper. This helper tells Ember that you are only interested in
- receiving changes on the object you are binding from. For example, if you
- are binding to a preference and you want to be notified if the preference
- has changed, but your object will not be changing the preference itself, you
- could do:
-
- ```
- bigTitlesBinding: Ember.Binding.oneWay("MyApp.preferencesController.bigTitles")
- ```
-
- This way if the value of `MyApp.preferencesController.bigTitles` changes the
- `bigTitles` property of your object will change also. However, if you
- change the value of your `bigTitles` property, it will not update the
- `preferencesController`.
-
- One way bindings are almost twice as fast to setup and twice as fast to
- execute because the binding only has to worry about changes to one side.
-
- You should consider using one way bindings anytime you have an object that
- may be created frequently and you do not intend to change a property; only
- to monitor it for changes (such as in the example above).
-
- ## Adding Bindings Manually
-
- All of the examples above show you how to configure a custom binding, but the
- result of these customizations will be a binding template, not a fully active
- Binding instance. The binding will actually become active only when you
- instantiate the object the binding belongs to. It is useful however, to
- understand what actually happens when the binding is activated.
-
- For a binding to function it must have at least a `from` property and a `to`
- property. The `from` property path points to the object/key that you want to
- bind from while the `to` path points to the object/key you want to bind to.
-
- When you define a custom binding, you are usually describing the property
- you want to bind from (such as `MyApp.someController.value` in the examples
- above). When your object is created, it will automatically assign the value
- you want to bind `to` based on the name of your binding key. In the
- examples above, during init, Ember objects will effectively call
- something like this on your binding:
-
- ```javascript
- binding = Ember.Binding.from("valueBinding").to("value");
- ```
-
- This creates a new binding instance based on the template you provide, and
- sets the to path to the `value` property of the new object. Now that the
- binding is fully configured with a `from` and a `to`, it simply needs to be
- connected to become active. This is done through the `connect()` method:
-
- ```javascript
- binding.connect(this);
- ```
-
- Note that when you connect a binding you pass the object you want it to be
- connected to. This object will be used as the root for both the from and
- to side of the binding when inspecting relative paths. This allows the
- binding to be automatically inherited by subclassed objects as well.
-
- This also allows you to bind between objects using the paths you declare in
- `from` and `to`:
-
- ```javascript
- // Example 1
- binding = Ember.Binding.from("App.someObject.value").to("value");
- binding.connect(this);
-
- // Example 2
- binding = Ember.Binding.from("parentView.value").to("App.someObject.value");
- binding.connect(this);
- ```
-
- Now that the binding is connected, it will observe both the from and to side
- and relay changes.
-
- If you ever needed to do so (you almost never will, but it is useful to
- understand this anyway), you could manually create an active binding by
- using the `Ember.bind()` helper method. (This is the same method used by
- to setup your bindings on objects):
-
- ```javascript
- Ember.bind(MyApp.anotherObject, "value", "MyApp.someController.value");
- ```
-
- Both of these code fragments have the same effect as doing the most friendly
- form of binding creation like so:
-
- ```javascript
- MyApp.anotherObject = Ember.Object.create({
- valueBinding: "MyApp.someController.value",
-
- // OTHER CODE FOR THIS OBJECT...
- });
- ```
-
- Ember's built in binding creation method makes it easy to automatically
- create bindings for you. You should always use the highest-level APIs
- available, even if you understand how it works underneath.
-
- @class Binding
- @namespace Ember
- @since Ember 0.9
- */
- // Ember.Binding = Binding; ES6TODO: where to put this?
-
- /**
- Global helper method to create a new binding. Just pass the root object
- along with a `to` and `from` path to create and connect the binding.
-
- @method bind
- @for Ember
- @param {Object} obj The root object of the transform.
- @param {String} to The path to the 'to' side of the binding.
- Must be relative to obj.
- @param {String} from The path to the 'from' side of the binding.
- Must be relative to obj or a global path.
- @return {Ember.Binding} binding instance
- */
-
- function bind(obj, to, from) {
- return new Binding(to, from).connect(obj);
- }
-
- /**
- @method oneWay
- @for Ember
- @param {Object} obj The root object of the transform.
- @param {String} to The path to the 'to' side of the binding.
- Must be relative to obj.
- @param {String} from The path to the 'from' side of the binding.
- Must be relative to obj or a global path.
- @return {Ember.Binding} binding instance
- */
-
- function oneWay(obj, to, from) {
- return new Binding(to, from).oneWay().connect(obj);
- }
-
- exports.isGlobalPath = path_cache.isGlobal;
-
-});
-enifed('ember-metal/cache', ['exports', 'ember-metal/dictionary'], function (exports, dictionary) {
-
- 'use strict';
-
- exports['default'] = Cache;
-
- function Cache(limit, func) {
- this.store = dictionary['default'](null);
- this.size = 0;
- this.misses = 0;
- this.hits = 0;
- this.limit = limit;
- this.func = func;
- }
-
- var UNDEFINED = function () {};
-
- Cache.prototype = {
- set: function (key, value) {
- if (this.limit > this.size) {
- this.size++;
- if (value === undefined) {
- this.store[key] = UNDEFINED;
- } else {
- this.store[key] = value;
- }
- }
-
- return value;
- },
-
- get: function (key) {
- var value = this.store[key];
-
- if (value === undefined) {
- this.misses++;
- value = this.set(key, this.func(key));
- } else if (value === UNDEFINED) {
- this.hits++;
- value = undefined;
- } else {
- this.hits++;
- // nothing to translate
- }
-
- return value;
- },
-
- purge: function () {
- this.store = dictionary['default'](null);
- this.size = 0;
- this.hits = 0;
- this.misses = 0;
- }
- };
-
-});
-enifed('ember-metal/chains', ['exports', 'ember-metal/core', 'ember-metal/property_get', 'ember-metal/utils', 'ember-metal/array', 'ember-metal/watch_key'], function (exports, Ember, property_get, utils, array, watch_key) {
-
- 'use strict';
-
- exports.flushPendingChains = flushPendingChains;
- exports.finishChains = finishChains;
- exports.removeChainWatcher = removeChainWatcher;
- exports.ChainNode = ChainNode;
-
- var warn = Ember['default'].warn;
- var FIRST_KEY = /^([^\.]+)/;
-
- function firstKey(path) {
- return path.match(FIRST_KEY)[0];
- }
-
- function isObject(obj) {
- return obj && typeof obj === 'object';
- }
-
- var pendingQueue = [];
-
- // attempts to add the pendingQueue chains again. If some of them end up
- // back in the queue and reschedule is true, schedules a timeout to try
- // again.
-
- function flushPendingChains() {
- if (pendingQueue.length === 0) {
- return;
- }
-
- var queue = pendingQueue;
- pendingQueue = [];
-
- array.forEach.call(queue, function (q) {
- q[0].add(q[1]);
- });
-
- warn('Watching an undefined global, Ember expects watched globals to be' + ' setup by the time the run loop is flushed, check for typos', pendingQueue.length === 0);
- }
-
- function addChainWatcher(obj, keyName, node) {
- if (!isObject(obj)) {
- return;
- }
-
- var m = utils.meta(obj);
- var nodes = m.chainWatchers;
-
- if (!m.hasOwnProperty('chainWatchers')) {
- // FIXME?!
- nodes = m.chainWatchers = {};
- }
-
- if (!nodes[keyName]) {
- nodes[keyName] = [];
- }
- nodes[keyName].push(node);
- watch_key.watchKey(obj, keyName, m);
- }
-
- function removeChainWatcher(obj, keyName, node) {
- if (!isObject(obj)) {
- return;
- }
-
- var m = obj['__ember_meta__'];
- if (m && !m.hasOwnProperty('chainWatchers')) {
- return;
- }
-
- var nodes = m && m.chainWatchers;
-
- if (nodes && nodes[keyName]) {
- nodes = nodes[keyName];
- for (var i = 0, l = nodes.length; i < l; i++) {
- if (nodes[i] === node) {
- nodes.splice(i, 1);
- break;
- }
- }
- }
- watch_key.unwatchKey(obj, keyName, m);
- }
-
- // A ChainNode watches a single key on an object. If you provide a starting
- // value for the key then the node won't actually watch it. For a root node
- // pass null for parent and key and object for value.
- function ChainNode(parent, key, value) {
- this._parent = parent;
- this._key = key;
-
- // _watching is true when calling get(this._parent, this._key) will
- // return the value of this node.
- //
- // It is false for the root of a chain (because we have no parent)
- // and for global paths (because the parent node is the object with
- // the observer on it)
- this._watching = value === undefined;
-
- this._value = value;
- this._paths = {};
- if (this._watching) {
- this._object = parent.value();
- if (this._object) {
- addChainWatcher(this._object, this._key, this);
- }
- }
-
- // Special-case: the EachProxy relies on immediate evaluation to
- // establish its observers.
- //
- // TODO: Replace this with an efficient callback that the EachProxy
- // can implement.
- if (this._parent && this._parent._key === '@each') {
- this.value();
- }
- }
-
- function lazyGet(obj, key) {
- if (!obj) {
- return;
- }
-
- var meta = obj['__ember_meta__'];
- // check if object meant only to be a prototype
- if (meta && meta.proto === obj) {
- return;
- }
-
- if (key === "@each") {
- return property_get.get(obj, key);
- }
-
- // if a CP only return cached value
- var possibleDesc = obj[key];
- var desc = possibleDesc !== null && typeof possibleDesc === 'object' && possibleDesc.isDescriptor ? possibleDesc : undefined;
- if (desc && desc._cacheable) {
- if (meta.cache && key in meta.cache) {
- return meta.cache[key];
- } else {
- return;
- }
- }
-
- return property_get.get(obj, key);
- }
-
- ChainNode.prototype = {
- value: function () {
- if (this._value === undefined && this._watching) {
- var obj = this._parent.value();
- this._value = lazyGet(obj, this._key);
- }
- return this._value;
- },
-
- destroy: function () {
- if (this._watching) {
- var obj = this._object;
- if (obj) {
- removeChainWatcher(obj, this._key, this);
- }
- this._watching = false; // so future calls do nothing
- }
- },
-
- // copies a top level object only
- copy: function (obj) {
- var ret = new ChainNode(null, null, obj);
- var paths = this._paths;
- var path;
-
- for (path in paths) {
- // this check will also catch non-number vals.
- if (paths[path] <= 0) {
- continue;
- }
- ret.add(path);
- }
- return ret;
- },
-
- // called on the root node of a chain to setup watchers on the specified
- // path.
- add: function (path) {
- var obj, tuple, key, src, paths;
-
- paths = this._paths;
- paths[path] = (paths[path] || 0) + 1;
-
- obj = this.value();
- tuple = property_get.normalizeTuple(obj, path);
-
- // the path was a local path
- if (tuple[0] && tuple[0] === obj) {
- path = tuple[1];
- key = firstKey(path);
- path = path.slice(key.length + 1);
-
- // global path, but object does not exist yet.
- // put into a queue and try to connect later.
- } else if (!tuple[0]) {
- pendingQueue.push([this, path]);
- tuple.length = 0;
- return;
-
- // global path, and object already exists
- } else {
- src = tuple[0];
- key = path.slice(0, 0 - (tuple[1].length + 1));
- path = tuple[1];
- }
-
- tuple.length = 0;
- this.chain(key, path, src);
- },
-
- // called on the root node of a chain to teardown watcher on the specified
- // path
- remove: function (path) {
- var obj, tuple, key, src, paths;
-
- paths = this._paths;
- if (paths[path] > 0) {
- paths[path]--;
- }
-
- obj = this.value();
- tuple = property_get.normalizeTuple(obj, path);
- if (tuple[0] === obj) {
- path = tuple[1];
- key = firstKey(path);
- path = path.slice(key.length + 1);
- } else {
- src = tuple[0];
- key = path.slice(0, 0 - (tuple[1].length + 1));
- path = tuple[1];
- }
-
- tuple.length = 0;
- this.unchain(key, path);
- },
-
- count: 0,
-
- chain: function (key, path, src) {
- var chains = this._chains;
- var node;
- if (!chains) {
- chains = this._chains = {};
- }
-
- node = chains[key];
- if (!node) {
- node = chains[key] = new ChainNode(this, key, src);
- }
- node.count++; // count chains...
-
- // chain rest of path if there is one
- if (path) {
- key = firstKey(path);
- path = path.slice(key.length + 1);
- node.chain(key, path); // NOTE: no src means it will observe changes...
- }
- },
-
- unchain: function (key, path) {
- var chains = this._chains;
- var node = chains[key];
-
- // unchain rest of path first...
- if (path && path.length > 1) {
- var nextKey = firstKey(path);
- var nextPath = path.slice(nextKey.length + 1);
- node.unchain(nextKey, nextPath);
- }
-
- // delete node if needed.
- node.count--;
- if (node.count <= 0) {
- delete chains[node._key];
- node.destroy();
- }
- },
-
- willChange: function (events) {
- var chains = this._chains;
- if (chains) {
- for (var key in chains) {
- if (!chains.hasOwnProperty(key)) {
- continue;
- }
- chains[key].willChange(events);
- }
- }
-
- if (this._parent) {
- this._parent.chainWillChange(this, this._key, 1, events);
- }
- },
-
- chainWillChange: function (chain, path, depth, events) {
- if (this._key) {
- path = this._key + '.' + path;
- }
-
- if (this._parent) {
- this._parent.chainWillChange(this, path, depth + 1, events);
- } else {
- if (depth > 1) {
- events.push(this.value(), path);
- }
- path = 'this.' + path;
- if (this._paths[path] > 0) {
- events.push(this.value(), path);
- }
- }
- },
-
- chainDidChange: function (chain, path, depth, events) {
- if (this._key) {
- path = this._key + '.' + path;
- }
-
- if (this._parent) {
- this._parent.chainDidChange(this, path, depth + 1, events);
- } else {
- if (depth > 1) {
- events.push(this.value(), path);
- }
- path = 'this.' + path;
- if (this._paths[path] > 0) {
- events.push(this.value(), path);
- }
- }
- },
-
- didChange: function (events) {
- // invalidate my own value first.
- if (this._watching) {
- var obj = this._parent.value();
- if (obj !== this._object) {
- removeChainWatcher(this._object, this._key, this);
- this._object = obj;
- addChainWatcher(obj, this._key, this);
- }
- this._value = undefined;
-
- // Special-case: the EachProxy relies on immediate evaluation to
- // establish its observers.
- if (this._parent && this._parent._key === '@each') {
- this.value();
- }
- }
-
- // then notify chains...
- var chains = this._chains;
- if (chains) {
- for (var key in chains) {
- if (!chains.hasOwnProperty(key)) {
- continue;
- }
- chains[key].didChange(events);
- }
- }
-
- // if no events are passed in then we only care about the above wiring update
- if (events === null) {
- return;
- }
-
- // and finally tell parent about my path changing...
- if (this._parent) {
- this._parent.chainDidChange(this, this._key, 1, events);
- }
- }
- };
-
- function finishChains(obj) {
- // We only create meta if we really have to
- var m = obj['__ember_meta__'];
- var chains, chainWatchers, chainNodes;
-
- if (m) {
- // finish any current chains node watchers that reference obj
- chainWatchers = m.chainWatchers;
- if (chainWatchers) {
- for (var key in chainWatchers) {
- if (!chainWatchers.hasOwnProperty(key)) {
- continue;
- }
-
- chainNodes = chainWatchers[key];
- if (chainNodes) {
- for (var i = 0, l = chainNodes.length; i < l; i++) {
- chainNodes[i].didChange(null);
- }
- }
- }
- }
- // copy chains from prototype
- chains = m.chains;
- if (chains && chains.value() !== obj) {
- utils.meta(obj).chains = chains = chains.copy(obj);
- }
- }
- }
-
-});
-enifed('ember-metal/computed', ['exports', 'ember-metal/property_set', 'ember-metal/utils', 'ember-metal/expand_properties', 'ember-metal/error', 'ember-metal/properties', 'ember-metal/property_events', 'ember-metal/dependent_keys'], function (exports, property_set, utils, expandProperties, EmberError, properties, property_events, dependent_keys) {
-
- 'use strict';
-
- exports.ComputedProperty = ComputedProperty;
- exports.computed = computed;
- exports.cacheFor = cacheFor;
-
- var metaFor = utils.meta;
-
- function UNDEFINED() {}
-
- // ..........................................................
- // COMPUTED PROPERTY
- //
-
- /**
- A computed property transforms an object's function into a property.
-
- By default the function backing the computed property will only be called
- once and the result will be cached. You can specify various properties
- that your computed property depends on. This will force the cached
- result to be recomputed if the dependencies are modified.
-
- In the following example we declare a computed property (by calling
- `.property()` on the fullName function) and setup the property
- dependencies (depending on firstName and lastName). The fullName function
- will be called once (regardless of how many times it is accessed) as long
- as its dependencies have not changed. Once firstName or lastName are updated
- any future calls (or anything bound) to fullName will incorporate the new
- values.
-
- ```javascript
- var Person = Ember.Object.extend({
- // these will be supplied by `create`
- firstName: null,
- lastName: null,
-
- fullName: function() {
- var firstName = this.get('firstName');
- var lastName = this.get('lastName');
-
- return firstName + ' ' + lastName;
- }.property('firstName', 'lastName')
- });
-
- var tom = Person.create({
- firstName: 'Tom',
- lastName: 'Dale'
- });
-
- tom.get('fullName') // 'Tom Dale'
- ```
-
- You can also define what Ember should do when setting a computed property.
- If you try to set a computed property, it will be invoked with the key and
- value you want to set it to. You can also accept the previous value as the
- third parameter.
-
- ```javascript
- var Person = Ember.Object.extend({
- // these will be supplied by `create`
- firstName: null,
- lastName: null,
-
- fullName: function(key, value, oldValue) {
- // getter
- if (arguments.length === 1) {
- var firstName = this.get('firstName');
- var lastName = this.get('lastName');
-
- return firstName + ' ' + lastName;
-
- // setter
- } else {
- var name = value.split(' ');
-
- this.set('firstName', name[0]);
- this.set('lastName', name[1]);
-
- return value;
- }
- }.property('firstName', 'lastName')
- });
-
- var person = Person.create();
-
- person.set('fullName', 'Peter Wagenet');
- person.get('firstName'); // 'Peter'
- person.get('lastName'); // 'Wagenet'
- ```
-
- @class ComputedProperty
- @namespace Ember
- @constructor
- */
- function ComputedProperty(config, opts) {
- this.isDescriptor = true;
-
- if (typeof config === "function") {
- config.__ember_arity = config.length;
- this._getter = config;
- if (config.__ember_arity > 1) {
- Ember.deprecate("Using the same function as getter and setter is deprecated.", false, {
- url: "http://emberjs.com/deprecations/v1.x/#toc_computed-properties-with-a-shared-getter-and-setter"
- });
- this._setter = config;
- }
- } else {
- this._getter = config.get;
- this._setter = config.set;
- if (this._setter && this._setter.__ember_arity === undefined) {
- this._setter.__ember_arity = this._setter.length;
- }
- }
-
- this._dependentKeys = undefined;
- this._suspended = undefined;
- this._meta = undefined;
-
- Ember.deprecate("Passing opts.cacheable to the CP constructor is deprecated. Invoke `volatile()` on the CP instead.", !opts || !opts.hasOwnProperty('cacheable'));
- this._cacheable = opts && opts.cacheable !== undefined ? opts.cacheable : true; // TODO: Set always to `true` once this deprecation is gone.
- this._dependentKeys = opts && opts.dependentKeys;
- Ember.deprecate("Passing opts.readOnly to the CP constructor is deprecated. All CPs are writable by default. You can invoke `readOnly()` on the CP to change this.", !opts || !opts.hasOwnProperty('readOnly'));
- this._readOnly = opts && (opts.readOnly !== undefined || !!opts.readOnly) || false; // TODO: Set always to `false` once this deprecation is gone.
- }
-
- ComputedProperty.prototype = new properties.Descriptor();
-
- var ComputedPropertyPrototype = ComputedProperty.prototype;
-
- /**
- Properties are cacheable by default. Computed property will automatically
- cache the return value of your function until one of the dependent keys changes.
-
- Call `volatile()` to set it into non-cached mode. When in this mode
- the computed property will not automatically cache the return value.
-
- However, if a property is properly observable, there is no reason to disable
- caching.
-
- @method cacheable
- @param {Boolean} aFlag optional set to `false` to disable caching
- @return {Ember.ComputedProperty} this
- @chainable
- @deprecated All computed properties are cacheble by default. Use `volatile()` instead to opt-out to caching.
- */
- ComputedPropertyPrototype.cacheable = function (aFlag) {
- Ember.deprecate('ComputedProperty.cacheable() is deprecated. All computed properties are cacheable by default.');
- this._cacheable = aFlag !== false;
- return this;
- };
-
- /**
- Call on a computed property to set it into non-cached mode. When in this
- mode the computed property will not automatically cache the return value.
-
- ```javascript
- var outsideService = Ember.Object.extend({
- value: function() {
- return OutsideService.getValue();
- }.property().volatile()
- }).create();
- ```
-
- @method volatile
- @return {Ember.ComputedProperty} this
- @chainable
- */
- ComputedPropertyPrototype["volatile"] = function () {
- this._cacheable = false;
- return this;
- };
-
- /**
- Call on a computed property to set it into read-only mode. When in this
- mode the computed property will throw an error when set.
-
- ```javascript
- var Person = Ember.Object.extend({
- guid: function() {
- return 'guid-guid-guid';
- }.property().readOnly()
- });
-
- var person = Person.create();
-
- person.set('guid', 'new-guid'); // will throw an exception
- ```
-
- @method readOnly
- @return {Ember.ComputedProperty} this
- @chainable
- */
- ComputedPropertyPrototype.readOnly = function (readOnly) {
- Ember.deprecate('Passing arguments to ComputedProperty.readOnly() is deprecated.', arguments.length === 0);
- this._readOnly = readOnly === undefined || !!readOnly; // Force to true once this deprecation is gone
- Ember.assert("Computed properties that define a setter using the new syntax cannot be read-only", !(this._readOnly && this._setter && this._setter !== this._getter));
-
- return this;
- };
-
- /**
- Sets the dependent keys on this computed property. Pass any number of
- arguments containing key paths that this computed property depends on.
-
- ```javascript
- var President = Ember.Object.extend({
- fullName: computed(function() {
- return this.get('firstName') + ' ' + this.get('lastName');
-
- // Tell Ember that this computed property depends on firstName
- // and lastName
- }).property('firstName', 'lastName')
- });
-
- var president = President.create({
- firstName: 'Barack',
- lastName: 'Obama'
- });
-
- president.get('fullName'); // 'Barack Obama'
- ```
-
- @method property
- @param {String} path* zero or more property paths
- @return {Ember.ComputedProperty} this
- @chainable
- */
- ComputedPropertyPrototype.property = function () {
- var args;
-
- var addArg = function (property) {
- args.push(property);
- };
-
- args = [];
- for (var i = 0, l = arguments.length; i < l; i++) {
- expandProperties['default'](arguments[i], addArg);
- }
-
- this._dependentKeys = args;
- return this;
- };
-
- /**
- In some cases, you may want to annotate computed properties with additional
- metadata about how they function or what values they operate on. For example,
- computed property functions may close over variables that are then no longer
- available for introspection.
-
- You can pass a hash of these values to a computed property like this:
-
- ```
- person: function() {
- var personId = this.get('personId');
- return App.Person.create({ id: personId });
- }.property().meta({ type: App.Person })
- ```
-
- The hash that you pass to the `meta()` function will be saved on the
- computed property descriptor under the `_meta` key. Ember runtime
- exposes a public API for retrieving these values from classes,
- via the `metaForProperty()` function.
-
- @method meta
- @param {Hash} meta
- @chainable
- */
-
- ComputedPropertyPrototype.meta = function (meta) {
- if (arguments.length === 0) {
- return this._meta || {};
- } else {
- this._meta = meta;
- return this;
- }
- };
-
- /* impl descriptor API */
- ComputedPropertyPrototype.didChange = function (obj, keyName) {
- // _suspended is set via a CP.set to ensure we don't clear
- // the cached value set by the setter
- if (this._cacheable && this._suspended !== obj) {
- var meta = metaFor(obj);
- if (meta.cache && meta.cache[keyName] !== undefined) {
- meta.cache[keyName] = undefined;
- dependent_keys.removeDependentKeys(this, obj, keyName, meta);
- }
- }
- };
-
- function finishChains(chainNodes) {
- for (var i = 0, l = chainNodes.length; i < l; i++) {
- chainNodes[i].didChange(null);
- }
- }
-
- /**
- Access the value of the function backing the computed property.
- If this property has already been cached, return the cached result.
- Otherwise, call the function passing the property name as an argument.
-
- ```javascript
- var Person = Ember.Object.extend({
- fullName: function(keyName) {
- // the keyName parameter is 'fullName' in this case.
- return this.get('firstName') + ' ' + this.get('lastName');
- }.property('firstName', 'lastName')
- });
-
-
- var tom = Person.create({
- firstName: 'Tom',
- lastName: 'Dale'
- });
-
- tom.get('fullName') // 'Tom Dale'
- ```
-
- @method get
- @param {String} keyName The key being accessed.
- @return {Object} The return value of the function backing the CP.
- */
- ComputedPropertyPrototype.get = function (obj, keyName) {
- var ret, cache, meta, chainNodes;
- if (this._cacheable) {
- meta = metaFor(obj);
- cache = meta.cache;
-
- var result = cache && cache[keyName];
-
- if (result === UNDEFINED) {
- return undefined;
- } else if (result !== undefined) {
- return result;
- }
-
- ret = this._getter.call(obj, keyName);
- cache = meta.cache;
- if (!cache) {
- cache = meta.cache = {};
- }
- if (ret === undefined) {
- cache[keyName] = UNDEFINED;
- } else {
- cache[keyName] = ret;
- }
-
- chainNodes = meta.chainWatchers && meta.chainWatchers[keyName];
- if (chainNodes) {
- finishChains(chainNodes);
- }
- dependent_keys.addDependentKeys(this, obj, keyName, meta);
- } else {
- ret = this._getter.call(obj, keyName);
- }
- return ret;
- };
-
- /**
- Set the value of a computed property. If the function that backs your
- computed property does not accept arguments then the default action for
- setting would be to define the property on the current object, and set
- the value of the property to the value being set.
-
- Generally speaking if you intend for your computed property to be set
- your backing function should accept either two or three arguments.
-
- ```javascript
- var Person = Ember.Object.extend({
- // these will be supplied by `create`
- firstName: null,
- lastName: null,
-
- fullName: function(key, value, oldValue) {
- // getter
- if (arguments.length === 1) {
- var firstName = this.get('firstName');
- var lastName = this.get('lastName');
-
- return firstName + ' ' + lastName;
-
- // setter
- } else {
- var name = value.split(' ');
-
- this.set('firstName', name[0]);
- this.set('lastName', name[1]);
-
- return value;
- }
- }.property('firstName', 'lastName')
- });
-
- var person = Person.create();
-
- person.set('fullName', 'Peter Wagenet');
- person.get('firstName'); // 'Peter'
- person.get('lastName'); // 'Wagenet'
- ```
-
- @method set
- @param {String} keyName The key being accessed.
- @param {Object} newValue The new value being assigned.
- @param {String} oldValue The old value being replaced.
- @return {Object} The return value of the function backing the CP.
- */
- ComputedPropertyPrototype.set = function computedPropertySetWithSuspend(obj, keyName, value) {
- var oldSuspended = this._suspended;
-
- this._suspended = obj;
-
- try {
- this._set(obj, keyName, value);
- } finally {
- this._suspended = oldSuspended;
- }
- };
-
- ComputedPropertyPrototype._set = function computedPropertySet(obj, keyName, value) {
- var cacheable = this._cacheable;
- var setter = this._setter;
- var meta = metaFor(obj, cacheable);
- var cache = meta.cache;
- var hadCachedValue = false;
-
- var cachedValue, ret;
-
- if (this._readOnly) {
- throw new EmberError['default']("Cannot set read-only property \"" + keyName + "\" on object: " + utils.inspect(obj));
- }
-
- if (cacheable && cache && cache[keyName] !== undefined) {
- if (cache[keyName] !== UNDEFINED) {
- cachedValue = cache[keyName];
- }
-
- hadCachedValue = true;
- }
-
- if (!setter) {
- properties.defineProperty(obj, keyName, null, cachedValue);
- property_set.set(obj, keyName, value);
- return;
- } else if (setter.__ember_arity === 2) {
- // Is there any way of deprecate this in a sensitive way?
- // Maybe now that getters and setters are the prefered options we can....
- ret = setter.call(obj, keyName, value);
- } else {
- ret = setter.call(obj, keyName, value, cachedValue);
- }
-
- if (hadCachedValue && cachedValue === ret) {
- return;
- }
-
- var watched = meta.watching[keyName];
- if (watched) {
- property_events.propertyWillChange(obj, keyName);
- }
-
- if (hadCachedValue) {
- cache[keyName] = undefined;
- }
-
- if (cacheable) {
- if (!hadCachedValue) {
- dependent_keys.addDependentKeys(this, obj, keyName, meta);
- }
- if (!cache) {
- cache = meta.cache = {};
- }
- if (ret === undefined) {
- cache[keyName] = UNDEFINED;
- } else {
- cache[keyName] = ret;
- }
- }
-
- if (watched) {
- property_events.propertyDidChange(obj, keyName);
- }
-
- return ret;
- };
-
- /* called before property is overridden */
- ComputedPropertyPrototype.teardown = function (obj, keyName) {
- var meta = metaFor(obj);
-
- if (meta.cache) {
- if (keyName in meta.cache) {
- dependent_keys.removeDependentKeys(this, obj, keyName, meta);
- }
-
- if (this._cacheable) {
- delete meta.cache[keyName];
- }
- }
-
- return null; // no value to restore
- };
-
- /**
- This helper returns a new property descriptor that wraps the passed
- computed property function. You can use this helper to define properties
- with mixins or via `Ember.defineProperty()`.
-
- The function you pass will be used to both get and set property values.
- The function should accept two parameters, key and value. If value is not
- undefined you should set the value first. In either case return the
- current value of the property.
-
- A computed property defined in this way might look like this:
-
- ```js
- var Person = Ember.Object.extend({
- firstName: 'Betty',
- lastName: 'Jones',
-
- fullName: Ember.computed('firstName', 'lastName', function(key, value) {
- return this.get('firstName') + ' ' + this.get('lastName');
- })
- });
-
- var client = Person.create();
-
- client.get('fullName'); // 'Betty Jones'
-
- client.set('lastName', 'Fuller');
- client.get('fullName'); // 'Betty Fuller'
- ```
-
- _Note: This is the preferred way to define computed properties when writing third-party
- libraries that depend on or use Ember, since there is no guarantee that the user
- will have prototype extensions enabled._
-
- You might use this method if you disabled
- [Prototype Extensions](http://emberjs.com/guides/configuring-ember/disabling-prototype-extensions/).
- The alternative syntax might look like this
- (if prototype extensions are enabled, which is the default behavior):
-
- ```js
- fullName: function () {
- return this.get('firstName') + ' ' + this.get('lastName');
- }.property('firstName', 'lastName')
- ```
-
- @class computed
- @namespace Ember
- @constructor
- @static
- @param {String} [dependentKeys*] Optional dependent keys that trigger this computed property.
- @param {Function} func The computed property function.
- @return {Ember.ComputedProperty} property descriptor instance
- */
- function computed(func) {
- var args;
-
- if (arguments.length > 1) {
- args = [].slice.call(arguments);
- func = args.pop();
- }
-
- var cp = new ComputedProperty(func);
- // jscs:disable
-
- // Empty block on purpose
-
- if (args) {
- cp.property.apply(cp, args);
- }
-
- return cp;
- }
-
- /**
- Returns the cached value for a property, if one exists.
- This can be useful for peeking at the value of a computed
- property that is generated lazily, without accidentally causing
- it to be created.
-
- @method cacheFor
- @for Ember
- @param {Object} obj the object whose property you want to check
- @param {String} key the name of the property whose cached value you want
- to return
- @return {Object} the cached value
- */
- function cacheFor(obj, key) {
- var meta = obj['__ember_meta__'];
- var cache = meta && meta.cache;
- var ret = cache && cache[key];
-
- if (ret === UNDEFINED) {
- return undefined;
- }
- return ret;
- }
-
- cacheFor.set = function (cache, key, value) {
- if (value === undefined) {
- cache[key] = UNDEFINED;
- } else {
- cache[key] = value;
- }
- };
-
- cacheFor.get = function (cache, key) {
- var ret = cache[key];
- if (ret === UNDEFINED) {
- return undefined;
- }
- return ret;
- };
-
- cacheFor.remove = function (cache, key) {
- cache[key] = undefined;
- };
-
-});
-enifed('ember-metal/computed_macros', ['exports', 'ember-metal/core', 'ember-metal/property_get', 'ember-metal/property_set', 'ember-metal/computed', 'ember-metal/is_empty', 'ember-metal/is_none', 'ember-metal/alias'], function (exports, Ember, property_get, property_set, computed, isEmpty, isNone, alias) {
-
- 'use strict';
-
- exports.empty = empty;
- exports.notEmpty = notEmpty;
- exports.none = none;
- exports.not = not;
- exports.bool = bool;
- exports.match = match;
- exports.equal = equal;
- exports.gt = gt;
- exports.gte = gte;
- exports.lt = lt;
- exports.lte = lte;
- exports.oneWay = oneWay;
- exports.readOnly = readOnly;
- exports.defaultTo = defaultTo;
- exports.deprecatingAlias = deprecatingAlias;
-
- function getProperties(self, propertyNames) {
- var ret = {};
- for (var i = 0; i < propertyNames.length; i++) {
- ret[propertyNames[i]] = property_get.get(self, propertyNames[i]);
- }
- return ret;
- }
-
- function generateComputedWithProperties(macro) {
- return function () {
- for (var _len = arguments.length, properties = Array(_len), _key = 0; _key < _len; _key++) {
- properties[_key] = arguments[_key];
- }
-
- var computedFunc = computed.computed(function () {
- return macro.apply(this, [getProperties(this, properties)]);
- });
-
- return computedFunc.property.apply(computedFunc, properties);
- };
- }
-
- /**
- A computed property that returns true if the value of the dependent
- property is null, an empty string, empty array, or empty function.
-
- Example
-
- ```javascript
- var ToDoList = Ember.Object.extend({
- isDone: Ember.computed.empty('todos')
- });
-
- var todoList = ToDoList.create({
- todos: ['Unit Test', 'Documentation', 'Release']
- });
-
- todoList.get('isDone'); // false
- todoList.get('todos').clear();
- todoList.get('isDone'); // true
- ```
-
- @since 1.6.0
- @method empty
- @for Ember.computed
- @param {String} dependentKey
- @return {Ember.ComputedProperty} computed property which negate
- the original value for property
- */
-
- function empty(dependentKey) {
- return computed.computed(dependentKey + '.length', function () {
- return isEmpty['default'](property_get.get(this, dependentKey));
- });
- }
-
- /**
- A computed property that returns true if the value of the dependent
- property is NOT null, an empty string, empty array, or empty function.
-
- Example
-
- ```javascript
- var Hamster = Ember.Object.extend({
- hasStuff: Ember.computed.notEmpty('backpack')
- });
-
- var hamster = Hamster.create({ backpack: ['Food', 'Sleeping Bag', 'Tent'] });
-
- hamster.get('hasStuff'); // true
- hamster.get('backpack').clear(); // []
- hamster.get('hasStuff'); // false
- ```
-
- @method notEmpty
- @for Ember.computed
- @param {String} dependentKey
- @return {Ember.ComputedProperty} computed property which returns true if
- original value for property is not empty.
- */
-
- function notEmpty(dependentKey) {
- return computed.computed(dependentKey + '.length', function () {
- return !isEmpty['default'](property_get.get(this, dependentKey));
- });
- }
-
- /**
- A computed property that returns true if the value of the dependent
- property is null or undefined. This avoids errors from JSLint complaining
- about use of ==, which can be technically confusing.
-
- Example
-
- ```javascript
- var Hamster = Ember.Object.extend({
- isHungry: Ember.computed.none('food')
- });
-
- var hamster = Hamster.create();
-
- hamster.get('isHungry'); // true
- hamster.set('food', 'Banana');
- hamster.get('isHungry'); // false
- hamster.set('food', null);
- hamster.get('isHungry'); // true
- ```
-
- @method none
- @for Ember.computed
- @param {String} dependentKey
- @return {Ember.ComputedProperty} computed property which
- returns true if original value for property is null or undefined.
- */
-
- function none(dependentKey) {
- return computed.computed(dependentKey, function () {
- return isNone['default'](property_get.get(this, dependentKey));
- });
- }
-
- /**
- A computed property that returns the inverse boolean value
- of the original value for the dependent property.
-
- Example
-
- ```javascript
- var User = Ember.Object.extend({
- isAnonymous: Ember.computed.not('loggedIn')
- });
-
- var user = User.create({loggedIn: false});
-
- user.get('isAnonymous'); // true
- user.set('loggedIn', true);
- user.get('isAnonymous'); // false
- ```
-
- @method not
- @for Ember.computed
- @param {String} dependentKey
- @return {Ember.ComputedProperty} computed property which returns
- inverse of the original value for property
- */
-
- function not(dependentKey) {
- return computed.computed(dependentKey, function () {
- return !property_get.get(this, dependentKey);
- });
- }
-
- /**
- A computed property that converts the provided dependent property
- into a boolean value.
-
- ```javascript
- var Hamster = Ember.Object.extend({
- hasBananas: Ember.computed.bool('numBananas')
- });
-
- var hamster = Hamster.create();
-
- hamster.get('hasBananas'); // false
- hamster.set('numBananas', 0);
- hamster.get('hasBananas'); // false
- hamster.set('numBananas', 1);
- hamster.get('hasBananas'); // true
- hamster.set('numBananas', null);
- hamster.get('hasBananas'); // false
- ```
-
- @method bool
- @for Ember.computed
- @param {String} dependentKey
- @return {Ember.ComputedProperty} computed property which converts
- to boolean the original value for property
- */
-
- function bool(dependentKey) {
- return computed.computed(dependentKey, function () {
- return !!property_get.get(this, dependentKey);
- });
- }
-
- /**
- A computed property which matches the original value for the
- dependent property against a given RegExp, returning `true`
- if they values matches the RegExp and `false` if it does not.
-
- Example
-
- ```javascript
- var User = Ember.Object.extend({
- hasValidEmail: Ember.computed.match('email', /^.+@.+\..+$/)
- });
-
- var user = User.create({loggedIn: false});
-
- user.get('hasValidEmail'); // false
- user.set('email', '');
- user.get('hasValidEmail'); // false
- user.set('email', 'ember_hamster@example.com');
- user.get('hasValidEmail'); // true
- ```
-
- @method match
- @for Ember.computed
- @param {String} dependentKey
- @param {RegExp} regexp
- @return {Ember.ComputedProperty} computed property which match
- the original value for property against a given RegExp
- */
-
- function match(dependentKey, regexp) {
- return computed.computed(dependentKey, function () {
- var value = property_get.get(this, dependentKey);
-
- return typeof value === 'string' ? regexp.test(value) : false;
- });
- }
-
- /**
- A computed property that returns true if the provided dependent property
- is equal to the given value.
-
- Example
-
- ```javascript
- var Hamster = Ember.Object.extend({
- napTime: Ember.computed.equal('state', 'sleepy')
- });
-
- var hamster = Hamster.create();
-
- hamster.get('napTime'); // false
- hamster.set('state', 'sleepy');
- hamster.get('napTime'); // true
- hamster.set('state', 'hungry');
- hamster.get('napTime'); // false
- ```
-
- @method equal
- @for Ember.computed
- @param {String} dependentKey
- @param {String|Number|Object} value
- @return {Ember.ComputedProperty} computed property which returns true if
- the original value for property is equal to the given value.
- */
-
- function equal(dependentKey, value) {
- return computed.computed(dependentKey, function () {
- return property_get.get(this, dependentKey) === value;
- });
- }
-
- /**
- A computed property that returns true if the provided dependent property
- is greater than the provided value.
-
- Example
-
- ```javascript
- var Hamster = Ember.Object.extend({
- hasTooManyBananas: Ember.computed.gt('numBananas', 10)
- });
-
- var hamster = Hamster.create();
-
- hamster.get('hasTooManyBananas'); // false
- hamster.set('numBananas', 3);
- hamster.get('hasTooManyBananas'); // false
- hamster.set('numBananas', 11);
- hamster.get('hasTooManyBananas'); // true
- ```
-
- @method gt
- @for Ember.computed
- @param {String} dependentKey
- @param {Number} value
- @return {Ember.ComputedProperty} computed property which returns true if
- the original value for property is greater than given value.
- */
-
- function gt(dependentKey, value) {
- return computed.computed(dependentKey, function () {
- return property_get.get(this, dependentKey) > value;
- });
- }
-
- /**
- A computed property that returns true if the provided dependent property
- is greater than or equal to the provided value.
-
- Example
-
- ```javascript
- var Hamster = Ember.Object.extend({
- hasTooManyBananas: Ember.computed.gte('numBananas', 10)
- });
-
- var hamster = Hamster.create();
-
- hamster.get('hasTooManyBananas'); // false
- hamster.set('numBananas', 3);
- hamster.get('hasTooManyBananas'); // false
- hamster.set('numBananas', 10);
- hamster.get('hasTooManyBananas'); // true
- ```
-
- @method gte
- @for Ember.computed
- @param {String} dependentKey
- @param {Number} value
- @return {Ember.ComputedProperty} computed property which returns true if
- the original value for property is greater or equal then given value.
- */
-
- function gte(dependentKey, value) {
- return computed.computed(dependentKey, function () {
- return property_get.get(this, dependentKey) >= value;
- });
- }
-
- /**
- A computed property that returns true if the provided dependent property
- is less than the provided value.
-
- Example
-
- ```javascript
- var Hamster = Ember.Object.extend({
- needsMoreBananas: Ember.computed.lt('numBananas', 3)
- });
-
- var hamster = Hamster.create();
-
- hamster.get('needsMoreBananas'); // true
- hamster.set('numBananas', 3);
- hamster.get('needsMoreBananas'); // false
- hamster.set('numBananas', 2);
- hamster.get('needsMoreBananas'); // true
- ```
-
- @method lt
- @for Ember.computed
- @param {String} dependentKey
- @param {Number} value
- @return {Ember.ComputedProperty} computed property which returns true if
- the original value for property is less then given value.
- */
-
- function lt(dependentKey, value) {
- return computed.computed(dependentKey, function () {
- return property_get.get(this, dependentKey) < value;
- });
- }
-
- /**
- A computed property that returns true if the provided dependent property
- is less than or equal to the provided value.
-
- Example
-
- ```javascript
- var Hamster = Ember.Object.extend({
- needsMoreBananas: Ember.computed.lte('numBananas', 3)
- });
-
- var hamster = Hamster.create();
-
- hamster.get('needsMoreBananas'); // true
- hamster.set('numBananas', 5);
- hamster.get('needsMoreBananas'); // false
- hamster.set('numBananas', 3);
- hamster.get('needsMoreBananas'); // true
- ```
-
- @method lte
- @for Ember.computed
- @param {String} dependentKey
- @param {Number} value
- @return {Ember.ComputedProperty} computed property which returns true if
- the original value for property is less or equal than given value.
- */
-
- function lte(dependentKey, value) {
- return computed.computed(dependentKey, function () {
- return property_get.get(this, dependentKey) <= value;
- });
- }
-
- /**
- A computed property that performs a logical `and` on the
- original values for the provided dependent properties.
-
- Example
-
- ```javascript
- var Hamster = Ember.Object.extend({
- readyForCamp: Ember.computed.and('hasTent', 'hasBackpack')
- });
-
- var hamster = Hamster.create();
-
- hamster.get('readyForCamp'); // false
- hamster.set('hasTent', true);
- hamster.get('readyForCamp'); // false
- hamster.set('hasBackpack', true);
- hamster.get('readyForCamp'); // true
- hamster.set('hasBackpack', 'Yes');
- hamster.get('readyForCamp'); // 'Yes'
- ```
-
- @method and
- @for Ember.computed
- @param {String} dependentKey*
- @return {Ember.ComputedProperty} computed property which performs
- a logical `and` on the values of all the original values for properties.
- */
- var and = generateComputedWithProperties(function (properties) {
- var value;
- for (var key in properties) {
- value = properties[key];
- if (properties.hasOwnProperty(key) && !value) {
- return false;
- }
- }
- return value;
- });
-
- var or = generateComputedWithProperties(function (properties) {
- for (var key in properties) {
- if (properties.hasOwnProperty(key) && properties[key]) {
- return properties[key];
- }
- }
- return false;
- });
-
- var any = generateComputedWithProperties(function (properties) {
- for (var key in properties) {
- if (properties.hasOwnProperty(key) && properties[key]) {
- return properties[key];
- }
- }
- return null;
- });
-
- var collect = generateComputedWithProperties(function (properties) {
- var res = Ember['default'].A();
- for (var key in properties) {
- if (properties.hasOwnProperty(key)) {
- if (isNone['default'](properties[key])) {
- res.push(null);
- } else {
- res.push(properties[key]);
- }
- }
- }
- return res;
- });
-
- function oneWay(dependentKey) {
- return alias['default'](dependentKey).oneWay();
- }
-
- /**
- This is a more semantically meaningful alias of `computed.oneWay`,
- whose name is somewhat ambiguous as to which direction the data flows.
-
- @method reads
- @for Ember.computed
- @param {String} dependentKey
- @return {Ember.ComputedProperty} computed property which creates a
- one way computed property to the original value for property.
- */
-
- /**
- Where `computed.oneWay` provides oneWay bindings, `computed.readOnly` provides
- a readOnly one way binding. Very often when using `computed.oneWay` one does
- not also want changes to propagate back up, as they will replace the value.
-
- This prevents the reverse flow, and also throws an exception when it occurs.
-
- Example
-
- ```javascript
- var User = Ember.Object.extend({
- firstName: null,
- lastName: null,
- nickName: Ember.computed.readOnly('firstName')
- });
-
- var teddy = User.create({
- firstName: 'Teddy',
- lastName: 'Zeenny'
- });
-
- teddy.get('nickName'); // 'Teddy'
- teddy.set('nickName', 'TeddyBear'); // throws Exception
- // throw new Ember.Error('Cannot Set: nickName on: ' );`
- teddy.get('firstName'); // 'Teddy'
- ```
-
- @method readOnly
- @for Ember.computed
- @param {String} dependentKey
- @return {Ember.ComputedProperty} computed property which creates a
- one way computed property to the original value for property.
- @since 1.5.0
- */
-
- function readOnly(dependentKey) {
- return alias['default'](dependentKey).readOnly();
- }
-
- /**
- A computed property that acts like a standard getter and setter,
- but returns the value at the provided `defaultPath` if the
- property itself has not been set to a value
-
- Example
-
- ```javascript
- var Hamster = Ember.Object.extend({
- wishList: Ember.computed.defaultTo('favoriteFood')
- });
-
- var hamster = Hamster.create({ favoriteFood: 'Banana' });
-
- hamster.get('wishList'); // 'Banana'
- hamster.set('wishList', 'More Unit Tests');
- hamster.get('wishList'); // 'More Unit Tests'
- hamster.get('favoriteFood'); // 'Banana'
- ```
-
- @method defaultTo
- @for Ember.computed
- @param {String} defaultPath
- @return {Ember.ComputedProperty} computed property which acts like
- a standard getter and setter, but defaults to the value from `defaultPath`.
- @deprecated Use `Ember.computed.oneWay` or custom CP with default instead.
- */
-
- function defaultTo(defaultPath) {
- return computed.computed({
- get: function (key) {
- Ember['default'].deprecate('Usage of Ember.computed.defaultTo is deprecated, use `Ember.computed.oneWay` instead.');
- return property_get.get(this, defaultPath);
- },
-
- set: function (key, newValue, cachedValue) {
- Ember['default'].deprecate('Usage of Ember.computed.defaultTo is deprecated, use `Ember.computed.oneWay` instead.');
- return newValue != null ? newValue : property_get.get(this, defaultPath);
- }
- });
- }
-
- /**
- Creates a new property that is an alias for another property
- on an object. Calls to `get` or `set` this property behave as
- though they were called on the original property, but also
- print a deprecation warning.
-
- @method deprecatingAlias
- @for Ember.computed
- @param {String} dependentKey
- @return {Ember.ComputedProperty} computed property which creates an
- alias with a deprecation to the original value for property.
- @since 1.7.0
- */
-
- function deprecatingAlias(dependentKey) {
- return computed.computed(dependentKey, {
- get: function (key) {
- Ember['default'].deprecate("Usage of `" + key + "` is deprecated, use `" + dependentKey + "` instead.");
- return property_get.get(this, dependentKey);
- },
- set: function (key, value) {
- Ember['default'].deprecate("Usage of `" + key + "` is deprecated, use `" + dependentKey + "` instead.");
- property_set.set(this, dependentKey, value);
- return value;
- }
- });
- }
-
- exports.and = and;
- exports.or = or;
- exports.any = any;
- exports.collect = collect;
-
-});
-enifed('ember-metal/core', ['exports'], function (exports) {
-
- 'use strict';
-
- exports.K = K;
-
- /*globals Ember:true,ENV,EmberENV */
-
- /**
- @module ember
- @submodule ember-metal
- */
-
- /**
- All Ember methods and functions are defined inside of this namespace. You
- generally should not add new properties to this namespace as it may be
- overwritten by future versions of Ember.
-
- You can also use the shorthand `Em` instead of `Ember`.
-
- Ember-Runtime is a framework that provides core functions for Ember including
- cross-platform functions, support for property observing and objects. Its
- focus is on small size and performance. You can use this in place of or
- along-side other cross-platform libraries such as jQuery.
-
- The core Runtime framework is based on the jQuery API with a number of
- performance optimizations.
-
- @class Ember
- @static
- @version 1.12.2
- */
-
- if ('undefined' === typeof Ember) {
- // Create core object. Make it act like an instance of Ember.Namespace so that
- // objects assigned to it are given a sane string representation.
- Ember = {};
- }
-
- // Default imports, exports and lookup to the global object;
- var global = mainContext || {}; // jshint ignore:line
- Ember.imports = Ember.imports || global;
- Ember.lookup = Ember.lookup || global;
- var emExports = Ember.exports = Ember.exports || global;
-
- // aliases needed to keep minifiers from removing the global context
- emExports.Em = emExports.Ember = Ember;
-
- // Make sure these are set whether Ember was already defined or not
-
- Ember.isNamespace = true;
-
- Ember.toString = function () {
- return 'Ember';
- };
-
- /**
- @property VERSION
- @type String
- @default '1.12.2'
- @static
- */
- Ember.VERSION = '1.12.2';
-
- /**
- Standard environmental variables. You can define these in a global `EmberENV`
- variable before loading Ember to control various configuration settings.
-
- For backwards compatibility with earlier versions of Ember the global `ENV`
- variable will be used if `EmberENV` is not defined.
-
- @property ENV
- @type Hash
- */
-
- if (Ember.ENV) {
- // do nothing if Ember.ENV is already setup
- Ember.assert('Ember.ENV should be an object.', 'object' !== typeof Ember.ENV);
- } else if ('undefined' !== typeof EmberENV) {
- Ember.ENV = EmberENV;
- } else if ('undefined' !== typeof ENV) {
- Ember.ENV = ENV;
- } else {
- Ember.ENV = {};
- }
-
- Ember.config = Ember.config || {};
-
- // We disable the RANGE API by default for performance reasons
- if ('undefined' === typeof Ember.ENV.DISABLE_RANGE_API) {
- Ember.ENV.DISABLE_RANGE_API = true;
- }
-
- /**
- Hash of enabled Canary features. Add to this before creating your application.
-
- You can also define `EmberENV.FEATURES` if you need to enable features flagged at runtime.
-
- @class FEATURES
- @namespace Ember
- @static
- @since 1.1.0
- */
- Ember.FEATURES = { "features-stripped-test": false, "ember-routing-named-substates": true, "mandatory-setter": true, "ember-htmlbars-component-generation": false, "ember-htmlbars-component-helper": true, "ember-htmlbars-inline-if-helper": true, "ember-htmlbars-attribute-syntax": true, "ember-routing-transitioning-classes": true, "new-computed-syntax": true, "ember-testing-checkbox-helpers": false, "ember-metal-stream": false, "ember-application-instance-initializers": true, "ember-application-initializer-context": true, "ember-router-willtransition": true, "ember-application-visit": false, "ember-views-component-block-info": false, "ember-routing-core-outlet": false, "ember-libraries-isregistered": false }; //jshint ignore:line
-
- if (Ember.ENV.FEATURES) {
- for (var feature in Ember.ENV.FEATURES) {
- if (Ember.ENV.FEATURES.hasOwnProperty(feature)) {
- Ember.FEATURES[feature] = Ember.ENV.FEATURES[feature];
- }
- }
- }
-
- /**
- Test that a feature is enabled. Parsed by Ember's build tools to leave
- experimental features out of beta/stable builds.
-
- You can define the following configuration options:
-
- * `EmberENV.ENABLE_ALL_FEATURES` - force all features to be enabled.
- * `EmberENV.ENABLE_OPTIONAL_FEATURES` - enable any features that have not been explicitly
- enabled/disabled.
-
- @method isEnabled
- @param {String} feature
- @return {Boolean}
- @for Ember.FEATURES
- @since 1.1.0
- */
-
- Ember.FEATURES.isEnabled = function (feature) {
- var featureValue = Ember.FEATURES[feature];
-
- if (Ember.ENV.ENABLE_ALL_FEATURES) {
- return true;
- } else if (featureValue === true || featureValue === false || featureValue === undefined) {
- return featureValue;
- } else if (Ember.ENV.ENABLE_OPTIONAL_FEATURES) {
- return true;
- } else {
- return false;
- }
- };
-
- // ..........................................................
- // BOOTSTRAP
- //
-
- /**
- Determines whether Ember should enhance some built-in object prototypes to
- provide a more friendly API. If enabled, a few methods will be added to
- `Function`, `String`, and `Array`. `Object.prototype` will not be enhanced,
- which is the one that causes most trouble for people.
-
- In general we recommend leaving this option set to true since it rarely
- conflicts with other code. If you need to turn it off however, you can
- define an `EmberENV.EXTEND_PROTOTYPES` config to disable it.
-
- @property EXTEND_PROTOTYPES
- @type Boolean
- @default true
- @for Ember
- */
- Ember.EXTEND_PROTOTYPES = Ember.ENV.EXTEND_PROTOTYPES;
-
- if (typeof Ember.EXTEND_PROTOTYPES === 'undefined') {
- Ember.EXTEND_PROTOTYPES = true;
- }
-
- /**
- Determines whether Ember logs a full stack trace during deprecation warnings
-
- @property LOG_STACKTRACE_ON_DEPRECATION
- @type Boolean
- @default true
- */
- Ember.LOG_STACKTRACE_ON_DEPRECATION = Ember.ENV.LOG_STACKTRACE_ON_DEPRECATION !== false;
-
- /**
- Determines whether Ember should add ECMAScript 5 Array shims to older browsers.
-
- @property SHIM_ES5
- @type Boolean
- @default Ember.EXTEND_PROTOTYPES
- */
- 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. Always returns `this`.
-
- @method K
- @private
- @return {Object}
- */
- function K() {
- return this;
- }
- Ember.K = K;
- //TODO: ES6 GLOBAL TODO
-
- // Stub out the methods defined by the ember-debug package in case it's not loaded
-
- if ('undefined' === typeof Ember.assert) {
- Ember.assert = K;
- }
- if ('undefined' === typeof Ember.warn) {
- Ember.warn = K;
- }
- if ('undefined' === typeof Ember.debug) {
- Ember.debug = K;
- }
- if ('undefined' === typeof Ember.runInDebug) {
- Ember.runInDebug = K;
- }
- if ('undefined' === typeof Ember.deprecate) {
- Ember.deprecate = K;
- }
- if ('undefined' === typeof Ember.deprecateFunc) {
- Ember.deprecateFunc = function (_, func) {
- return func;
- };
- }
-
- exports['default'] = Ember;
-
-});
-enifed('ember-metal/dependent_keys', ['exports', 'ember-metal/platform/create', 'ember-metal/watching'], function (exports, o_create, watching) {
-
-
- exports.addDependentKeys = addDependentKeys;
- exports.removeDependentKeys = removeDependentKeys;
-
- "REMOVE_USE_STRICT: true";function keysForDep(depsMeta, depKey) {
- var keys = depsMeta[depKey];
- if (!keys) {
- // if there are no dependencies yet for a the given key
- // create a new empty list of dependencies for the key
- keys = depsMeta[depKey] = {};
- } else if (!depsMeta.hasOwnProperty(depKey)) {
- // otherwise if the dependency list is inherited from
- // a superclass, clone the hash
- keys = depsMeta[depKey] = o_create['default'](keys);
- }
- return keys;
- }
-
- function metaForDeps(meta) {
- return keysForDep(meta, 'deps');
- }
-
- function addDependentKeys(desc, obj, keyName, meta) {
- // the descriptor has a list of dependent keys, so
- // add all of its dependent keys.
- var depsMeta, idx, len, depKey, keys;
- var depKeys = desc._dependentKeys;
- if (!depKeys) {
- return;
- }
-
- depsMeta = metaForDeps(meta);
-
- for (idx = 0, len = depKeys.length; idx < len; idx++) {
- depKey = depKeys[idx];
- // Lookup keys meta for depKey
- keys = keysForDep(depsMeta, depKey);
- // Increment the number of times depKey depends on keyName.
- keys[keyName] = (keys[keyName] || 0) + 1;
- // Watch the depKey
- watching.watch(obj, depKey, meta);
- }
- }
-
- function removeDependentKeys(desc, obj, keyName, meta) {
- // the descriptor has a list of dependent keys, so
- // remove all of its dependent keys.
- var depKeys = desc._dependentKeys;
- var depsMeta, idx, len, depKey, keys;
- if (!depKeys) {
- return;
- }
-
- depsMeta = metaForDeps(meta);
-
- for (idx = 0, len = depKeys.length; idx < len; idx++) {
- depKey = depKeys[idx];
- // Lookup keys meta for depKey
- keys = keysForDep(depsMeta, depKey);
- // Decrement the number of times depKey depends on keyName.
- keys[keyName] = (keys[keyName] || 0) - 1;
- // Unwatch the depKey
- watching.unwatch(obj, depKey, meta);
- }
- }
-
-});
-enifed('ember-metal/deprecate_property', ['exports', 'ember-metal/core', 'ember-metal/platform/define_property', 'ember-metal/properties', 'ember-metal/property_get', 'ember-metal/property_set'], function (exports, Ember, define_property, properties, property_get, property_set) {
-
- 'use strict';
-
- exports.deprecateProperty = deprecateProperty;
-
- function deprecateProperty(object, deprecatedKey, newKey) {
- function deprecate() {
- Ember['default'].deprecate("Usage of `" + deprecatedKey + "` is deprecated, use `" + newKey + "` instead.");
- }
-
- if (define_property.hasPropertyAccessors) {
- properties.defineProperty(object, deprecatedKey, {
- configurable: true,
- enumerable: false,
- set: function (value) {
- deprecate();
- property_set.set(this, newKey, value);
- },
- get: function () {
- deprecate();
- return property_get.get(this, newKey);
- }
- });
- }
- }
-
-});
-enifed('ember-metal/dictionary', ['exports', 'ember-metal/platform/create'], function (exports, create) {
-
- 'use strict';
-
-
- exports['default'] = makeDictionary;
- function makeDictionary(parent) {
- var dict = create['default'](parent);
- dict['_dict'] = null;
- delete dict['_dict'];
- return dict;
- }
-
-});
-enifed('ember-metal/enumerable_utils', ['exports', 'ember-metal/array'], function (exports, ember_metal__array) {
-
- 'use strict';
-
- exports.map = map;
- exports.forEach = forEach;
- exports.filter = filter;
- exports.indexOf = indexOf;
- exports.indexesOf = indexesOf;
- exports.addObject = addObject;
- exports.removeObject = removeObject;
- exports._replace = _replace;
- exports.replace = replace;
- exports.intersection = intersection;
-
- var splice = Array.prototype.splice;
-
- /**
- * Defines some convenience methods for working with Enumerables.
- * `Ember.EnumerableUtils` uses `Ember.ArrayPolyfills` when necessary.
- *
- * @class EnumerableUtils
- * @namespace Ember
- * @static
- * */
-
- /**
- * Calls the map function on the passed object with a specified callback. This
- * uses `Ember.ArrayPolyfill`'s-map method when necessary.
- *
- * @method map
- * @param {Object} obj The object that should be mapped
- * @param {Function} callback The callback to execute
- * @param {Object} thisArg Value to use as this when executing *callback*
- *
- * @return {Array} An array of mapped values.
- */
-
- function map(obj, callback, thisArg) {
- return obj.map ? obj.map(callback, thisArg) : ember_metal__array.map.call(obj, callback, thisArg);
- }
-
- /**
- * Calls the forEach function on the passed object with a specified callback. This
- * uses `Ember.ArrayPolyfill`'s-forEach method when necessary.
- *
- * @method forEach
- * @param {Object} obj The object to call forEach on
- * @param {Function} callback The callback to execute
- * @param {Object} thisArg Value to use as this when executing *callback*
- *
- */
-
- function forEach(obj, callback, thisArg) {
- return obj.forEach ? obj.forEach(callback, thisArg) : ember_metal__array.forEach.call(obj, callback, thisArg);
- }
-
- /**
- * Calls the filter function on the passed object with a specified callback. This
- * uses `Ember.ArrayPolyfill`'s-filter method when necessary.
- *
- * @method filter
- * @param {Object} obj The object to call filter on
- * @param {Function} callback The callback to execute
- * @param {Object} thisArg Value to use as this when executing *callback*
- *
- * @return {Array} An array containing the filtered values
- * @since 1.4.0
- */
-
- function filter(obj, callback, thisArg) {
- return obj.filter ? obj.filter(callback, thisArg) : ember_metal__array.filter.call(obj, callback, thisArg);
- }
-
- /**
- * Calls the indexOf function on the passed object with a specified callback. This
- * uses `Ember.ArrayPolyfill`'s-indexOf method when necessary.
- *
- * @method indexOf
- * @param {Object} obj The object to call indexOn on
- * @param {Function} callback The callback to execute
- * @param {Object} index The index to start searching from
- *
- */
-
- function indexOf(obj, element, index) {
- return obj.indexOf ? obj.indexOf(element, index) : ember_metal__array.indexOf.call(obj, element, index);
- }
-
- /**
- * Returns an array of indexes of the first occurrences of the passed elements
- * on the passed object.
- *
- * ```javascript
- * var array = [1, 2, 3, 4, 5];
- * Ember.EnumerableUtils.indexesOf(array, [2, 5]); // [1, 4]
- *
- * var fubar = "Fubarr";
- * Ember.EnumerableUtils.indexesOf(fubar, ['b', 'r']); // [2, 4]
- * ```
- *
- * @method indexesOf
- * @param {Object} obj The object to check for element indexes
- * @param {Array} elements The elements to search for on *obj*
- *
- * @return {Array} An array of indexes.
- *
- */
-
- function indexesOf(obj, elements) {
- return elements === undefined ? [] : map(elements, function (item) {
- return indexOf(obj, item);
- });
- }
-
- /**
- * Adds an object to an array. If the array already includes the object this
- * method has no effect.
- *
- * @method addObject
- * @param {Array} array The array the passed item should be added to
- * @param {Object} item The item to add to the passed array
- *
- * @return 'undefined'
- */
-
- function addObject(array, item) {
- var index = indexOf(array, item);
- if (index === -1) {
- array.push(item);
- }
- }
-
- /**
- * Removes an object from an array. If the array does not contain the passed
- * object this method has no effect.
- *
- * @method removeObject
- * @param {Array} array The array to remove the item from.
- * @param {Object} item The item to remove from the passed array.
- *
- * @return 'undefined'
- */
-
- function removeObject(array, item) {
- var index = indexOf(array, item);
- if (index !== -1) {
- array.splice(index, 1);
- }
- }
-
- function _replace(array, idx, amt, objects) {
- var args = [].concat(objects);
- var ret = [];
- // https://code.google.com/p/chromium/issues/detail?id=56588
- var size = 60000;
- var start = idx;
- var ends = amt;
- var count, chunk;
-
- while (args.length) {
- count = ends > size ? size : ends;
- if (count <= 0) {
- count = 0;
- }
-
- chunk = args.splice(0, size);
- chunk = [start, count].concat(chunk);
-
- start += size;
- ends -= count;
-
- ret = ret.concat(splice.apply(array, chunk));
- }
- return ret;
- }
-
- /**
- * Replaces objects in an array with the passed objects.
- *
- * ```javascript
- * var array = [1,2,3];
- * Ember.EnumerableUtils.replace(array, 1, 2, [4, 5]); // [1, 4, 5]
- *
- * var array = [1,2,3];
- * Ember.EnumerableUtils.replace(array, 1, 1, [4, 5]); // [1, 4, 5, 3]
- *
- * var array = [1,2,3];
- * Ember.EnumerableUtils.replace(array, 10, 1, [4, 5]); // [1, 2, 3, 4, 5]
- * ```
- *
- * @method replace
- * @param {Array} array The array the objects should be inserted into.
- * @param {Number} idx Starting index in the array to replace. If *idx* >=
- * length, then append to the end of the array.
- * @param {Number} amt Number of elements that should be removed from the array,
- * starting at *idx*
- * @param {Array} objects An array of zero or more objects that should be
- * inserted into the array at *idx*
- *
- * @return {Array} The modified array.
- */
-
- function replace(array, idx, amt, objects) {
- if (array.replace) {
- return array.replace(idx, amt, objects);
- } else {
- return _replace(array, idx, amt, objects);
- }
- }
-
- /**
- * Calculates the intersection of two arrays. This method returns a new array
- * filled with the records that the two passed arrays share with each other.
- * If there is no intersection, an empty array will be returned.
- *
- * ```javascript
- * var array1 = [1, 2, 3, 4, 5];
- * var array2 = [1, 3, 5, 6, 7];
- *
- * Ember.EnumerableUtils.intersection(array1, array2); // [1, 3, 5]
- *
- * var array1 = [1, 2, 3];
- * var array2 = [4, 5, 6];
- *
- * Ember.EnumerableUtils.intersection(array1, array2); // []
- * ```
- *
- * @method intersection
- * @param {Array} array1 The first array
- * @param {Array} array2 The second array
- *
- * @return {Array} The intersection of the two passed arrays.
- */
-
- function intersection(array1, array2) {
- var result = [];
- forEach(array1, function (element) {
- if (indexOf(array2, element) >= 0) {
- result.push(element);
- }
- });
-
- return result;
- }
-
- // TODO: this only exists to maintain the existing api, as we move forward it
- // should only be part of the "global build" via some shim
- exports['default'] = {
- _replace: _replace,
- addObject: addObject,
- filter: filter,
- forEach: forEach,
- indexOf: indexOf,
- indexesOf: indexesOf,
- intersection: intersection,
- map: map,
- removeObject: removeObject,
- replace: replace
- };
-
-});
-enifed('ember-metal/environment', ['exports', 'ember-metal/core'], function (exports, Ember) {
-
- 'use strict';
-
- var environment;
-
- // This code attempts to automatically detect an environment with DOM
- // by searching for window and document.createElement. An environment
- // with DOM may disable the DOM functionality of Ember explicitly by
- // defining a `disableBrowserEnvironment` ENV.
- var hasDOM = typeof window !== 'undefined' && typeof document !== 'undefined' && typeof document.createElement !== 'undefined' && !Ember['default'].ENV.disableBrowserEnvironment;
-
- if (hasDOM) {
- environment = {
- hasDOM: true,
- isChrome: !!window.chrome && !window.opera,
- location: window.location,
- history: window.history,
- userAgent: window.navigator.userAgent,
- global: window
- };
- } else {
- environment = {
- hasDOM: false,
- isChrome: false,
- location: null,
- history: null,
- userAgent: "Lynx (textmode)",
- global: null
- };
- }
-
- exports['default'] = environment;
-
-});
-enifed('ember-metal/error', ['exports', 'ember-metal/platform/create'], function (exports, create) {
-
- 'use strict';
-
- var errorProps = ['description', 'fileName', 'lineNumber', 'message', 'name', 'number', 'stack'];
-
- /**
- A subclass of the JavaScript Error object for use in Ember.
-
- @class Error
- @namespace Ember
- @extends Error
- @constructor
- */
- function EmberError() {
- var tmp = Error.apply(this, arguments);
-
- // Adds a `stack` property to the given error object that will yield the
- // stack trace at the time captureStackTrace was called.
- // When collecting the stack trace all frames above the topmost call
- // to this function, including that call, will be left out of the
- // stack trace.
- // This is useful because we can hide Ember implementation details
- // that are not very helpful for the user.
- if (Error.captureStackTrace) {
- Error.captureStackTrace(this, Ember.Error);
- }
- // Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work.
- for (var idx = 0; idx < errorProps.length; idx++) {
- this[errorProps[idx]] = tmp[errorProps[idx]];
- }
- }
-
- EmberError.prototype = create['default'](Error.prototype);
-
- exports['default'] = EmberError;
-
-});
-enifed('ember-metal/events', ['exports', 'ember-metal/core', 'ember-metal/utils', 'ember-metal/platform/create'], function (exports, Ember, utils, create) {
-
-
- exports.accumulateListeners = accumulateListeners;
- exports.addListener = addListener;
- exports.suspendListener = suspendListener;
- exports.suspendListeners = suspendListeners;
- exports.watchedEvents = watchedEvents;
- exports.sendEvent = sendEvent;
- exports.hasListeners = hasListeners;
- exports.listenersFor = listenersFor;
- exports.on = on;
- exports.removeListener = removeListener;
-
- "REMOVE_USE_STRICT: true";var ONCE = 1;
- var SUSPENDED = 2;
-
- /*
- The event system uses a series of nested hashes to store listeners on an
- object. When a listener is registered, or when an event arrives, these
- hashes are consulted to determine which target and action pair to invoke.
-
- The hashes are stored in the object's meta hash, and look like this:
-
- // Object's meta hash
- {
- listeners: { // variable name: `listenerSet`
- "foo:changed": [ // variable name: `actions`
- target, method, flags
- ]
- }
- }
-
- */
-
- function indexOf(array, target, method) {
- var index = -1;
- // hashes are added to the end of the event array
- // so it makes sense to start searching at the end
- // of the array and search in reverse
- for (var i = array.length - 3; i >= 0; i -= 3) {
- if (target === array[i] && method === array[i + 1]) {
- index = i;
- break;
- }
- }
- return index;
- }
-
- function actionsFor(obj, eventName) {
- var meta = utils.meta(obj, true);
- var actions;
- var listeners = meta.listeners;
-
- if (!listeners) {
- listeners = meta.listeners = create['default'](null);
- listeners.__source__ = obj;
- } else if (listeners.__source__ !== obj) {
- // setup inherited copy of the listeners object
- listeners = meta.listeners = create['default'](listeners);
- listeners.__source__ = obj;
- }
-
- actions = listeners[eventName];
-
- // if there are actions, but the eventName doesn't exist in our listeners, then copy them from the prototype
- if (actions && actions.__source__ !== obj) {
- actions = listeners[eventName] = listeners[eventName].slice();
- actions.__source__ = obj;
- } else if (!actions) {
- actions = listeners[eventName] = [];
- actions.__source__ = obj;
- }
-
- return actions;
- }
-
- function accumulateListeners(obj, eventName, otherActions) {
- var meta = obj['__ember_meta__'];
- var actions = meta && meta.listeners && meta.listeners[eventName];
-
- if (!actions) {
- return;
- }
-
- var newActions = [];
-
- for (var i = actions.length - 3; i >= 0; i -= 3) {
- var target = actions[i];
- var method = actions[i + 1];
- var flags = actions[i + 2];
- var actionIndex = indexOf(otherActions, target, method);
-
- if (actionIndex === -1) {
- otherActions.push(target, method, flags);
- newActions.push(target, method, flags);
- }
- }
-
- return newActions;
- }
-
- /**
- Add an event listener
-
- @method addListener
- @for Ember
- @param obj
- @param {String} eventName
- @param {Object|Function} target 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['default'].assert("You must pass at least an object and event name to Ember.addListener", !!obj && !!eventName);
-
- if (!method && 'function' === typeof target) {
- method = target;
- target = null;
- }
-
- var actions = actionsFor(obj, eventName);
- var actionIndex = indexOf(actions, target, method);
- var flags = 0;
-
- if (once) {
- flags |= ONCE;
- }
-
- if (actionIndex !== -1) {
- return;
- }
-
- actions.push(target, method, flags);
-
- if ('function' === typeof obj.didAddListener) {
- obj.didAddListener(eventName, target, method);
- }
- }
-
- /**
- Remove an event listener
-
- Arguments should match those passed to `Ember.addListener`.
-
- @method removeListener
- @for Ember
- @param obj
- @param {String} eventName
- @param {Object|Function} target A target object or a function
- @param {Function|String} method A function or the name of a function to be called on `target`
- */
- function removeListener(obj, eventName, target, method) {
- Ember['default'].assert("You must pass at least an object and event name to Ember.removeListener", !!obj && !!eventName);
-
- if (!method && 'function' === typeof target) {
- method = target;
- target = null;
- }
-
- function _removeListener(target, method) {
- var actions = actionsFor(obj, eventName);
- var actionIndex = indexOf(actions, target, method);
-
- // action doesn't exist, give up silently
- if (actionIndex === -1) {
- return;
- }
-
- actions.splice(actionIndex, 3);
-
- if ('function' === typeof obj.didRemoveListener) {
- obj.didRemoveListener(eventName, target, method);
- }
- }
-
- if (method) {
- _removeListener(target, method);
- } else {
- var meta = obj['__ember_meta__'];
- var actions = meta && meta.listeners && meta.listeners[eventName];
-
- if (!actions) {
- return;
- }
- for (var i = actions.length - 3; i >= 0; i -= 3) {
- _removeListener(actions[i], actions[i + 1]);
- }
- }
- }
-
- /**
- Suspend listener during callback.
-
- This should only be used by the target of the event listener
- when it is taking an action that would cause the event, e.g.
- an object might suspend its property change listener while it is
- setting that property.
-
- @method suspendListener
- @for Ember
-
- @private
- @param obj
- @param {String} eventName
- @param {Object|Function} target A target object or a function
- @param {Function|String} method A function or the name of a function to be called on `target`
- @param {Function} callback
- */
-
- function suspendListener(obj, eventName, target, method, callback) {
- if (!method && 'function' === typeof target) {
- method = target;
- target = null;
- }
-
- var actions = actionsFor(obj, eventName);
- var actionIndex = indexOf(actions, target, method);
-
- if (actionIndex !== -1) {
- actions[actionIndex + 2] |= SUSPENDED; // mark the action as suspended
- }
-
- function tryable() {
- return callback.call(target);
- }
- function finalizer() {
- if (actionIndex !== -1) {
- actions[actionIndex + 2] &= ~SUSPENDED;
- }
- }
-
- return utils.tryFinally(tryable, finalizer);
- }
-
- /**
- Suspends multiple listeners during a callback.
-
- @method suspendListeners
- @for Ember
-
- @private
- @param obj
- @param {Array} eventNames Array of event names
- @param {Object|Function} target A target object or a function
- @param {Function|String} method A function or the name of a function to be called on `target`
- @param {Function} callback
- */
-
- function suspendListeners(obj, eventNames, target, method, callback) {
- if (!method && 'function' === typeof target) {
- method = target;
- target = null;
- }
-
- var suspendedActions = [];
- var actionsList = [];
- var eventName, actions, i, l;
-
- for (i = 0, l = eventNames.length; i < l; i++) {
- eventName = eventNames[i];
- actions = actionsFor(obj, eventName);
- var actionIndex = indexOf(actions, target, method);
-
- if (actionIndex !== -1) {
- actions[actionIndex + 2] |= SUSPENDED;
- suspendedActions.push(actionIndex);
- actionsList.push(actions);
- }
- }
-
- function tryable() {
- return callback.call(target);
- }
-
- function finalizer() {
- for (var i = 0, l = suspendedActions.length; i < l; i++) {
- var actionIndex = suspendedActions[i];
- actionsList[i][actionIndex + 2] &= ~SUSPENDED;
- }
- }
-
- return utils.tryFinally(tryable, finalizer);
- }
-
- /**
- Return a list of currently watched events
-
- @private
- @method watchedEvents
- @for Ember
- @param obj
- */
-
- function watchedEvents(obj) {
- var listeners = obj['__ember_meta__'].listeners;
- var ret = [];
-
- if (listeners) {
- for (var eventName in listeners) {
- if (eventName !== '__source__' && listeners[eventName]) {
- ret.push(eventName);
- }
- }
- }
- return ret;
- }
-
- /**
- Send an event. The execution of suspended listeners
- is skipped, and once listeners are removed. A listener without
- a target is executed on the passed object. If an array of actions
- is not passed, the actions stored on the passed object are invoked.
-
- @method sendEvent
- @for Ember
- @param obj
- @param {String} eventName
- @param {Array} params Optional parameters for each listener.
- @param {Array} actions Optional array of actions (listeners).
- @return true
- */
-
- function sendEvent(obj, eventName, params, actions) {
- // first give object a chance to handle it
- if (obj !== Ember['default'] && 'function' === typeof obj.sendEvent) {
- obj.sendEvent(eventName, params);
- }
-
- if (!actions) {
- var meta = obj['__ember_meta__'];
- actions = meta && meta.listeners && meta.listeners[eventName];
- }
-
- if (!actions) {
- return;
- }
-
- for (var i = actions.length - 3; i >= 0; i -= 3) {
- // looping in reverse for once listeners
- var target = actions[i];
- var method = actions[i + 1];
- var flags = actions[i + 2];
-
- if (!method) {
- continue;
- }
- if (flags & SUSPENDED) {
- continue;
- }
- if (flags & ONCE) {
- removeListener(obj, eventName, target, method);
- }
- if (!target) {
- target = obj;
- }
- if ('string' === typeof method) {
- if (params) {
- utils.applyStr(target, method, params);
- } else {
- target[method]();
- }
- } else {
- if (params) {
- utils.apply(target, method, params);
- } else {
- method.call(target);
- }
- }
- }
- return true;
- }
-
- /**
- @private
- @method hasListeners
- @for Ember
- @param obj
- @param {String} eventName
- */
-
- function hasListeners(obj, eventName) {
- var meta = obj['__ember_meta__'];
- var actions = meta && meta.listeners && meta.listeners[eventName];
-
- return !!(actions && actions.length);
- }
-
- /**
- @private
- @method listenersFor
- @for Ember
- @param obj
- @param {String} eventName
- */
-
- function listenersFor(obj, eventName) {
- var ret = [];
- var meta = obj['__ember_meta__'];
- var actions = meta && meta.listeners && meta.listeners[eventName];
-
- if (!actions) {
- return ret;
- }
-
- for (var i = 0, l = actions.length; i < l; i += 3) {
- var target = actions[i];
- var method = actions[i + 1];
- ret.push([target, method]);
- }
-
- return ret;
- }
-
- /**
- Define a property as a function that should be executed when
- a specified event or events are triggered.
-
-
- ``` javascript
- var Job = Ember.Object.extend({
- logCompleted: Ember.on('completed', function() {
- console.log('Job completed!');
- })
- });
-
- var job = Job.create();
-
- Ember.sendEvent(job, 'completed'); // Logs 'Job completed!'
- ```
-
- @method on
- @for Ember
- @param {String} eventNames*
- @param {Function} func
- @return func
- */
-
- function on() {
- for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
- args[_key] = arguments[_key];
- }
-
- var func = args.pop();
- var events = args;
- func.__ember_listens__ = events;
- return func;
- }
-
-});
-enifed('ember-metal/expand_properties', ['exports', 'ember-metal/error', 'ember-metal/enumerable_utils', 'ember-metal/utils'], function (exports, EmberError, enumerable_utils, utils) {
-
- 'use strict';
-
-
- exports['default'] = expandProperties;
-
- var SPLIT_REGEX = /\{|\}/;
-
- /**
- Expands `pattern`, invoking `callback` for each expansion.
-
- The only pattern supported is brace-expansion, anything else will be passed
- once to `callback` directly.
-
- Example
-
- ```js
- function echo(arg){ console.log(arg); }
-
- Ember.expandProperties('foo.bar', echo); //=> 'foo.bar'
- Ember.expandProperties('{foo,bar}', echo); //=> 'foo', 'bar'
- Ember.expandProperties('foo.{bar,baz}', echo); //=> 'foo.bar', 'foo.baz'
- Ember.expandProperties('{foo,bar}.baz', echo); //=> 'foo.baz', 'bar.baz'
- Ember.expandProperties('foo.{bar,baz}.@each', echo) //=> 'foo.bar.@each', 'foo.baz.@each'
- Ember.expandProperties('{foo,bar}.{spam,eggs}', echo) //=> 'foo.spam', 'foo.eggs', 'bar.spam', 'bar.eggs'
- Ember.expandProperties('{foo}.bar.{baz}') //=> 'foo.bar.baz'
- ```
-
- @method
- @private
- @param {String} pattern The property pattern to expand.
- @param {Function} callback The callback to invoke. It is invoked once per
- expansion, and is passed the expansion.
- */
- function expandProperties(pattern, callback) {
- if (pattern.indexOf(' ') > -1) {
- throw new EmberError['default']('Brace expanded properties cannot contain spaces, e.g. \'user.{firstName, lastName}\' should be \'user.{firstName,lastName}\'');
- }
-
- if ('string' === utils.typeOf(pattern)) {
- var parts = pattern.split(SPLIT_REGEX);
- var properties = [parts];
-
- enumerable_utils.forEach(parts, function (part, index) {
- if (part.indexOf(',') >= 0) {
- properties = duplicateAndReplace(properties, part.split(','), index);
- }
- });
-
- enumerable_utils.forEach(properties, function (property) {
- callback(property.join(''));
- });
- } else {
- callback(pattern);
- }
- }
-
- function duplicateAndReplace(properties, currentParts, index) {
- var all = [];
-
- enumerable_utils.forEach(properties, function (property) {
- enumerable_utils.forEach(currentParts, function (part) {
- var current = property.slice(0);
- current[index] = part;
- all.push(current);
- });
- });
-
- return all;
- }
-
-});
-enifed('ember-metal/get_properties', ['exports', 'ember-metal/property_get', 'ember-metal/utils'], function (exports, property_get, utils) {
-
- 'use strict';
-
-
- exports['default'] = getProperties;
- function getProperties(obj) {
- var ret = {};
- var propertyNames = arguments;
- var i = 1;
-
- if (arguments.length === 2 && utils.typeOf(arguments[1]) === 'array') {
- i = 0;
- propertyNames = arguments[1];
- }
- for (var len = propertyNames.length; i < len; i++) {
- ret[propertyNames[i]] = property_get.get(obj, propertyNames[i]);
- }
- return ret;
- }
-
-});
-enifed('ember-metal/injected_property', ['exports', 'ember-metal/core', 'ember-metal/computed', 'ember-metal/alias', 'ember-metal/properties', 'ember-metal/platform/create'], function (exports, Ember, computed, alias, properties, create) {
-
- 'use strict';
-
- function InjectedProperty(type, name) {
- this.type = type;
- this.name = name;
-
- this._super$Constructor(injectedPropertyGet);
- AliasedPropertyPrototype.oneWay.call(this);
- }
-
- function injectedPropertyGet(keyName) {
- var possibleDesc = this[keyName];
- var desc = possibleDesc !== null && typeof possibleDesc === 'object' && possibleDesc.isDescriptor ? possibleDesc : undefined;
-
- Ember['default'].assert("Attempting to lookup an injected property on an object without a container, ensure that the object was instantiated via a container.", this.container);
-
- return this.container.lookup(desc.type + ':' + (desc.name || keyName));
- }
-
- InjectedProperty.prototype = create['default'](properties.Descriptor.prototype);
-
- var InjectedPropertyPrototype = InjectedProperty.prototype;
- var ComputedPropertyPrototype = computed.ComputedProperty.prototype;
- var AliasedPropertyPrototype = alias.AliasedProperty.prototype;
-
- InjectedPropertyPrototype._super$Constructor = computed.ComputedProperty;
-
- InjectedPropertyPrototype.get = ComputedPropertyPrototype.get;
- InjectedPropertyPrototype.readOnly = ComputedPropertyPrototype.readOnly;
-
- InjectedPropertyPrototype.teardown = ComputedPropertyPrototype.teardown;
-
- exports['default'] = InjectedProperty;
-
-});
-enifed('ember-metal/instrumentation', ['exports', 'ember-metal/core', 'ember-metal/utils'], function (exports, Ember, utils) {
-
- 'use strict';
-
- exports.instrument = instrument;
- exports._instrumentStart = _instrumentStart;
- exports.subscribe = subscribe;
- exports.unsubscribe = unsubscribe;
- exports.reset = reset;
-
- var subscribers = [];
- var cache = {};
-
- var populateListeners = function (name) {
- var listeners = [];
- var subscriber;
-
- for (var i = 0, l = subscribers.length; i < l; i++) {
- subscriber = subscribers[i];
- if (subscriber.regex.test(name)) {
- listeners.push(subscriber.object);
- }
- }
-
- cache[name] = listeners;
- return listeners;
- };
-
- var time = (function () {
- var perf = 'undefined' !== typeof window ? window.performance || {} : {};
- var fn = perf.now || perf.mozNow || perf.webkitNow || perf.msNow || perf.oNow;
- // fn.bind will be available in all the browsers that support the advanced window.performance... ;-)
- return fn ? fn.bind(perf) : function () {
- return +new Date();
- };
- })();
-
- /**
- Notifies event's subscribers, calls `before` and `after` hooks.
-
- @method instrument
- @namespace Ember.Instrumentation
-
- @param {String} [name] Namespaced event name.
- @param {Object} payload
- @param {Function} callback Function that you're instrumenting.
- @param {Object} binding Context that instrument function is called with.
- */
-
- function instrument(name, _payload, callback, binding) {
- if (arguments.length <= 3 && typeof _payload === 'function') {
- binding = callback;
- callback = _payload;
- _payload = undefined;
- }
- if (subscribers.length === 0) {
- return callback.call(binding);
- }
- var payload = _payload || {};
- var finalizer = _instrumentStart(name, function () {
- return payload;
- });
- if (finalizer) {
- var tryable = function _instrumenTryable() {
- return callback.call(binding);
- };
- var catchable = function _instrumentCatchable(e) {
- payload.exception = e;
- };
- return utils.tryCatchFinally(tryable, catchable, finalizer);
- } else {
- return callback.call(binding);
- }
- }
-
- // private for now
-
- function _instrumentStart(name, _payload) {
- var listeners = cache[name];
-
- if (!listeners) {
- listeners = populateListeners(name);
- }
-
- if (listeners.length === 0) {
- return;
- }
-
- var payload = _payload();
-
- var STRUCTURED_PROFILE = Ember['default'].STRUCTURED_PROFILE;
- var timeName;
- if (STRUCTURED_PROFILE) {
- timeName = name + ": " + payload.object;
- console.time(timeName);
- }
-
- var l = listeners.length;
- var beforeValues = new Array(l);
- var i, listener;
- var timestamp = time();
- for (i = 0; i < l; i++) {
- listener = listeners[i];
- beforeValues[i] = listener.before(name, timestamp, payload);
- }
-
- return function _instrumentEnd() {
- var i, l, listener;
- var timestamp = time();
- for (i = 0, l = listeners.length; i < l; i++) {
- listener = listeners[i];
- listener.after(name, timestamp, payload, beforeValues[i]);
- }
-
- if (STRUCTURED_PROFILE) {
- console.timeEnd(timeName);
- }
- };
- }
-
- /**
- Subscribes to a particular event or instrumented block of code.
-
- @method subscribe
- @namespace Ember.Instrumentation
-
- @param {String} [pattern] Namespaced event name.
- @param {Object} [object] Before and After hooks.
-
- @return {Subscriber}
- */
-
- function subscribe(pattern, object) {
- var paths = pattern.split(".");
- var path;
- var regex = [];
-
- for (var i = 0, l = paths.length; i < l; i++) {
- path = paths[i];
- if (path === "*") {
- regex.push("[^\\.]*");
- } else {
- regex.push(path);
- }
- }
-
- regex = regex.join("\\.");
- regex = regex + "(\\..*)?";
-
- var subscriber = {
- pattern: pattern,
- regex: new RegExp("^" + regex + "$"),
- object: object
- };
-
- subscribers.push(subscriber);
- cache = {};
-
- return subscriber;
- }
-
- /**
- Unsubscribes from a particular event or instrumented block of code.
-
- @method unsubscribe
- @namespace Ember.Instrumentation
-
- @param {Object} [subscriber]
- */
-
- function unsubscribe(subscriber) {
- var index;
-
- for (var i = 0, l = subscribers.length; i < l; i++) {
- if (subscribers[i] === subscriber) {
- index = i;
- }
- }
-
- subscribers.splice(index, 1);
- cache = {};
- }
-
- /**
- Resets `Ember.Instrumentation` by flushing list of subscribers.
-
- @method reset
- @namespace Ember.Instrumentation
- */
-
- function reset() {
- subscribers.length = 0;
- cache = {};
- }
-
- exports.subscribers = subscribers;
-
-});
-enifed('ember-metal/is_blank', ['exports', 'ember-metal/is_empty'], function (exports, isEmpty) {
-
- 'use strict';
-
-
- exports['default'] = isBlank;
- function isBlank(obj) {
- return isEmpty['default'](obj) || typeof obj === 'string' && obj.match(/\S/) === null;
- }
-
-});
-enifed('ember-metal/is_empty', ['exports', 'ember-metal/property_get', 'ember-metal/is_none'], function (exports, property_get, isNone) {
-
- 'use strict';
-
- function isEmpty(obj) {
- var none = isNone['default'](obj);
- if (none) {
- return none;
- }
-
- if (typeof obj.size === 'number') {
- return !obj.size;
- }
-
- var objectType = typeof obj;
-
- if (objectType === 'object') {
- var size = property_get.get(obj, 'size');
- if (typeof size === 'number') {
- return !size;
- }
- }
-
- if (typeof obj.length === 'number' && objectType !== 'function') {
- return !obj.length;
- }
-
- if (objectType === 'object') {
- var length = property_get.get(obj, 'length');
- if (typeof length === 'number') {
- return !length;
- }
- }
-
- return false;
- }
-
- exports['default'] = isEmpty;
-
-});
-enifed('ember-metal/is_none', ['exports'], function (exports) {
-
- 'use strict';
-
- /**
- Returns true if the passed value is null or undefined. This avoids errors
- from JSLint complaining about use of ==, which can be technically
- confusing.
-
- ```javascript
- Ember.isNone(); // true
- Ember.isNone(null); // true
- Ember.isNone(undefined); // true
- Ember.isNone(''); // false
- Ember.isNone([]); // false
- Ember.isNone(function() {}); // false
- ```
-
- @method isNone
- @for Ember
- @param {Object} obj Value to test
- @return {Boolean}
- */
- function isNone(obj) {
- return obj === null || obj === undefined;
- }
-
- exports['default'] = isNone;
-
-});
-enifed('ember-metal/is_present', ['exports', 'ember-metal/is_blank'], function (exports, isBlank) {
-
- 'use strict';
-
-
- exports['default'] = isPresent;
- function isPresent(obj) {
- return !isBlank['default'](obj);
- }
-
-});
-enifed('ember-metal/keys', ['exports', 'ember-metal/platform/define_property'], function (exports, define_property) {
-
- 'use strict';
-
- var keys = Object.keys;
-
- if (!keys || !define_property.canDefineNonEnumerableProperties) {
- // modified from
- // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys
- keys = (function () {
- var hasOwnProperty = Object.prototype.hasOwnProperty;
- var hasDontEnumBug = !({ toString: null }).propertyIsEnumerable('toString');
- var dontEnums = ['toString', 'toLocaleString', 'valueOf', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'constructor'];
- var dontEnumsLength = dontEnums.length;
-
- return function keys(obj) {
- if (typeof obj !== 'object' && (typeof obj !== 'function' || obj === null)) {
- throw new TypeError('Object.keys called on non-object');
- }
-
- var result = [];
- var prop, i;
-
- for (prop in obj) {
- if (prop !== '_super' && prop.lastIndexOf('__', 0) !== 0 && hasOwnProperty.call(obj, prop)) {
- result.push(prop);
- }
- }
-
- if (hasDontEnumBug) {
- for (i = 0; i < dontEnumsLength; i++) {
- if (hasOwnProperty.call(obj, dontEnums[i])) {
- result.push(dontEnums[i]);
- }
- }
- }
- return result;
- };
- })();
- }
-
- exports['default'] = keys;
-
-});
-enifed('ember-metal/libraries', ['exports', 'ember-metal/core', 'ember-metal/enumerable_utils'], function (exports, Ember, enumerable_utils) {
-
- 'use strict';
-
- function Libraries() {
- this._registry = [];
- this._coreLibIndex = 0;
- }
-
- Libraries.prototype = {
- constructor: Libraries,
-
- _getLibraryByName: function (name) {
- var libs = this._registry;
- var count = libs.length;
-
- for (var i = 0; i < count; i++) {
- if (libs[i].name === name) {
- return libs[i];
- }
- }
- },
-
- register: function (name, version, isCoreLibrary) {
- var index = this._registry.length;
-
- if (!this._getLibraryByName(name)) {
- if (isCoreLibrary) {
- index = this._coreLibIndex++;
- }
- this._registry.splice(index, 0, { name: name, version: version });
- } else {
- Ember['default'].warn("Library \"" + name + "\" is already registered with Ember.");
- }
- },
-
- registerCoreLibrary: function (name, version) {
- this.register(name, version, true);
- },
-
- deRegister: function (name) {
- var lib = this._getLibraryByName(name);
- var index;
-
- if (lib) {
- index = enumerable_utils.indexOf(this._registry, lib);
- this._registry.splice(index, 1);
- }
- },
-
- each: function (callback) {
- Ember['default'].deprecate('Using Ember.libraries.each() is deprecated. Access to a list of registered libraries is currently a private API. If you are not knowingly accessing this method, your out-of-date Ember Inspector may be doing so.');
- enumerable_utils.forEach(this._registry, function (lib) {
- callback(lib.name, lib.version);
- });
- }
- };
-
-
- exports['default'] = Libraries;
-
-});
-enifed('ember-metal/logger', ['exports', 'ember-metal/core', 'ember-metal/error'], function (exports, Ember, EmberError) {
-
- 'use strict';
-
- function K() {
- return this;
- }
-
- function consoleMethod(name) {
- var consoleObj, logToConsole;
- if (Ember['default'].imports.console) {
- consoleObj = Ember['default'].imports.console;
- } else if (typeof console !== 'undefined') {
- consoleObj = console;
- }
-
- var method = typeof consoleObj === 'object' ? consoleObj[name] : null;
-
- if (method) {
- // Older IE doesn't support bind, but Chrome needs it
- if (typeof method.bind === 'function') {
- logToConsole = method.bind(consoleObj);
- logToConsole.displayName = 'console.' + name;
- return logToConsole;
- } else if (typeof method.apply === 'function') {
- logToConsole = function () {
- method.apply(consoleObj, arguments);
- };
- logToConsole.displayName = 'console.' + name;
- return logToConsole;
- } else {
- return function () {
- var message = Array.prototype.join.call(arguments, ', ');
- method(message);
- };
- }
- }
- }
-
- function assertPolyfill(test, message) {
- if (!test) {
- try {
- // attempt to preserve the stack
- throw new EmberError['default']("assertion failed: " + message);
- } catch (error) {
- setTimeout(function () {
- throw error;
- }, 0);
- }
- }
- }
-
- /**
- Inside Ember-Metal, simply uses the methods from `imports.console`.
- Override this to provide more robust logging functionality.
-
- @class Logger
- @namespace Ember
- */
- exports['default'] = {
- /**
- Logs the arguments to the console.
- You can pass as many arguments as you want and they will be joined together with a space.
- ```javascript
- var foo = 1;
- Ember.Logger.log('log value of foo:', foo);
- // "log value of foo: 1" will be printed to the console
- ```
- @method log
- @for Ember.Logger
- @param {*} arguments
- */
- log: consoleMethod('log') || K,
-
- /**
- Prints the arguments to the console with a warning icon.
- You can pass as many arguments as you want and they will be joined together with a space.
- ```javascript
- Ember.Logger.warn('Something happened!');
- // "Something happened!" will be printed to the console with a warning icon.
- ```
- @method warn
- @for Ember.Logger
- @param {*} arguments
- */
- warn: consoleMethod('warn') || K,
-
- /**
- Prints the arguments to the console with an error icon, red text and a stack trace.
- You can pass as many arguments as you want and they will be joined together with a space.
- ```javascript
- Ember.Logger.error('Danger! Danger!');
- // "Danger! Danger!" will be printed to the console in red text.
- ```
- @method error
- @for Ember.Logger
- @param {*} arguments
- */
- error: consoleMethod('error') || K,
-
- /**
- Logs the arguments to the console.
- You can pass as many arguments as you want and they will be joined together with a space.
- ```javascript
- var foo = 1;
- Ember.Logger.info('log value of foo:', foo);
- // "log value of foo: 1" will be printed to the console
- ```
- @method info
- @for Ember.Logger
- @param {*} arguments
- */
- info: consoleMethod('info') || K,
-
- /**
- Logs the arguments to the console in blue text.
- You can pass as many arguments as you want and they will be joined together with a space.
- ```javascript
- var foo = 1;
- Ember.Logger.debug('log value of foo:', foo);
- // "log value of foo: 1" will be printed to the console
- ```
- @method debug
- @for Ember.Logger
- @param {*} arguments
- */
- debug: consoleMethod('debug') || consoleMethod('info') || K,
-
- /**
- If the value passed into `Ember.Logger.assert` is not truthy it will throw an error with a stack trace.
- ```javascript
- Ember.Logger.assert(true); // undefined
- Ember.Logger.assert(true === false); // Throws an Assertion failed error.
- ```
- @method assert
- @for Ember.Logger
- @param {Boolean} bool Value to test
- */
- assert: consoleMethod('assert') || assertPolyfill
- };
-
-});
-enifed('ember-metal/map', ['exports', 'ember-metal/utils', 'ember-metal/array', 'ember-metal/platform/create', 'ember-metal/deprecate_property'], function (exports, utils, array, create, deprecate_property) {
-
- 'use strict';
-
- exports.OrderedSet = OrderedSet;
- exports.Map = Map;
- exports.MapWithDefault = MapWithDefault;
-
- /**
- @module ember-metal
- */
-
- /*
- JavaScript (before ES6) does not have a Map implementation. Objects,
- which are often used as dictionaries, may only have Strings as keys.
-
- Because Ember has a way to get a unique identifier for every object
- via `Ember.guidFor`, we can implement a performant Map with arbitrary
- keys. Because it is commonly used in low-level bookkeeping, Map is
- implemented as a pure JavaScript object for performance.
-
- This implementation follows the current iteration of the ES6 proposal for
- maps (http://wiki.ecmascript.org/doku.php?id=harmony:simple_maps_and_sets),
- with one exception: as we do not have the luxury of in-VM iteration, we implement a
- forEach method for iteration.
-
- Map is mocked out to look like an Ember object, so you can do
- `Ember.Map.create()` for symmetry with other Ember classes.
- */
-
- function missingFunction(fn) {
- throw new TypeError(Object.prototype.toString.call(fn) + " is not a function");
- }
-
- function missingNew(name) {
- throw new TypeError("Constructor " + name + " requires 'new'");
- }
-
- function copyNull(obj) {
- var output = create['default'](null);
-
- for (var prop in obj) {
- // hasOwnPropery is not needed because obj is Object.create(null);
- output[prop] = obj[prop];
- }
-
- return output;
- }
-
- function copyMap(original, newObject) {
- var keys = original._keys.copy();
- var values = copyNull(original._values);
-
- newObject._keys = keys;
- newObject._values = values;
- newObject.size = original.size;
-
- return newObject;
- }
-
- /**
- This class is used internally by Ember and Ember Data.
- Please do not use it at this time. We plan to clean it up
- and add many tests soon.
-
- @class OrderedSet
- @namespace Ember
- @constructor
- @private
- */
- function OrderedSet() {
-
- if (this instanceof OrderedSet) {
- this.clear();
- this._silenceRemoveDeprecation = false;
- } else {
- missingNew("OrderedSet");
- }
- }
-
- /**
- @method create
- @static
- @return {Ember.OrderedSet}
- */
- OrderedSet.create = function () {
- var Constructor = this;
-
- return new Constructor();
- };
-
- OrderedSet.prototype = {
- constructor: OrderedSet,
- /**
- @method clear
- */
- clear: function () {
- this.presenceSet = create['default'](null);
- this.list = [];
- this.size = 0;
- },
-
- /**
- @method add
- @param obj
- @param guid (optional, and for internal use)
- @return {Ember.OrderedSet}
- */
- add: function (obj, _guid) {
- var guid = _guid || utils.guidFor(obj);
- var presenceSet = this.presenceSet;
- var list = this.list;
-
- if (presenceSet[guid] !== true) {
- presenceSet[guid] = true;
- this.size = list.push(obj);
- }
-
- return this;
- },
-
- /**
- @deprecated
- @method remove
- @param obj
- @param _guid (optional and for internal use only)
- @return {Boolean}
- */
- remove: function (obj, _guid) {
- Ember.deprecate('Calling `OrderedSet.prototype.remove` has been deprecated, please use `OrderedSet.prototype.delete` instead.', this._silenceRemoveDeprecation);
-
- return this["delete"](obj, _guid);
- },
-
- /**
- @since 1.8.0
- @method delete
- @param obj
- @param _guid (optional and for internal use only)
- @return {Boolean}
- */
- "delete": function (obj, _guid) {
- var guid = _guid || utils.guidFor(obj);
- var presenceSet = this.presenceSet;
- var list = this.list;
-
- if (presenceSet[guid] === true) {
- delete presenceSet[guid];
- var index = array.indexOf.call(list, obj);
- if (index > -1) {
- list.splice(index, 1);
- }
- this.size = list.length;
- return true;
- } else {
- return false;
- }
- },
-
- /**
- @method isEmpty
- @return {Boolean}
- */
- isEmpty: function () {
- return this.size === 0;
- },
-
- /**
- @method has
- @param obj
- @return {Boolean}
- */
- has: function (obj) {
- if (this.size === 0) {
- return false;
- }
-
- var guid = utils.guidFor(obj);
- var presenceSet = this.presenceSet;
-
- return presenceSet[guid] === true;
- },
-
- /**
- @method forEach
- @param {Function} fn
- @param self
- */
- forEach: function (fn /*, ...thisArg*/) {
- if (typeof fn !== 'function') {
- missingFunction(fn);
- }
-
- if (this.size === 0) {
- return;
- }
-
- var list = this.list;
- var length = arguments.length;
- var i;
-
- if (length === 2) {
- for (i = 0; i < list.length; i++) {
- fn.call(arguments[1], list[i]);
- }
- } else {
- for (i = 0; i < list.length; i++) {
- fn(list[i]);
- }
- }
- },
-
- /**
- @method toArray
- @return {Array}
- */
- toArray: function () {
- return this.list.slice();
- },
-
- /**
- @method copy
- @return {Ember.OrderedSet}
- */
- copy: function () {
- var Constructor = this.constructor;
- var set = new Constructor();
-
- set._silenceRemoveDeprecation = this._silenceRemoveDeprecation;
- set.presenceSet = copyNull(this.presenceSet);
- set.list = this.toArray();
- set.size = this.size;
-
- return set;
- }
- };
-
- deprecate_property.deprecateProperty(OrderedSet.prototype, 'length', 'size');
-
- /**
- A Map stores values indexed by keys. Unlike JavaScript's
- default Objects, the keys of a Map can be any JavaScript
- object.
-
- Internally, a Map has two data structures:
-
- 1. `keys`: an OrderedSet of all of the existing keys
- 2. `values`: a JavaScript Object indexed by the `Ember.guidFor(key)`
-
- When a key/value pair is added for the first time, we
- add the key to the `keys` OrderedSet, and create or
- replace an entry in `values`. When an entry is deleted,
- we delete its entry in `keys` and `values`.
-
- @class Map
- @namespace Ember
- @private
- @constructor
- */
- function Map() {
- if (this instanceof this.constructor) {
- this._keys = OrderedSet.create();
- this._keys._silenceRemoveDeprecation = true;
- this._values = create['default'](null);
- this.size = 0;
- } else {
- missingNew("OrderedSet");
- }
- }
-
- Ember.Map = Map;
-
- /**
- @method create
- @static
- */
- Map.create = function () {
- var Constructor = this;
- return new Constructor();
- };
-
- Map.prototype = {
- constructor: Map,
-
- /**
- This property will change as the number of objects in the map changes.
- @since 1.8.0
- @property size
- @type number
- @default 0
- */
- size: 0,
-
- /**
- Retrieve the value associated with a given key.
- @method get
- @param {*} key
- @return {*} the value associated with the key, or `undefined`
- */
- get: function (key) {
- if (this.size === 0) {
- return;
- }
-
- var values = this._values;
- var guid = utils.guidFor(key);
-
- return values[guid];
- },
-
- /**
- Adds a value to the map. If a value for the given key has already been
- provided, the new value will replace the old value.
- @method set
- @param {*} key
- @param {*} value
- @return {Ember.Map}
- */
- set: function (key, value) {
- var keys = this._keys;
- var values = this._values;
- var guid = utils.guidFor(key);
-
- // ensure we don't store -0
- var k = key === -0 ? 0 : key;
-
- keys.add(k, guid);
-
- values[guid] = value;
-
- this.size = keys.size;
-
- return this;
- },
-
- /**
- @deprecated see delete
- Removes a value from the map for an associated key.
- @method remove
- @param {*} key
- @return {Boolean} true if an item was removed, false otherwise
- */
- remove: function (key) {
- Ember.deprecate('Calling `Map.prototype.remove` has been deprecated, please use `Map.prototype.delete` instead.');
-
- return this["delete"](key);
- },
-
- /**
- Removes a value from the map for an associated key.
- @since 1.8.0
- @method delete
- @param {*} key
- @return {Boolean} true if an item was removed, false otherwise
- */
- "delete": function (key) {
- if (this.size === 0) {
- return false;
- }
- // don't use ES6 "delete" because it will be annoying
- // to use in browsers that are not ES6 friendly;
- var keys = this._keys;
- var values = this._values;
- var guid = utils.guidFor(key);
-
- if (keys["delete"](key, guid)) {
- delete values[guid];
- this.size = keys.size;
- return true;
- } else {
- return false;
- }
- },
-
- /**
- Check whether a key is present.
- @method has
- @param {*} key
- @return {Boolean} true if the item was present, false otherwise
- */
- has: function (key) {
- return this._keys.has(key);
- },
-
- /**
- Iterate over all the keys and values. Calls the function once
- for each key, passing in value, key, and the map being iterated over,
- in that order.
- The keys are guaranteed to be iterated over in insertion order.
- @method forEach
- @param {Function} callback
- @param {*} self if passed, the `this` value inside the
- callback. By default, `this` is the map.
- */
- forEach: function (callback /*, ...thisArg*/) {
- if (typeof callback !== 'function') {
- missingFunction(callback);
- }
-
- if (this.size === 0) {
- return;
- }
-
- var length = arguments.length;
- var map = this;
- var cb, thisArg;
-
- if (length === 2) {
- thisArg = arguments[1];
- cb = function (key) {
- callback.call(thisArg, map.get(key), key, map);
- };
- } else {
- cb = function (key) {
- callback(map.get(key), key, map);
- };
- }
-
- this._keys.forEach(cb);
- },
-
- /**
- @method clear
- */
- clear: function () {
- this._keys.clear();
- this._values = create['default'](null);
- this.size = 0;
- },
-
- /**
- @method copy
- @return {Ember.Map}
- */
- copy: function () {
- return copyMap(this, new Map());
- }
- };
-
- deprecate_property.deprecateProperty(Map.prototype, 'length', 'size');
-
- /**
- @class MapWithDefault
- @namespace Ember
- @extends Ember.Map
- @private
- @constructor
- @param [options]
- @param {*} [options.defaultValue]
- */
- function MapWithDefault(options) {
- this._super$constructor();
- this.defaultValue = options.defaultValue;
- }
-
- /**
- @method create
- @static
- @param [options]
- @param {*} [options.defaultValue]
- @return {Ember.MapWithDefault|Ember.Map} If options are passed, returns
- `Ember.MapWithDefault` otherwise returns `Ember.Map`
- */
- MapWithDefault.create = function (options) {
- if (options) {
- return new MapWithDefault(options);
- } else {
- return new Map();
- }
- };
-
- MapWithDefault.prototype = create['default'](Map.prototype);
- MapWithDefault.prototype.constructor = MapWithDefault;
- MapWithDefault.prototype._super$constructor = Map;
- MapWithDefault.prototype._super$get = Map.prototype.get;
-
- /**
- Retrieve the value associated with a given key.
-
- @method get
- @param {*} key
- @return {*} the value associated with the key, or the default value
- */
- MapWithDefault.prototype.get = function (key) {
- var hasValue = this.has(key);
-
- if (hasValue) {
- return this._super$get(key);
- } else {
- var defaultValue = this.defaultValue(key);
- this.set(key, defaultValue);
- return defaultValue;
- }
- };
-
- /**
- @method copy
- @return {Ember.MapWithDefault}
- */
- MapWithDefault.prototype.copy = function () {
- var Constructor = this.constructor;
- return copyMap(this, new Constructor({
- defaultValue: this.defaultValue
- }));
- };
-
- exports['default'] = Map;
-
-});
-enifed('ember-metal/merge', ['exports', 'ember-metal/keys'], function (exports, keys) {
-
- 'use strict';
-
-
- exports['default'] = merge;
- function merge(original, updates) {
- if (!updates || typeof updates !== 'object') {
- return original;
- }
-
- var props = keys['default'](updates);
- var prop;
- var length = props.length;
-
- for (var i = 0; i < length; i++) {
- prop = props[i];
- original[prop] = updates[prop];
- }
-
- return original;
- }
-
-});
-enifed('ember-metal/mixin', ['exports', 'ember-metal/core', 'ember-metal/merge', 'ember-metal/array', 'ember-metal/platform/create', 'ember-metal/property_get', 'ember-metal/property_set', 'ember-metal/utils', 'ember-metal/expand_properties', 'ember-metal/properties', 'ember-metal/computed', 'ember-metal/binding', 'ember-metal/observer', 'ember-metal/events', 'ember-metal/streams/utils'], function (exports, Ember, merge, array, o_create, property_get, property_set, utils, expandProperties, ember_metal__properties, computed, ember_metal__binding, ember_metal__observer, events, streams__utils) {
-
-
- exports.mixin = mixin;
- exports.required = required;
- exports.aliasMethod = aliasMethod;
- exports.observer = observer;
- exports.immediateObserver = immediateObserver;
- exports.beforeObserver = beforeObserver;
- exports.Mixin = Mixin;
-
- "REMOVE_USE_STRICT: true";var REQUIRED;
- var a_slice = [].slice;
-
- function superFunction() {
- var func = this.__nextSuper;
- var ret;
-
- if (func) {
- var length = arguments.length;
- this.__nextSuper = null;
- if (length === 0) {
- ret = func.call(this);
- } else if (length === 1) {
- ret = func.call(this, arguments[0]);
- } else if (length === 2) {
- ret = func.call(this, arguments[0], arguments[1]);
- } else {
- ret = func.apply(this, arguments);
- }
- this.__nextSuper = func;
- return ret;
- }
- }
-
- // ensure we prime superFunction to mitigate
- // v8 bug potentially incorrectly deopts this function: https://code.google.com/p/v8/issues/detail?id=3709
- var primer = {
- __nextSuper: function (a, b, c, d) {}
- };
-
- superFunction.call(primer);
- superFunction.call(primer, 1);
- superFunction.call(primer, 1, 2);
- superFunction.call(primer, 1, 2, 3);
-
- function mixinsMeta(obj) {
- var m = utils.meta(obj, true);
- var ret = m.mixins;
- if (!ret) {
- ret = m.mixins = {};
- } else if (!m.hasOwnProperty('mixins')) {
- ret = m.mixins = o_create['default'](ret);
- }
- return ret;
- }
-
- function isMethod(obj) {
- return 'function' === typeof obj && obj.isMethod !== false && obj !== Boolean && obj !== Object && obj !== Number && obj !== Array && obj !== Date && obj !== String;
- }
-
- var CONTINUE = {};
-
- function mixinProperties(mixinsMeta, mixin) {
- var guid;
-
- if (mixin instanceof Mixin) {
- guid = utils.guidFor(mixin);
- if (mixinsMeta[guid]) {
- return CONTINUE;
- }
- mixinsMeta[guid] = mixin;
- return mixin.properties;
- } else {
- return mixin; // apply anonymous mixin properties
- }
- }
-
- function concatenatedMixinProperties(concatProp, props, values, base) {
- var concats;
-
- // reset before adding each new mixin to pickup concats from previous
- concats = values[concatProp] || base[concatProp];
- if (props[concatProp]) {
- concats = concats ? concats.concat(props[concatProp]) : props[concatProp];
- }
-
- return concats;
- }
-
- function giveDescriptorSuper(meta, key, property, values, descs, base) {
- var superProperty;
-
- // Computed properties override methods, and do not call super to them
- if (values[key] === undefined) {
- // Find the original descriptor in a parent mixin
- superProperty = descs[key];
- }
-
- // If we didn't find the original descriptor in a parent mixin, find
- // it on the original object.
- if (!superProperty) {
- var possibleDesc = base[key];
- var superDesc = possibleDesc !== null && typeof possibleDesc === 'object' && possibleDesc.isDescriptor ? possibleDesc : undefined;
-
- superProperty = superDesc;
- }
-
- if (superProperty === undefined || !(superProperty instanceof computed.ComputedProperty)) {
- return property;
- }
-
- // Since multiple mixins may inherit from the same parent, we need
- // to clone the computed property so that other mixins do not receive
- // the wrapped version.
- property = o_create['default'](property);
- property._getter = utils.wrap(property._getter, superProperty._getter);
- if (superProperty._setter) {
- if (property._setter) {
- property._setter = utils.wrap(property._setter, superProperty._setter);
- } else {
- property._setter = superProperty._setter;
- }
- }
-
- return property;
- }
-
- var sourceAvailable = (function () {
- return this;
- }).toString().indexOf('return this;') > -1;
-
- function giveMethodSuper(obj, key, method, values, descs) {
- var superMethod;
-
- // Methods overwrite computed properties, and do not call super to them.
- if (descs[key] === undefined) {
- // Find the original method in a parent mixin
- superMethod = values[key];
- }
-
- // If we didn't find the original value in a parent mixin, find it in
- // the original object
- superMethod = superMethod || obj[key];
-
- // Only wrap the new method if the original method was a function
- if (superMethod === undefined || 'function' !== typeof superMethod) {
- return method;
- }
-
- var hasSuper;
- if (sourceAvailable) {
- hasSuper = method.__hasSuper;
-
- if (hasSuper === undefined) {
- hasSuper = method.toString().indexOf('_super') > -1;
- method.__hasSuper = hasSuper;
- }
- }
-
- if (sourceAvailable === false || hasSuper) {
- return utils.wrap(method, superMethod);
- } else {
- return method;
- }
- }
-
- function applyConcatenatedProperties(obj, key, value, values) {
- var baseValue = values[key] || obj[key];
-
- if (baseValue) {
- if ('function' === typeof baseValue.concat) {
- if (value === null || value === undefined) {
- return baseValue;
- } else {
- return baseValue.concat(value);
- }
- } else {
- return utils.makeArray(baseValue).concat(value);
- }
- } else {
- return utils.makeArray(value);
- }
- }
-
- function applyMergedProperties(obj, key, value, values) {
- var baseValue = values[key] || obj[key];
-
- Ember['default'].assert("You passed in `" + JSON.stringify(value) + "` as the value for `" + key + "` but `" + key + "` cannot be an Array", !utils.isArray(value));
-
- if (!baseValue) {
- return value;
- }
-
- var newBase = merge['default']({}, baseValue);
- var hasFunction = false;
-
- for (var prop in value) {
- if (!value.hasOwnProperty(prop)) {
- continue;
- }
-
- var propValue = value[prop];
- if (isMethod(propValue)) {
- // TODO: support for Computed Properties, etc?
- hasFunction = true;
- newBase[prop] = giveMethodSuper(obj, prop, propValue, baseValue, {});
- } else {
- newBase[prop] = propValue;
- }
- }
-
- if (hasFunction) {
- newBase._super = superFunction;
- }
-
- return newBase;
- }
-
- function addNormalizedProperty(base, key, value, meta, descs, values, concats, mergings) {
- if (value instanceof ember_metal__properties.Descriptor) {
- if (value === REQUIRED && descs[key]) {
- return CONTINUE;
- }
-
- // Wrap descriptor function to implement
- // __nextSuper() if needed
- if (value._getter) {
- value = giveDescriptorSuper(meta, key, value, values, descs, base);
- }
-
- descs[key] = value;
- values[key] = undefined;
- } else {
- if (concats && array.indexOf.call(concats, key) >= 0 || key === 'concatenatedProperties' || key === 'mergedProperties') {
- value = applyConcatenatedProperties(base, key, value, values);
- } else if (mergings && array.indexOf.call(mergings, key) >= 0) {
- value = applyMergedProperties(base, key, value, values);
- } else if (isMethod(value)) {
- value = giveMethodSuper(base, key, value, values, descs);
- }
-
- descs[key] = undefined;
- values[key] = value;
- }
- }
-
- function mergeMixins(mixins, m, descs, values, base, keys) {
- var currentMixin, props, key, concats, mergings, meta;
-
- function removeKeys(keyName) {
- delete descs[keyName];
- delete values[keyName];
- }
-
- for (var i = 0, l = mixins.length; i < l; i++) {
- currentMixin = mixins[i];
- Ember['default'].assert("Expected hash or Mixin instance, got " + Object.prototype.toString.call(currentMixin), typeof currentMixin === 'object' && currentMixin !== null && Object.prototype.toString.call(currentMixin) !== '[object Array]');
-
- props = mixinProperties(m, currentMixin);
- if (props === CONTINUE) {
- continue;
- }
-
- if (props) {
- meta = utils.meta(base);
- if (base.willMergeMixin) {
- base.willMergeMixin(props);
- }
- concats = concatenatedMixinProperties('concatenatedProperties', props, values, base);
- mergings = concatenatedMixinProperties('mergedProperties', props, values, base);
-
- for (key in props) {
- if (!props.hasOwnProperty(key)) {
- continue;
- }
- keys.push(key);
- addNormalizedProperty(base, key, props[key], meta, descs, values, concats, mergings);
- }
-
- // manually copy toString() because some JS engines do not enumerate it
- if (props.hasOwnProperty('toString')) {
- base.toString = props.toString;
- }
- } else if (currentMixin.mixins) {
- mergeMixins(currentMixin.mixins, m, descs, values, base, keys);
- if (currentMixin._without) {
- array.forEach.call(currentMixin._without, removeKeys);
- }
- }
- }
- }
-
- var IS_BINDING = /^.+Binding$/;
-
- function detectBinding(obj, key, value, m) {
- if (IS_BINDING.test(key)) {
- var bindings = m.bindings;
- if (!bindings) {
- bindings = m.bindings = {};
- } else if (!m.hasOwnProperty('bindings')) {
- bindings = m.bindings = o_create['default'](m.bindings);
- }
- bindings[key] = value;
- }
- }
-
- function connectStreamBinding(obj, key, stream) {
- var onNotify = function (stream) {
- ember_metal__observer._suspendObserver(obj, key, null, didChange, function () {
- property_set.trySet(obj, key, stream.value());
- });
- };
-
- var didChange = function () {
- stream.setValue(property_get.get(obj, key), onNotify);
- };
-
- // Initialize value
- property_set.set(obj, key, stream.value());
-
- ember_metal__observer.addObserver(obj, key, null, didChange);
-
- stream.subscribe(onNotify);
-
- if (obj._streamBindingSubscriptions === undefined) {
- obj._streamBindingSubscriptions = o_create['default'](null);
- }
-
- obj._streamBindingSubscriptions[key] = onNotify;
- }
-
- function connectBindings(obj, m) {
- // TODO Mixin.apply(instance) should disconnect binding if exists
- var bindings = m.bindings;
- var key, binding, to;
- if (bindings) {
- for (key in bindings) {
- binding = bindings[key];
- if (binding) {
- to = key.slice(0, -7); // strip Binding off end
- if (streams__utils.isStream(binding)) {
- connectStreamBinding(obj, to, binding);
- continue;
- } else if (binding instanceof ember_metal__binding.Binding) {
- binding = binding.copy(); // copy prototypes' instance
- binding.to(to);
- } else {
- // binding is string path
- binding = new ember_metal__binding.Binding(to, binding);
- }
- binding.connect(obj);
- obj[key] = binding;
- }
- }
- // mark as applied
- m.bindings = {};
- }
- }
-
- function finishPartial(obj, m) {
- connectBindings(obj, m || utils.meta(obj));
- return obj;
- }
-
- function followAlias(obj, desc, m, descs, values) {
- var altKey = desc.methodName;
- var value;
- var possibleDesc;
- if (descs[altKey] || values[altKey]) {
- value = values[altKey];
- desc = descs[altKey];
- } else if ((possibleDesc = obj[altKey]) && possibleDesc !== null && typeof possibleDesc === 'object' && possibleDesc.isDescriptor) {
- desc = possibleDesc;
- value = undefined;
- } else {
- desc = undefined;
- value = obj[altKey];
- }
-
- return { desc: desc, value: value };
- }
-
- function updateObserversAndListeners(obj, key, observerOrListener, pathsKey, updateMethod) {
- var paths = observerOrListener[pathsKey];
-
- if (paths) {
- for (var i = 0, l = paths.length; i < l; i++) {
- updateMethod(obj, paths[i], null, key);
- }
- }
- }
-
- function replaceObserversAndListeners(obj, key, observerOrListener) {
- var prev = obj[key];
-
- if ('function' === typeof prev) {
- updateObserversAndListeners(obj, key, prev, '__ember_observesBefore__', ember_metal__observer.removeBeforeObserver);
- updateObserversAndListeners(obj, key, prev, '__ember_observes__', ember_metal__observer.removeObserver);
- updateObserversAndListeners(obj, key, prev, '__ember_listens__', events.removeListener);
- }
-
- if ('function' === typeof observerOrListener) {
- updateObserversAndListeners(obj, key, observerOrListener, '__ember_observesBefore__', ember_metal__observer.addBeforeObserver);
- updateObserversAndListeners(obj, key, observerOrListener, '__ember_observes__', ember_metal__observer.addObserver);
- updateObserversAndListeners(obj, key, observerOrListener, '__ember_listens__', events.addListener);
- }
- }
-
- function applyMixin(obj, mixins, partial) {
- var descs = {};
- var values = {};
- var m = utils.meta(obj);
- var keys = [];
- var key, value, desc;
-
- obj._super = superFunction;
-
- // Go through all mixins and hashes passed in, and:
- //
- // * Handle concatenated properties
- // * Handle merged properties
- // * Set up _super wrapping if necessary
- // * Set up computed property descriptors
- // * Copying `toString` in broken browsers
- mergeMixins(mixins, mixinsMeta(obj), descs, values, obj, keys);
-
- for (var i = 0, l = keys.length; i < l; i++) {
- key = keys[i];
- if (key === 'constructor' || !values.hasOwnProperty(key)) {
- continue;
- }
-
- desc = descs[key];
- value = values[key];
-
- if (desc === REQUIRED) {
- continue;
- }
-
- while (desc && desc instanceof Alias) {
- var followed = followAlias(obj, desc, m, descs, values);
- desc = followed.desc;
- value = followed.value;
- }
-
- if (desc === undefined && value === undefined) {
- continue;
- }
-
- replaceObserversAndListeners(obj, key, value);
- detectBinding(obj, key, value, m);
- ember_metal__properties.defineProperty(obj, key, desc, value, m);
- }
-
- if (!partial) {
- // don't apply to prototype
- finishPartial(obj, m);
- }
-
- return obj;
- }
-
- /**
- @method mixin
- @for Ember
- @param obj
- @param mixins*
- @return obj
- */
-
- function mixin(obj) {
- for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
- args[_key - 1] = arguments[_key];
- }
-
- applyMixin(obj, args, false);
- return obj;
- }
-
- /**
- The `Ember.Mixin` class allows you to create mixins, whose properties can be
- added to other classes. For instance,
-
- ```javascript
- App.Editable = Ember.Mixin.create({
- edit: function() {
- console.log('starting to edit');
- this.set('isEditing', true);
- },
- isEditing: false
- });
-
- // Mix mixins into classes by passing them as the first arguments to
- // .extend.
- App.CommentView = Ember.View.extend(App.Editable, {
- template: Ember.Handlebars.compile('{{#if view.isEditing}}...{{else}}...{{/if}}')
- });
-
- commentView = App.CommentView.create();
- commentView.edit(); // outputs 'starting to edit'
- ```
-
- Note that Mixins are created with `Ember.Mixin.create`, not
- `Ember.Mixin.extend`.
-
- Note that mixins extend a constructor's prototype so arrays and object literals
- defined as properties will be shared amongst objects that implement the mixin.
- If you want to define a property in a mixin that is not shared, you can define
- it either as a computed property or have it be created on initialization of the object.
-
- ```javascript
- //filters array will be shared amongst any object implementing mixin
- App.Filterable = Ember.Mixin.create({
- filters: Ember.A()
- });
-
- //filters will be a separate array for every object implementing the mixin
- App.Filterable = Ember.Mixin.create({
- filters: Ember.computed(function() {return Ember.A();})
- });
-
- //filters will be created as a separate array during the object's initialization
- App.Filterable = Ember.Mixin.create({
- init: function() {
- this._super.apply(this, arguments);
- this.set("filters", Ember.A());
- }
- });
- ```
-
- @class Mixin
- @namespace Ember
- */
- exports['default'] = Mixin;
- function Mixin(args, properties) {
- this.properties = properties;
-
- var length = args && args.length;
-
- if (length > 0) {
- var m = new Array(length);
-
- for (var i = 0; i < length; i++) {
- var x = args[i];
- if (x instanceof Mixin) {
- m[i] = x;
- } else {
- m[i] = new Mixin(undefined, x);
- }
- }
-
- this.mixins = m;
- } else {
- this.mixins = undefined;
- }
- this.ownerConstructor = undefined;
- }
-
- Mixin._apply = applyMixin;
-
- Mixin.applyPartial = function (obj) {
- var args = a_slice.call(arguments, 1);
- return applyMixin(obj, args, true);
- };
-
- Mixin.finishPartial = finishPartial;
-
- // ES6TODO: this relies on a global state?
- Ember['default'].anyUnprocessedMixins = false;
-
- /**
- @method create
- @static
- @param arguments*
- */
- Mixin.create = function () {
- // ES6TODO: this relies on a global state?
- Ember['default'].anyUnprocessedMixins = true;
- var M = this;
-
- for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
- args[_key2] = arguments[_key2];
- }
-
- return new M(args, undefined);
- };
-
- var MixinPrototype = Mixin.prototype;
-
- /**
- @method reopen
- @param arguments*
- */
- MixinPrototype.reopen = function () {
- var currentMixin;
-
- if (this.properties) {
- currentMixin = new Mixin(undefined, this.properties);
- this.properties = undefined;
- this.mixins = [currentMixin];
- } else if (!this.mixins) {
- this.mixins = [];
- }
-
- var len = arguments.length;
- var mixins = this.mixins;
- var idx;
-
- for (idx = 0; idx < len; idx++) {
- currentMixin = arguments[idx];
- Ember['default'].assert("Expected hash or Mixin instance, got " + Object.prototype.toString.call(currentMixin), typeof currentMixin === 'object' && currentMixin !== null && Object.prototype.toString.call(currentMixin) !== '[object Array]');
-
- if (currentMixin instanceof Mixin) {
- mixins.push(currentMixin);
- } else {
- mixins.push(new Mixin(undefined, currentMixin));
- }
- }
-
- return this;
- };
-
- /**
- @method apply
- @param obj
- @return applied object
- */
- MixinPrototype.apply = function (obj) {
- return applyMixin(obj, [this], false);
- };
-
- MixinPrototype.applyPartial = function (obj) {
- return applyMixin(obj, [this], true);
- };
-
- function _detect(curMixin, targetMixin, seen) {
- var guid = utils.guidFor(curMixin);
-
- if (seen[guid]) {
- return false;
- }
- seen[guid] = true;
-
- if (curMixin === targetMixin) {
- return true;
- }
- var mixins = curMixin.mixins;
- var loc = mixins ? mixins.length : 0;
- while (--loc >= 0) {
- if (_detect(mixins[loc], targetMixin, seen)) {
- return true;
- }
- }
- return false;
- }
-
- /**
- @method detect
- @param obj
- @return {Boolean}
- */
- MixinPrototype.detect = function (obj) {
- if (!obj) {
- return false;
- }
- if (obj instanceof Mixin) {
- return _detect(obj, this, {});
- }
- var m = obj['__ember_meta__'];
- var mixins = m && m.mixins;
- if (mixins) {
- return !!mixins[utils.guidFor(this)];
- }
- return false;
- };
-
- MixinPrototype.without = function () {
- var ret = new Mixin([this]);
-
- for (var _len3 = arguments.length, args = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
- args[_key3] = arguments[_key3];
- }
-
- ret._without = args;
- return ret;
- };
-
- function _keys(ret, mixin, seen) {
- if (seen[utils.guidFor(mixin)]) {
- return;
- }
- seen[utils.guidFor(mixin)] = true;
-
- if (mixin.properties) {
- var props = mixin.properties;
- for (var key in props) {
- if (props.hasOwnProperty(key)) {
- ret[key] = true;
- }
- }
- } else if (mixin.mixins) {
- array.forEach.call(mixin.mixins, function (x) {
- _keys(ret, x, seen);
- });
- }
- }
-
- MixinPrototype.keys = function () {
- var keys = {};
- var seen = {};
- var ret = [];
- _keys(keys, this, seen);
- for (var key in keys) {
- if (keys.hasOwnProperty(key)) {
- ret.push(key);
- }
- }
- return ret;
- };
-
- // returns the mixins currently applied to the specified object
- // TODO: Make Ember.mixin
- Mixin.mixins = function (obj) {
- var m = obj['__ember_meta__'];
- var mixins = m && m.mixins;
- var ret = [];
-
- if (!mixins) {
- return ret;
- }
-
- for (var key in mixins) {
- var currentMixin = mixins[key];
-
- // skip primitive mixins since these are always anonymous
- if (!currentMixin.properties) {
- ret.push(currentMixin);
- }
- }
-
- return ret;
- };
-
- REQUIRED = new ember_metal__properties.Descriptor();
- REQUIRED.toString = function () {
- return '(Required Property)';
- };
-
- /**
- Denotes a required property for a mixin
-
- @method required
- @for Ember
- */
-
- function required() {
- Ember['default'].deprecate('Ember.required is deprecated as its behavior is inconsistent and unreliable.', false);
- return REQUIRED;
- }
-
- function Alias(methodName) {
- this.isDescriptor = true;
- this.methodName = methodName;
- }
-
- Alias.prototype = new ember_metal__properties.Descriptor();
-
- /**
- Makes a method available via an additional name.
-
- ```javascript
- App.Person = Ember.Object.extend({
- name: function() {
- return 'Tomhuda Katzdale';
- },
- moniker: Ember.aliasMethod('name')
- });
-
- var goodGuy = App.Person.create();
-
- goodGuy.name(); // 'Tomhuda Katzdale'
- goodGuy.moniker(); // 'Tomhuda Katzdale'
- ```
-
- @method aliasMethod
- @for Ember
- @param {String} methodName name of the method to alias
- */
-
- function aliasMethod(methodName) {
- return new Alias(methodName);
- }
-
- // ..........................................................
- // OBSERVER HELPER
- //
-
- /**
- Specify a method that observes property changes.
-
- ```javascript
- Ember.Object.extend({
- valueObserver: Ember.observer('value', function() {
- // Executes whenever the "value" property changes
- })
- });
- ```
-
- In the future this method may become asynchronous. If you want to ensure
- synchronous behavior, use `immediateObserver`.
-
- Also available as `Function.prototype.observes` if prototype extensions are
- enabled.
-
- @method observer
- @for Ember
- @param {String} propertyNames*
- @param {Function} func
- @return func
- */
-
- function observer() {
- for (var _len4 = arguments.length, args = Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
- args[_key4] = arguments[_key4];
- }
-
- var func = args.slice(-1)[0];
- var paths;
-
- var addWatchedProperty = function (path) {
- paths.push(path);
- };
- var _paths = args.slice(0, -1);
-
- if (typeof func !== "function") {
- // revert to old, soft-deprecated argument ordering
-
- func = args[0];
- _paths = args.slice(1);
- }
-
- paths = [];
-
- for (var i = 0; i < _paths.length; ++i) {
- expandProperties['default'](_paths[i], addWatchedProperty);
- }
-
- if (typeof func !== "function") {
- throw new Ember['default'].Error("Ember.observer called without a function");
- }
-
- func.__ember_observes__ = paths;
- return func;
- }
-
- /**
- Specify a method that observes property changes.
-
- ```javascript
- Ember.Object.extend({
- valueObserver: Ember.immediateObserver('value', function() {
- // Executes whenever the "value" property changes
- })
- });
- ```
-
- In the future, `Ember.observer` may become asynchronous. In this event,
- `Ember.immediateObserver` will maintain the synchronous behavior.
-
- Also available as `Function.prototype.observesImmediately` if prototype extensions are
- enabled.
-
- @method immediateObserver
- @for Ember
- @param {String} propertyNames*
- @param {Function} func
- @return func
- */
-
- function immediateObserver() {
- for (var i = 0, l = arguments.length; i < l; i++) {
- var arg = arguments[i];
- Ember['default'].assert("Immediate observers must observe internal properties only, not properties on other objects.", typeof arg !== "string" || arg.indexOf('.') === -1);
- }
-
- return observer.apply(this, arguments);
- }
-
- /**
- When observers fire, they are called with the arguments `obj`, `keyName`.
-
- Note, `@each.property` observer is called per each add or replace of an element
- and it's not called with a specific enumeration item.
-
- A `beforeObserver` fires before a property changes.
-
- A `beforeObserver` is an alternative form of `.observesBefore()`.
-
- ```javascript
- App.PersonView = Ember.View.extend({
- friends: [{ name: 'Tom' }, { name: 'Stefan' }, { name: 'Kris' }],
-
- valueWillChange: Ember.beforeObserver('content.value', function(obj, keyName) {
- this.changingFrom = obj.get(keyName);
- }),
-
- valueDidChange: Ember.observer('content.value', function(obj, keyName) {
- // only run if updating a value already in the DOM
- if (this.get('state') === 'inDOM') {
- var color = obj.get(keyName) > this.changingFrom ? 'green' : 'red';
- // logic
- }
- }),
-
- friendsDidChange: Ember.observer('friends.@each.name', function(obj, keyName) {
- // some logic
- // obj.get(keyName) returns friends array
- })
- });
- ```
-
- Also available as `Function.prototype.observesBefore` if prototype extensions are
- enabled.
-
- @method beforeObserver
- @for Ember
- @param {String} propertyNames*
- @param {Function} func
- @return func
- */
-
- function beforeObserver() {
- for (var _len5 = arguments.length, args = Array(_len5), _key5 = 0; _key5 < _len5; _key5++) {
- args[_key5] = arguments[_key5];
- }
-
- var func = args.slice(-1)[0];
- var paths;
-
- var addWatchedProperty = function (path) {
- paths.push(path);
- };
-
- var _paths = args.slice(0, -1);
-
- if (typeof func !== "function") {
- // revert to old, soft-deprecated argument ordering
-
- func = args[0];
- _paths = args.slice(1);
- }
-
- paths = [];
-
- for (var i = 0; i < _paths.length; ++i) {
- expandProperties['default'](_paths[i], addWatchedProperty);
- }
-
- if (typeof func !== "function") {
- throw new Ember['default'].Error("Ember.beforeObserver called without a function");
- }
-
- func.__ember_observesBefore__ = paths;
- return func;
- }
-
- exports.IS_BINDING = IS_BINDING;
- exports.REQUIRED = REQUIRED;
-
-});
-enifed('ember-metal/observer', ['exports', 'ember-metal/watching', 'ember-metal/array', 'ember-metal/events'], function (exports, watching, array, ember_metal__events) {
-
- 'use strict';
-
- exports.addObserver = addObserver;
- exports.observersFor = observersFor;
- exports.removeObserver = removeObserver;
- exports.addBeforeObserver = addBeforeObserver;
- exports._suspendBeforeObserver = _suspendBeforeObserver;
- exports._suspendObserver = _suspendObserver;
- exports._suspendBeforeObservers = _suspendBeforeObservers;
- exports._suspendObservers = _suspendObservers;
- exports.beforeObserversFor = beforeObserversFor;
- exports.removeBeforeObserver = removeBeforeObserver;
-
- var AFTER_OBSERVERS = ':change';
- var BEFORE_OBSERVERS = ':before';
-
- function changeEvent(keyName) {
- return keyName + AFTER_OBSERVERS;
- }
-
- function beforeEvent(keyName) {
- return keyName + BEFORE_OBSERVERS;
- }
-
- /**
- @method addObserver
- @for Ember
- @param obj
- @param {String} path
- @param {Object|Function} targetOrMethod
- @param {Function|String} [method]
- */
-
- function addObserver(obj, _path, target, method) {
- ember_metal__events.addListener(obj, changeEvent(_path), target, method);
- watching.watch(obj, _path);
-
- return this;
- }
-
- function observersFor(obj, path) {
- return ember_metal__events.listenersFor(obj, changeEvent(path));
- }
-
- /**
- @method removeObserver
- @for Ember
- @param obj
- @param {String} path
- @param {Object|Function} target
- @param {Function|String} [method]
- */
-
- function removeObserver(obj, path, target, method) {
- watching.unwatch(obj, path);
- ember_metal__events.removeListener(obj, changeEvent(path), target, method);
-
- return this;
- }
-
- /**
- @method addBeforeObserver
- @for Ember
- @param obj
- @param {String} path
- @param {Object|Function} target
- @param {Function|String} [method]
- */
-
- function addBeforeObserver(obj, path, target, method) {
- ember_metal__events.addListener(obj, beforeEvent(path), target, method);
- watching.watch(obj, path);
-
- return this;
- }
-
- // Suspend observer during callback.
- //
- // This should only be used by the target of the observer
- // while it is setting the observed path.
-
- function _suspendBeforeObserver(obj, path, target, method, callback) {
- return ember_metal__events.suspendListener(obj, beforeEvent(path), target, method, callback);
- }
-
- function _suspendObserver(obj, path, target, method, callback) {
- return ember_metal__events.suspendListener(obj, changeEvent(path), target, method, callback);
- }
-
- function _suspendBeforeObservers(obj, paths, target, method, callback) {
- var events = array.map.call(paths, beforeEvent);
- return ember_metal__events.suspendListeners(obj, events, target, method, callback);
- }
-
- function _suspendObservers(obj, paths, target, method, callback) {
- var events = array.map.call(paths, changeEvent);
- return ember_metal__events.suspendListeners(obj, events, target, method, callback);
- }
-
- function beforeObserversFor(obj, path) {
- return ember_metal__events.listenersFor(obj, beforeEvent(path));
- }
-
- /**
- @method removeBeforeObserver
- @for Ember
- @param obj
- @param {String} path
- @param {Object|Function} target
- @param {Function|String} [method]
- */
-
- function removeBeforeObserver(obj, path, target, method) {
- watching.unwatch(obj, path);
- ember_metal__events.removeListener(obj, beforeEvent(path), target, method);
-
- return this;
- }
-
-});
-enifed('ember-metal/observer_set', ['exports', 'ember-metal/utils', 'ember-metal/events'], function (exports, utils, events) {
-
- 'use strict';
-
- exports['default'] = ObserverSet;
- function ObserverSet() {
- this.clear();
- }
-
- ObserverSet.prototype.add = function (sender, keyName, eventName) {
- var observerSet = this.observerSet;
- var observers = this.observers;
- var senderGuid = utils.guidFor(sender);
- var keySet = observerSet[senderGuid];
- var index;
-
- if (!keySet) {
- observerSet[senderGuid] = keySet = {};
- }
- index = keySet[keyName];
- if (index === undefined) {
- index = observers.push({
- sender: sender,
- keyName: keyName,
- eventName: eventName,
- listeners: []
- }) - 1;
- keySet[keyName] = index;
- }
- return observers[index].listeners;
- };
-
- ObserverSet.prototype.flush = function () {
- var observers = this.observers;
- var i, len, observer, sender;
- this.clear();
- for (i = 0, len = observers.length; i < len; ++i) {
- observer = observers[i];
- sender = observer.sender;
- if (sender.isDestroying || sender.isDestroyed) {
- continue;
- }
- events.sendEvent(sender, observer.eventName, [sender, observer.keyName], observer.listeners);
- }
- };
-
- ObserverSet.prototype.clear = function () {
- this.observerSet = {};
- this.observers = [];
- };
-
-});
-enifed('ember-metal/path_cache', ['exports', 'ember-metal/cache'], function (exports, Cache) {
-
- 'use strict';
-
- exports.isGlobal = isGlobal;
- exports.isGlobalPath = isGlobalPath;
- exports.hasThis = hasThis;
- exports.isPath = isPath;
- exports.getFirstKey = getFirstKey;
- exports.getTailPath = getTailPath;
-
- var IS_GLOBAL = /^[A-Z$]/;
- var IS_GLOBAL_PATH = /^[A-Z$].*[\.]/;
- var HAS_THIS = 'this.';
-
- var isGlobalCache = new Cache['default'](1000, function (key) {
- return IS_GLOBAL.test(key);
- });
-
- var isGlobalPathCache = new Cache['default'](1000, function (key) {
- return IS_GLOBAL_PATH.test(key);
- });
-
- var hasThisCache = new Cache['default'](1000, function (key) {
- return key.lastIndexOf(HAS_THIS, 0) === 0;
- });
-
- var firstDotIndexCache = new Cache['default'](1000, function (key) {
- return key.indexOf('.');
- });
-
- var firstKeyCache = new Cache['default'](1000, function (path) {
- var index = firstDotIndexCache.get(path);
- if (index === -1) {
- return path;
- } else {
- return path.slice(0, index);
- }
- });
-
- var tailPathCache = new Cache['default'](1000, function (path) {
- var index = firstDotIndexCache.get(path);
- if (index !== -1) {
- return path.slice(index + 1);
- }
- });
-
- var caches = {
- isGlobalCache: isGlobalCache,
- isGlobalPathCache: isGlobalPathCache,
- hasThisCache: hasThisCache,
- firstDotIndexCache: firstDotIndexCache,
- firstKeyCache: firstKeyCache,
- tailPathCache: tailPathCache
- };
-
- function isGlobal(path) {
- return isGlobalCache.get(path);
- }
-
- function isGlobalPath(path) {
- return isGlobalPathCache.get(path);
- }
-
- function hasThis(path) {
- return hasThisCache.get(path);
- }
-
- function isPath(path) {
- return firstDotIndexCache.get(path) !== -1;
- }
-
- function getFirstKey(path) {
- return firstKeyCache.get(path);
- }
-
- function getTailPath(path) {
- return tailPathCache.get(path);
- }
-
- exports.caches = caches;
-
-});
-enifed('ember-metal/platform/create', ['exports', 'ember-metal/platform/define_properties'], function (exports, defineProperties) {
-
-
-
-
- "REMOVE_USE_STRICT: true";var create;
- // ES5 15.2.3.5
- // http://es5.github.com/#x15.2.3.5
- if (!(Object.create && !Object.create(null).hasOwnProperty)) {
- /* jshint scripturl:true, proto:true */
- // Contributed by Brandon Benvie, October, 2012
- var createEmpty;
- var supportsProto = !({ '__proto__': null } instanceof Object);
- // the following produces false positives
- // in Opera Mini => not a reliable check
- // Object.prototype.__proto__ === null
- if (supportsProto || typeof document === 'undefined') {
- createEmpty = function () {
- return { "__proto__": null };
- };
- } else {
- // In old IE __proto__ can't be used to manually set `null`, nor does
- // any other method exist to make an object that inherits from nothing,
- // aside from Object.prototype itself. Instead, create a new global
- // object and *steal* its Object.prototype and strip it bare. This is
- // used as the prototype to create nullary objects.
- createEmpty = function () {
- var iframe = document.createElement('iframe');
- var parent = document.body || document.documentElement;
- iframe.style.display = 'none';
- parent.appendChild(iframe);
- iframe.src = 'javascript:';
- var empty = iframe.contentWindow.Object.prototype;
- parent.removeChild(iframe);
- iframe = null;
- delete empty.constructor;
- delete empty.hasOwnProperty;
- delete empty.propertyIsEnumerable;
- delete empty.isPrototypeOf;
- delete empty.toLocaleString;
- delete empty.toString;
- delete empty.valueOf;
-
- function Empty() {}
- Empty.prototype = empty;
- // short-circuit future calls
- createEmpty = function () {
- return new Empty();
- };
- return new Empty();
- };
- }
-
- create = Object.create = function create(prototype, properties) {
-
- var object;
- function Type() {} // An empty constructor.
-
- if (prototype === null) {
- object = createEmpty();
- } else {
- if (typeof prototype !== "object" && typeof prototype !== "function") {
- // In the native implementation `parent` can be `null`
- // OR *any* `instanceof Object` (Object|Function|Array|RegExp|etc)
- // Use `typeof` tho, b/c in old IE, DOM elements are not `instanceof Object`
- // like they are in modern browsers. Using `Object.create` on DOM elements
- // is...err...probably inappropriate, but the native version allows for it.
- throw new TypeError("Object prototype may only be an Object or null"); // same msg as Chrome
- }
-
- Type.prototype = prototype;
-
- object = new Type();
- }
-
- if (properties !== undefined) {
- defineProperties['default'](object, properties);
- }
-
- return object;
- };
- } else {
- create = Object.create;
- }
-
- exports['default'] = create;
-
-});
-enifed('ember-metal/platform/define_properties', ['exports', 'ember-metal/platform/define_property'], function (exports, define_property) {
-
- 'use strict';
-
- var defineProperties = Object.defineProperties;
-
- // ES5 15.2.3.7
- // http://es5.github.com/#x15.2.3.7
- if (!defineProperties) {
- defineProperties = function defineProperties(object, properties) {
- for (var property in properties) {
- if (properties.hasOwnProperty(property) && property !== "__proto__") {
- define_property.defineProperty(object, property, properties[property]);
- }
- }
- return object;
- };
-
- Object.defineProperties = defineProperties;
- }
-
- exports['default'] = defineProperties;
-
-});
-enifed('ember-metal/platform/define_property', ['exports'], function (exports) {
-
- 'use strict';
-
- /*globals Node */
-
- /**
- @class platform
- @namespace Ember
- @static
- */
-
- /**
- Set to true if the platform supports native getters and setters.
-
- @property hasPropertyAccessors
- @final
- */
-
- /**
- Identical to `Object.defineProperty()`. Implements as much functionality
- as possible if not available natively.
-
- @method defineProperty
- @param {Object} obj The object to modify
- @param {String} keyName property name to modify
- @param {Object} desc descriptor hash
- @return {void}
- */
- var defineProperty = (function checkCompliance(defineProperty) {
- if (!defineProperty) {
- return;
- }
-
- try {
- var a = 5;
- var obj = {};
- defineProperty(obj, 'a', {
- configurable: true,
- enumerable: true,
- get: function () {
- return a;
- },
- set: function (v) {
- a = v;
- }
- });
- if (obj.a !== 5) {
- return;
- }
-
- obj.a = 10;
- if (a !== 10) {
- return;
- }
-
- // check non-enumerability
- defineProperty(obj, 'a', {
- configurable: true,
- enumerable: false,
- writable: true,
- value: true
- });
- for (var key in obj) {
- if (key === 'a') {
- return;
- }
- }
-
- // Detects a bug in Android <3.2 where you cannot redefine a property using
- // Object.defineProperty once accessors have already been set.
- if (obj.a !== true) {
- return;
- }
-
- // Detects a bug in Android <3 where redefining a property without a value changes the value
- // Object.defineProperty once accessors have already been set.
- defineProperty(obj, 'a', {
- enumerable: false
- });
- if (obj.a !== true) {
- return;
- }
-
- // defineProperty is compliant
- return defineProperty;
- } catch (e) {
- // IE8 defines Object.defineProperty but calling it on an Object throws
- return;
- }
- })(Object.defineProperty);
-
- var hasES5CompliantDefineProperty = !!defineProperty;
-
- if (hasES5CompliantDefineProperty && typeof document !== 'undefined') {
- // This is for Safari 5.0, which supports Object.defineProperty, but not
- // on DOM nodes.
- var canDefinePropertyOnDOM = (function () {
- try {
- defineProperty(document.createElement('div'), 'definePropertyOnDOM', {});
- return true;
- } catch (e) {}
-
- return false;
- })();
-
- if (!canDefinePropertyOnDOM) {
- defineProperty = function (obj, keyName, desc) {
- var isNode;
-
- if (typeof Node === "object") {
- isNode = obj instanceof Node;
- } else {
- isNode = typeof obj === "object" && typeof obj.nodeType === "number" && typeof obj.nodeName === "string";
- }
-
- if (isNode) {
- // TODO: Should we have a warning here?
- return obj[keyName] = desc.value;
- } else {
- return Object.defineProperty(obj, keyName, desc);
- }
- };
- }
- }
-
- if (!hasES5CompliantDefineProperty) {
- defineProperty = function definePropertyPolyfill(obj, keyName, desc) {
- if (!desc.get) {
- obj[keyName] = desc.value;
- }
- };
- }
-
- var hasPropertyAccessors = hasES5CompliantDefineProperty;
- var canDefineNonEnumerableProperties = hasES5CompliantDefineProperty;
-
- exports.hasES5CompliantDefineProperty = hasES5CompliantDefineProperty;
- exports.defineProperty = defineProperty;
- exports.hasPropertyAccessors = hasPropertyAccessors;
- exports.canDefineNonEnumerableProperties = canDefineNonEnumerableProperties;
-
-});
-enifed('ember-metal/properties', ['exports', 'ember-metal/core', 'ember-metal/utils', 'ember-metal/platform/define_property', 'ember-metal/property_events'], function (exports, Ember, utils, define_property, property_events) {
-
- 'use strict';
-
- exports.Descriptor = Descriptor;
- exports.MANDATORY_SETTER_FUNCTION = MANDATORY_SETTER_FUNCTION;
- exports.DEFAULT_GETTER_FUNCTION = DEFAULT_GETTER_FUNCTION;
- exports.defineProperty = defineProperty;
-
- function Descriptor() {
- this.isDescriptor = true;
- }
-
- // ..........................................................
- // DEFINING PROPERTIES API
- //
-
- function MANDATORY_SETTER_FUNCTION(name) {
- return function SETTER_FUNCTION(value) {
- Ember['default'].assert("You must use Ember.set() to set the `" + name + "` property (of " + this + ") to `" + value + "`.", false);
- };
- }
-
- function DEFAULT_GETTER_FUNCTION(name) {
- return function GETTER_FUNCTION() {
- var meta = this['__ember_meta__'];
- return meta && meta.values[name];
- };
- }
-
- /**
- NOTE: This is a low-level method used by other parts of the API. You almost
- never want to call this method directly. Instead you should use
- `Ember.mixin()` to define new properties.
-
- Defines a property on an object. This method works much like the ES5
- `Object.defineProperty()` method except that it can also accept computed
- properties and other special descriptors.
-
- Normally this method takes only three parameters. However if you pass an
- instance of `Descriptor` as the third param then you can pass an
- optional value as the fourth parameter. This is often more efficient than
- creating new descriptor hashes for each property.
-
- ## Examples
-
- ```javascript
- // ES5 compatible mode
- Ember.defineProperty(contact, 'firstName', {
- writable: true,
- configurable: false,
- enumerable: true,
- value: 'Charles'
- });
-
- // define a simple property
- Ember.defineProperty(contact, 'lastName', undefined, 'Jolley');
-
- // define a computed property
- Ember.defineProperty(contact, 'fullName', Ember.computed(function() {
- return this.firstName+' '+this.lastName;
- }).property('firstName', 'lastName'));
- ```
-
- @private
- @method defineProperty
- @for Ember
- @param {Object} obj the object to define this property on. This may be a prototype.
- @param {String} keyName the name of the property
- @param {Descriptor} [desc] an instance of `Descriptor` (typically a
- computed property) or an ES5 descriptor.
- You must provide this or `data` but not both.
- @param {*} [data] something other than a descriptor, that will
- become the explicit value of this property.
- */
-
- function defineProperty(obj, keyName, desc, data, meta) {
- var possibleDesc, existingDesc, watching, value;
-
- if (!meta) {
- meta = utils.meta(obj);
- }
- var watchEntry = meta.watching[keyName];
- possibleDesc = obj[keyName];
- existingDesc = possibleDesc !== null && typeof possibleDesc === 'object' && possibleDesc.isDescriptor ? possibleDesc : undefined;
-
- watching = watchEntry !== undefined && watchEntry > 0;
-
- if (existingDesc) {
- existingDesc.teardown(obj, keyName);
- }
-
- if (desc instanceof Descriptor) {
- value = desc;
-
-
- if (watching && define_property.hasPropertyAccessors) {
- define_property.defineProperty(obj, keyName, {
- configurable: true,
- enumerable: true,
- writable: true,
- value: value
- });
- } else {
- obj[keyName] = value;
- }
- if (desc.setup) {
- desc.setup(obj, keyName);
- }
- } else {
- if (desc == null) {
- value = data;
-
-
- if (watching && define_property.hasPropertyAccessors) {
- meta.values[keyName] = data;
- define_property.defineProperty(obj, keyName, {
- configurable: true,
- enumerable: true,
- set: MANDATORY_SETTER_FUNCTION(keyName),
- get: DEFAULT_GETTER_FUNCTION(keyName)
- });
- } else {
- obj[keyName] = data;
- }
- } else {
- value = desc;
-
- // compatibility with ES5
- define_property.defineProperty(obj, keyName, desc);
- }
- }
-
- // if key is being watched, override chains that
- // were initialized with the prototype
- if (watching) {
- property_events.overrideChains(obj, keyName, meta);
- }
-
- // The `value` passed to the `didDefineProperty` hook is
- // either the descriptor or data, whichever was passed.
- if (obj.didDefineProperty) {
- obj.didDefineProperty(obj, keyName, value);
- }
-
- return this;
- }
-
-});
-enifed('ember-metal/property_events', ['exports', 'ember-metal/utils', 'ember-metal/events', 'ember-metal/observer_set'], function (exports, utils, ember_metal__events, ObserverSet) {
-
- 'use strict';
-
- exports.propertyWillChange = propertyWillChange;
- exports.propertyDidChange = propertyDidChange;
- exports.overrideChains = overrideChains;
- exports.beginPropertyChanges = beginPropertyChanges;
- exports.endPropertyChanges = endPropertyChanges;
- exports.changeProperties = changeProperties;
-
- var beforeObserverSet = new ObserverSet['default']();
- var observerSet = new ObserverSet['default']();
- var deferred = 0;
-
- // ..........................................................
- // PROPERTY CHANGES
- //
-
- /**
- This function is called just before an object property is about to change.
- It will notify any before observers and prepare caches among other things.
-
- Normally you will not need to call this method directly but if for some
- reason you can't directly watch a property you can invoke this method
- manually along with `Ember.propertyDidChange()` which you should call just
- after the property value changes.
-
- @method propertyWillChange
- @for Ember
- @param {Object} obj The object with the property that will change
- @param {String} keyName The property key (or path) that will change.
- @return {void}
- */
- function propertyWillChange(obj, keyName) {
- var m = obj['__ember_meta__'];
- var watching = m && m.watching[keyName] > 0 || keyName === 'length';
- var proto = m && m.proto;
- var possibleDesc = obj[keyName];
- var desc = possibleDesc !== null && typeof possibleDesc === 'object' && possibleDesc.isDescriptor ? possibleDesc : undefined;
-
- if (!watching) {
- return;
- }
-
- if (proto === obj) {
- return;
- }
-
- if (desc && desc.willChange) {
- desc.willChange(obj, keyName);
- }
-
- dependentKeysWillChange(obj, keyName, m);
- chainsWillChange(obj, keyName, m);
- notifyBeforeObservers(obj, keyName);
- }
-
- /**
- This function is called just after an object property has changed.
- It will notify any observers and clear caches among other things.
-
- Normally you will not need to call this method directly but if for some
- reason you can't directly watch a property you can invoke this method
- manually along with `Ember.propertyWillChange()` which you should call just
- before the property value changes.
-
- @method propertyDidChange
- @for Ember
- @param {Object} obj The object with the property that will change
- @param {String} keyName The property key (or path) that will change.
- @return {void}
- */
- function propertyDidChange(obj, keyName) {
- var m = obj['__ember_meta__'];
- var watching = m && m.watching[keyName] > 0 || keyName === 'length';
- var proto = m && m.proto;
- var possibleDesc = obj[keyName];
- var desc = possibleDesc !== null && typeof possibleDesc === 'object' && possibleDesc.isDescriptor ? possibleDesc : undefined;
-
- if (proto === obj) {
- return;
- }
-
- // shouldn't this mean that we're watching this key?
- if (desc && desc.didChange) {
- desc.didChange(obj, keyName);
- }
-
- if (!watching && keyName !== 'length') {
- return;
- }
-
- if (m && m.deps && m.deps[keyName]) {
- dependentKeysDidChange(obj, keyName, m);
- }
-
- chainsDidChange(obj, keyName, m, false);
- notifyObservers(obj, keyName);
- }
-
- var WILL_SEEN, DID_SEEN;
- // called whenever a property is about to change to clear the cache of any dependent keys (and notify those properties of changes, etc...)
- function dependentKeysWillChange(obj, depKey, meta) {
- if (obj.isDestroying) {
- return;
- }
-
- var deps;
- if (meta && meta.deps && (deps = meta.deps[depKey])) {
- var seen = WILL_SEEN;
- var top = !seen;
-
- if (top) {
- seen = WILL_SEEN = {};
- }
-
- iterDeps(propertyWillChange, obj, deps, depKey, seen, meta);
-
- if (top) {
- WILL_SEEN = null;
- }
- }
- }
-
- // called whenever a property has just changed to update dependent keys
- function dependentKeysDidChange(obj, depKey, meta) {
- if (obj.isDestroying) {
- return;
- }
-
- var deps;
- if (meta && meta.deps && (deps = meta.deps[depKey])) {
- var seen = DID_SEEN;
- var top = !seen;
-
- if (top) {
- seen = DID_SEEN = {};
- }
-
- iterDeps(propertyDidChange, obj, deps, depKey, seen, meta);
-
- if (top) {
- DID_SEEN = null;
- }
- }
- }
-
- function keysOf(obj) {
- var keys = [];
-
- for (var key in obj) {
- keys.push(key);
- }
-
- return keys;
- }
-
- function iterDeps(method, obj, deps, depKey, seen, meta) {
- var keys, key, i, possibleDesc, desc;
- var guid = utils.guidFor(obj);
- var current = seen[guid];
-
- if (!current) {
- current = seen[guid] = {};
- }
-
- if (current[depKey]) {
- return;
- }
-
- current[depKey] = true;
-
- if (deps) {
- keys = keysOf(deps);
- for (i = 0; i < keys.length; i++) {
- key = keys[i];
- possibleDesc = obj[key];
- desc = possibleDesc !== null && typeof possibleDesc === 'object' && possibleDesc.isDescriptor ? possibleDesc : undefined;
-
- if (desc && desc._suspended === obj) {
- continue;
- }
-
- method(obj, key);
- }
- }
- }
-
- function chainsWillChange(obj, keyName, m) {
- if (!(m.hasOwnProperty('chainWatchers') && m.chainWatchers[keyName])) {
- return;
- }
-
- var nodes = m.chainWatchers[keyName];
- var events = [];
- var i, l;
-
- for (i = 0, l = nodes.length; i < l; i++) {
- nodes[i].willChange(events);
- }
-
- for (i = 0, l = events.length; i < l; i += 2) {
- propertyWillChange(events[i], events[i + 1]);
- }
- }
-
- function chainsDidChange(obj, keyName, m, suppressEvents) {
- if (!(m && m.hasOwnProperty('chainWatchers') && m.chainWatchers[keyName])) {
- return;
- }
-
- var nodes = m.chainWatchers[keyName];
- var events = suppressEvents ? null : [];
- var i, l;
-
- for (i = 0, l = nodes.length; i < l; i++) {
- nodes[i].didChange(events);
- }
-
- if (suppressEvents) {
- return;
- }
-
- for (i = 0, l = events.length; i < l; i += 2) {
- propertyDidChange(events[i], events[i + 1]);
- }
- }
-
- function overrideChains(obj, keyName, m) {
- chainsDidChange(obj, keyName, m, true);
- }
-
- /**
- @method beginPropertyChanges
- @chainable
- @private
- */
- function beginPropertyChanges() {
- deferred++;
- }
-
- /**
- @method endPropertyChanges
- @private
- */
- function endPropertyChanges() {
- deferred--;
- if (deferred <= 0) {
- beforeObserverSet.clear();
- observerSet.flush();
- }
- }
-
- /**
- Make a series of property changes together in an
- exception-safe way.
-
- ```javascript
- Ember.changeProperties(function() {
- obj1.set('foo', mayBlowUpWhenSet);
- obj2.set('bar', baz);
- });
- ```
-
- @method changeProperties
- @param {Function} callback
- @param [binding]
- */
- function changeProperties(callback, binding) {
- beginPropertyChanges();
- utils.tryFinally(callback, endPropertyChanges, binding);
- }
-
- function notifyBeforeObservers(obj, keyName) {
- if (obj.isDestroying) {
- return;
- }
-
- var eventName = keyName + ':before';
- var listeners, added;
- if (deferred) {
- listeners = beforeObserverSet.add(obj, keyName, eventName);
- added = ember_metal__events.accumulateListeners(obj, eventName, listeners);
- ember_metal__events.sendEvent(obj, eventName, [obj, keyName], added);
- } else {
- ember_metal__events.sendEvent(obj, eventName, [obj, keyName]);
- }
- }
-
- function notifyObservers(obj, keyName) {
- if (obj.isDestroying) {
- return;
- }
-
- var eventName = keyName + ':change';
- var listeners;
- if (deferred) {
- listeners = observerSet.add(obj, keyName, eventName);
- ember_metal__events.accumulateListeners(obj, eventName, listeners);
- } else {
- ember_metal__events.sendEvent(obj, eventName, [obj, keyName]);
- }
- }
-
-});
-enifed('ember-metal/property_get', ['exports', 'ember-metal/core', 'ember-metal/error', 'ember-metal/path_cache', 'ember-metal/platform/define_property', 'ember-metal/is_none'], function (exports, Ember, EmberError, path_cache, define_property, isNone) {
-
- 'use strict';
-
- exports.get = get;
- exports.normalizeTuple = normalizeTuple;
- exports._getPath = _getPath;
- exports.getWithDefault = getWithDefault;
-
- var FIRST_KEY = /^([^\.]+)/;
-
- // ..........................................................
- // GET AND SET
- //
- // If we are on a platform that supports accessors we can use those.
- // Otherwise simulate accessors by looking up the property directly on the
- // object.
-
- /**
- Gets the value of a property on an object. If the property is computed,
- the function will be invoked. If the property is not defined but the
- object implements the `unknownProperty` method then that will be invoked.
-
- If you plan to run on IE8 and older browsers then you should use this
- method anytime you want to retrieve a property on an object that you don't
- know for sure is private. (Properties beginning with an underscore '_'
- are considered private.)
-
- On all newer browsers, you only need to use this method to retrieve
- properties if the property might not be defined on the object and you want
- to respect the `unknownProperty` handler. Otherwise you can ignore this
- method.
-
- Note that if the object itself is `undefined`, this method will throw
- an error.
-
- @method get
- @for Ember
- @param {Object} obj The object to retrieve from.
- @param {String} keyName The property key to retrieve
- @return {Object} the property value or `null`.
- */
-
- function get(obj, keyName) {
- // Helpers that operate with 'this' within an #each
- if (keyName === '') {
- return obj;
- }
-
- if (!keyName && 'string' === typeof obj) {
- keyName = obj;
- obj = Ember['default'].lookup;
- }
-
- Ember['default'].assert("Cannot call get with " + keyName + " key.", !!keyName);
- Ember['default'].assert("Cannot call get with '" + keyName + "' on an undefined object.", obj !== undefined);
-
- if (isNone['default'](obj)) {
- return _getPath(obj, keyName);
- }
-
- var meta = obj['__ember_meta__'];
- var possibleDesc = obj[keyName];
- var desc = possibleDesc !== null && typeof possibleDesc === 'object' && possibleDesc.isDescriptor ? possibleDesc : undefined;
- var ret;
-
- if (desc === undefined && path_cache.isPath(keyName)) {
- return _getPath(obj, keyName);
- }
-
- if (desc) {
- return desc.get(obj, keyName);
- } else {
-
- if (define_property.hasPropertyAccessors && meta && meta.watching[keyName] > 0) {
- ret = meta.values[keyName];
- } else {
- ret = obj[keyName];
- }
-
- if (ret === undefined && 'object' === typeof obj && !(keyName in obj) && 'function' === typeof obj.unknownProperty) {
- return obj.unknownProperty(keyName);
- }
-
- return ret;
- }
- }
-
- /**
- Normalizes a target/path pair to reflect that actual target/path that should
- be observed, etc. This takes into account passing in global property
- paths (i.e. a path beginning with a capital letter not defined on the
- target).
-
- @private
- @method normalizeTuple
- @for Ember
- @param {Object} target The current target. May be `null`.
- @param {String} path A path on the target or a global property path.
- @return {Array} a temporary array with the normalized target/path pair.
- */
-
- function normalizeTuple(target, path) {
- var hasThis = path_cache.hasThis(path);
- var isGlobal = !hasThis && path_cache.isGlobal(path);
- var key;
-
- if (!target && !isGlobal) {
- return [undefined, ''];
- }
-
- if (hasThis) {
- path = path.slice(5);
- }
-
- if (!target || isGlobal) {
- target = Ember['default'].lookup;
- }
-
- if (isGlobal && path_cache.isPath(path)) {
- key = path.match(FIRST_KEY)[0];
- target = get(target, key);
- path = path.slice(key.length + 1);
- }
-
- // must return some kind of path to be valid else other things will break.
- validateIsPath(path);
-
- return [target, path];
- }
-
- function validateIsPath(path) {
- if (!path || path.length === 0) {
- throw new EmberError['default']("Object in path " + path + " could not be found or was destroyed.");
- }
- }
-
- function _getPath(root, path) {
- var hasThis, parts, tuple, idx, len;
-
- // detect complicated paths and normalize them
- hasThis = path_cache.hasThis(path);
-
- if (!root || hasThis) {
- tuple = normalizeTuple(root, path);
- root = tuple[0];
- path = tuple[1];
- tuple.length = 0;
- }
-
- parts = path.split(".");
- len = parts.length;
- for (idx = 0; root != null && idx < len; idx++) {
- root = get(root, parts[idx], true);
- if (root && root.isDestroyed) {
- return undefined;
- }
- }
- return root;
- }
-
- function getWithDefault(root, key, defaultValue) {
- var value = get(root, key);
-
- if (value === undefined) {
- return defaultValue;
- }
- return value;
- }
-
- exports['default'] = get;
-
-});
-enifed('ember-metal/property_set', ['exports', 'ember-metal/core', 'ember-metal/property_get', 'ember-metal/property_events', 'ember-metal/properties', 'ember-metal/error', 'ember-metal/path_cache', 'ember-metal/platform/define_property'], function (exports, Ember, property_get, property_events, properties, EmberError, path_cache, define_property) {
-
- 'use strict';
-
- exports.set = set;
- exports.trySet = trySet;
-
- function set(obj, keyName, value, tolerant) {
- if (typeof obj === 'string') {
- Ember['default'].assert("Path '" + obj + "' must be global if no obj is given.", path_cache.isGlobalPath(obj));
- value = keyName;
- keyName = obj;
- obj = Ember['default'].lookup;
- }
-
- Ember['default'].assert("Cannot call set with '" + keyName + "' key.", !!keyName);
-
- if (obj === Ember['default'].lookup) {
- return setPath(obj, keyName, value, tolerant);
- }
-
- var meta, possibleDesc, desc;
- if (obj) {
- meta = obj['__ember_meta__'];
- possibleDesc = obj[keyName];
- desc = possibleDesc !== null && typeof possibleDesc === 'object' && possibleDesc.isDescriptor ? possibleDesc : undefined;
- }
-
- var isUnknown, currentValue;
- if ((!obj || desc === undefined) && path_cache.isPath(keyName)) {
- return setPath(obj, keyName, value, tolerant);
- }
-
- Ember['default'].assert("You need to provide an object and key to `set`.", !!obj && keyName !== undefined);
- Ember['default'].assert('calling set on destroyed object', !obj.isDestroyed);
-
- if (desc) {
- desc.set(obj, keyName, value);
- } else {
-
- if (obj !== null && value !== undefined && typeof obj === 'object' && obj[keyName] === value) {
- return value;
- }
-
- isUnknown = 'object' === typeof obj && !(keyName in obj);
-
- // setUnknownProperty is called if `obj` is an object,
- // the property does not already exist, and the
- // `setUnknownProperty` method exists on the object
- if (isUnknown && 'function' === typeof obj.setUnknownProperty) {
- obj.setUnknownProperty(keyName, value);
- } else if (meta && meta.watching[keyName] > 0) {
- if (meta.proto !== obj) {
-
- if (define_property.hasPropertyAccessors) {
- currentValue = meta.values[keyName];
- } else {
- currentValue = obj[keyName];
- }
- }
- // only trigger a change if the value has changed
- if (value !== currentValue) {
- property_events.propertyWillChange(obj, keyName);
-
- if (define_property.hasPropertyAccessors) {
- if (currentValue === undefined && !(keyName in obj) || !Object.prototype.propertyIsEnumerable.call(obj, keyName)) {
- properties.defineProperty(obj, keyName, null, value); // setup mandatory setter
- } else {
- meta.values[keyName] = value;
- }
- } else {
- obj[keyName] = value;
- }
- property_events.propertyDidChange(obj, keyName);
- }
- } else {
- obj[keyName] = value;
- }
- }
- return value;
- }
-
- function setPath(root, path, value, tolerant) {
- var keyName;
-
- // get the last part of the path
- keyName = path.slice(path.lastIndexOf('.') + 1);
-
- // get the first part of the part
- path = path === keyName ? keyName : path.slice(0, path.length - (keyName.length + 1));
-
- // unless the path is this, look up the first part to
- // get the root
- if (path !== 'this') {
- root = property_get._getPath(root, path);
- }
-
- if (!keyName || keyName.length === 0) {
- throw new EmberError['default']('Property set failed: You passed an empty path');
- }
-
- if (!root) {
- if (tolerant) {
- return;
- } else {
- throw new EmberError['default']('Property set failed: object in path "' + path + '" could not be found or was destroyed.');
- }
- }
-
- return set(root, keyName, value);
- }
-
- /**
- Error-tolerant form of `Ember.set`. Will not blow up if any part of the
- chain is `undefined`, `null`, or destroyed.
-
- This is primarily used when syncing bindings, which may try to update after
- an object has been destroyed.
-
- @method trySet
- @for Ember
- @param {Object} obj The object to modify.
- @param {String} path The property path to set
- @param {Object} value The value to set
- */
-
- function trySet(root, path, value) {
- return set(root, path, value, true);
- }
-
-});
-enifed('ember-metal/run_loop', ['exports', 'ember-metal/core', 'ember-metal/utils', 'ember-metal/array', 'ember-metal/property_events', 'backburner'], function (exports, Ember, utils, array, property_events, Backburner) {
-
- 'use strict';
-
- function onBegin(current) {
- run.currentRunLoop = current;
- }
-
- function onEnd(current, next) {
- run.currentRunLoop = next;
- }
-
- // ES6TODO: should Backburner become es6?
- var backburner = new Backburner['default'](['sync', 'actions', 'destroy'], {
- GUID_KEY: utils.GUID_KEY,
- sync: {
- before: property_events.beginPropertyChanges,
- after: property_events.endPropertyChanges
- },
- defaultQueue: 'actions',
- onBegin: onBegin,
- onEnd: onEnd,
- onErrorTarget: Ember['default'],
- onErrorMethod: 'onerror'
- });
-
- // ..........................................................
- // run - this is ideally the only public API the dev sees
- //
-
- /**
- Runs the passed target and method inside of a RunLoop, ensuring any
- deferred actions including bindings and views updates are flushed at the
- end.
-
- Normally you should not need to invoke this method yourself. However if
- you are implementing raw event handlers when interfacing with other
- libraries or plugins, you should probably wrap all of your code inside this
- call.
-
- ```javascript
- run(function() {
- // code to be executed within a RunLoop
- });
- ```
-
- @class run
- @namespace Ember
- @static
- @constructor
- @param {Object} [target] target of method to call
- @param {Function|String} method Method to invoke.
- May be a function or a string. If you pass a string
- then it will be looked up on the passed target.
- @param {Object} [args*] Any additional arguments you wish to pass to the method.
- @return {Object} return value from invoking the passed function.
- */
- exports['default'] = run;
- function run() {
- return backburner.run.apply(backburner, arguments);
- }
-
- /**
- If no run-loop is present, it creates a new one. If a run loop is
- present it will queue itself to run on the existing run-loops action
- queue.
-
- Please note: This is not for normal usage, and should be used sparingly.
-
- If invoked when not within a run loop:
-
- ```javascript
- run.join(function() {
- // creates a new run-loop
- });
- ```
-
- Alternatively, if called within an existing run loop:
-
- ```javascript
- run(function() {
- // creates a new run-loop
- run.join(function() {
- // joins with the existing run-loop, and queues for invocation on
- // the existing run-loops action queue.
- });
- });
- ```
-
- @method join
- @namespace Ember
- @param {Object} [target] target of method to call
- @param {Function|String} method Method to invoke.
- May be a function or a string. If you pass a string
- then it will be looked up on the passed target.
- @param {Object} [args*] Any additional arguments you wish to pass to the method.
- @return {Object} Return value from invoking the passed function. Please note,
- when called within an existing loop, no return value is possible.
- */
- run.join = function () {
- return backburner.join.apply(backburner, arguments);
- };
-
- /**
- Allows you to specify which context to call the specified function in while
- adding the execution of that function to the Ember run loop. This ability
- makes this method a great way to asynchronously integrate third-party libraries
- into your Ember application.
-
- `run.bind` takes two main arguments, the desired context and the function to
- invoke in that context. Any additional arguments will be supplied as arguments
- to the function that is passed in.
-
- Let's use the creation of a TinyMCE component as an example. Currently,
- TinyMCE provides a setup configuration option we can use to do some processing
- after the TinyMCE instance is initialized but before it is actually rendered.
- We can use that setup option to do some additional setup for our component.
- The component itself could look something like the following:
-
- ```javascript
- App.RichTextEditorComponent = Ember.Component.extend({
- initializeTinyMCE: Ember.on('didInsertElement', function() {
- tinymce.init({
- selector: '#' + this.$().prop('id'),
- setup: Ember.run.bind(this, this.setupEditor)
- });
- }),
-
- setupEditor: function(editor) {
- this.set('editor', editor);
-
- editor.on('change', function() {
- console.log('content changed!');
- });
- }
- });
- ```
-
- In this example, we use Ember.run.bind to bind the setupEditor method to the
- context of the App.RichTextEditorComponent and to have the invocation of that
- method be safely handled and executed by the Ember run loop.
-
- @method bind
- @namespace Ember
- @param {Object} [target] target of method to call
- @param {Function|String} method Method to invoke.
- May be a function or a string. If you pass a string
- then it will be looked up on the passed target.
- @param {Object} [args*] Any additional arguments you wish to pass to the method.
- @return {Function} returns a new function that will always have a particular context
- @since 1.4.0
- */
- run.bind = function () {
- for (var _len = arguments.length, curried = Array(_len), _key = 0; _key < _len; _key++) {
- curried[_key] = arguments[_key];
- }
-
- return function () {
- for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
- args[_key2] = arguments[_key2];
- }
-
- return run.join.apply(run, curried.concat(args));
- };
- };
-
- run.backburner = backburner;
- run.currentRunLoop = null;
- run.queues = backburner.queueNames;
-
- /**
- Begins a new RunLoop. Any deferred actions invoked after the begin will
- be buffered until you invoke a matching call to `run.end()`. This is
- a lower-level way to use a RunLoop instead of using `run()`.
-
- ```javascript
- run.begin();
- // code to be executed within a RunLoop
- run.end();
- ```
-
- @method begin
- @return {void}
- */
- run.begin = function () {
- backburner.begin();
- };
-
- /**
- Ends a RunLoop. This must be called sometime after you call
- `run.begin()` to flush any deferred actions. This is a lower-level way
- to use a RunLoop instead of using `run()`.
-
- ```javascript
- run.begin();
- // code to be executed within a RunLoop
- run.end();
- ```
-
- @method end
- @return {void}
- */
- run.end = function () {
- backburner.end();
- };
-
- /**
- Array of named queues. This array determines the order in which queues
- are flushed at the end of the RunLoop. You can define your own queues by
- simply adding the queue name to this array. Normally you should not need
- to inspect or modify this property.
-
- @property queues
- @type Array
- @default ['sync', 'actions', 'destroy']
- */
-
- /**
- Adds the passed target/method and any optional arguments to the named
- queue to be executed at the end of the RunLoop. If you have not already
- started a RunLoop when calling this method one will be started for you
- automatically.
-
- At the end of a RunLoop, any methods scheduled in this way will be invoked.
- Methods will be invoked in an order matching the named queues defined in
- the `run.queues` property.
-
- ```javascript
- run.schedule('sync', this, function() {
- // this will be executed in the first RunLoop queue, when bindings are synced
- console.log('scheduled on sync queue');
- });
-
- run.schedule('actions', this, function() {
- // this will be executed in the 'actions' queue, after bindings have synced.
- console.log('scheduled on actions queue');
- });
-
- // Note the functions will be run in order based on the run queues order.
- // Output would be:
- // scheduled on sync queue
- // scheduled on actions queue
- ```
-
- @method schedule
- @param {String} queue The name of the queue to schedule against.
- Default queues are 'sync' and 'actions'
- @param {Object} [target] target object to use as the context when invoking a method.
- @param {String|Function} method The method to invoke. If you pass a string it
- will be resolved on the target object at the time the scheduled item is
- invoked allowing you to change the target function.
- @param {Object} [arguments*] Optional arguments to be passed to the queued method.
- @return {void}
- */
- run.schedule = function () /* queue, target, method */{
- checkAutoRun();
- backburner.schedule.apply(backburner, arguments);
- };
-
- // Used by global test teardown
- run.hasScheduledTimers = function () {
- return backburner.hasTimers();
- };
-
- // Used by global test teardown
- run.cancelTimers = function () {
- backburner.cancelTimers();
- };
-
- /**
- Immediately flushes any events scheduled in the 'sync' queue. Bindings
- use this queue so this method is a useful way to immediately force all
- bindings in the application to sync.
-
- You should call this method anytime you need any changed state to propagate
- throughout the app immediately without repainting the UI (which happens
- in the later 'render' queue added by the `ember-views` package).
-
- ```javascript
- run.sync();
- ```
-
- @method sync
- @return {void}
- */
- run.sync = function () {
- if (backburner.currentInstance) {
- backburner.currentInstance.queues.sync.flush();
- }
- };
-
- /**
- Invokes the passed target/method and optional arguments after a specified
- period of time. The last parameter of this method must always be a number
- of milliseconds.
-
- You should use this method whenever you need to run some action after a
- period of time instead of using `setTimeout()`. This method will ensure that
- items that expire during the same script execution cycle all execute
- together, which is often more efficient than using a real setTimeout.
-
- ```javascript
- run.later(myContext, function() {
- // code here will execute within a RunLoop in about 500ms with this == myContext
- }, 500);
- ```
-
- @method later
- @param {Object} [target] target of method to invoke
- @param {Function|String} method The method to invoke.
- If you pass a string it will be resolved on the
- target at the time the method is invoked.
- @param {Object} [args*] Optional arguments to pass to the timeout.
- @param {Number} wait Number of milliseconds to wait.
- @return {*} Timer information for use in cancelling, see `run.cancel`.
- */
- run.later = function () /*target, method*/{
- return backburner.later.apply(backburner, arguments);
- };
-
- /**
- Schedule a function to run one time during the current RunLoop. This is equivalent
- to calling `scheduleOnce` with the "actions" queue.
-
- @method once
- @param {Object} [target] The target of the method to invoke.
- @param {Function|String} method The method to invoke.
- If you pass a string it will be resolved on the
- target at the time the method is invoked.
- @param {Object} [args*] Optional arguments to pass to the timeout.
- @return {Object} Timer information for use in cancelling, see `run.cancel`.
- */
- run.once = function () {
- checkAutoRun();
-
- for (var _len3 = arguments.length, args = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
- args[_key3] = arguments[_key3];
- }
-
- args.unshift('actions');
- return backburner.scheduleOnce.apply(backburner, args);
- };
-
- /**
- Schedules a function to run one time in a given queue of the current RunLoop.
- Calling this method with the same queue/target/method combination will have
- no effect (past the initial call).
-
- Note that although you can pass optional arguments these will not be
- considered when looking for duplicates. New arguments will replace previous
- calls.
-
- ```javascript
- function sayHi() {
- console.log('hi');
- }
-
- run(function() {
- run.scheduleOnce('afterRender', myContext, sayHi);
- run.scheduleOnce('afterRender', myContext, sayHi);
- // sayHi will only be executed once, in the afterRender queue of the RunLoop
- });
- ```
-
- Also note that passing an anonymous function to `run.scheduleOnce` will
- not prevent additional calls with an identical anonymous function from
- scheduling the items multiple times, e.g.:
-
- ```javascript
- function scheduleIt() {
- run.scheduleOnce('actions', myContext, function() {
- console.log('Closure');
- });
- }
-
- scheduleIt();
- scheduleIt();
-
- // "Closure" will print twice, even though we're using `run.scheduleOnce`,
- // because the function we pass to it is anonymous and won't match the
- // previously scheduled operation.
- ```
-
- Available queues, and their order, can be found at `run.queues`
-
- @method scheduleOnce
- @param {String} [queue] The name of the queue to schedule against. Default queues are 'sync' and 'actions'.
- @param {Object} [target] The target of the method to invoke.
- @param {Function|String} method The method to invoke.
- If you pass a string it will be resolved on the
- target at the time the method is invoked.
- @param {Object} [args*] Optional arguments to pass to the timeout.
- @return {Object} Timer information for use in cancelling, see `run.cancel`.
- */
- run.scheduleOnce = function () /*queue, target, method*/{
- checkAutoRun();
- return backburner.scheduleOnce.apply(backburner, arguments);
- };
-
- /**
- Schedules an item to run from within a separate run loop, after
- control has been returned to the system. This is equivalent to calling
- `run.later` with a wait time of 1ms.
-
- ```javascript
- run.next(myContext, function() {
- // code to be executed in the next run loop,
- // which will be scheduled after the current one
- });
- ```
-
- Multiple operations scheduled with `run.next` will coalesce
- into the same later run loop, along with any other operations
- scheduled by `run.later` that expire right around the same
- time that `run.next` operations will fire.
-
- Note that there are often alternatives to using `run.next`.
- For instance, if you'd like to schedule an operation to happen
- after all DOM element operations have completed within the current
- run loop, you can make use of the `afterRender` run loop queue (added
- by the `ember-views` package, along with the preceding `render` queue
- where all the DOM element operations happen). Example:
-
- ```javascript
- App.MyCollectionView = Ember.CollectionView.extend({
- didInsertElement: function() {
- run.scheduleOnce('afterRender', this, 'processChildElements');
- },
- processChildElements: function() {
- // ... do something with collectionView's child view
- // elements after they've finished rendering, which
- // can't be done within the CollectionView's
- // `didInsertElement` hook because that gets run
- // before the child elements have been added to the DOM.
- }
- });
- ```
-
- One benefit of the above approach compared to using `run.next` is
- that you will be able to perform DOM/CSS operations before unprocessed
- elements are rendered to the screen, which may prevent flickering or
- other artifacts caused by delaying processing until after rendering.
-
- The other major benefit to the above approach is that `run.next`
- introduces an element of non-determinism, which can make things much
- harder to test, due to its reliance on `setTimeout`; it's much harder
- to guarantee the order of scheduled operations when they are scheduled
- outside of the current run loop, i.e. with `run.next`.
-
- @method next
- @param {Object} [target] target of method to invoke
- @param {Function|String} method The method to invoke.
- If you pass a string it will be resolved on the
- target at the time the method is invoked.
- @param {Object} [args*] Optional arguments to pass to the timeout.
- @return {Object} Timer information for use in cancelling, see `run.cancel`.
- */
- run.next = function () {
- for (var _len4 = arguments.length, args = Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
- args[_key4] = arguments[_key4];
- }
-
- args.push(1);
- return backburner.later.apply(backburner, args);
- };
-
- /**
- Cancels a scheduled item. Must be a value returned by `run.later()`,
- `run.once()`, `run.next()`, `run.debounce()`, or
- `run.throttle()`.
-
- ```javascript
- var runNext = run.next(myContext, function() {
- // will not be executed
- });
-
- run.cancel(runNext);
-
- var runLater = run.later(myContext, function() {
- // will not be executed
- }, 500);
-
- run.cancel(runLater);
-
- var runOnce = run.once(myContext, function() {
- // will not be executed
- });
-
- run.cancel(runOnce);
-
- var throttle = run.throttle(myContext, function() {
- // will not be executed
- }, 1, false);
-
- run.cancel(throttle);
-
- var debounce = run.debounce(myContext, function() {
- // will not be executed
- }, 1);
-
- run.cancel(debounce);
-
- var debounceImmediate = run.debounce(myContext, function() {
- // will be executed since we passed in true (immediate)
- }, 100, true);
-
- // the 100ms delay until this method can be called again will be cancelled
- run.cancel(debounceImmediate);
- ```
-
- @method cancel
- @param {Object} timer Timer object to cancel
- @return {Boolean} true if cancelled or false/undefined if it wasn't found
- */
- run.cancel = function (timer) {
- return backburner.cancel(timer);
- };
-
- /**
- Delay calling the target method until the debounce period has elapsed
- with no additional debounce calls. If `debounce` is called again before
- the specified time has elapsed, the timer is reset and the entire period
- must pass again before the target method is called.
-
- This method should be used when an event may be called multiple times
- but the action should only be called once when the event is done firing.
- A common example is for scroll events where you only want updates to
- happen once scrolling has ceased.
-
- ```javascript
- function whoRan() {
- console.log(this.name + ' ran.');
- }
-
- var myContext = { name: 'debounce' };
-
- run.debounce(myContext, whoRan, 150);
-
- // less than 150ms passes
- run.debounce(myContext, whoRan, 150);
-
- // 150ms passes
- // whoRan is invoked with context myContext
- // console logs 'debounce ran.' one time.
- ```
-
- Immediate allows you to run the function immediately, but debounce
- other calls for this function until the wait time has elapsed. If
- `debounce` is called again before the specified time has elapsed,
- the timer is reset and the entire period must pass again before
- the method can be called again.
-
- ```javascript
- function whoRan() {
- console.log(this.name + ' ran.');
- }
-
- var myContext = { name: 'debounce' };
-
- run.debounce(myContext, whoRan, 150, true);
-
- // console logs 'debounce ran.' one time immediately.
- // 100ms passes
- run.debounce(myContext, whoRan, 150, true);
-
- // 150ms passes and nothing else is logged to the console and
- // the debouncee is no longer being watched
- run.debounce(myContext, whoRan, 150, true);
-
- // console logs 'debounce ran.' one time immediately.
- // 150ms passes and nothing else is logged to the console and
- // the debouncee is no longer being watched
-
- ```
-
- @method debounce
- @param {Object} [target] target of method to invoke
- @param {Function|String} method The method to invoke.
- May be a function or a string. If you pass a string
- then it will be looked up on the passed target.
- @param {Object} [args*] Optional arguments to pass to the timeout.
- @param {Number} wait Number of milliseconds to wait.
- @param {Boolean} immediate Trigger the function on the leading instead
- of the trailing edge of the wait interval. Defaults to false.
- @return {Array} Timer information for use in cancelling, see `run.cancel`.
- */
- run.debounce = function () {
- return backburner.debounce.apply(backburner, arguments);
- };
-
- /**
- Ensure that the target method is never called more frequently than
- the specified spacing period. The target method is called immediately.
-
- ```javascript
- function whoRan() {
- console.log(this.name + ' ran.');
- }
-
- var myContext = { name: 'throttle' };
-
- run.throttle(myContext, whoRan, 150);
- // whoRan is invoked with context myContext
- // console logs 'throttle ran.'
-
- // 50ms passes
- run.throttle(myContext, whoRan, 150);
-
- // 50ms passes
- run.throttle(myContext, whoRan, 150);
-
- // 150ms passes
- run.throttle(myContext, whoRan, 150);
- // whoRan is invoked with context myContext
- // console logs 'throttle ran.'
- ```
-
- @method throttle
- @param {Object} [target] target of method to invoke
- @param {Function|String} method The method to invoke.
- May be a function or a string. If you pass a string
- then it will be looked up on the passed target.
- @param {Object} [args*] Optional arguments to pass to the timeout.
- @param {Number} spacing Number of milliseconds to space out requests.
- @param {Boolean} immediate Trigger the function on the leading instead
- of the trailing edge of the wait interval. Defaults to true.
- @return {Array} Timer information for use in cancelling, see `run.cancel`.
- */
- run.throttle = function () {
- return backburner.throttle.apply(backburner, arguments);
- };
-
- // Make sure it's not an autorun during testing
- function checkAutoRun() {
- if (!run.currentRunLoop) {
- Ember['default'].assert('You have turned on testing mode, which disabled the run-loop\'s autorun.\n You will need to wrap any code with asynchronous side-effects in a run', !Ember['default'].testing);
- }
- }
-
- /**
- Add a new named queue after the specified queue.
-
- The queue to add will only be added once.
-
- @method _addQueue
- @param {String} name the name of the queue to add.
- @param {String} after the name of the queue to add after.
- @private
- */
- run._addQueue = function (name, after) {
- if (array.indexOf.call(run.queues, name) === -1) {
- run.queues.splice(array.indexOf.call(run.queues, after) + 1, 0, name);
- }
- };
-
-});
-enifed('ember-metal/set_properties', ['exports', 'ember-metal/property_events', 'ember-metal/property_set', 'ember-metal/keys'], function (exports, property_events, property_set, keys) {
-
- 'use strict';
-
-
- exports['default'] = setProperties;
- function setProperties(obj, properties) {
- if (!properties || typeof properties !== "object") {
- return obj;
- }
- property_events.changeProperties(function () {
- var props = keys['default'](properties);
- var propertyName;
-
- for (var i = 0, l = props.length; i < l; i++) {
- propertyName = props[i];
-
- property_set.set(obj, propertyName, properties[propertyName]);
- }
- });
- return obj;
- }
-
-});
-enifed('ember-metal/streams/conditional', ['exports', 'ember-metal/streams/stream', 'ember-metal/streams/utils', 'ember-metal/platform/create'], function (exports, Stream, utils, create) {
-
- 'use strict';
-
-
-
- exports['default'] = conditional;
-
- function conditional(test, consequent, alternate) {
- if (utils.isStream(test)) {
- return new ConditionalStream(test, consequent, alternate);
- } else {
- if (test) {
- return consequent;
- } else {
- return alternate;
- }
- }
- }
-
- function ConditionalStream(test, consequent, alternate) {
- this.init();
-
- this.oldTestResult = undefined;
- this.test = test;
- this.consequent = consequent;
- this.alternate = alternate;
- }
-
- ConditionalStream.prototype = create['default'](Stream['default'].prototype);
-
- ConditionalStream.prototype.valueFn = function () {
- var oldTestResult = this.oldTestResult;
- var newTestResult = !!utils.read(this.test);
-
- if (newTestResult !== oldTestResult) {
- switch (oldTestResult) {
- case true:
- utils.unsubscribe(this.consequent, this.notify, this);break;
- case false:
- utils.unsubscribe(this.alternate, this.notify, this);break;
- case undefined:
- utils.subscribe(this.test, this.notify, this);
- }
-
- switch (newTestResult) {
- case true:
- utils.subscribe(this.consequent, this.notify, this);break;
- case false:
- utils.subscribe(this.alternate, this.notify, this);
- }
-
- this.oldTestResult = newTestResult;
- }
-
- return newTestResult ? utils.read(this.consequent) : utils.read(this.alternate);
- };
-
-});
-enifed('ember-metal/streams/simple', ['exports', 'ember-metal/merge', 'ember-metal/streams/stream', 'ember-metal/platform/create', 'ember-metal/streams/utils'], function (exports, merge, Stream, create, utils) {
-
- 'use strict';
-
- function SimpleStream(source) {
- this.init();
- this.source = source;
-
- if (utils.isStream(source)) {
- source.subscribe(this._didChange, this);
- }
- }
-
- SimpleStream.prototype = create['default'](Stream['default'].prototype);
-
- merge['default'](SimpleStream.prototype, {
- valueFn: function () {
- return utils.read(this.source);
- },
-
- setValue: function (value) {
- var source = this.source;
-
- if (utils.isStream(source)) {
- source.setValue(value);
- }
- },
-
- setSource: function (nextSource) {
- var prevSource = this.source;
- if (nextSource !== prevSource) {
- if (utils.isStream(prevSource)) {
- prevSource.unsubscribe(this._didChange, this);
- }
-
- if (utils.isStream(nextSource)) {
- nextSource.subscribe(this._didChange, this);
- }
-
- this.source = nextSource;
- this.notify();
- }
- },
-
- _didChange: function () {
- this.notify();
- },
-
- _super$destroy: Stream['default'].prototype.destroy,
-
- destroy: function () {
- if (this._super$destroy()) {
- if (utils.isStream(this.source)) {
- this.source.unsubscribe(this._didChange, this);
- }
- this.source = undefined;
- return true;
- }
- }
- });
-
- exports['default'] = SimpleStream;
-
-});
-enifed('ember-metal/streams/stream', ['exports', 'ember-metal/platform/create', 'ember-metal/path_cache'], function (exports, create, path_cache) {
-
- 'use strict';
-
- function Subscriber(callback, context) {
- this.next = null;
- this.prev = null;
- this.callback = callback;
- this.context = context;
- }
-
- Subscriber.prototype.removeFrom = function (stream) {
- var next = this.next;
- var prev = this.prev;
-
- if (prev) {
- prev.next = next;
- } else {
- stream.subscriberHead = next;
- }
-
- if (next) {
- next.prev = prev;
- } else {
- stream.subscriberTail = prev;
- }
- };
-
- /*
- @public
- @class Stream
- @namespace Ember.stream
- @constructor
- */
- function Stream(fn) {
- this.init();
- this.valueFn = fn;
- }
-
- Stream.prototype = {
- isStream: true,
-
- init: function () {
- this.state = 'dirty';
- this.cache = undefined;
- this.subscriberHead = null;
- this.subscriberTail = null;
- this.children = undefined;
- this._label = undefined;
- },
-
- get: function (path) {
- var firstKey = path_cache.getFirstKey(path);
- var tailPath = path_cache.getTailPath(path);
-
- if (this.children === undefined) {
- this.children = create['default'](null);
- }
-
- var keyStream = this.children[firstKey];
-
- if (keyStream === undefined) {
- keyStream = this._makeChildStream(firstKey, path);
- this.children[firstKey] = keyStream;
- }
-
- if (tailPath === undefined) {
- return keyStream;
- } else {
- return keyStream.get(tailPath);
- }
- },
-
- value: function () {
- if (this.state === 'clean') {
- return this.cache;
- } else if (this.state === 'dirty') {
- this.state = 'clean';
- return this.cache = this.valueFn();
- }
- // TODO: Ensure value is never called on a destroyed stream
- // so that we can uncomment this assertion.
- //
- // Ember.assert("Stream error: value was called in an invalid state: " + this.state);
- },
-
- valueFn: function () {
- throw new Error("Stream error: valueFn not implemented");
- },
-
- setValue: function () {
- throw new Error("Stream error: setValue not implemented");
- },
-
- notify: function () {
- this.notifyExcept();
- },
-
- notifyExcept: function (callbackToSkip, contextToSkip) {
- if (this.state === 'clean') {
- this.state = 'dirty';
- this._notifySubscribers(callbackToSkip, contextToSkip);
- }
- },
-
- subscribe: function (callback, context) {
- var subscriber = new Subscriber(callback, context, this);
- if (this.subscriberHead === null) {
- this.subscriberHead = this.subscriberTail = subscriber;
- } else {
- var tail = this.subscriberTail;
- tail.next = subscriber;
- subscriber.prev = tail;
- this.subscriberTail = subscriber;
- }
-
- var stream = this;
- return function () {
- subscriber.removeFrom(stream);
- };
- },
-
- unsubscribe: function (callback, context) {
- var subscriber = this.subscriberHead;
-
- while (subscriber) {
- var next = subscriber.next;
- if (subscriber.callback === callback && subscriber.context === context) {
- subscriber.removeFrom(this);
- }
- subscriber = next;
- }
- },
-
- _notifySubscribers: function (callbackToSkip, contextToSkip) {
- var subscriber = this.subscriberHead;
-
- while (subscriber) {
- var next = subscriber.next;
-
- var callback = subscriber.callback;
- var context = subscriber.context;
-
- subscriber = next;
-
- if (callback === callbackToSkip && context === contextToSkip) {
- continue;
- }
-
- if (context === undefined) {
- callback(this);
- } else {
- callback.call(context, this);
- }
- }
- },
-
- destroy: function () {
- if (this.state !== 'destroyed') {
- this.state = 'destroyed';
-
- var children = this.children;
- for (var key in children) {
- children[key].destroy();
- }
-
- this.subscriberHead = this.subscriberTail = null;
-
- return true;
- }
- },
-
- isGlobal: function () {
- var stream = this;
- while (stream !== undefined) {
- if (stream._isRoot) {
- return stream._isGlobal;
- }
- stream = stream.source;
- }
- }
- };
-
- exports['default'] = Stream;
-
-});
-enifed('ember-metal/streams/stream_binding', ['exports', 'ember-metal/platform/create', 'ember-metal/merge', 'ember-metal/run_loop', 'ember-metal/streams/stream'], function (exports, create, merge, run, Stream) {
-
- 'use strict';
-
- function StreamBinding(stream) {
- Ember.assert("StreamBinding error: tried to bind to object that is not a stream", stream && stream.isStream);
-
- this.init();
- this.stream = stream;
- this.senderCallback = undefined;
- this.senderContext = undefined;
- this.senderValue = undefined;
-
- stream.subscribe(this._onNotify, this);
- }
-
- StreamBinding.prototype = create['default'](Stream['default'].prototype);
-
- merge['default'](StreamBinding.prototype, {
- valueFn: function () {
- return this.stream.value();
- },
-
- _onNotify: function () {
- this._scheduleSync(undefined, undefined, this);
- },
-
- setValue: function (value, callback, context) {
- this._scheduleSync(value, callback, context);
- },
-
- _scheduleSync: function (value, callback, context) {
- if (this.senderCallback === undefined && this.senderContext === undefined) {
- this.senderCallback = callback;
- this.senderContext = context;
- this.senderValue = value;
- run['default'].schedule('sync', this, this._sync);
- } else if (this.senderContext !== this) {
- this.senderCallback = callback;
- this.senderContext = context;
- this.senderValue = value;
- }
- },
-
- _sync: function () {
- if (this.state === 'destroyed') {
- return;
- }
-
- if (this.senderContext !== this) {
- this.stream.setValue(this.senderValue);
- }
-
- var senderCallback = this.senderCallback;
- var senderContext = this.senderContext;
- this.senderCallback = undefined;
- this.senderContext = undefined;
- this.senderValue = undefined;
-
- // Force StreamBindings to always notify
- this.state = 'clean';
-
- this.notifyExcept(senderCallback, senderContext);
- },
-
- _super$destroy: Stream['default'].prototype.destroy,
-
- destroy: function () {
- if (this._super$destroy()) {
- this.stream.unsubscribe(this._onNotify, this);
- return true;
- }
- }
- });
-
- exports['default'] = StreamBinding;
-
-});
-enifed('ember-metal/streams/utils', ['exports', './stream'], function (exports, Stream) {
-
- 'use strict';
-
- exports.isStream = isStream;
- exports.subscribe = subscribe;
- exports.unsubscribe = unsubscribe;
- exports.read = read;
- exports.readArray = readArray;
- exports.readHash = readHash;
- exports.scanArray = scanArray;
- exports.scanHash = scanHash;
- exports.concat = concat;
- exports.chain = chain;
-
- function isStream(object) {
- return object && object.isStream;
- }
-
- /*
- A method of subscribing to a stream which is safe for use with a non-stream
- object. If a non-stream object is passed, the function does nothing.
-
- @public
- @for Ember.stream
- @function subscribe
- @param {Object|Stream} object object or stream to potentially subscribe to
- @param {Function} callback function to run when stream value changes
- @param {Object} [context] the callback will be executed with this context if it
- is provided
- */
-
- function subscribe(object, callback, context) {
- if (object && object.isStream) {
- object.subscribe(callback, context);
- }
- }
-
- /*
- A method of unsubscribing from a stream which is safe for use with a non-stream
- object. If a non-stream object is passed, the function does nothing.
-
- @public
- @for Ember.stream
- @function unsubscribe
- @param {Object|Stream} object object or stream to potentially unsubscribe from
- @param {Function} callback function originally passed to `subscribe()`
- @param {Object} [context] object originally passed to `subscribe()`
- */
-
- function unsubscribe(object, callback, context) {
- if (object && object.isStream) {
- object.unsubscribe(callback, context);
- }
- }
-
- /*
- Retrieve the value of a stream, or in the case a non-stream object is passed,
- return the object itself.
-
- @public
- @for Ember.stream
- @function read
- @param {Object|Stream} object object to return the value of
- @return the stream's current value, or the non-stream object itself
- */
-
- function read(object) {
- if (object && object.isStream) {
- return object.value();
- } else {
- return object;
- }
- }
-
- /*
- Map an array, replacing any streams with their values.
-
- @public
- @for Ember.stream
- @function readArray
- @param {Array} array The array to read values from
- @return {Array} a new array of the same length with the values of non-stream
- objects mapped from their original positions untouched, and
- the values of stream objects retaining their original position
- and replaced with the stream's current value.
- */
-
- function readArray(array) {
- var length = array.length;
- var ret = new Array(length);
- for (var i = 0; i < length; i++) {
- ret[i] = read(array[i]);
- }
- return ret;
- }
-
- /*
- Map a hash, replacing any stream property values with the current value of that
- stream.
-
- @public
- @for Ember.stream
- @function readHash
- @param {Object} object The hash to read keys and values from
- @return {Object} a new object with the same keys as the passed object. The
- property values in the new object are the original values in
- the case of non-stream objects, and the streams' current
- values in the case of stream objects.
- */
-
- function readHash(object) {
- var ret = {};
- for (var key in object) {
- ret[key] = read(object[key]);
- }
- return ret;
- }
-
- /*
- Check whether an array contains any stream values
-
- @public
- @for Ember.stream
- @function scanArray
- @param {Array} array array given to a handlebars helper
- @return {Boolean} `true` if the array contains a stream/bound value, `false`
- otherwise
- */
-
- function scanArray(array) {
- var length = array.length;
- var containsStream = false;
-
- for (var i = 0; i < length; i++) {
- if (isStream(array[i])) {
- containsStream = true;
- break;
- }
- }
-
- return containsStream;
- }
-
- /*
- Check whether a hash has any stream property values
-
- @public
- @for Ember.stream
- @function scanHash
- @param {Object} hash "hash" argument given to a handlebars helper
- @return {Boolean} `true` if the object contains a stream/bound value, `false`
- otherwise
- */
-
- function scanHash(hash) {
- var containsStream = false;
-
- for (var prop in hash) {
- if (isStream(hash[prop])) {
- containsStream = true;
- break;
- }
- }
-
- return containsStream;
- }
-
- /*
- Join an array, with any streams replaced by their current values
-
- @public
- @for Ember.stream
- @function concat
- @param {Array} array An array containing zero or more stream objects and
- zero or more non-stream objects
- @param {String} separator string to be used to join array elements
- @return {String} String with array elements concatenated and joined by the
- provided separator, and any stream array members having been
- replaced by the current value of the stream
- */
-
- function concat(array, separator) {
- // TODO: Create subclass ConcatStream < Stream. Defer
- // subscribing to streams until the value() is called.
- var hasStream = scanArray(array);
- if (hasStream) {
- var i, l;
- var stream = new Stream['default'](function () {
- return readArray(array).join(separator);
- });
-
- for (i = 0, l = array.length; i < l; i++) {
- subscribe(array[i], stream.notify, stream);
- }
-
- return stream;
- } else {
- return array.join(separator);
- }
- }
-
- /*
- Generate a new stream by providing a source stream and a function that can
- be used to transform the stream's value. In the case of a non-stream object,
- returns the result of the function.
-
- The value to transform would typically be available to the function you pass
- to `chain()` via scope. For example:
-
- ```javascript
- var source = ...; // stream returning a number
- // or a numeric (non-stream) object
- var result = chain(source, function() {
- var currentValue = read(source);
- return currentValue + 1;
- });
- ```
-
- In the example, result is a stream if source is a stream, or a number of
- source was numeric.
-
- @public
- @for Ember.stream
- @function chain
- @param {Object|Stream} value A stream or non-stream object
- @param {Function} fn function to be run when the stream value changes, or to
- be run once in the case of a non-stream object
- @return {Object|Stream} In the case of a stream `value` parameter, a new
- stream that will be updated with the return value of
- the provided function `fn`. In the case of a
- non-stream object, the return value of the provided
- function `fn`.
- */
-
- function chain(value, fn) {
- if (isStream(value)) {
- var stream = new Stream['default'](fn);
- subscribe(value, stream.notify, stream);
- return stream;
- } else {
- return fn();
- }
- }
-
-});
-enifed('ember-metal/utils', ['exports', 'ember-metal/core', 'ember-metal/platform/create', 'ember-metal/platform/define_property', 'ember-metal/array'], function (exports, Ember, o_create, define_property, array) {
-
-
- exports.uuid = uuid;
- exports.generateGuid = generateGuid;
- exports.guidFor = guidFor;
- exports.getMeta = getMeta;
- exports.setMeta = setMeta;
- exports.metaPath = metaPath;
- exports.wrap = wrap;
- exports.makeArray = makeArray;
- exports.tryInvoke = tryInvoke;
- exports.inspect = inspect;
- exports.apply = apply;
- exports.applyStr = applyStr;
- exports.meta = meta;
- exports.typeOf = typeOf;
- exports.isArray = isArray;
- exports.canInvoke = canInvoke;
-
- "REMOVE_USE_STRICT: true";var _uuid = 0;
-
- /**
- Generates a universally unique identifier. This method
- is used internally by Ember for assisting with
- the generation of GUID's and other unique identifiers
- such as `bind-attr` data attributes.
-
- @public
- @return {Number} [description]
- */
-
- function uuid() {
- return ++_uuid;
- }
-
- /**
- Prefix used for guids through out Ember.
- @private
- @property GUID_PREFIX
- @for Ember
- @type String
- @final
- */
- var GUID_PREFIX = 'ember';
-
- // Used for guid generation...
- var numberCache = [];
- var stringCache = {};
-
- /**
- Strongly hint runtimes to intern the provided string.
-
- When do I need to use this function?
-
- For the most part, never. Pre-mature optimization is bad, and often the
- runtime does exactly what you need it to, and more often the trade-off isn't
- worth it.
-
- Why?
-
- Runtimes store strings in at least 2 different representations:
- Ropes and Symbols (interned strings). The Rope provides a memory efficient
- data-structure for strings created from concatenation or some other string
- manipulation like splitting.
-
- Unfortunately checking equality of different ropes can be quite costly as
- runtimes must resort to clever string comparison algorithms. These
- algorithms typically cost in proportion to the length of the string.
- Luckily, this is where the Symbols (interned strings) shine. As Symbols are
- unique by their string content, equality checks can be done by pointer
- comparison.
-
- How do I know if my string is a rope or symbol?
-
- Typically (warning general sweeping statement, but truthy in runtimes at
- present) static strings created as part of the JS source are interned.
- Strings often used for comparisons can be interned at runtime if some
- criteria are met. One of these criteria can be the size of the entire rope.
- For example, in chrome 38 a rope longer then 12 characters will not
- intern, nor will segments of that rope.
-
- Some numbers: http://jsperf.com/eval-vs-keys/8
-
- Known Trickâ„¢
-
- @private
- @return {String} interned version of the provided string
- */
- function intern(str) {
- var obj = {};
- obj[str] = 1;
- for (var key in obj) {
- if (key === str) {
- return key;
- }
- }
- return str;
- }
-
- /**
- A unique key used to assign guids and other private metadata to objects.
- If you inspect an object in your browser debugger you will often see these.
- They can be safely ignored.
-
- On browsers that support it, these properties are added with enumeration
- disabled so they won't show up when you iterate over your properties.
-
- @private
- @property GUID_KEY
- @for Ember
- @type String
- @final
- */
- var GUID_KEY = intern('__ember' + +new Date());
-
- var GUID_DESC = {
- writable: true,
- configurable: true,
- enumerable: false,
- value: null
- };
-
- var undefinedDescriptor = {
- configurable: true,
- writable: true,
- enumerable: false,
- value: undefined
- };
-
- var nullDescriptor = {
- configurable: true,
- writable: true,
- enumerable: false,
- value: null
- };
-
- var META_DESC = {
- writable: true,
- configurable: true,
- enumerable: false,
- value: null
- };
-
- var EMBER_META_PROPERTY = {
- name: '__ember_meta__',
- descriptor: META_DESC
- };
-
- var GUID_KEY_PROPERTY = {
- name: GUID_KEY,
- descriptor: nullDescriptor
- };
-
- var NEXT_SUPER_PROPERTY = {
- name: '__nextSuper',
- descriptor: undefinedDescriptor
- };
-
- function generateGuid(obj, prefix) {
- if (!prefix) {
- prefix = GUID_PREFIX;
- }
-
- var ret = prefix + uuid();
- if (obj) {
- if (obj[GUID_KEY] === null) {
- obj[GUID_KEY] = ret;
- } else {
- GUID_DESC.value = ret;
- if (obj.__defineNonEnumerable) {
- obj.__defineNonEnumerable(GUID_KEY_PROPERTY);
- } else {
- define_property.defineProperty(obj, GUID_KEY, GUID_DESC);
- }
- }
- }
- return ret;
- }
-
- /**
- Returns a unique id for the object. If the object does not yet have a guid,
- one will be assigned to it. You can call this on any object,
- `Ember.Object`-based or not, but be aware that it will add a `_guid`
- property.
-
- You can also use this method on DOM Element objects.
-
- @private
- @method guidFor
- @for Ember
- @param {Object} obj any object, string, number, Element, or primitive
- @return {String} the unique guid for this instance.
- */
-
- function guidFor(obj) {
-
- // special cases where we don't want to add a key to object
- if (obj === undefined) {
- return "(undefined)";
- }
-
- if (obj === null) {
- return "(null)";
- }
-
- var ret;
- var type = typeof obj;
-
- // Don't allow prototype changes to String etc. to change the guidFor
- switch (type) {
- case 'number':
- ret = numberCache[obj];
-
- if (!ret) {
- ret = numberCache[obj] = 'nu' + obj;
- }
-
- return ret;
-
- case 'string':
- ret = stringCache[obj];
-
- if (!ret) {
- ret = stringCache[obj] = 'st' + uuid();
- }
-
- return ret;
-
- case 'boolean':
- return obj ? '(true)' : '(false)';
-
- default:
- if (obj[GUID_KEY]) {
- return obj[GUID_KEY];
- }
-
- if (obj === Object) {
- return '(Object)';
- }
-
- if (obj === Array) {
- return '(Array)';
- }
-
- ret = GUID_PREFIX + uuid();
-
- if (obj[GUID_KEY] === null) {
- obj[GUID_KEY] = ret;
- } else {
- GUID_DESC.value = ret;
-
- if (obj.__defineNonEnumerable) {
- obj.__defineNonEnumerable(GUID_KEY_PROPERTY);
- } else {
- define_property.defineProperty(obj, GUID_KEY, GUID_DESC);
- }
- }
- return ret;
- }
- }
-
- // ..........................................................
- // META
- //
- function Meta(obj) {
- this.watching = {};
- this.cache = undefined;
- this.cacheMeta = undefined;
- this.source = obj;
- this.deps = undefined;
- this.listeners = undefined;
- this.mixins = undefined;
- this.bindings = undefined;
- this.chains = undefined;
- this.values = undefined;
- this.proto = undefined;
- }
-
- Meta.prototype = {
- chainWatchers: null // FIXME
- };
-
- if (!define_property.canDefineNonEnumerableProperties) {
- // on platforms that don't support enumerable false
- // make meta fail jQuery.isPlainObject() to hide from
- // jQuery.extend() by having a property that fails
- // hasOwnProperty check.
- Meta.prototype.__preventPlainObject__ = true;
-
- // Without non-enumerable properties, meta objects will be output in JSON
- // unless explicitly suppressed
- Meta.prototype.toJSON = function () {};
- }
-
- // Placeholder for non-writable metas.
- var EMPTY_META = new Meta(null);
-
-
- if (define_property.hasPropertyAccessors) {
- EMPTY_META.values = {};
- }
-
-
- /**
- Retrieves the meta hash for an object. If `writable` is true ensures the
- hash is writable for this object as well.
-
- The meta object contains information about computed property descriptors as
- well as any watched properties and other information. You generally will
- not access this information directly but instead work with higher level
- methods that manipulate this hash indirectly.
-
- @method meta
- @for Ember
- @private
-
- @param {Object} obj The object to retrieve meta for
- @param {Boolean} [writable=true] Pass `false` if you do not intend to modify
- the meta hash, allowing the method to avoid making an unnecessary copy.
- @return {Object} the meta hash for an object
- */
- function meta(obj, writable) {
- var ret = obj.__ember_meta__;
- if (writable === false) {
- return ret || EMPTY_META;
- }
-
- if (!ret) {
- if (define_property.canDefineNonEnumerableProperties) {
- if (obj.__defineNonEnumerable) {
- obj.__defineNonEnumerable(EMBER_META_PROPERTY);
- } else {
- define_property.defineProperty(obj, '__ember_meta__', META_DESC);
- }
- }
-
- ret = new Meta(obj);
-
-
- if (define_property.hasPropertyAccessors) {
- ret.values = {};
- }
-
-
- obj.__ember_meta__ = ret;
- } else if (ret.source !== obj) {
- if (obj.__defineNonEnumerable) {
- obj.__defineNonEnumerable(EMBER_META_PROPERTY);
- } else {
- define_property.defineProperty(obj, '__ember_meta__', META_DESC);
- }
-
- ret = o_create['default'](ret);
- ret.watching = o_create['default'](ret.watching);
- ret.cache = undefined;
- ret.cacheMeta = undefined;
- ret.source = obj;
-
-
- if (define_property.hasPropertyAccessors) {
- ret.values = o_create['default'](ret.values);
- }
-
-
- obj['__ember_meta__'] = ret;
- }
- return ret;
- }
-
- function getMeta(obj, property) {
- var _meta = meta(obj, false);
- return _meta[property];
- }
-
- function setMeta(obj, property, value) {
- var _meta = meta(obj, true);
- _meta[property] = value;
- return value;
- }
-
- /**
- @deprecated
- @private
-
- In order to store defaults for a class, a prototype may need to create
- a default meta object, which will be inherited by any objects instantiated
- from the class's constructor.
-
- However, the properties of that meta object are only shallow-cloned,
- so if a property is a hash (like the event system's `listeners` hash),
- it will by default be shared across all instances of that class.
-
- This method allows extensions to deeply clone a series of nested hashes or
- other complex objects. For instance, the event system might pass
- `['listeners', 'foo:change', 'ember157']` to `prepareMetaPath`, which will
- walk down the keys provided.
-
- For each key, if the key does not exist, it is created. If it already
- exists and it was inherited from its constructor, the constructor's
- key is cloned.
-
- You can also pass false for `writable`, which will simply return
- undefined if `prepareMetaPath` discovers any part of the path that
- shared or undefined.
-
- @method metaPath
- @for Ember
- @param {Object} obj The object whose meta we are examining
- @param {Array} path An array of keys to walk down
- @param {Boolean} writable whether or not to create a new meta
- (or meta property) if one does not already exist or if it's
- shared with its constructor
- */
-
- function metaPath(obj, path, writable) {
- Ember['default'].deprecate("Ember.metaPath is deprecated and will be removed from future releases.");
- var _meta = meta(obj, writable);
- var keyName, value;
-
- for (var i = 0, l = path.length; i < l; i++) {
- keyName = path[i];
- value = _meta[keyName];
-
- if (!value) {
- if (!writable) {
- return undefined;
- }
- value = _meta[keyName] = { __ember_source__: obj };
- } else if (value.__ember_source__ !== obj) {
- if (!writable) {
- return undefined;
- }
- value = _meta[keyName] = o_create['default'](value);
- value.__ember_source__ = obj;
- }
-
- _meta = value;
- }
-
- return value;
- }
-
- /**
- Wraps the passed function so that `this._super` will point to the superFunc
- when the function is invoked. This is the primitive we use to implement
- calls to super.
-
- @private
- @method wrap
- @for Ember
- @param {Function} func The function to call
- @param {Function} superFunc The super function.
- @return {Function} wrapped function.
- */
-
- function wrap(func, superFunc) {
- function superWrapper() {
- var ret;
- var sup = this && this.__nextSuper;
- var length = arguments.length;
-
- if (this) {
- this.__nextSuper = superFunc;
- }
-
- if (length === 0) {
- ret = func.call(this);
- } else if (length === 1) {
- ret = func.call(this, arguments[0]);
- } else if (length === 2) {
- ret = func.call(this, arguments[0], arguments[1]);
- } else {
- var args = new Array(length);
- for (var i = 0; i < length; i++) {
- args[i] = arguments[i];
- }
- ret = apply(this, func, args);
- }
-
- if (this) {
- this.__nextSuper = sup;
- }
-
- return ret;
- }
-
- superWrapper.wrappedFunction = func;
- superWrapper.__ember_observes__ = func.__ember_observes__;
- superWrapper.__ember_observesBefore__ = func.__ember_observesBefore__;
- superWrapper.__ember_listens__ = func.__ember_listens__;
-
- return superWrapper;
- }
-
- var EmberArray;
-
- /**
- Returns true if the passed object is an array or Array-like.
-
- Ember Array Protocol:
-
- - the object has an objectAt property
- - the object is a native Array
- - the object is an Object, and has a length property
-
- Unlike `Ember.typeOf` this method returns true even if the passed object is
- not formally array but appears to be array-like (i.e. implements `Ember.Array`)
-
- ```javascript
- Ember.isArray(); // false
- Ember.isArray([]); // true
- Ember.isArray(Ember.ArrayProxy.create({ content: [] })); // true
- ```
-
- @method isArray
- @for Ember
- @param {Object} obj The object to test
- @return {Boolean} true if the passed object is an array or Array-like
- */
- // ES6TODO: Move up to runtime? This is only use in ember-metal by concatenatedProperties
- function isArray(obj) {
- var modulePath, type;
-
- if (typeof EmberArray === "undefined") {
- modulePath = 'ember-runtime/mixins/array';
- if (Ember['default'].__loader.registry[modulePath]) {
- EmberArray = Ember['default'].__loader.require(modulePath)['default'];
- }
- }
-
- if (!obj || obj.setInterval) {
- return false;
- }
- if (Array.isArray && Array.isArray(obj)) {
- return true;
- }
- if (EmberArray && EmberArray.detect(obj)) {
- return true;
- }
-
- type = typeOf(obj);
- if ('array' === type) {
- return true;
- }
- if (obj.length !== undefined && 'object' === type) {
- return true;
- }
- return false;
- }
-
- /**
- Forces the passed object to be part of an array. If the object is already
- an array or array-like, it will return the object. Otherwise, it will add the object to
- an array. If obj is `null` or `undefined`, it will return an empty array.
-
- ```javascript
- Ember.makeArray(); // []
- Ember.makeArray(null); // []
- Ember.makeArray(undefined); // []
- Ember.makeArray('lindsay'); // ['lindsay']
- Ember.makeArray([1, 2, 42]); // [1, 2, 42]
-
- var controller = Ember.ArrayProxy.create({ content: [] });
-
- Ember.makeArray(controller) === controller; // true
- ```
-
- @method makeArray
- @for Ember
- @param {Object} obj the object
- @return {Array}
- */
-
- function makeArray(obj) {
- if (obj === null || obj === undefined) {
- return [];
- }
- return isArray(obj) ? obj : [obj];
- }
-
- /**
- Checks to see if the `methodName` exists on the `obj`.
-
- ```javascript
- var foo = { bar: function() { return 'bar'; }, baz: null };
-
- Ember.canInvoke(foo, 'bar'); // true
- Ember.canInvoke(foo, 'baz'); // false
- Ember.canInvoke(foo, 'bat'); // false
- ```
-
- @method canInvoke
- @for Ember
- @param {Object} obj The object to check for the method
- @param {String} methodName The method name to check for
- @return {Boolean}
- */
- function canInvoke(obj, methodName) {
- return !!(obj && typeof obj[methodName] === 'function');
- }
-
- /**
- Checks to see if the `methodName` exists on the `obj`,
- and if it does, invokes it with the arguments passed.
-
- ```javascript
- var d = new Date('03/15/2013');
-
- Ember.tryInvoke(d, 'getTime'); // 1363320000000
- Ember.tryInvoke(d, 'setFullYear', [2014]); // 1394856000000
- Ember.tryInvoke(d, 'noSuchMethod', [2014]); // undefined
- ```
-
- @method tryInvoke
- @for Ember
- @param {Object} obj The object to check for the method
- @param {String} methodName The method name to check for
- @param {Array} [args] The arguments to pass to the method
- @return {*} the return value of the invoked method or undefined if it cannot be invoked
- */
-
- function tryInvoke(obj, methodName, args) {
- if (canInvoke(obj, methodName)) {
- return args ? applyStr(obj, methodName, args) : applyStr(obj, methodName);
- }
- }
-
- // https://github.com/emberjs/ember.js/pull/1617
- var needsFinallyFix = (function () {
- var count = 0;
- try {
- // jscs:disable
- try {} finally {
- count++;
- throw new Error('needsFinallyFixTest');
- }
- // jscs:enable
- } catch (e) {}
-
- return count !== 1;
- })();
-
- /**
- Provides try/finally functionality, while working
- around Safari's double finally bug.
-
- ```javascript
- var tryable = function() {
- someResource.lock();
- runCallback(); // May throw error.
- };
-
- var finalizer = function() {
- someResource.unlock();
- };
-
- Ember.tryFinally(tryable, finalizer);
- ```
-
- @method tryFinally
- @deprecated Use JavaScript's native try/finally
- @for Ember
- @param {Function} tryable The function to run the try callback
- @param {Function} finalizer The function to run the finally callback
- @param {Object} [binding] The optional calling object. Defaults to 'this'
- @return {*} The return value is the that of the finalizer,
- unless that value is undefined, in which case it is the return value
- of the tryable
- */
-
- var tryFinally;
- if (needsFinallyFix) {
- tryFinally = function (tryable, finalizer, binding) {
- var result, finalResult, finalError;
-
- binding = binding || this;
-
- try {
- result = tryable.call(binding);
- } finally {
- try {
- finalResult = finalizer.call(binding);
- } catch (e) {
- finalError = e;
- }
- }
-
- if (finalError) {
- throw finalError;
- }
-
- return finalResult === undefined ? result : finalResult;
- };
- } else {
- tryFinally = function (tryable, finalizer, binding) {
- var result, finalResult;
-
- binding = binding || this;
-
- try {
- result = tryable.call(binding);
- } finally {
- finalResult = finalizer.call(binding);
- }
-
- return finalResult === undefined ? result : finalResult;
- };
- }
-
- var deprecatedTryFinally = function () {
- Ember['default'].deprecate("tryFinally is deprecated. Please use JavaScript's native try/finally.", false);
- return tryFinally.apply(this, arguments);
- };
-
- /**
- Provides try/catch/finally functionality, while working
- around Safari's double finally bug.
-
- ```javascript
- var tryable = function() {
- for (i = 0, l = listeners.length; i < l; i++) {
- listener = listeners[i];
- beforeValues[i] = listener.before(name, time(), payload);
- }
-
- return callback.call(binding);
- };
-
- var catchable = function(e) {
- payload = payload || {};
- payload.exception = e;
- };
-
- var finalizer = function() {
- for (i = 0, l = listeners.length; i < l; i++) {
- listener = listeners[i];
- listener.after(name, time(), payload, beforeValues[i]);
- }
- };
-
- Ember.tryCatchFinally(tryable, catchable, finalizer);
- ```
-
- @method tryCatchFinally
- @deprecated Use JavaScript's native try/catch/finally instead
- @for Ember
- @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 {Object} [binding] The optional calling object. Defaults to 'this'
- @return {*} The return value is the that of the finalizer,
- unless that value is undefined, in which case it is the return value
- of the tryable.
- */
- var tryCatchFinally;
- if (needsFinallyFix) {
- tryCatchFinally = function (tryable, catchable, finalizer, binding) {
- var result, finalResult, finalError;
-
- binding = binding || this;
-
- try {
- result = tryable.call(binding);
- } catch (error) {
- result = catchable.call(binding, error);
- } finally {
- try {
- finalResult = finalizer.call(binding);
- } catch (e) {
- finalError = e;
- }
- }
-
- if (finalError) {
- throw finalError;
- }
-
- return finalResult === undefined ? result : finalResult;
- };
- } else {
- tryCatchFinally = function (tryable, catchable, finalizer, binding) {
- var result, finalResult;
-
- binding = binding || this;
-
- try {
- result = tryable.call(binding);
- } catch (error) {
- result = catchable.call(binding, error);
- } finally {
- finalResult = finalizer.call(binding);
- }
-
- return finalResult === undefined ? result : finalResult;
- };
- }
-
- var deprecatedTryCatchFinally = function () {
- Ember['default'].deprecate("tryCatchFinally is deprecated. Please use JavaScript's native try/catch/finally.", false);
- return tryCatchFinally.apply(this, arguments);
- };
-
- // ........................................
- // TYPING & ARRAY MESSAGING
- //
-
- var TYPE_MAP = {};
- var t = "Boolean Number String Function Array Date RegExp Object".split(" ");
- array.forEach.call(t, function (name) {
- TYPE_MAP["[object " + name + "]"] = name.toLowerCase();
- });
-
- var toString = Object.prototype.toString;
-
- var EmberObject;
-
- /**
- Returns a consistent type for the passed item.
-
- Use this instead of the built-in `typeof` to get the type of an item.
- It will return the same result across all browsers and includes a bit
- more detail. Here is what will be returned:
-
- | Return Value | Meaning |
- |---------------|------------------------------------------------------|
- | 'string' | String primitive or String object. |
- | 'number' | Number primitive or Number object. |
- | 'boolean' | Boolean primitive or Boolean object. |
- | 'null' | Null value |
- | 'undefined' | Undefined value |
- | 'function' | A function |
- | 'array' | An instance of Array |
- | 'regexp' | An instance of RegExp |
- | 'date' | An instance of Date |
- | 'class' | An Ember class (created using Ember.Object.extend()) |
- | 'instance' | An Ember object instance |
- | 'error' | An instance of the Error object |
- | 'object' | A JavaScript object not inheriting from Ember.Object |
-
- Examples:
-
- ```javascript
- Ember.typeOf(); // 'undefined'
- Ember.typeOf(null); // 'null'
- Ember.typeOf(undefined); // 'undefined'
- Ember.typeOf('michael'); // 'string'
- Ember.typeOf(new String('michael')); // 'string'
- Ember.typeOf(101); // 'number'
- Ember.typeOf(new Number(101)); // 'number'
- Ember.typeOf(true); // 'boolean'
- Ember.typeOf(new Boolean(true)); // 'boolean'
- Ember.typeOf(Ember.makeArray); // 'function'
- Ember.typeOf([1, 2, 90]); // 'array'
- Ember.typeOf(/abc/); // 'regexp'
- Ember.typeOf(new Date()); // 'date'
- Ember.typeOf(Ember.Object.extend()); // 'class'
- Ember.typeOf(Ember.Object.create()); // 'instance'
- Ember.typeOf(new Error('teamocil')); // 'error'
-
- // 'normal' JavaScript object
- Ember.typeOf({ a: 'b' }); // 'object'
- ```
-
- @method typeOf
- @for Ember
- @param {Object} item the item to check
- @return {String} the type
- */
- function typeOf(item) {
- var ret, modulePath;
-
- // ES6TODO: Depends on Ember.Object which is defined in runtime.
- if (typeof EmberObject === "undefined") {
- modulePath = 'ember-runtime/system/object';
- if (Ember['default'].__loader.registry[modulePath]) {
- EmberObject = Ember['default'].__loader.require(modulePath)['default'];
- }
- }
-
- ret = item === null || item === undefined ? String(item) : TYPE_MAP[toString.call(item)] || 'object';
-
- if (ret === 'function') {
- if (EmberObject && EmberObject.detect(item)) {
- ret = 'class';
- }
- } else if (ret === 'object') {
- if (item instanceof Error) {
- ret = 'error';
- } else if (EmberObject && item instanceof EmberObject) {
- ret = 'instance';
- } else if (item instanceof Date) {
- ret = 'date';
- }
- }
-
- return ret;
- }
-
- /**
- Convenience method to inspect an object. This method will attempt to
- convert the object into a useful string description.
-
- It is a pretty simple implementation. If you want something more robust,
- use something like JSDump: https://github.com/NV/jsDump
-
- @method inspect
- @for Ember
- @param {Object} obj The object you want to inspect.
- @return {String} A description of the object
- @since 1.4.0
- */
-
- function inspect(obj) {
- var type = typeOf(obj);
- if (type === 'array') {
- return '[' + obj + ']';
- }
- if (type !== 'object') {
- return obj + '';
- }
-
- var v;
- var ret = [];
- for (var key in obj) {
- if (obj.hasOwnProperty(key)) {
- v = obj[key];
- if (v === 'toString') {
- continue;
- } // ignore useless items
- if (typeOf(v) === 'function') {
- v = "function() { ... }";
- }
-
- if (v && typeof v.toString !== 'function') {
- ret.push(key + ": " + toString.call(v));
- } else {
- ret.push(key + ": " + v);
- }
- }
- }
- return "{" + ret.join(", ") + "}";
- }
-
- // The following functions are intentionally minified to keep the functions
- // below Chrome's function body size inlining limit of 600 chars.
- /**
- @param {Object} target
- @param {Function} method
- @param {Array} args
- */
-
- function apply(t, m, a) {
- var l = a && a.length;
- if (!a || !l) {
- return m.call(t);
- }
- switch (l) {
- case 1:
- return m.call(t, a[0]);
- case 2:
- return m.call(t, a[0], a[1]);
- case 3:
- return m.call(t, a[0], a[1], a[2]);
- case 4:
- return m.call(t, a[0], a[1], a[2], a[3]);
- case 5:
- return m.call(t, a[0], a[1], a[2], a[3], a[4]);
- default:
- return m.apply(t, a);
- }
- }
-
- /**
- @param {Object} target
- @param {String} method
- @param {Array} args
- */
-
- function applyStr(t, m, a) {
- var l = a && a.length;
- if (!a || !l) {
- return t[m]();
- }
- switch (l) {
- case 1:
- return t[m](a[0]);
- case 2:
- return t[m](a[0], a[1]);
- case 3:
- return t[m](a[0], a[1], a[2]);
- case 4:
- return t[m](a[0], a[1], a[2], a[3]);
- case 5:
- return t[m](a[0], a[1], a[2], a[3], a[4]);
- default:
- return t[m].apply(t, a);
- }
- }
-
- exports.GUID_DESC = GUID_DESC;
- exports.EMBER_META_PROPERTY = EMBER_META_PROPERTY;
- exports.GUID_KEY_PROPERTY = GUID_KEY_PROPERTY;
- exports.NEXT_SUPER_PROPERTY = NEXT_SUPER_PROPERTY;
- exports.GUID_KEY = GUID_KEY;
- exports.META_DESC = META_DESC;
- exports.EMPTY_META = EMPTY_META;
- exports.tryCatchFinally = tryCatchFinally;
- exports.deprecatedTryCatchFinally = deprecatedTryCatchFinally;
- exports.tryFinally = tryFinally;
- exports.deprecatedTryFinally = deprecatedTryFinally;
-
-});
-enifed('ember-metal/watch_key', ['exports', 'ember-metal/core', 'ember-metal/utils', 'ember-metal/platform/define_property', 'ember-metal/properties'], function (exports, Ember, utils, define_property, properties) {
-
- 'use strict';
-
- exports.watchKey = watchKey;
- exports.unwatchKey = unwatchKey;
-
- function watchKey(obj, keyName, meta) {
- // can't watch length on Array - it is special...
- if (keyName === 'length' && utils.typeOf(obj) === 'array') {
- return;
- }
-
- var m = meta || utils.meta(obj);
- var watching = m.watching;
-
- // activate watching first time
- if (!watching[keyName]) {
- watching[keyName] = 1;
-
- var possibleDesc = obj[keyName];
- var desc = possibleDesc !== null && typeof possibleDesc === 'object' && possibleDesc.isDescriptor ? possibleDesc : undefined;
- if (desc && desc.willWatch) {
- desc.willWatch(obj, keyName);
- }
-
- if ('function' === typeof obj.willWatchProperty) {
- obj.willWatchProperty(keyName);
- }
-
-
- if (define_property.hasPropertyAccessors) {
- handleMandatorySetter(m, obj, keyName);
- }
-
- } else {
- watching[keyName] = (watching[keyName] || 0) + 1;
- }
- }
-
-
- var handleMandatorySetter = function handleMandatorySetter(m, obj, keyName) {
- var descriptor = Object.getOwnPropertyDescriptor && Object.getOwnPropertyDescriptor(obj, keyName);
- var configurable = descriptor ? descriptor.configurable : true;
- var isWritable = descriptor ? descriptor.writable : true;
- var hasValue = descriptor ? 'value' in descriptor : true;
- var possibleDesc = descriptor && descriptor.value;
- var isDescriptor = possibleDesc !== null && typeof possibleDesc === 'object' && possibleDesc.isDescriptor;
-
- if (isDescriptor) {
- return;
- }
-
- // this x in Y deopts, so keeping it in this function is better;
- if (configurable && isWritable && hasValue && keyName in obj) {
- m.values[keyName] = obj[keyName];
- define_property.defineProperty(obj, keyName, {
- configurable: true,
- enumerable: Object.prototype.propertyIsEnumerable.call(obj, keyName),
- set: properties.MANDATORY_SETTER_FUNCTION(keyName),
- get: properties.DEFAULT_GETTER_FUNCTION(keyName)
- });
- }
- };
-
-
- // This is super annoying, but required until
- // https://github.com/babel/babel/issues/906 is resolved
- ; // jshint ignore:line
-
- function unwatchKey(obj, keyName, meta) {
- var m = meta || utils.meta(obj);
- var watching = m.watching;
-
- if (watching[keyName] === 1) {
- watching[keyName] = 0;
-
- var possibleDesc = obj[keyName];
- var desc = possibleDesc !== null && typeof possibleDesc === 'object' && possibleDesc.isDescriptor ? possibleDesc : undefined;
- if (desc && desc.didUnwatch) {
- desc.didUnwatch(obj, keyName);
- }
-
- if ('function' === typeof obj.didUnwatchProperty) {
- obj.didUnwatchProperty(keyName);
- }
-
-
- if (!desc && define_property.hasPropertyAccessors && keyName in obj) {
- define_property.defineProperty(obj, keyName, {
- configurable: true,
- enumerable: Object.prototype.propertyIsEnumerable.call(obj, keyName),
- set: function (val) {
- // redefine to set as enumerable
- define_property.defineProperty(obj, keyName, {
- configurable: true,
- writable: true,
- enumerable: true,
- value: val
- });
- delete m.values[keyName];
- },
- get: properties.DEFAULT_GETTER_FUNCTION(keyName)
- });
- }
-
- } else if (watching[keyName] > 1) {
- watching[keyName]--;
- }
- }
-
-});
-enifed('ember-metal/watch_path', ['exports', 'ember-metal/utils', 'ember-metal/chains'], function (exports, utils, chains) {
-
- 'use strict';
-
- exports.watchPath = watchPath;
- exports.unwatchPath = unwatchPath;
-
- function chainsFor(obj, meta) {
- var m = meta || utils.meta(obj);
- var ret = m.chains;
- if (!ret) {
- ret = m.chains = new chains.ChainNode(null, null, obj);
- } else if (ret.value() !== obj) {
- ret = m.chains = ret.copy(obj);
- }
- return ret;
- }
-
- function watchPath(obj, keyPath, meta) {
- // can't watch length on Array - it is special...
- if (keyPath === 'length' && utils.typeOf(obj) === 'array') {
- return;
- }
-
- var m = meta || utils.meta(obj);
- var watching = m.watching;
-
- if (!watching[keyPath]) {
- // activate watching first time
- watching[keyPath] = 1;
- chainsFor(obj, m).add(keyPath);
- } else {
- watching[keyPath] = (watching[keyPath] || 0) + 1;
- }
- }
-
- function unwatchPath(obj, keyPath, meta) {
- var m = meta || utils.meta(obj);
- var watching = m.watching;
-
- if (watching[keyPath] === 1) {
- watching[keyPath] = 0;
- chainsFor(obj, m).remove(keyPath);
- } else if (watching[keyPath] > 1) {
- watching[keyPath]--;
- }
- }
-
-});
-enifed('ember-metal/watching', ['exports', 'ember-metal/utils', 'ember-metal/chains', 'ember-metal/watch_key', 'ember-metal/watch_path', 'ember-metal/path_cache'], function (exports, utils, chains, watch_key, watch_path, path_cache) {
-
- 'use strict';
-
- exports.isWatching = isWatching;
- exports.unwatch = unwatch;
- exports.destroy = destroy;
- exports.watch = watch;
-
- function watch(obj, _keyPath, m) {
- // can't watch length on Array - it is special...
- if (_keyPath === 'length' && utils.typeOf(obj) === 'array') {
- return;
- }
-
- if (!path_cache.isPath(_keyPath)) {
- watch_key.watchKey(obj, _keyPath, m);
- } else {
- watch_path.watchPath(obj, _keyPath, m);
- }
- }
-
- function isWatching(obj, key) {
- var meta = obj['__ember_meta__'];
- return (meta && meta.watching[key]) > 0;
- }
-
- watch.flushPending = chains.flushPendingChains;
-
- function unwatch(obj, _keyPath, m) {
- // can't watch length on Array - it is special...
- if (_keyPath === 'length' && utils.typeOf(obj) === 'array') {
- return;
- }
-
- if (!path_cache.isPath(_keyPath)) {
- watch_key.unwatchKey(obj, _keyPath, m);
- } else {
- watch_path.unwatchPath(obj, _keyPath, m);
- }
- }
-
- var NODE_STACK = [];
-
- /**
- Tears down the meta on an object so that it can be garbage collected.
- Multiple calls will have no effect.
-
- @method destroy
- @for Ember
- @param {Object} obj the object to destroy
- @return {void}
- */
-
- function destroy(obj) {
- var meta = obj['__ember_meta__'];
- var node, nodes, key, nodeObject;
-
- if (meta) {
- obj['__ember_meta__'] = null;
- // remove chainWatchers to remove circular references that would prevent GC
- node = meta.chains;
- if (node) {
- NODE_STACK.push(node);
- // process tree
- while (NODE_STACK.length > 0) {
- node = NODE_STACK.pop();
- // push children
- nodes = node._chains;
- if (nodes) {
- for (key in nodes) {
- if (nodes.hasOwnProperty(key)) {
- NODE_STACK.push(nodes[key]);
- }
- }
- }
- // remove chainWatcher in node object
- if (node._watching) {
- nodeObject = node._object;
- if (nodeObject) {
- chains.removeChainWatcher(nodeObject, node._key, node);
- }
- }
- }
- }
- }
- }
-
-});
-enifed('ember-template-compiler', ['exports', 'ember-metal/core', 'ember-template-compiler/system/precompile', 'ember-template-compiler/system/compile', 'ember-template-compiler/system/template', 'ember-template-compiler/plugins', 'ember-template-compiler/plugins/transform-each-in-to-hash', 'ember-template-compiler/plugins/transform-with-as-to-hash', 'ember-template-compiler/compat'], function (exports, _Ember, precompile, compile, template, plugins, TransformEachInToHash, TransformWithAsToHash) {
-
- 'use strict';
-
- plugins.registerPlugin('ast', TransformWithAsToHash['default']);
- plugins.registerPlugin('ast', TransformEachInToHash['default']);
-
- exports._Ember = _Ember['default'];
- exports.precompile = precompile['default'];
- exports.compile = compile['default'];
- exports.template = template['default'];
- exports.registerPlugin = plugins.registerPlugin;
-
-});
-enifed('ember-template-compiler/compat', ['ember-metal/core', 'ember-template-compiler/compat/precompile', 'ember-template-compiler/system/compile', 'ember-template-compiler/system/template'], function (Ember, precompile, compile, template) {
-
- 'use strict';
-
- var EmberHandlebars = Ember['default'].Handlebars = Ember['default'].Handlebars || {};
-
- EmberHandlebars.precompile = precompile['default'];
- EmberHandlebars.compile = compile['default'];
- EmberHandlebars.template = template['default'];
-
-});
-enifed('ember-template-compiler/compat/precompile', ['exports', 'ember-template-compiler/system/compile_options'], function (exports, compileOptions) {
-
- 'use strict';
-
- /**
- @module ember
- @submodule ember-template-compiler
- */
- var compile, compileSpec;
-
- exports['default'] = function (string) {
- if ((!compile || !compileSpec) && Ember.__loader.registry['htmlbars-compiler/compiler']) {
- var Compiler = requireModule('htmlbars-compiler/compiler');
-
- compile = Compiler.compile;
- compileSpec = Compiler.compileSpec;
- }
-
- if (!compile || !compileSpec) {
- throw new Error('Cannot call `precompile` without the template compiler loaded. Please load `ember-template-compiler.js` prior to calling `precompile`.');
- }
-
- var asObject = arguments[1] === undefined ? true : arguments[1];
- var compileFunc = asObject ? compile : compileSpec;
-
- return compileFunc(string, compileOptions['default']());
- }
-
-});
-enifed('ember-template-compiler/plugins', ['exports'], function (exports) {
-
- 'use strict';
-
- exports.registerPlugin = registerPlugin;
-
- var plugins = {
- ast: []
- };
-
- /**
- Adds an AST plugin to be used by Ember.HTMLBars.compile.
-
- @private
- @method registerASTPlugin
- */
-
- function registerPlugin(type, Plugin) {
- if (!plugins[type]) {
- throw new Error('Attempting to register "' + Plugin + '" as "' + type + '" which is not a valid HTMLBars plugin type.');
- }
-
- plugins[type].push(Plugin);
- }
-
- exports['default'] = plugins;
-
-});
-enifed('ember-template-compiler/plugins/transform-each-in-to-hash', ['exports'], function (exports) {
-
- 'use strict';
-
- /**
- @module ember
- @submodule ember-htmlbars
- */
-
- /**
- An HTMLBars AST transformation that replaces all instances of
-
- ```handlebars
- {{#each item in items}}
- {{/each}}
- ```
-
- with
-
- ```handlebars
- {{#each items keyword="item"}}
- {{/each}}
- ```
-
- @class TransformEachInToHash
- @private
- */
- function TransformEachInToHash(options) {
- // set later within HTMLBars to the syntax package
- this.syntax = null;
- this.options = options || {};
- }
-
- /**
- @private
- @method transform
- @param {AST} The AST to be transformed.
- */
- TransformEachInToHash.prototype.transform = function TransformEachInToHash_transform(ast) {
- var pluginContext = this;
- var walker = new pluginContext.syntax.Walker();
- var b = pluginContext.syntax.builders;
-
- walker.visit(ast, function (node) {
- if (pluginContext.validate(node)) {
-
- if (node.program && node.program.blockParams.length) {
- throw new Error('You cannot use keyword (`{{each foo in bar}}`) and block params (`{{each bar as |foo|}}`) at the same time.');
- }
-
- var removedParams = node.sexpr.params.splice(0, 2);
- var keyword = removedParams[0].original;
-
- // TODO: This may not be necessary.
- if (!node.sexpr.hash) {
- node.sexpr.hash = b.hash();
- }
-
- node.sexpr.hash.pairs.push(b.pair('keyword', b.string(keyword)));
- }
- });
-
- return ast;
- };
-
- TransformEachInToHash.prototype.validate = function TransformEachInToHash_validate(node) {
- return (node.type === 'BlockStatement' || node.type === 'MustacheStatement') && node.sexpr.path.original === 'each' && node.sexpr.params.length === 3 && node.sexpr.params[1].type === 'PathExpression' && node.sexpr.params[1].original === 'in';
- };
-
- exports['default'] = TransformEachInToHash;
-
-});
-enifed('ember-template-compiler/plugins/transform-with-as-to-hash', ['exports'], function (exports) {
-
- 'use strict';
-
- /**
- @module ember
- @submodule ember-htmlbars
- */
-
- /**
- An HTMLBars AST transformation that replaces all instances of
-
- ```handlebars
- {{#with foo.bar as bar}}
- {{/with}}
- ```
-
- with
-
- ```handlebars
- {{#with foo.bar as |bar|}}
- {{/with}}
- ```
-
- @private
- @class TransformWithAsToHash
- */
- function TransformWithAsToHash(options) {
- // set later within HTMLBars to the syntax package
- this.syntax = null;
- this.options = options;
- }
-
- /**
- @private
- @method transform
- @param {AST} The AST to be transformed.
- */
- TransformWithAsToHash.prototype.transform = function TransformWithAsToHash_transform(ast) {
- var pluginContext = this;
- var walker = new pluginContext.syntax.Walker();
- var moduleName = this.options.moduleName;
-
- walker.visit(ast, function (node) {
- if (pluginContext.validate(node)) {
-
- if (node.program && node.program.blockParams.length) {
- throw new Error('You cannot use keyword (`{{with foo as bar}}`) and block params (`{{with foo as |bar|}}`) at the same time.');
- }
-
- Ember.deprecate("Using {{with}} without block syntax is deprecated. " + "Please use standard block form (`{{#with foo as |bar|}}`) " + (moduleName ? " in `" + moduleName + "` " : "") + "instead.", false, { url: "http://emberjs.com/deprecations/v1.x/#toc_code-as-code-sytnax-for-code-with-code" });
-
- var removedParams = node.sexpr.params.splice(1, 2);
- var keyword = removedParams[1].original;
- node.program.blockParams = [keyword];
- }
- });
-
- return ast;
- };
-
- TransformWithAsToHash.prototype.validate = function TransformWithAsToHash_validate(node) {
- return node.type === 'BlockStatement' && node.sexpr.path.original === 'with' && node.sexpr.params.length === 3 && node.sexpr.params[1].type === 'PathExpression' && node.sexpr.params[1].original === 'as';
- };
-
- exports['default'] = TransformWithAsToHash;
-
-});
-enifed('ember-template-compiler/system/compile', ['exports', 'ember-template-compiler/system/compile_options', 'ember-template-compiler/system/template'], function (exports, compileOptions, template) {
-
- 'use strict';
-
-
- var compile;exports['default'] = function (templateString, options) {
- if (!compile && Ember.__loader.registry['htmlbars-compiler/compiler']) {
- compile = requireModule('htmlbars-compiler/compiler').compile;
- }
-
- if (!compile) {
- throw new Error('Cannot call `compile` without the template compiler loaded. Please load `ember-template-compiler.js` prior to calling `compile`.');
- }
-
- var templateSpec = compile(templateString, compileOptions['default'](options));
-
- return template['default'](templateSpec);
- }
-
-});
-enifed('ember-template-compiler/system/compile_options', ['exports', 'ember-metal/core', 'ember-template-compiler/plugins'], function (exports, Ember, plugins) {
-
- 'use strict';
-
- /**
- @module ember
- @submodule ember-template-compiler
- */
-
- exports['default'] = function (_options) {
- var disableComponentGeneration = true;
-
- var options = _options || {};
- // When calling `Ember.Handlebars.compile()` a second argument of `true`
- // had a special meaning (long since lost), this just gaurds against
- // `options` being true, and causing an error during compilation.
- if (options === true) {
- options = {};
- }
-
- options.revision = 'Ember@1.12.2';
- options.disableComponentGeneration = disableComponentGeneration;
- options.plugins = plugins['default'];
-
- return options;
- }
-
-});
-enifed('ember-template-compiler/system/precompile', ['exports', 'ember-template-compiler/system/compile_options'], function (exports, compileOptions) {
-
- 'use strict';
-
- /**
- @module ember
- @submodule ember-template-compiler
- */
-
- var compileSpec;
-
- /**
- Uses HTMLBars `compile` function to process a string into a compiled template string.
- The returned string must be passed through `Ember.HTMLBars.template`.
-
- This is not present in production builds.
-
- @private
- @method precompile
- @param {String} templateString This is the string to be compiled by HTMLBars.
- */
- exports['default'] = function (templateString, options) {
- if (!compileSpec && Ember.__loader.registry['htmlbars-compiler/compiler']) {
- compileSpec = requireModule('htmlbars-compiler/compiler').compileSpec;
- }
-
- if (!compileSpec) {
- throw new Error('Cannot call `compileSpec` without the template compiler loaded. Please load `ember-template-compiler.js` prior to calling `compileSpec`.');
- }
-
- return compileSpec(templateString, compileOptions['default'](options));
- }
-
-});
-enifed('ember-template-compiler/system/template', ['exports'], function (exports) {
-
- 'use strict';
-
- /**
- @module ember
- @submodule ember-template-compiler
- */
-
- exports['default'] = function (templateSpec) {
- templateSpec.isTop = true;
- templateSpec.isMethod = false;
-
- return templateSpec;
- }
- /**
- Augments the default precompiled output of an HTMLBars template with
- additional information needed by Ember.
-
- @private
- @method template
- @param {Function} templateSpec This is the compiled HTMLBars template spec.
- */
-
-});
-enifed("htmlbars-compiler",
- ["./htmlbars-compiler/compiler","exports"],
- function(__dependency1__, __exports__) {
- "use strict";
- var compile = __dependency1__.compile;
- var compileSpec = __dependency1__.compileSpec;
- var template = __dependency1__.template;
-
- __exports__.compile = compile;
- __exports__.compileSpec = compileSpec;
- __exports__.template = template;
- });
-enifed("htmlbars-compiler/compiler",
- ["../htmlbars-syntax/parser","./template-compiler","exports"],
- function(__dependency1__, __dependency2__, __exports__) {
- "use strict";
- /*jshint evil:true*/
- var preprocess = __dependency1__.preprocess;
- var TemplateCompiler = __dependency2__["default"];
-
- /*
- * Compile a string into a template spec string. The template spec is a string
- * representation of a template. Usually, you would use compileSpec for
- * pre-compilation of a template on the server.
- *
- * Example usage:
- *
- * var templateSpec = compileSpec("Howdy {{name}}");
- * // This next step is basically what plain compile does
- * var template = new Function("return " + templateSpec)();
- *
- * @method compileSpec
- * @param {String} string An HTMLBars template string
- * @return {TemplateSpec} A template spec string
- */
- function compileSpec(string, options) {
- var ast = preprocess(string, options);
- var compiler = new TemplateCompiler(options);
- var program = compiler.compile(ast);
- return program;
- }
-
- __exports__.compileSpec = compileSpec;/*
- * @method template
- * @param {TemplateSpec} templateSpec A precompiled template
- * @return {Template} A template spec string
- */
- function template(templateSpec) {
- return new Function("return " + templateSpec)();
- }
-
- __exports__.template = template;/*
- * Compile a string into a template rendering function
- *
- * Example usage:
- *
- * // Template is the hydration portion of the compiled template
- * var template = compile("Howdy {{name}}");
- *
- * // Template accepts three arguments:
- * //
- * // 1. A context object
- * // 2. An env object
- * // 3. A contextualElement (optional, document.body is the default)
- * //
- * // The env object *must* have at least these two properties:
- * //
- * // 1. `hooks` - Basic hooks for rendering a template
- * // 2. `dom` - An instance of DOMHelper
- * //
- * import {hooks} from 'htmlbars-runtime';
- * import {DOMHelper} from 'morph';
- * var context = {name: 'whatever'},
- * env = {hooks: hooks, dom: new DOMHelper()},
- * contextualElement = document.body;
- * var domFragment = template(context, env, contextualElement);
- *
- * @method compile
- * @param {String} string An HTMLBars template string
- * @param {Object} options A set of options to provide to the compiler
- * @return {Template} A function for rendering the template
- */
- function compile(string, options) {
- return template(compileSpec(string, options));
- }
-
- __exports__.compile = compile;
- });
-enifed("htmlbars-compiler/fragment-javascript-compiler",
- ["./utils","../htmlbars-util/quoting","exports"],
- function(__dependency1__, __dependency2__, __exports__) {
- "use strict";
- var processOpcodes = __dependency1__.processOpcodes;
- var string = __dependency2__.string;
-
- var svgNamespace = "http://www.w3.org/2000/svg",
- // http://www.w3.org/html/wg/drafts/html/master/syntax.html#html-integration-point
- svgHTMLIntegrationPoints = {'foreignObject':true, 'desc':true, 'title':true};
-
-
- function FragmentJavaScriptCompiler() {
- this.source = [];
- this.depth = -1;
- }
-
- __exports__["default"] = FragmentJavaScriptCompiler;
-
- FragmentJavaScriptCompiler.prototype.compile = function(opcodes, options) {
- this.source.length = 0;
- this.depth = -1;
- this.indent = (options && options.indent) || "";
- this.namespaceFrameStack = [{namespace: null, depth: null}];
- this.domNamespace = null;
-
- this.source.push('function build(dom) {\n');
- processOpcodes(this, opcodes);
- this.source.push(this.indent+'}');
-
- return this.source.join('');
- };
-
- FragmentJavaScriptCompiler.prototype.createFragment = function() {
- var el = 'el'+(++this.depth);
- this.source.push(this.indent+' var '+el+' = dom.createDocumentFragment();\n');
- };
-
- FragmentJavaScriptCompiler.prototype.createElement = function(tagName) {
- var el = 'el'+(++this.depth);
- if (tagName === 'svg') {
- this.pushNamespaceFrame({namespace: svgNamespace, depth: this.depth});
- }
- this.ensureNamespace();
- this.source.push(this.indent+' var '+el+' = dom.createElement('+string(tagName)+');\n');
- if (svgHTMLIntegrationPoints[tagName]) {
- this.pushNamespaceFrame({namespace: null, depth: this.depth});
- }
- };
-
- FragmentJavaScriptCompiler.prototype.createText = function(str) {
- var el = 'el'+(++this.depth);
- this.source.push(this.indent+' var '+el+' = dom.createTextNode('+string(str)+');\n');
- };
-
- FragmentJavaScriptCompiler.prototype.createComment = function(str) {
- var el = 'el'+(++this.depth);
- this.source.push(this.indent+' var '+el+' = dom.createComment('+string(str)+');\n');
- };
-
- FragmentJavaScriptCompiler.prototype.returnNode = function() {
- var el = 'el'+this.depth;
- this.source.push(this.indent+' return '+el+';\n');
- };
-
- FragmentJavaScriptCompiler.prototype.setAttribute = function(name, value, namespace) {
- var el = 'el'+this.depth;
- if (namespace) {
- this.source.push(this.indent+' dom.setAttributeNS('+el+','+string(namespace)+','+string(name)+','+string(value)+');\n');
- } else {
- this.source.push(this.indent+' dom.setAttribute('+el+','+string(name)+','+string(value)+');\n');
- }
- };
-
- FragmentJavaScriptCompiler.prototype.appendChild = function() {
- if (this.depth === this.getCurrentNamespaceFrame().depth) {
- this.popNamespaceFrame();
- }
- var child = 'el'+(this.depth--);
- var el = 'el'+this.depth;
- this.source.push(this.indent+' dom.appendChild('+el+', '+child+');\n');
- };
-
- FragmentJavaScriptCompiler.prototype.getCurrentNamespaceFrame = function() {
- return this.namespaceFrameStack[this.namespaceFrameStack.length-1];
- };
-
- FragmentJavaScriptCompiler.prototype.pushNamespaceFrame = function(frame) {
- this.namespaceFrameStack.push(frame);
- };
-
- FragmentJavaScriptCompiler.prototype.popNamespaceFrame = function() {
- return this.namespaceFrameStack.pop();
- };
-
- FragmentJavaScriptCompiler.prototype.ensureNamespace = function() {
- var correctNamespace = this.getCurrentNamespaceFrame().namespace;
- if (this.domNamespace !== correctNamespace) {
- this.source.push(this.indent+' dom.setNamespace('+(correctNamespace ? string(correctNamespace) : 'null')+');\n');
- this.domNamespace = correctNamespace;
- }
- };
- });
-enifed("htmlbars-compiler/fragment-opcode-compiler",
- ["./template-visitor","./utils","../htmlbars-util","../htmlbars-util/array-utils","exports"],
- function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __exports__) {
- "use strict";
- var TemplateVisitor = __dependency1__["default"];
- var processOpcodes = __dependency2__.processOpcodes;
- var getAttrNamespace = __dependency3__.getAttrNamespace;
- var forEach = __dependency4__.forEach;
-
- function FragmentOpcodeCompiler() {
- this.opcodes = [];
- }
-
- __exports__["default"] = FragmentOpcodeCompiler;
-
- FragmentOpcodeCompiler.prototype.compile = function(ast) {
- var templateVisitor = new TemplateVisitor();
- templateVisitor.visit(ast);
-
- processOpcodes(this, templateVisitor.actions);
-
- return this.opcodes;
- };
-
- FragmentOpcodeCompiler.prototype.opcode = function(type, params) {
- this.opcodes.push([type, params]);
- };
-
- FragmentOpcodeCompiler.prototype.text = function(text) {
- this.opcode('createText', [text.chars]);
- this.opcode('appendChild');
- };
-
- FragmentOpcodeCompiler.prototype.comment = function(comment) {
- this.opcode('createComment', [comment.value]);
- this.opcode('appendChild');
- };
-
- FragmentOpcodeCompiler.prototype.openElement = function(element) {
- this.opcode('createElement', [element.tag]);
- forEach(element.attributes, this.attribute, this);
- };
-
- FragmentOpcodeCompiler.prototype.closeElement = function() {
- this.opcode('appendChild');
- };
-
- FragmentOpcodeCompiler.prototype.startProgram = function() {
- this.opcodes.length = 0;
- this.opcode('createFragment');
- };
-
- FragmentOpcodeCompiler.prototype.endProgram = function() {
- this.opcode('returnNode');
- };
-
- FragmentOpcodeCompiler.prototype.mustache = function() {
- this.pushMorphPlaceholderNode();
- };
-
- FragmentOpcodeCompiler.prototype.component = function() {
- this.pushMorphPlaceholderNode();
- };
-
- FragmentOpcodeCompiler.prototype.block = function() {
- this.pushMorphPlaceholderNode();
- };
-
- FragmentOpcodeCompiler.prototype.pushMorphPlaceholderNode = function() {
- this.opcode('createComment', [""]);
- this.opcode('appendChild');
- };
-
- FragmentOpcodeCompiler.prototype.attribute = function(attr) {
- if (attr.value.type === 'TextNode') {
- var namespace = getAttrNamespace(attr.name);
- this.opcode('setAttribute', [attr.name, attr.value.chars, namespace]);
- }
- };
-
- FragmentOpcodeCompiler.prototype.setNamespace = function(namespace) {
- this.opcode('setNamespace', [namespace]);
- };
- });
-enifed("htmlbars-compiler/hydration-javascript-compiler",
- ["./utils","../htmlbars-util/quoting","exports"],
- function(__dependency1__, __dependency2__, __exports__) {
- "use strict";
- var processOpcodes = __dependency1__.processOpcodes;
- var string = __dependency2__.string;
- var array = __dependency2__.array;
-
- function HydrationJavaScriptCompiler() {
- this.stack = [];
- this.source = [];
- this.mustaches = [];
- this.parents = [['fragment']];
- this.parentCount = 0;
- this.morphs = [];
- this.fragmentProcessing = [];
- this.hooks = undefined;
- }
-
- __exports__["default"] = HydrationJavaScriptCompiler;
-
- var prototype = HydrationJavaScriptCompiler.prototype;
-
- prototype.compile = function(opcodes, options) {
- this.stack.length = 0;
- this.mustaches.length = 0;
- this.source.length = 0;
- this.parents.length = 1;
- this.parents[0] = ['fragment'];
- this.morphs.length = 0;
- this.fragmentProcessing.length = 0;
- this.parentCount = 0;
- this.indent = (options && options.indent) || "";
- this.hooks = {};
- this.hasOpenBoundary = false;
- this.hasCloseBoundary = false;
-
- processOpcodes(this, opcodes);
-
- if (this.hasOpenBoundary) {
- this.source.unshift(this.indent+" dom.insertBoundary(fragment, 0);\n");
- }
-
- if (this.hasCloseBoundary) {
- this.source.unshift(this.indent+" dom.insertBoundary(fragment, null);\n");
- }
-
- var i, l;
- if (this.morphs.length) {
- var morphs = "";
- for (i = 0, l = this.morphs.length; i < l; ++i) {
- var morph = this.morphs[i];
- morphs += this.indent+' var '+morph[0]+' = '+morph[1]+';\n';
- }
- this.source.unshift(morphs);
- }
-
- if (this.fragmentProcessing.length) {
- var processing = "";
- for (i = 0, l = this.fragmentProcessing.length; i < l; ++i) {
- processing += this.indent+' '+this.fragmentProcessing[i]+'\n';
- }
- this.source.unshift(processing);
- }
-
- return this.source.join('');
- };
-
- prototype.prepareArray = function(length) {
- var values = [];
-
- for (var i = 0; i < length; i++) {
- values.push(this.stack.pop());
- }
-
- this.stack.push('[' + values.join(', ') + ']');
- };
-
- prototype.prepareObject = function(size) {
- var pairs = [];
-
- for (var i = 0; i < size; i++) {
- pairs.push(this.stack.pop() + ': ' + this.stack.pop());
- }
-
- this.stack.push('{' + pairs.join(', ') + '}');
- };
-
- prototype.pushRaw = function(value) {
- this.stack.push(value);
- };
-
- prototype.openBoundary = function() {
- this.hasOpenBoundary = true;
- };
-
- prototype.closeBoundary = function() {
- this.hasCloseBoundary = true;
- };
-
- prototype.pushLiteral = function(value) {
- if (typeof value === 'string') {
- this.stack.push(string(value));
- } else {
- this.stack.push(value.toString());
- }
- };
-
- prototype.pushHook = function(name, args) {
- this.hooks[name] = true;
- this.stack.push(name + '(' + args.join(', ') + ')');
- };
-
- prototype.pushGetHook = function(path) {
- this.pushHook('get', [
- 'env',
- 'context',
- string(path)
- ]);
- };
-
- prototype.pushSexprHook = function() {
- this.pushHook('subexpr', [
- 'env',
- 'context',
- this.stack.pop(), // path
- this.stack.pop(), // params
- this.stack.pop() // hash
- ]);
- };
-
- prototype.pushConcatHook = function() {
- this.pushHook('concat', [
- 'env',
- this.stack.pop() // parts
- ]);
- };
-
- prototype.printHook = function(name, args) {
- this.hooks[name] = true;
- this.source.push(this.indent + ' ' + name + '(' + args.join(', ') + ');\n');
- };
-
- prototype.printSetHook = function(name, index) {
- this.printHook('set', [
- 'env',
- 'context',
- string(name),
- 'blockArguments[' + index + ']'
- ]);
- };
-
- prototype.printBlockHook = function(morphNum, templateId, inverseId) {
- this.printHook('block', [
- 'env',
- 'morph' + morphNum,
- 'context',
- this.stack.pop(), // path
- this.stack.pop(), // params
- this.stack.pop(), // hash
- templateId === null ? 'null' : 'child' + templateId,
- inverseId === null ? 'null' : 'child' + inverseId
- ]);
- };
-
- prototype.printInlineHook = function(morphNum) {
- this.printHook('inline', [
- 'env',
- 'morph' + morphNum,
- 'context',
- this.stack.pop(), // path
- this.stack.pop(), // params
- this.stack.pop() // hash
- ]);
- };
-
- prototype.printContentHook = function(morphNum) {
- this.printHook('content', [
- 'env',
- 'morph' + morphNum,
- 'context',
- this.stack.pop() // path
- ]);
- };
-
- prototype.printComponentHook = function(morphNum, templateId) {
- this.printHook('component', [
- 'env',
- 'morph' + morphNum,
- 'context',
- this.stack.pop(), // path
- this.stack.pop(), // attrs
- templateId === null ? 'null' : 'child' + templateId
- ]);
- };
-
- prototype.printAttributeHook = function(attrMorphNum, elementNum) {
- this.printHook('attribute', [
- 'env',
- 'attrMorph' + attrMorphNum,
- 'element' + elementNum,
- this.stack.pop(), // name
- this.stack.pop() // value
- ]);
- };
-
- prototype.printElementHook = function(elementNum) {
- this.printHook('element', [
- 'env',
- 'element' + elementNum,
- 'context',
- this.stack.pop(), // path
- this.stack.pop(), // params
- this.stack.pop() // hash
- ]);
- };
-
- prototype.createMorph = function(morphNum, parentPath, startIndex, endIndex, escaped) {
- var isRoot = parentPath.length === 0;
- var parent = this.getParent();
-
- var morphMethod = escaped ? 'createMorphAt' : 'createUnsafeMorphAt';
- var morph = "dom."+morphMethod+"("+parent+
- ","+(startIndex === null ? "-1" : startIndex)+
- ","+(endIndex === null ? "-1" : endIndex)+
- (isRoot ? ",contextualElement)" : ")");
-
- this.morphs.push(['morph' + morphNum, morph]);
- };
-
- prototype.createAttrMorph = function(attrMorphNum, elementNum, name, escaped, namespace) {
- var morphMethod = escaped ? 'createAttrMorph' : 'createUnsafeAttrMorph';
- var morph = "dom."+morphMethod+"(element"+elementNum+", '"+name+(namespace ? "', '"+namespace : '')+"')";
- this.morphs.push(['attrMorph' + attrMorphNum, morph]);
- };
-
- prototype.repairClonedNode = function(blankChildTextNodes, isElementChecked) {
- var parent = this.getParent(),
- processing = 'if (this.cachedFragment) { dom.repairClonedNode('+parent+','+
- array(blankChildTextNodes)+
- ( isElementChecked ? ',true' : '' )+
- '); }';
- this.fragmentProcessing.push(
- processing
- );
- };
-
- prototype.shareElement = function(elementNum){
- var elementNodesName = "element" + elementNum;
- this.fragmentProcessing.push('var '+elementNodesName+' = '+this.getParent()+';');
- this.parents[this.parents.length-1] = [elementNodesName];
- };
-
- prototype.consumeParent = function(i) {
- var newParent = this.lastParent().slice();
- newParent.push(i);
-
- this.parents.push(newParent);
- };
-
- prototype.popParent = function() {
- this.parents.pop();
- };
-
- prototype.getParent = function() {
- var last = this.lastParent().slice();
- var frag = last.shift();
-
- if (!last.length) {
- return frag;
- }
-
- return 'dom.childAt(' + frag + ', [' + last.join(', ') + '])';
- };
-
- prototype.lastParent = function() {
- return this.parents[this.parents.length-1];
- };
- });
-enifed("htmlbars-compiler/hydration-opcode-compiler",
- ["./template-visitor","./utils","../htmlbars-util","../htmlbars-util/array-utils","../htmlbars-syntax/utils","exports"],
- function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __exports__) {
- "use strict";
- var TemplateVisitor = __dependency1__["default"];
- var processOpcodes = __dependency2__.processOpcodes;
- var getAttrNamespace = __dependency3__.getAttrNamespace;
- var forEach = __dependency4__.forEach;
- var isHelper = __dependency5__.isHelper;
-
- function unwrapMustache(mustache) {
- if (isHelper(mustache.sexpr)) {
- return mustache.sexpr;
- } else {
- return mustache.sexpr.path;
- }
- }
-
- function detectIsElementChecked(element){
- for (var i=0, len=element.attributes.length;i 0) {
- this.opcode('repairClonedNode', blankChildTextNodes);
- }
- };
-
- HydrationOpcodeCompiler.prototype.endProgram = function() {
- distributeMorphs(this.morphs, this.opcodes);
- };
-
- HydrationOpcodeCompiler.prototype.text = function() {
- ++this.currentDOMChildIndex;
- };
-
- HydrationOpcodeCompiler.prototype.comment = function() {
- ++this.currentDOMChildIndex;
- };
-
- HydrationOpcodeCompiler.prototype.openElement = function(element, pos, len, mustacheCount, blankChildTextNodes) {
- distributeMorphs(this.morphs, this.opcodes);
- ++this.currentDOMChildIndex;
-
- this.element = this.currentDOMChildIndex;
-
- this.opcode('consumeParent', this.currentDOMChildIndex);
-
- // If our parent reference will be used more than once, cache its reference.
- if (mustacheCount > 1) {
- this.opcode('shareElement', ++this.elementNum);
- this.element = null; // Set element to null so we don't cache it twice
- }
-
- var isElementChecked = detectIsElementChecked(element);
- if (blankChildTextNodes.length > 0 || isElementChecked) {
- this.opcode( 'repairClonedNode',
- blankChildTextNodes,
- isElementChecked );
- }
-
- this.paths.push(this.currentDOMChildIndex);
- this.currentDOMChildIndex = -1;
-
- forEach(element.attributes, this.attribute, this);
- forEach(element.modifiers, this.elementModifier, this);
- };
-
- HydrationOpcodeCompiler.prototype.closeElement = function() {
- distributeMorphs(this.morphs, this.opcodes);
- this.opcode('popParent');
- this.currentDOMChildIndex = this.paths.pop();
- };
-
- HydrationOpcodeCompiler.prototype.mustache = function(mustache, childIndex, childCount) {
- this.pushMorphPlaceholderNode(childIndex, childCount);
-
- var sexpr = mustache.sexpr;
-
- var morphNum = this.morphNum++;
- var start = this.currentDOMChildIndex;
- var end = this.currentDOMChildIndex;
- this.morphs.push([morphNum, this.paths.slice(), start, end, mustache.escaped]);
-
- if (isHelper(sexpr)) {
- prepareSexpr(this, sexpr);
- this.opcode('printInlineHook', morphNum);
- } else {
- preparePath(this, sexpr.path);
- this.opcode('printContentHook', morphNum);
- }
- };
-
- HydrationOpcodeCompiler.prototype.block = function(block, childIndex, childCount) {
- this.pushMorphPlaceholderNode(childIndex, childCount);
-
- var sexpr = block.sexpr;
-
- var morphNum = this.morphNum++;
- var start = this.currentDOMChildIndex;
- var end = this.currentDOMChildIndex;
- this.morphs.push([morphNum, this.paths.slice(), start, end, true]);
-
- var templateId = this.templateId++;
- var inverseId = block.inverse === null ? null : this.templateId++;
-
- prepareSexpr(this, sexpr);
- this.opcode('printBlockHook', morphNum, templateId, inverseId);
- };
-
- HydrationOpcodeCompiler.prototype.component = function(component, childIndex, childCount) {
- this.pushMorphPlaceholderNode(childIndex, childCount);
-
- var program = component.program || {};
- var blockParams = program.blockParams || [];
-
- var morphNum = this.morphNum++;
- var start = this.currentDOMChildIndex;
- var end = this.currentDOMChildIndex;
- this.morphs.push([morphNum, this.paths.slice(), start, end, true]);
-
- var attrs = component.attributes;
- for (var i = attrs.length - 1; i >= 0; i--) {
- var name = attrs[i].name;
- var value = attrs[i].value;
-
- // TODO: Introduce context specific AST nodes to avoid switching here.
- if (value.type === 'TextNode') {
- this.opcode('pushLiteral', value.chars);
- } else if (value.type === 'MustacheStatement') {
- this.accept(unwrapMustache(value));
- } else if (value.type === 'ConcatStatement') {
- prepareParams(this, value.parts);
- this.opcode('pushConcatHook');
- }
-
- this.opcode('pushLiteral', name);
- }
-
- this.opcode('prepareObject', attrs.length);
- this.opcode('pushLiteral', component.tag);
- this.opcode('printComponentHook', morphNum, this.templateId++, blockParams.length);
- };
-
- HydrationOpcodeCompiler.prototype.attribute = function(attr) {
- var value = attr.value;
- var escaped = true;
- var namespace = getAttrNamespace(attr.name);
-
- // TODO: Introduce context specific AST nodes to avoid switching here.
- if (value.type === 'TextNode') {
- return;
- } else if (value.type === 'MustacheStatement') {
- escaped = value.escaped;
- this.accept(unwrapMustache(value));
- } else if (value.type === 'ConcatStatement') {
- prepareParams(this, value.parts);
- this.opcode('pushConcatHook');
- }
-
- this.opcode('pushLiteral', attr.name);
-
- if (this.element !== null) {
- this.opcode('shareElement', ++this.elementNum);
- this.element = null;
- }
-
- var attrMorphNum = this.attrMorphNum++;
- this.opcode('createAttrMorph', attrMorphNum, this.elementNum, attr.name, escaped, namespace);
- this.opcode('printAttributeHook', attrMorphNum, this.elementNum);
- };
-
- HydrationOpcodeCompiler.prototype.elementModifier = function(modifier) {
- prepareSexpr(this, modifier.sexpr);
-
- // If we have a helper in a node, and this element has not been cached, cache it
- if (this.element !== null) {
- this.opcode('shareElement', ++this.elementNum);
- this.element = null; // Reset element so we don't cache it more than once
- }
-
- this.opcode('printElementHook', this.elementNum);
- };
-
- HydrationOpcodeCompiler.prototype.pushMorphPlaceholderNode = function(childIndex, childCount) {
- if (this.paths.length === 0) {
- if (childIndex === 0) {
- this.opcode('openBoundary');
- }
- if (childIndex === childCount - 1) {
- this.opcode('closeBoundary');
- }
- }
- this.comment();
- };
-
- HydrationOpcodeCompiler.prototype.SubExpression = function(sexpr) {
- prepareSexpr(this, sexpr);
- this.opcode('pushSexprHook');
- };
-
- HydrationOpcodeCompiler.prototype.PathExpression = function(path) {
- this.opcode('pushGetHook', path.original);
- };
-
- HydrationOpcodeCompiler.prototype.StringLiteral = function(node) {
- this.opcode('pushLiteral', node.value);
- };
-
- HydrationOpcodeCompiler.prototype.BooleanLiteral = function(node) {
- this.opcode('pushLiteral', node.value);
- };
-
- HydrationOpcodeCompiler.prototype.NumberLiteral = function(node) {
- this.opcode('pushLiteral', node.value);
- };
-
- function preparePath(compiler, path) {
- compiler.opcode('pushLiteral', path.original);
- }
-
- function prepareParams(compiler, params) {
- for (var i = params.length - 1; i >= 0; i--) {
- var param = params[i];
- compiler[param.type](param);
- }
-
- compiler.opcode('prepareArray', params.length);
- }
-
- function prepareHash(compiler, hash) {
- var pairs = hash.pairs;
-
- for (var i = pairs.length - 1; i >= 0; i--) {
- var key = pairs[i].key;
- var value = pairs[i].value;
-
- compiler[value.type](value);
- compiler.opcode('pushLiteral', key);
- }
-
- compiler.opcode('prepareObject', pairs.length);
- }
-
- function prepareSexpr(compiler, sexpr) {
- prepareHash(compiler, sexpr.hash);
- prepareParams(compiler, sexpr.params);
- preparePath(compiler, sexpr.path);
- }
-
- function distributeMorphs(morphs, opcodes) {
- if (morphs.length === 0) {
- return;
- }
-
- // Splice morphs after the most recent shareParent/consumeParent.
- var o;
- for (o = opcodes.length - 1; o >= 0; --o) {
- var opcode = opcodes[o][0];
- if (opcode === 'shareElement' || opcode === 'consumeParent' || opcode === 'popParent') {
- break;
- }
- }
-
- var spliceArgs = [o + 1, 0];
- for (var i = 0; i < morphs.length; ++i) {
- spliceArgs.push(['createMorph', morphs[i].slice()]);
- }
- opcodes.splice.apply(opcodes, spliceArgs);
- morphs.length = 0;
- }
- });
-enifed("htmlbars-compiler/template-compiler",
- ["./fragment-opcode-compiler","./fragment-javascript-compiler","./hydration-opcode-compiler","./hydration-javascript-compiler","./template-visitor","./utils","../htmlbars-util/quoting","exports"],
- function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __dependency6__, __dependency7__, __exports__) {
- "use strict";
- var FragmentOpcodeCompiler = __dependency1__["default"];
- var FragmentJavaScriptCompiler = __dependency2__["default"];
- var HydrationOpcodeCompiler = __dependency3__["default"];
- var HydrationJavaScriptCompiler = __dependency4__["default"];
- var TemplateVisitor = __dependency5__["default"];
- var processOpcodes = __dependency6__.processOpcodes;
- var repeat = __dependency7__.repeat;
-
- function TemplateCompiler(options) {
- this.options = options || {};
- this.revision = this.options.revision || "HTMLBars@0.11.4.d11ed3e4";
- this.fragmentOpcodeCompiler = new FragmentOpcodeCompiler();
- this.fragmentCompiler = new FragmentJavaScriptCompiler();
- this.hydrationOpcodeCompiler = new HydrationOpcodeCompiler();
- this.hydrationCompiler = new HydrationJavaScriptCompiler();
- this.templates = [];
- this.childTemplates = [];
- }
-
- __exports__["default"] = TemplateCompiler;
-
- TemplateCompiler.prototype.compile = function(ast) {
- var templateVisitor = new TemplateVisitor();
- templateVisitor.visit(ast);
-
- processOpcodes(this, templateVisitor.actions);
-
- return this.templates.pop();
- };
-
- TemplateCompiler.prototype.startProgram = function(program, childTemplateCount, blankChildTextNodes) {
- this.fragmentOpcodeCompiler.startProgram(program, childTemplateCount, blankChildTextNodes);
- this.hydrationOpcodeCompiler.startProgram(program, childTemplateCount, blankChildTextNodes);
-
- this.childTemplates.length = 0;
- while(childTemplateCount--) {
- this.childTemplates.push(this.templates.pop());
- }
- };
-
- TemplateCompiler.prototype.getChildTemplateVars = function(indent) {
- var vars = '';
- if (this.childTemplates) {
- for (var i = 0; i < this.childTemplates.length; i++) {
- vars += indent + 'var child' + i + ' = ' + this.childTemplates[i] + ';\n';
- }
- }
- return vars;
- };
-
- TemplateCompiler.prototype.getHydrationHooks = function(indent, hooks) {
- var hookVars = [];
- for (var hook in hooks) {
- hookVars.push(hook + ' = hooks.' + hook);
- }
-
- if (hookVars.length > 0) {
- return indent + 'var hooks = env.hooks, ' + hookVars.join(', ') + ';\n';
- } else {
- return '';
- }
- };
-
- TemplateCompiler.prototype.endProgram = function(program, programDepth) {
- this.fragmentOpcodeCompiler.endProgram(program);
- this.hydrationOpcodeCompiler.endProgram(program);
-
- var indent = repeat(" ", programDepth);
- var options = {
- indent: indent + " "
- };
-
- // function build(dom) { return fragment; }
- var fragmentProgram = this.fragmentCompiler.compile(
- this.fragmentOpcodeCompiler.opcodes,
- options
- );
-
- // function hydrate(fragment) { return mustaches; }
- var hydrationProgram = this.hydrationCompiler.compile(
- this.hydrationOpcodeCompiler.opcodes,
- options
- );
-
- var blockParams = program.blockParams || [];
-
- var templateSignature = 'context, env, contextualElement';
- if (blockParams.length > 0) {
- templateSignature += ', blockArguments';
- }
-
- var template =
- '(function() {\n' +
- this.getChildTemplateVars(indent + ' ') +
- indent+' return {\n' +
- indent+' isHTMLBars: true,\n' +
- indent+' revision: "' + this.revision + '",\n' +
- indent+' blockParams: ' + blockParams.length + ',\n' +
- indent+' cachedFragment: null,\n' +
- indent+' hasRendered: false,\n' +
- indent+' build: ' + fragmentProgram + ',\n' +
- indent+' render: function render(' + templateSignature + ') {\n' +
- indent+' var dom = env.dom;\n' +
- this.getHydrationHooks(indent + ' ', this.hydrationCompiler.hooks) +
- indent+' dom.detectNamespace(contextualElement);\n' +
- indent+' var fragment;\n' +
- indent+' if (env.useFragmentCache && dom.canClone) {\n' +
- indent+' if (this.cachedFragment === null) {\n' +
- indent+' fragment = this.build(dom);\n' +
- indent+' if (this.hasRendered) {\n' +
- indent+' this.cachedFragment = fragment;\n' +
- indent+' } else {\n' +
- indent+' this.hasRendered = true;\n' +
- indent+' }\n' +
- indent+' }\n' +
- indent+' if (this.cachedFragment) {\n' +
- indent+' fragment = dom.cloneNode(this.cachedFragment, true);\n' +
- indent+' }\n' +
- indent+' } else {\n' +
- indent+' fragment = this.build(dom);\n' +
- indent+' }\n' +
- hydrationProgram +
- indent+' return fragment;\n' +
- indent+' }\n' +
- indent+' };\n' +
- indent+'}())';
-
- this.templates.push(template);
- };
-
- TemplateCompiler.prototype.openElement = function(element, i, l, r, c, b) {
- this.fragmentOpcodeCompiler.openElement(element, i, l, r, c, b);
- this.hydrationOpcodeCompiler.openElement(element, i, l, r, c, b);
- };
-
- TemplateCompiler.prototype.closeElement = function(element, i, l, r) {
- this.fragmentOpcodeCompiler.closeElement(element, i, l, r);
- this.hydrationOpcodeCompiler.closeElement(element, i, l, r);
- };
-
- TemplateCompiler.prototype.component = function(component, i, l, s) {
- this.fragmentOpcodeCompiler.component(component, i, l, s);
- this.hydrationOpcodeCompiler.component(component, i, l, s);
- };
-
- TemplateCompiler.prototype.block = function(block, i, l, s) {
- this.fragmentOpcodeCompiler.block(block, i, l, s);
- this.hydrationOpcodeCompiler.block(block, i, l, s);
- };
-
- TemplateCompiler.prototype.text = function(string, i, l, r) {
- this.fragmentOpcodeCompiler.text(string, i, l, r);
- this.hydrationOpcodeCompiler.text(string, i, l, r);
- };
-
- TemplateCompiler.prototype.comment = function(string, i, l, r) {
- this.fragmentOpcodeCompiler.comment(string, i, l, r);
- this.hydrationOpcodeCompiler.comment(string, i, l, r);
- };
-
- TemplateCompiler.prototype.mustache = function (mustache, i, l, s) {
- this.fragmentOpcodeCompiler.mustache(mustache, i, l, s);
- this.hydrationOpcodeCompiler.mustache(mustache, i, l, s);
- };
-
- TemplateCompiler.prototype.setNamespace = function(namespace) {
- this.fragmentOpcodeCompiler.setNamespace(namespace);
- };
- });
-enifed("htmlbars-compiler/template-visitor",
- ["exports"],
- function(__exports__) {
- "use strict";
- var push = Array.prototype.push;
-
- function Frame() {
- this.parentNode = null;
- this.children = null;
- this.childIndex = null;
- this.childCount = null;
- this.childTemplateCount = 0;
- this.mustacheCount = 0;
- this.actions = [];
- }
-
- /**
- * Takes in an AST and outputs a list of actions to be consumed
- * by a compiler. For example, the template
- *
- * foo{{bar}}
baz
- *
- * produces the actions
- *
- * [['startProgram', [programNode, 0]],
- * ['text', [textNode, 0, 3]],
- * ['mustache', [mustacheNode, 1, 3]],
- * ['openElement', [elementNode, 2, 3, 0]],
- * ['text', [textNode, 0, 1]],
- * ['closeElement', [elementNode, 2, 3],
- * ['endProgram', [programNode]]]
- *
- * This visitor walks the AST depth first and backwards. As
- * a result the bottom-most child template will appear at the
- * top of the actions list whereas the root template will appear
- * at the bottom of the list. For example,
- *
- *