12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136 |
- /**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- var computed = Em.computed;
- var get = Em.get;
- var makeArray = Em.makeArray;
- var slice = [].slice;
- var dataUtils = require('utils/data_manipulation');
- /**
- * Returns hash with values of name properties from the context
- * If <code>propertyName</code> starts with 'App.', <code>App</code> is used as context, <code>self</code> used otherwise
- * If some <code>propertyName</code> starts with '!' its value will be inverted
- *
- * @param {object} self current context
- * @param {string[]} propertyNames needed properties
- * @returns {object} hash with needed values
- */
- function getProperties(self, propertyNames) {
- var ret = {};
- for (var i = 0; i < propertyNames.length; i++) {
- var propertyName = propertyNames[i];
- var shouldBeInverted = propertyName.startsWith('!');
- propertyName = shouldBeInverted ? propertyName.substr(1) : propertyName;
- var isApp = propertyName.startsWith('App.');
- var name = isApp ? propertyName.replace('App.', '') : propertyName;
- var value = isApp ? App.get(name) : self.get(name);
- value = shouldBeInverted ? !value : value;
- ret[propertyName] = value;
- }
- return ret;
- }
- /**
- * Returns value of named property from the context
- * If <code>propertyName</code> starts with 'App.', <code>App</code> is used as context, <code>self</code> used otherwise
- *
- * @param {object} self current context
- * @param {string} propertyName needed property
- * @returns {*} needed value
- */
- function smartGet(self, propertyName) {
- var isApp = propertyName.startsWith('App.');
- var name = isApp ? propertyName.replace('App.', '') : propertyName;
- return isApp ? App.get(name) : self.get(name);
- }
- /**
- * Returns list with values of name properties from the context
- * If <code>propertyName</code> starts with 'App.', <code>App</code> is used as context, <code>self</code> used otherwise
- *
- * @param {object} self current context
- * @param {string[]} propertyNames needed properties
- * @returns {array} list of needed values
- */
- function getValues(self, propertyNames) {
- return propertyNames.map(function (propertyName) {
- return smartGet(self, propertyName);
- });
- }
- function generateComputedWithKey(macro) {
- return function () {
- var properties = slice.call(arguments, 1);
- var key = arguments[0];
- var computedFunc = computed(function () {
- var values = getValues(this, properties);
- return macro.call(this, key, values);
- });
- return computedFunc.property.apply(computedFunc, properties);
- }
- }
- function generateComputedWithProperties(macro) {
- return function () {
- var properties = slice.call(arguments);
- var computedFunc = computed(function () {
- return macro.apply(this, [getProperties(this, properties)]);
- });
- var realProperties = properties.slice().invoke('replace', '!', '');
- return computedFunc.property.apply(computedFunc, realProperties);
- };
- }
- function generateComputedWithValues(macro) {
- return function () {
- var properties = slice.call(arguments);
- var computedFunc = computed(function () {
- return macro.apply(this, [getValues(this, properties)]);
- });
- return computedFunc.property.apply(computedFunc, properties);
- };
- }
- /**
- *
- * A computed property that returns true if the provided dependent property
- * is equal to the given value.
- * App.*-keys are supported
- * 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
- * @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.
- * @public
- */
- computed.equal = function (dependentKey, value) {
- return computed(dependentKey, function () {
- return smartGet(this, dependentKey) === value;
- }).cacheable();
- };
- /**
- * A computed property that returns true if the provided dependent property is not equal to the given value
- * App.*-keys are supported
- * <pre>
- * var o = Em.Object.create({
- * p1: 'a',
- * p2: Em.computed.notEqual('p1', 'a')
- * });
- * console.log(o.get('p2')); // false
- * o.set('p1', 'b');
- * console.log(o.get('p2')); // true
- * </pre>
- *
- * @method notEqual
- * @param {string} dependentKey
- * @param {*} value
- * @returns {Ember.ComputedProperty}
- */
- computed.notEqual = function (dependentKey, value) {
- return computed(dependentKey, function () {
- return smartGet(this, dependentKey) !== value;
- });
- };
- /**
- * A computed property that returns true if provided dependent properties are equal to the each other
- * App.*-keys are supported
- * <pre>
- * var o = Em.Object.create({
- * p1: 'a',
- * p2: 'b',
- * p3: Em.computed.equalProperties('p1', 'p2')
- * });
- * console.log(o.get('p3')); // false
- * o.set('p1', 'b');
- * console.log(o.get('p3')); // true
- * </pre>
- *
- * @method equalProperties
- * @param {string} dependentKey1
- * @param {string} dependentKey2
- * @returns {Ember.ComputedProperty}
- */
- computed.equalProperties = function (dependentKey1, dependentKey2) {
- return computed(dependentKey1, dependentKey2, function () {
- return smartGet(this, dependentKey1) === smartGet(this, dependentKey2);
- });
- };
- /**
- * A computed property that returns true if provided dependent properties are not equal to the each other
- * App.*-keys are supported
- * <pre>
- * var o = Em.Object.create({
- * p1: 'a',
- * p2: 'b',
- * p3: Em.computed.notEqualProperties('p1', 'p2')
- * });
- * console.log(o.get('p3')); // true
- * o.set('p1', 'b');
- * console.log(o.get('p3')); // false
- * </pre>
- *
- * @method notEqualProperties
- * @param {string} dependentKey1
- * @param {string} dependentKey2
- * @returns {Ember.ComputedProperty}
- */
- computed.notEqualProperties = function (dependentKey1, dependentKey2) {
- return computed(dependentKey1, dependentKey2, function () {
- return smartGet(this, dependentKey1) !== smartGet(this, dependentKey2);
- });
- };
- /**
- * A computed property that returns grouped collection's items by propertyName-value
- *
- * @method groupBy
- * @param {string} collectionKey
- * @param {string} propertyName
- * @returns {Ember.ComputedProperty}
- */
- computed.groupBy = function (collectionKey, propertyName) {
- return computed(collectionKey + '.@each.' + propertyName, function () {
- var collection = get(this, collectionKey);
- return dataUtils.groupPropertyValues(collection, propertyName);
- });
- };
- /**
- * A computed property that returns filtered collection by propertyName values-list
- * Wrapper to filterProperty-method that allows using list of values to filter
- *
- * @method filterByMany
- * @param {string} collectionKey
- * @param {string} propertyName
- * @param {array} valuesToFilter
- * @returns {Ember.ComputedProperty}
- */
- computed.filterByMany = function (collectionKey, propertyName, valuesToFilter) {
- return computed(collectionKey + '.@each.' + propertyName, function () {
- var collection = get(this, collectionKey);
- return dataUtils.filterPropertyValues(collection, propertyName, makeArray(valuesToFilter));
- });
- };
- /**
- * A computed property that returns collection without elements with value that is in <code>valuesToReject</code>
- * Exclude objects from <code>collection</code> if its <code>key</code> exist in <code>valuesToReject</code>
- *
- * @method rejectMany
- * @param {string} collectionKey
- * @param {string} propertyName
- * @param {array} valuesToReject
- * @returns {Ember.ComputedProperty}
- */
- computed.rejectMany = function (collectionKey, propertyName, valuesToReject) {
- return computed(collectionKey + '.@each.' + propertyName, function () {
- var collection = get(this, collectionKey);
- return dataUtils.rejectPropertyValues(collection, propertyName, makeArray(valuesToReject));
- });
- };
- /**
- * A computed property that returns trueValue if dependent value is true and falseValue otherwise
- * App.*-keys are supported
- * <pre>
- * var o = Em.Object.create({
- * p1: true,
- * p2: Em.computed.ifThenElse('p1', 'abc', 'cba')
- * });
- * console.log(o.get('p2')); // 'abc'
- * o.set('p1', false);
- * console.log(o.get('p2')); // 'cba'
- * </pre>
- *
- * @method ifThenElse
- * @param {string} dependentKey
- * @param {*} trueValue
- * @param {*} falseValue
- * @returns {Ember.ComputedProperty}
- */
- computed.ifThenElse = function (dependentKey, trueValue, falseValue) {
- return computed(dependentKey, function () {
- return smartGet(this, dependentKey) ? trueValue : falseValue;
- });
- };
- /**
- * A computed property that is equal to the logical 'and'
- * Takes any number of arguments
- * Returns true if all of them are truly, false - otherwise
- * App.*-keys are supported
- * <pre>
- * var o = Em.Object.create({
- * p1: true,
- * p2: true,
- * p3: true,
- * p4: Em.computed.and('p1', 'p2', 'p3')
- * });
- * console.log(o.get('p4')); // true
- * o.set('p1', false);
- * console.log(o.get('p4')); // false
- * </pre>
- *
- * @method and
- * @param {...string} dependentKeys
- * @returns {Ember.ComputedProperty}
- */
- computed.and = generateComputedWithProperties(function (properties) {
- var value;
- for (var key in properties) {
- value = !!properties[key];
- if (properties.hasOwnProperty(key) && !value) {
- return false;
- }
- }
- return value;
- });
- /**
- * A computed property that is equal to the logical 'or'
- * Takes any number of arguments
- * Returns true if at least one of them is truly, false - otherwise
- * App.*-keys are supported
- * <pre>
- * var o = Em.Object.create({
- * p1: false,
- * p2: false,
- * p3: false,
- * p4: Em.computed.or('p1', 'p2', 'p3')
- * });
- * console.log(o.get('p4')); // false
- * o.set('p1', true);
- * console.log(o.get('p4')); // true
- * </pre>
- *
- * @method or
- * @param {...string} dependentKeys
- * @returns {Ember.ComputedProperty}
- */
- computed.or = generateComputedWithProperties(function (properties) {
- var value;
- for (var key in properties) {
- value = !!properties[key];
- if (properties.hasOwnProperty(key) && value) {
- return value;
- }
- }
- return value;
- });
- /**
- * A computed property that returns sum on the dependent properties values
- * Takes any number of arguments
- * App.*-keys are supported
- * <pre>
- * var o = Em.Object.create({
- * p1: 1,
- * p2: 2,
- * p3: 3,
- * p4: Em.computed.sumProperties('p1', 'p2', 'p3')
- * });
- * console.log(o.get('p4')); // 6
- * o.set('p1', 2);
- * console.log(o.get('p4')); // 7
- * </pre>
- *
- * @method sumProperties
- * @param {...string} dependentKeys
- * @returns {Ember.ComputedProperty}
- */
- computed.sumProperties = generateComputedWithProperties(function (properties) {
- var sum = 0;
- for (var key in properties) {
- if (properties.hasOwnProperty(key)) {
- sum += Number(properties[key]);
- }
- }
- return sum;
- });
- /**
- * A computed property that returns true if dependent value is greater or equal to the needed value
- * App.*-keys are supported
- * <pre>
- * var o = Em.Object.create({
- * p1: 4,
- * p2: Em.computed.gte('p1', 1)
- * });
- * console.log(o.get('p2')); // true
- * o.set('p1', 4);
- * console.log(o.get('p2')); // true
- * o.set('p1', 5);
- * console.log(o.get('p2')); // false
- * </pre>
- *
- * @method gte
- * @param {string} dependentKey
- * @param {*} value
- * @returns {Ember.ComputedProperty}
- */
- computed.gte = function (dependentKey, value) {
- return computed(dependentKey, function () {
- return smartGet(this, dependentKey) >= value;
- });
- };
- /**
- * A computed property that returns true if first dependent property is greater or equal to the second dependent property
- * App.*-keys are supported
- * <pre>
- * var o = Em.Object.create({
- * p1: 4,
- * p2: 1,
- * p3: Em.computed.gteProperties('p1', 'p2')
- * });
- * console.log(o.get('p3')); // true
- * o.set('p2', 4);
- * console.log(o.get('p3')); // true
- * o.set('p2', 5);
- * console.log(o.get('p3')); // false
- * </pre>
- *
- * @method gteProperties
- * @param {string} dependentKey1
- * @param {string} dependentKey2
- * @returns {Ember.ComputedProperty}
- */
- computed.gteProperties = function (dependentKey1, dependentKey2) {
- return computed(dependentKey1, dependentKey2, function () {
- return smartGet(this, dependentKey1) >= smartGet(this, dependentKey2);
- });
- };
- /**
- * A computed property that returns true if dependent property is less or equal to the needed value
- * App.*-keys are supported
- * <pre>
- * var o = Em.Object.create({
- * p1: 4,
- * p2: Em.computed.lte('p1', 1)
- * });
- * console.log(o.get('p2')); // false
- * o.set('p1', 4);
- * console.log(o.get('p2')); // true
- * o.set('p1', 5);
- * console.log(o.get('p2')); // true
- * </pre>
- *
- * @method lte
- * @param {string} dependentKey
- * @param {*} value
- * @returns {Ember.ComputedProperty}
- */
- computed.lte = function (dependentKey, value) {
- return computed(dependentKey, function () {
- return smartGet(this, dependentKey) <= value;
- });
- };
- /**
- * A computed property that returns true if first dependent property is less or equal to the second dependent property
- * App.*-keys are supported
- * <pre>
- * var o = Em.Object.create({
- * p1: 4,
- * p2: 1,
- * p3: Em.computed.lteProperties('p1', 'p2')
- * });
- * console.log(o.get('p3')); // false
- * o.set('p2', 4);
- * console.log(o.get('p3')); // true
- * o.set('p2', 5);
- * console.log(o.get('p3')); // true
- * </pre>
- *
- * @method lteProperties
- * @param {string} dependentKey1
- * @param {string} dependentKey2
- * @returns {Ember.ComputedProperty}
- */
- computed.lteProperties = function (dependentKey1, dependentKey2) {
- return computed(dependentKey1, dependentKey2, function () {
- return smartGet(this, dependentKey1) <= smartGet(this, dependentKey2);
- });
- };
- /**
- * A computed property that returns true if dependent value is greater than the needed value
- * App.*-keys are supported
- * <pre>
- * var o = Em.Object.create({
- * p1: 4,
- * p2: Em.computed.gt('p1', 1)
- * });
- * console.log(o.get('p2')); // true
- * o.set('p1', 4);
- * console.log(o.get('p2')); // false
- * o.set('p1', 5);
- * console.log(o.get('p2')); // false
- * </pre>
- *
- * @method gt
- * @param {string} dependentKey
- * @param {*} value
- * @returns {Ember.ComputedProperty}
- */
- computed.gt = function (dependentKey, value) {
- return computed(dependentKey, function () {
- return smartGet(this, dependentKey) > value;
- });
- };
- /**
- * A computed property that returns true if first dependent property is greater than the second dependent property
- * App.*-keys are supported
- * <pre>
- * var o = Em.Object.create({
- * p1: 4,
- * p2: 1,
- * p3: Em.computed.gteProperties('p1', 'p2')
- * });
- * console.log(o.get('p3')); // true
- * o.set('p2', 4);
- * console.log(o.get('p3')); // false
- * o.set('p2', 5);
- * console.log(o.get('p3')); // false
- * </pre>
- *
- * @method gtProperties
- * @param {string} dependentKey1
- * @param {string} dependentKey2
- * @returns {Ember.ComputedProperty}
- */
- computed.gtProperties = function (dependentKey1, dependentKey2) {
- return computed(dependentKey1, dependentKey2, function () {
- return smartGet(this, dependentKey1) > smartGet(this, dependentKey2);
- });
- };
- /**
- * A computed property that returns true if dependent value is less than the needed value
- * App.*-keys are supported
- * <pre>
- * var o = Em.Object.create({
- * p1: 4,
- * p2: Em.computed.lt('p1', 1)
- * });
- * console.log(o.get('p2')); // false
- * o.set('p1', 4);
- * console.log(o.get('p2')); // false
- * o.set('p1', 5);
- * console.log(o.get('p2')); // true
- * </pre>
- *
- * @method lt
- * @param {string} dependentKey
- * @param {*} value
- * @returns {Ember.ComputedProperty}
- */
- computed.lt = function (dependentKey, value) {
- return computed(dependentKey, function () {
- return smartGet(this, dependentKey) < value;
- });
- };
- /**
- * A computed property that returns true if first dependent property is less than the second dependent property
- * App.*-keys are supported
- * <pre>
- * var o = Em.Object.create({
- * p1: 4,
- * p2: 1,
- * p3: Em.computed.ltProperties('p1', 'p2')
- * });
- * console.log(o.get('p3')); // false
- * o.set('p2', 4);
- * console.log(o.get('p3')); // false
- * o.set('p2', 5);
- * console.log(o.get('p3')); // true
- * </pre>
- *
- * @method gtProperties
- * @param {string} dependentKey1
- * @param {string} dependentKey2
- * @returns {Ember.ComputedProperty}
- */
- computed.ltProperties = function (dependentKey1, dependentKey2) {
- return computed(dependentKey1, dependentKey2, function () {
- return smartGet(this, dependentKey1) < smartGet(this, dependentKey2);
- });
- };
- /**
- * A computed property that returns true if dependent property is match to the needed regular expression
- * <pre>
- * var o = Em.Object.create({
- * p1: 'abc',
- * p2: Em.computed.match('p1', /^a/)
- * });
- * console.log(o.get('p2')); // true
- * o.set('p1', 'bc');
- * console.log(o.get('p2')); // false
- * </pre>
- *
- * @method match
- * @param {string} dependentKey
- * @param {RegExp} regexp
- * @returns {Ember.ComputedProperty}
- */
- computed.match = function (dependentKey, regexp) {
- return computed(dependentKey, function () {
- var value = get(this, dependentKey);
- if (!regexp) {
- return false;
- }
- return regexp.test(value);
- });
- };
- /**
- * A computed property that returns true of some collection's item has property with needed value
- * <pre>
- * var o = Em.Object.create({
- * p1: [{a: 1}, {a: 2}, {a: 3}],
- * p2: Em.computed.someBy('p1', 'a', 1)
- * });
- * console.log(o.get('p2')); // true
- * o.set('p1.0.a', 2);
- * console.log(o.get('p2')); // false
- * </pre>
- *
- * @method someBy
- * @param {string} collectionKey
- * @param {string} propertyName
- * @param {*} neededValue
- * @returns {Ember.ComputedProperty}
- */
- computed.someBy = function (collectionKey, propertyName, neededValue) {
- return computed(collectionKey + '.@each.' + propertyName, function () {
- var collection = smartGet(this, collectionKey);
- if (!collection) {
- return false;
- }
- return collection.someProperty(propertyName, neededValue);
- });
- };
- /**
- * A computed property that returns true of all collection's items have property with needed value
- * <pre>
- * var o = Em.Object.create({
- * p1: [{a: 1}, {a: 1}, {a: 1}],
- * p2: Em.computed.everyBy('p1', 'a', 1)
- * });
- * console.log(o.get('p2')); // true
- * o.set('p1.0.a', 2);
- * console.log(o.get('p2')); // false
- * </pre>
- *
- * @method everyBy
- * @param {string} collectionKey
- * @param {string} propertyName
- * @param {*} neededValue
- * @returns {Ember.ComputedProperty}
- */
- computed.everyBy = function (collectionKey, propertyName, neededValue) {
- return computed(collectionKey + '.@each.' + propertyName, function () {
- var collection = smartGet(this, collectionKey);
- if (!collection) {
- return false;
- }
- return collection.everyProperty(propertyName, neededValue);
- });
- };
- /**
- * A computed property that returns array with values of named property on all items in the collection
- * <pre>
- * var o = Em.Object.create({
- * p1: [{a: 1}, {a: 2}, {a: 3}],
- * p2: Em.computed.everyBy('p1', 'a')
- * });
- * console.log(o.get('p2')); // [1, 2, 3]
- * o.set('p1.0.a', 2);
- * console.log(o.get('p2')); // [2, 2, 3]
- * </pre>
- *
- * @method mapBy
- * @param {string} collectionKey
- * @param {string} propertyName
- * @returns {Ember.ComputedProperty}
- */
- computed.mapBy = function (collectionKey, propertyName) {
- return computed(collectionKey + '.@each.' + propertyName, function () {
- var collection = smartGet(this, collectionKey);
- if (!collection) {
- return [];
- }
- return collection.mapProperty(propertyName);
- });
- };
- /**
- * A computed property that returns array with collection's items that have needed property value
- * <pre>
- * var o = Em.Object.create({
- * p1: [{a: 1}, {a: 2}, {a: 3}],
- * p2: Em.computed.filterBy('p1', 'a', 2)
- * });
- * console.log(o.get('p2')); // [{a: 2}]
- * o.set('p1.0.a', 2);
- * console.log(o.get('p2')); // [{a: 2}, {a: 2}]
- * </pre>
- *
- * @method filterBy
- * @param {string} collectionKey
- * @param {string} propertyName
- * @param {*} neededValue
- * @returns {Ember.ComputedProperty}
- */
- computed.filterBy = function (collectionKey, propertyName, neededValue) {
- return computed(collectionKey + '.@each.' + propertyName, function () {
- var collection = smartGet(this, collectionKey);
- if (!collection) {
- return [];
- }
- return collection.filterProperty(propertyName, neededValue);
- });
- };
- /**
- * A computed property that returns first collection's item that has needed property value
- * <pre>
- * var o = Em.Object.create({
- * p1: [{a: 1, b: 1}, {a: 2, b: 2}, {a: 3, b: 3}],
- * p2: Em.computed.findBy('p1', 'a', 2)
- * });
- * console.log(o.get('p2')); // [{a: 2, b: 2}]
- * o.set('p1.0.a', 2);
- * console.log(o.get('p2')); // [{a: 2, b: 1}]
- * </pre>
- *
- * @method findBy
- * @param {string} collectionKey
- * @param {string} propertyName
- * @param {*} neededValue
- * @returns {Ember.ComputedProperty}
- */
- computed.findBy = function (collectionKey, propertyName, neededValue) {
- return computed(collectionKey + '.@each.' + propertyName, function () {
- var collection = smartGet(this, collectionKey);
- if (!collection) {
- return null;
- }
- return collection.findProperty(propertyName, neededValue);
- });
- };
- /**
- * A computed property that returns value equal to the dependent
- * Should be used as 'short-name' for deeply-nested values
- * App.*-keys are supported
- * <pre>
- * var o = Em.Object.create({
- * p1: {a: {b: {c: 2}}},
- * p2: Em.computed.alias('p1.a.b.c')
- * });
- * console.log(o.get('p2')); // 2
- * o.set('p1.a.b.c', 4);
- * console.log(o.get('p2')); // 4
- * </pre>
- *
- * @method alias
- * @param {string} dependentKey
- * @returns {Ember.ComputedProperty}
- */
- computed.alias = function (dependentKey) {
- return computed(dependentKey, function () {
- return smartGet(this, dependentKey);
- });
- };
- /**
- * A computed property that returns true if dependent property exists in the needed values
- * <pre>
- * var o = Em.Object.create({
- * p1: 2,
- * p2: Em.computed.existsIn('p1', [1, 2, 3])
- * });
- * console.log(o.get('p2')); // true
- * o.set('p1', 4);
- * console.log(o.get('p2')); // false
- * </pre>
- *
- * @method existsIn
- * @param {string} dependentKey
- * @param {array} neededValues
- * @returns {Ember.ComputedProperty}
- */
- computed.existsIn = function (dependentKey, neededValues) {
- return computed(dependentKey, function () {
- var value = smartGet(this, dependentKey);
- return makeArray(neededValues).contains(value);
- });
- };
- /**
- * A computed property that returns true if dependent property doesn't exist in the needed values
- * <pre>
- * var o = Em.Object.create({
- * p1: 2,
- * p2: Em.computed.notExistsIn('p1', [1, 2, 3])
- * });
- * console.log(o.get('p2')); // false
- * o.set('p1', 4);
- * console.log(o.get('p2')); // true
- * </pre>
- *
- * @method notExistsIn
- * @param {string} dependentKey
- * @param {array} neededValues
- * @returns {Ember.ComputedProperty}
- */
- computed.notExistsIn = function (dependentKey, neededValues) {
- return computed(dependentKey, function () {
- var value = smartGet(this, dependentKey);
- return !makeArray(neededValues).contains(value);
- });
- };
- /**
- * A computed property that returns result of calculation <code>(dependentProperty1/dependentProperty2 * 100)</code>
- * If accuracy is 0 (by default), result is rounded to integer
- * Otherwise - result is float with provided accuracy
- * App.*-keys are supported
- * <pre>
- * var o = Em.Object.create({
- * p1: 2,
- * p2: 4,
- * p3: Em.computed.percents('p1', 'p2')
- * });
- * console.log(o.get('p3')); // 50
- * o.set('p2', 5);
- * console.log(o.get('p3')); // 40
- * </pre>
- *
- * @method percents
- * @param {string} dependentKey1
- * @param {string} dependentKey2
- * @param {number} [accuracy=0]
- * @returns {Ember.ComputedProperty}
- */
- computed.percents = function (dependentKey1, dependentKey2, accuracy) {
- if (arguments.length < 3) {
- accuracy = 0;
- }
- return computed(dependentKey1, dependentKey2, function () {
- var v1 = Number(smartGet(this, dependentKey1));
- var v2 = Number(smartGet(this, dependentKey2));
- var result = v1 / v2 * 100;
- if (0 === accuracy) {
- return Math.round(result);
- }
- return parseFloat(result.toFixed(accuracy));
- });
- };
- /**
- * A computed property that returns result of <code>App.format.role</code> for dependent value
- * <pre>
- * var o = Em.Object.create({
- * p1: 'SECONDARY_NAMENODE',
- * p3: Em.computed.formatRole('p1', false)
- * });
- * console.log(o.get('p2')); // 'SNameNode'
- * o.set('p1', 'FLUME_HANDLER);
- * console.log(o.get('p2')); // 'Flume'
- * </pre>
- *
- * @method formatRole
- * @param {string} dependentKey
- * @param {boolean} isServiceRole
- * @returns {Ember.ComputedProperty}
- */
- computed.formatRole = function (dependentKey, isServiceRole) {
- return computed(dependentKey, function () {
- var value = get(this, dependentKey);
- return App.format.role(value, isServiceRole);
- });
- };
- /**
- * A computed property that returns sum of the named property in the each collection's item
- * <pre>
- * var o = Em.Object.create({
- * p1: [{a: 1}, {a: 2}, {a: 3}],
- * p2: Em.computed.sumBy('p1', 'a')
- * });
- * console.log(o.get('p2')); // 6
- * o.set('p1.0.a', 2);
- * console.log(o.get('p2')); // 7
- * </pre>
- *
- * @method sumBy
- * @param {string} collectionKey
- * @param {string} propertyName
- * @returns {Ember.ComputedProperty}
- */
- computed.sumBy = function (collectionKey, propertyName) {
- return computed(collectionKey + '.@each.' + propertyName, function () {
- var collection = smartGet(this, collectionKey);
- if (Em.isEmpty(collection)) {
- return 0;
- }
- var sum = 0;
- collection.forEach(function (item) {
- sum += Number(get(item, propertyName));
- });
- return sum;
- });
- };
- /**
- * A computed property that returns I18n-string formatted with dependent properties
- * Takes at least one argument
- * App.*-keys are supported
- *
- * @param {string} key key in the I18n-messages
- * @param {...string} dependentKeys
- * @method i18nFormat
- * @returns {Ember.ComputedProperty}
- */
- computed.i18nFormat = generateComputedWithKey(function (key, dependentValues) {
- var str = Em.I18n.t(key);
- if (!str) {
- return '';
- }
- return str.format.apply(str, dependentValues);
- });
- /**
- * A computed property that returns string formatted with dependent properties
- * Takes at least one argument
- * App.*-keys are supported
- * <pre>
- * var o = Em.Object.create({
- * p1: 'abc',
- * p2: 'cba',
- * p3: Em.computed.format('{0} => {1}', 'p1', 'p2')
- * });
- * console.log(o.get('p3')); // 'abc => cba'
- * o.set('p1', 'aaa');
- * console.log(o.get('p3')); // 'aaa => cba'
- * </pre>
- *
- * @param {string} str string to format
- * @param {...string} dependentKeys
- * @method format
- * @returns {Ember.ComputedProperty}
- */
- computed.format = generateComputedWithKey(function (str, dependentValues) {
- if (!str) {
- return '';
- }
- return str.format.apply(str, dependentValues);
- });
- /**
- * A computed property that returns dependent values joined with separator
- * Takes at least one argument
- * App.*-keys are supported
- * <pre>
- * var o = Em.Object.create({
- * p1: 'abc',
- * p2: 'cba',
- * p3: Em.computed.concat('|', 'p1', 'p2')
- * });
- * console.log(o.get('p3')); // 'abc|cba'
- * o.set('p1', 'aaa');
- * console.log(o.get('p3')); // 'aaa|cba'
- * </pre>
- *
- * @param {string} separator
- * @param {...string} dependentKeys
- * @method concat
- * @return {Ember.ComputedProperty}
- */
- computed.concat = generateComputedWithKey(function (separator, dependentValues) {
- return dependentValues.join(separator);
- });
- /**
- * A computed property that returns first not blank value from dependent values
- * Based on <code>Ember.isBlank</code>
- * Takes at least 1 argument
- * Dependent values order affects the result
- * App.*-keys are supported
- * <pre>
- * var o = Em.Object.create({
- * p1: null,
- * p2: '',
- * p3: 'abc'
- * p4: Em.computed.firstNotBlank('p1', 'p2', 'p3')
- * });
- * console.log(o.get('p4')); // 'abc'
- * o.set('p1', 'aaa');
- * console.log(o.get('p4')); // 'aaa'
- * </pre>
- *
- * @param {...string} dependentKeys
- * @method firstNotBlank
- * @return {Ember.ComputedProperty}
- */
- computed.firstNotBlank = generateComputedWithValues(function (values) {
- for (var i = 0; i < values.length; i++) {
- if (!Em.isBlank(values[i])) {
- return values[i];
- }
- }
- return null;
- });
- /**
- * A computed property that returns dependent value if it is truly or ('0'|0)
- * Returns <code>'n/a'</code> otherwise
- * App.*-keys are supported
- * <pre>
- * var o = Em.Object.create({
- * p1: 0,
- * p2: Em.computed.formatUnavailable('p1')
- * });
- * console.log(o.get('p2')); // 0
- * o.set('p1', 12);
- * console.log(o.get('p2')); // 12
- * o.set('p1', 'some string');
- * console.log(o.get('p2')); // 'n/a'
- * </pre>
- *
- * @param {string} dependentKey
- * @method formatUnavailable
- * @returns {Ember.ComputedProperty}
- */
- computed.formatUnavailable = function(dependentKey) {
- return computed(dependentKey, function () {
- var value = smartGet(this, dependentKey);
- return value || value == 0 ? value : Em.I18n.t('services.service.summary.notAvailable');
- });
- };
- /**
- * A computed property that returns one of provided values basing on dependent value
- * If dependent value is 0, <code>zeroMsg</code> is returned
- * If dependent value is 1, <code>oneMsg</code> is returned
- * If dependent value is greater than 1, <code>manyMsg</code> is returned
- * App.*-keys are supported
- * <pre>
- * var o = Em.Object.create({
- * p1: 0,
- * p2: Em.computed.formatUnavailable('p1', '0msg', '1msg', '2+msg')
- * });
- * console.log(o.get('p2')); // '0msg'
- * o.set('p1', 1);
- * console.log(o.get('p2')); // '1msg'
- * o.set('p1', 100500);
- * console.log(o.get('p2')); // '2+msg'
- * </pre>
- *
- * @param {string} dependentKey
- * @param {string} zeroMsg
- * @param {string} oneMsg
- * @param {string} manyMsg
- * @returns {Ember.ComputedProperty}
- * @method countBasedMessage
- */
- computed.countBasedMessage = function (dependentKey, zeroMsg, oneMsg, manyMsg) {
- return computed(dependentKey, function () {
- var value = Number(smartGet(this, dependentKey));
- if (value === 0) {
- return zeroMsg;
- }
- if (value > 1) {
- return manyMsg;
- }
- return oneMsg;
- });
- };
- /**
- * A computed property that returns property value according to the property key and object key
- * App.*-keys are supported
- * <pre>
- * var o = Em.Object.create({
- * p1: {a: 1, b: 2, c: 3},
- * p2: 'a',
- * p3: Em.computed.getByKey('p1', 'p2')
- * });
- * console.log(o.get('p3')); // 1
- * o.set('p2', 'b');
- * console.log(o.get('p3')); // 2
- * o.set('p2', 'c');
- * console.log(o.get('p3')); // 3
- * </pre>
- *
- * With `defaultValue`
- * <pre>
- * var o = Em.Object.create({
- * p1: {a: 1, b: 2, c: 3},
- * p2: 'd',
- * p3: Em.computed.getByKey('p1', 'p2', 100500)
- * });
- * console.log(o.get('p3')); // 100500 - default value is returned, because there is no key `d` in the `p1`
- * </pre>
- * <b>IMPORTANT!</b> This CP <b>SHOULD NOT</b> be used with for object with values equal to the views (like <code>{a: App.MyViewA, b: App.MyViewB}</code>)
- * This restriction exists because views may be undefined on the moment when this CP is calculated (files are not `required` yet)
- *
- * @param {string} objectKey
- * @param {string} propertyKey
- * @param {*} [defaultValue]
- * @returns {Ember.ComputedProperty}
- */
- computed.getByKey = function (objectKey, propertyKey, defaultValue) {
- return computed(objectKey, propertyKey, function () {
- var object = smartGet(this, objectKey);
- var property = smartGet(this, propertyKey);
- if (!object) {
- return null;
- }
- return object.hasOwnProperty(property) ? object[property] : defaultValue;
- });
- }
|