2011-07-17 08:05:43 +00:00
|
|
|
|
'use strict';
|
|
|
|
|
|
|
2010-04-01 21:10:28 +00:00
|
|
|
|
////////////////////////////////////
|
2010-04-01 00:56:16 +00:00
|
|
|
|
|
2010-08-18 23:23:12 +00:00
|
|
|
|
if (typeof document.getAttribute == $undefined)
|
2010-01-12 00:15:12 +00:00
|
|
|
|
document.getAttribute = function() {};
|
2010-01-06 00:36:58 +00:00
|
|
|
|
|
2010-11-01 20:44:39 +00:00
|
|
|
|
/**
|
2010-11-17 19:34:23 +00:00
|
|
|
|
* @ngdoc function
|
2010-11-01 20:44:39 +00:00
|
|
|
|
* @name angular.lowercase
|
|
|
|
|
|
* @function
|
|
|
|
|
|
*
|
2011-09-01 07:06:09 +00:00
|
|
|
|
* @description Converts the specified string to lowercase.
|
|
|
|
|
|
* @param {string} string String to be converted to lowercase.
|
2010-10-27 22:31:10 +00:00
|
|
|
|
* @returns {string} Lowercased string.
|
2010-11-01 20:44:39 +00:00
|
|
|
|
*/
|
2011-10-25 16:09:32 +00:00
|
|
|
|
var lowercase = function(string){return isString(string) ? string.toLowerCase() : string;};
|
2010-11-01 20:44:39 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2010-11-17 19:34:23 +00:00
|
|
|
|
* @ngdoc function
|
2010-11-10 20:02:49 +00:00
|
|
|
|
* @name angular.uppercase
|
2010-11-01 20:44:39 +00:00
|
|
|
|
* @function
|
|
|
|
|
|
*
|
2011-09-01 07:06:09 +00:00
|
|
|
|
* @description Converts the specified string to uppercase.
|
|
|
|
|
|
* @param {string} string String to be converted to uppercase.
|
2010-10-27 22:31:10 +00:00
|
|
|
|
* @returns {string} Uppercased string.
|
2010-11-01 20:44:39 +00:00
|
|
|
|
*/
|
2011-10-25 16:09:32 +00:00
|
|
|
|
var uppercase = function(string){return isString(string) ? string.toUpperCase() : string;};
|
2010-11-01 20:44:39 +00:00
|
|
|
|
|
|
|
|
|
|
|
2011-10-07 18:27:49 +00:00
|
|
|
|
var manualLowercase = function(s) {
|
2011-02-12 16:58:11 +00:00
|
|
|
|
return isString(s)
|
2011-10-25 16:09:32 +00:00
|
|
|
|
? s.replace(/[A-Z]/g, function(ch) {return fromCharCode(ch.charCodeAt(0) | 32);})
|
2011-02-12 16:58:11 +00:00
|
|
|
|
: s;
|
2010-10-19 04:20:47 +00:00
|
|
|
|
};
|
2011-10-07 18:27:49 +00:00
|
|
|
|
var manualUppercase = function(s) {
|
2011-02-12 16:58:11 +00:00
|
|
|
|
return isString(s)
|
2011-10-25 16:09:32 +00:00
|
|
|
|
? s.replace(/[a-z]/g, function(ch) {return fromCharCode(ch.charCodeAt(0) & ~32);})
|
2011-02-12 16:58:11 +00:00
|
|
|
|
: s;
|
2010-10-19 04:20:47 +00:00
|
|
|
|
};
|
2010-11-01 20:44:39 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// String#toLowerCase and String#toUpperCase don't produce correct results in browsers with Turkish
|
2011-08-19 00:41:57 +00:00
|
|
|
|
// locale, for this reason we need to detect this case and redefine lowercase/uppercase methods
|
|
|
|
|
|
// with correct but slower alternatives.
|
2010-10-19 04:20:47 +00:00
|
|
|
|
if ('i' !== 'I'.toLowerCase()) {
|
|
|
|
|
|
lowercase = manualLowercase;
|
2010-10-31 18:24:20 +00:00
|
|
|
|
uppercase = manualUppercase;
|
2010-10-19 04:20:47 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2011-10-25 16:09:32 +00:00
|
|
|
|
function fromCharCode(code) {return String.fromCharCode(code);}
|
2010-10-19 04:20:47 +00:00
|
|
|
|
|
2011-10-22 00:53:37 +00:00
|
|
|
|
/**
|
|
|
|
|
|
* Creates the element for IE8 and below to allow styling of widgets
|
2011-10-25 16:09:32 +00:00
|
|
|
|
* (http://ejohn.org/blog/html5-shiv/). This hack works only if angular is
|
|
|
|
|
|
* included synchronously at the top of the document before IE sees any
|
2011-10-22 00:53:37 +00:00
|
|
|
|
* unknown elements. See regression/issue-584.html.
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param {string} elementName Name of the widget.
|
|
|
|
|
|
* @returns {string} Lowercased string.
|
|
|
|
|
|
*/
|
|
|
|
|
|
function shivForIE(elementName) {
|
|
|
|
|
|
elementName = lowercase(elementName);
|
|
|
|
|
|
if (msie < 9 && elementName.charAt(0) != '@') { // ignore attr-widgets
|
|
|
|
|
|
document.createElement(elementName);
|
|
|
|
|
|
}
|
|
|
|
|
|
return elementName;
|
|
|
|
|
|
}
|
2010-10-19 04:20:47 +00:00
|
|
|
|
|
2011-04-19 23:34:49 +00:00
|
|
|
|
var _undefined = undefined,
|
|
|
|
|
|
_null = null,
|
2010-12-02 04:29:54 +00:00
|
|
|
|
$$scope = '$scope',
|
2010-08-18 23:23:12 +00:00
|
|
|
|
$angular = 'angular',
|
|
|
|
|
|
$array = 'array',
|
|
|
|
|
|
$boolean = 'boolean',
|
|
|
|
|
|
$console = 'console',
|
|
|
|
|
|
$date = 'date',
|
|
|
|
|
|
$length = 'length',
|
|
|
|
|
|
$name = 'name',
|
|
|
|
|
|
$noop = 'noop',
|
|
|
|
|
|
$null = 'null',
|
|
|
|
|
|
$number = 'number',
|
|
|
|
|
|
$object = 'object',
|
|
|
|
|
|
$string = 'string',
|
2010-12-02 04:29:54 +00:00
|
|
|
|
$value = 'value',
|
|
|
|
|
|
$selected = 'selected',
|
2010-08-18 23:23:12 +00:00
|
|
|
|
$undefined = 'undefined',
|
|
|
|
|
|
NOOP = 'noop',
|
2010-11-16 21:57:41 +00:00
|
|
|
|
Error = window.Error,
|
2010-10-16 04:38:41 +00:00
|
|
|
|
/** holds major version number for IE or NaN for real browsers */
|
|
|
|
|
|
msie = parseInt((/msie (\d+)/.exec(lowercase(navigator.userAgent)) || [])[1], 10),
|
2011-02-05 00:42:21 +00:00
|
|
|
|
jqLite, // delay binding since jQuery could be loaded after us.
|
|
|
|
|
|
jQuery, // delay binding
|
2011-03-09 04:20:49 +00:00
|
|
|
|
slice = [].slice,
|
|
|
|
|
|
push = [].push,
|
2011-02-12 16:58:11 +00:00
|
|
|
|
error = window[$console]
|
|
|
|
|
|
? bind(window[$console], window[$console]['error'] || noop)
|
|
|
|
|
|
: noop,
|
2010-11-01 20:44:39 +00:00
|
|
|
|
|
2011-01-26 05:03:37 +00:00
|
|
|
|
/** @name angular */
|
2011-11-02 23:32:46 +00:00
|
|
|
|
angular = window.angular || (window.angular = {}),
|
|
|
|
|
|
angularModule = angular.module || (angular.module = {}),
|
2011-02-07 00:32:37 +00:00
|
|
|
|
/** @name angular.markup */
|
2010-07-30 22:19:43 +00:00
|
|
|
|
angularTextMarkup = extensionMap(angular, 'markup'),
|
2011-02-07 00:32:37 +00:00
|
|
|
|
/** @name angular.attrMarkup */
|
2010-03-25 21:43:05 +00:00
|
|
|
|
angularAttrMarkup = extensionMap(angular, 'attrMarkup'),
|
2010-11-22 20:05:01 +00:00
|
|
|
|
/** @name angular.directive */
|
2011-11-09 01:19:54 +00:00
|
|
|
|
angularDirective = extensionMap(angular, 'directive', lowercase),
|
2010-11-22 20:05:01 +00:00
|
|
|
|
/** @name angular.widget */
|
2011-10-22 00:53:37 +00:00
|
|
|
|
angularWidget = extensionMap(angular, 'widget', shivForIE),
|
2011-09-08 20:56:29 +00:00
|
|
|
|
/** @name angular.service */
|
|
|
|
|
|
angularInputType = extensionMap(angular, 'inputType', lowercase),
|
2010-11-22 20:05:01 +00:00
|
|
|
|
/** @name angular.service */
|
2010-04-21 19:50:05 +00:00
|
|
|
|
angularCallbacks = extensionMap(angular, 'callbacks'),
|
2011-01-06 07:56:57 +00:00
|
|
|
|
nodeName_,
|
2011-07-17 07:47:11 +00:00
|
|
|
|
uid = ['0', '0', '0'],
|
2010-12-22 21:19:26 +00:00
|
|
|
|
DATE_ISOSTRING_LN = 24;
|
2010-04-01 00:56:16 +00:00
|
|
|
|
|
2010-11-25 05:12:52 +00:00
|
|
|
|
/**
|
|
|
|
|
|
* @ngdoc function
|
2011-01-08 06:02:23 +00:00
|
|
|
|
* @name angular.forEach
|
2010-11-25 05:12:52 +00:00
|
|
|
|
* @function
|
|
|
|
|
|
*
|
|
|
|
|
|
* @description
|
2011-09-01 07:06:09 +00:00
|
|
|
|
* Invokes the `iterator` function once for each item in `obj` collection, which can be either an
|
|
|
|
|
|
* object or an array. The `iterator` function is invoked with `iterator(value, key)`, where `value`
|
|
|
|
|
|
* is the value of an object property or an array element and `key` is the object property key or
|
|
|
|
|
|
* array element index. Specifying a `context` for the function is optional.
|
2011-01-08 06:02:23 +00:00
|
|
|
|
*
|
|
|
|
|
|
* Note: this function was previously known as `angular.foreach`.
|
2010-11-25 05:12:52 +00:00
|
|
|
|
*
|
|
|
|
|
|
<pre>
|
|
|
|
|
|
var values = {name: 'misko', gender: 'male'};
|
|
|
|
|
|
var log = [];
|
2011-01-08 06:02:23 +00:00
|
|
|
|
angular.forEach(values, function(value, key){
|
2010-11-25 05:12:52 +00:00
|
|
|
|
this.push(key + ': ' + value);
|
|
|
|
|
|
}, log);
|
|
|
|
|
|
expect(log).toEqual(['name: misko', 'gender:male']);
|
|
|
|
|
|
</pre>
|
|
|
|
|
|
*
|
|
|
|
|
|
* @param {Object|Array} obj Object to iterate over.
|
|
|
|
|
|
* @param {function()} iterator Iterator function.
|
2011-09-01 07:06:09 +00:00
|
|
|
|
* @param {Object=} context Object to become context (`this`) for the iterator function.
|
2011-07-30 01:42:16 +00:00
|
|
|
|
* @returns {Object|Array} Reference to `obj`.
|
2010-11-25 05:12:52 +00:00
|
|
|
|
*/
|
2011-01-08 06:02:23 +00:00
|
|
|
|
function forEach(obj, iterator, context) {
|
2010-03-23 21:57:11 +00:00
|
|
|
|
var key;
|
|
|
|
|
|
if (obj) {
|
2010-04-17 03:10:09 +00:00
|
|
|
|
if (isFunction(obj)){
|
2010-04-16 21:01:29 +00:00
|
|
|
|
for (key in obj) {
|
2010-08-18 23:23:12 +00:00
|
|
|
|
if (key != 'prototype' && key != $length && key != $name && obj.hasOwnProperty(key)) {
|
2010-04-16 21:01:29 +00:00
|
|
|
|
iterator.call(context, obj[key], key);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2011-01-08 06:02:23 +00:00
|
|
|
|
} else if (obj.forEach && obj.forEach !== forEach) {
|
2010-04-17 03:10:09 +00:00
|
|
|
|
obj.forEach(iterator, context);
|
2010-03-30 03:25:42 +00:00
|
|
|
|
} else if (isObject(obj) && isNumber(obj.length)) {
|
2010-03-23 21:57:11 +00:00
|
|
|
|
for (key = 0; key < obj.length; key++)
|
|
|
|
|
|
iterator.call(context, obj[key], key);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
for (key in obj)
|
|
|
|
|
|
iterator.call(context, obj[key], key);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return obj;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2011-09-08 20:56:29 +00:00
|
|
|
|
function sortedKeys(obj) {
|
2010-04-01 00:56:16 +00:00
|
|
|
|
var keys = [];
|
2011-09-08 20:56:29 +00:00
|
|
|
|
for (var key in obj) {
|
|
|
|
|
|
if (obj.hasOwnProperty(key)) {
|
|
|
|
|
|
keys.push(key);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return keys.sort();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function forEachSorted(obj, iterator, context) {
|
|
|
|
|
|
var keys = sortedKeys(obj)
|
2010-04-01 00:56:16 +00:00
|
|
|
|
for ( var i = 0; i < keys.length; i++) {
|
|
|
|
|
|
iterator.call(context, obj[keys[i]], keys[i]);
|
|
|
|
|
|
}
|
|
|
|
|
|
return keys;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2011-04-12 20:40:23 +00:00
|
|
|
|
/**
|
|
|
|
|
|
* A consistent way of creating unique IDs in angular. The ID is a sequence of alpha numeric
|
|
|
|
|
|
* characters such as '012ABC'. The reason why we are not using simply a number counter is that
|
|
|
|
|
|
* the number string gets longer over time, and it can also overflow, where as the the nextId
|
|
|
|
|
|
* will grow much slower, it is a string, and it will never overflow.
|
|
|
|
|
|
*
|
|
|
|
|
|
* @returns an unique alpha-numeric string
|
|
|
|
|
|
*/
|
|
|
|
|
|
function nextUid() {
|
|
|
|
|
|
var index = uid.length;
|
|
|
|
|
|
var digit;
|
|
|
|
|
|
|
|
|
|
|
|
while(index) {
|
|
|
|
|
|
index--;
|
|
|
|
|
|
digit = uid[index].charCodeAt(0);
|
|
|
|
|
|
if (digit == 57 /*'9'*/) {
|
|
|
|
|
|
uid[index] = 'A';
|
|
|
|
|
|
return uid.join('');
|
|
|
|
|
|
}
|
|
|
|
|
|
if (digit == 90 /*'Z'*/) {
|
|
|
|
|
|
uid[index] = '0';
|
|
|
|
|
|
} else {
|
|
|
|
|
|
uid[index] = String.fromCharCode(digit + 1);
|
|
|
|
|
|
return uid.join('');
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
uid.unshift('0');
|
|
|
|
|
|
return uid.join('');
|
|
|
|
|
|
}
|
2010-11-16 21:57:41 +00:00
|
|
|
|
|
2010-11-25 05:03:56 +00:00
|
|
|
|
/**
|
|
|
|
|
|
* @ngdoc function
|
|
|
|
|
|
* @name angular.extend
|
|
|
|
|
|
* @function
|
|
|
|
|
|
*
|
|
|
|
|
|
* @description
|
2011-08-19 00:41:57 +00:00
|
|
|
|
* Extends the destination object `dst` by copying all of the properties from the `src` object(s)
|
|
|
|
|
|
* to `dst`. You can specify multiple `src` objects.
|
2010-11-25 05:03:56 +00:00
|
|
|
|
*
|
2011-09-01 07:06:09 +00:00
|
|
|
|
* @param {Object} dst Destination object.
|
|
|
|
|
|
* @param {...Object} src Source object(s).
|
2010-11-25 05:03:56 +00:00
|
|
|
|
*/
|
2010-03-30 03:25:42 +00:00
|
|
|
|
function extend(dst) {
|
2011-01-08 06:02:23 +00:00
|
|
|
|
forEach(arguments, function(obj){
|
2010-03-30 03:25:42 +00:00
|
|
|
|
if (obj !== dst) {
|
2011-01-08 06:02:23 +00:00
|
|
|
|
forEach(obj, function(value, key){
|
2010-03-30 03:25:42 +00:00
|
|
|
|
dst[key] = value;
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
2010-03-23 21:57:11 +00:00
|
|
|
|
});
|
|
|
|
|
|
return dst;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-11-25 05:03:56 +00:00
|
|
|
|
|
2010-07-15 20:13:21 +00:00
|
|
|
|
function inherit(parent, extra) {
|
2011-10-07 18:27:49 +00:00
|
|
|
|
return extend(new (extend(function() {}, {prototype:parent}))(), extra);
|
2010-09-14 21:22:15 +00:00
|
|
|
|
}
|
2010-07-15 20:13:21 +00:00
|
|
|
|
|
2010-11-25 02:23:21 +00:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @ngdoc function
|
|
|
|
|
|
* @name angular.noop
|
|
|
|
|
|
* @function
|
|
|
|
|
|
*
|
|
|
|
|
|
* @description
|
2011-09-01 07:06:09 +00:00
|
|
|
|
* A function that performs no operations. This function can be useful when writing code in the
|
|
|
|
|
|
* functional style.
|
2010-11-25 02:23:21 +00:00
|
|
|
|
<pre>
|
|
|
|
|
|
function foo(callback) {
|
|
|
|
|
|
var result = calculateResult();
|
|
|
|
|
|
(callback || angular.noop)(result);
|
|
|
|
|
|
}
|
|
|
|
|
|
</pre>
|
|
|
|
|
|
*/
|
2010-03-30 03:25:42 +00:00
|
|
|
|
function noop() {}
|
2011-11-02 04:09:54 +00:00
|
|
|
|
noop.$inject = [];
|
2010-11-25 02:23:21 +00:00
|
|
|
|
|
2010-11-25 02:55:34 +00:00
|
|
|
|
|
2010-11-25 02:23:21 +00:00
|
|
|
|
/**
|
|
|
|
|
|
* @ngdoc function
|
|
|
|
|
|
* @name angular.identity
|
|
|
|
|
|
* @function
|
|
|
|
|
|
*
|
|
|
|
|
|
* @description
|
2011-09-01 07:06:09 +00:00
|
|
|
|
* A function that returns its first argument. This function is useful when writing code in the
|
|
|
|
|
|
* functional style.
|
2010-11-25 02:23:21 +00:00
|
|
|
|
*
|
|
|
|
|
|
<pre>
|
|
|
|
|
|
function transformer(transformationFn, value) {
|
|
|
|
|
|
return (transformationFn || identity)(value);
|
|
|
|
|
|
};
|
|
|
|
|
|
</pre>
|
|
|
|
|
|
*/
|
2010-03-30 03:25:42 +00:00
|
|
|
|
function identity($) {return $;}
|
2011-11-02 04:09:54 +00:00
|
|
|
|
identity.$inject = [];
|
2010-11-25 02:55:34 +00:00
|
|
|
|
|
|
|
|
|
|
|
2011-10-25 16:09:32 +00:00
|
|
|
|
function valueFn(value) {return function() {return value;};}
|
2010-10-30 18:57:13 +00:00
|
|
|
|
|
2010-07-20 23:55:32 +00:00
|
|
|
|
function extensionMap(angular, name, transform) {
|
2010-03-30 03:25:42 +00:00
|
|
|
|
var extPoint;
|
2011-10-07 18:27:49 +00:00
|
|
|
|
return angular[name] || (extPoint = angular[name] = function(name, fn, prop){
|
2010-07-20 23:55:32 +00:00
|
|
|
|
name = (transform || identity)(name);
|
2010-03-30 03:25:42 +00:00
|
|
|
|
if (isDefined(fn)) {
|
|
|
|
|
|
extPoint[name] = extend(fn, prop || {});
|
|
|
|
|
|
}
|
|
|
|
|
|
return extPoint[name];
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-11-25 16:19:14 +00:00
|
|
|
|
/**
|
|
|
|
|
|
* @ngdoc function
|
|
|
|
|
|
* @name angular.isUndefined
|
|
|
|
|
|
* @function
|
|
|
|
|
|
*
|
|
|
|
|
|
* @description
|
2011-09-01 07:06:09 +00:00
|
|
|
|
* Determines if a reference is undefined.
|
2010-11-25 16:19:14 +00:00
|
|
|
|
*
|
|
|
|
|
|
* @param {*} value Reference to check.
|
|
|
|
|
|
* @returns {boolean} True if `value` is undefined.
|
|
|
|
|
|
*/
|
2011-10-25 16:09:32 +00:00
|
|
|
|
function isUndefined(value){return typeof value == $undefined;}
|
2010-11-25 16:19:14 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @ngdoc function
|
|
|
|
|
|
* @name angular.isDefined
|
|
|
|
|
|
* @function
|
|
|
|
|
|
*
|
|
|
|
|
|
* @description
|
2011-09-01 07:06:09 +00:00
|
|
|
|
* Determines if a reference is defined.
|
2010-11-25 16:19:14 +00:00
|
|
|
|
*
|
|
|
|
|
|
* @param {*} value Reference to check.
|
|
|
|
|
|
* @returns {boolean} True if `value` is defined.
|
|
|
|
|
|
*/
|
2011-10-25 16:09:32 +00:00
|
|
|
|
function isDefined(value){return typeof value != $undefined;}
|
2010-11-25 16:19:14 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @ngdoc function
|
|
|
|
|
|
* @name angular.isObject
|
|
|
|
|
|
* @function
|
|
|
|
|
|
*
|
|
|
|
|
|
* @description
|
2011-09-01 07:06:09 +00:00
|
|
|
|
* Determines if a reference is an `Object`. Unlike `typeof` in JavaScript, `null`s are not
|
|
|
|
|
|
* considered to be objects.
|
2010-11-25 16:19:14 +00:00
|
|
|
|
*
|
|
|
|
|
|
* @param {*} value Reference to check.
|
|
|
|
|
|
* @returns {boolean} True if `value` is an `Object` but not `null`.
|
|
|
|
|
|
*/
|
2011-10-25 16:09:32 +00:00
|
|
|
|
function isObject(value){return value!=null && typeof value == $object;}
|
2010-11-25 16:19:14 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @ngdoc function
|
|
|
|
|
|
* @name angular.isString
|
|
|
|
|
|
* @function
|
|
|
|
|
|
*
|
|
|
|
|
|
* @description
|
2011-09-01 07:06:09 +00:00
|
|
|
|
* Determines if a reference is a `String`.
|
2010-11-25 16:19:14 +00:00
|
|
|
|
*
|
|
|
|
|
|
* @param {*} value Reference to check.
|
|
|
|
|
|
* @returns {boolean} True if `value` is a `String`.
|
|
|
|
|
|
*/
|
2011-10-25 16:09:32 +00:00
|
|
|
|
function isString(value){return typeof value == $string;}
|
2010-11-25 16:19:14 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @ngdoc function
|
|
|
|
|
|
* @name angular.isNumber
|
|
|
|
|
|
* @function
|
|
|
|
|
|
*
|
|
|
|
|
|
* @description
|
2011-09-01 07:06:09 +00:00
|
|
|
|
* Determines if a reference is a `Number`.
|
2010-11-25 16:19:14 +00:00
|
|
|
|
*
|
|
|
|
|
|
* @param {*} value Reference to check.
|
|
|
|
|
|
* @returns {boolean} True if `value` is a `Number`.
|
|
|
|
|
|
*/
|
2011-10-25 16:09:32 +00:00
|
|
|
|
function isNumber(value){return typeof value == $number;}
|
2010-11-25 16:19:14 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @ngdoc function
|
|
|
|
|
|
* @name angular.isDate
|
|
|
|
|
|
* @function
|
|
|
|
|
|
*
|
|
|
|
|
|
* @description
|
2011-09-01 07:06:09 +00:00
|
|
|
|
* Determines if a value is a date.
|
2010-11-25 16:19:14 +00:00
|
|
|
|
*
|
|
|
|
|
|
* @param {*} value Reference to check.
|
|
|
|
|
|
* @returns {boolean} True if `value` is a `Date`.
|
|
|
|
|
|
*/
|
2011-10-25 16:09:32 +00:00
|
|
|
|
function isDate(value){return value instanceof Date;}
|
2010-11-25 16:19:14 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @ngdoc function
|
|
|
|
|
|
* @name angular.isArray
|
|
|
|
|
|
* @function
|
|
|
|
|
|
*
|
|
|
|
|
|
* @description
|
2011-09-01 07:06:09 +00:00
|
|
|
|
* Determines if a reference is an `Array`.
|
2010-11-25 16:19:14 +00:00
|
|
|
|
*
|
|
|
|
|
|
* @param {*} value Reference to check.
|
|
|
|
|
|
* @returns {boolean} True if `value` is an `Array`.
|
|
|
|
|
|
*/
|
2011-10-25 16:09:32 +00:00
|
|
|
|
function isArray(value) {return value instanceof Array;}
|
2010-11-25 16:19:14 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @ngdoc function
|
|
|
|
|
|
* @name angular.isFunction
|
|
|
|
|
|
* @function
|
|
|
|
|
|
*
|
|
|
|
|
|
* @description
|
2011-09-01 07:06:09 +00:00
|
|
|
|
* Determines if a reference is a `Function`.
|
2010-11-25 16:19:14 +00:00
|
|
|
|
*
|
|
|
|
|
|
* @param {*} value Reference to check.
|
|
|
|
|
|
* @returns {boolean} True if `value` is a `Function`.
|
|
|
|
|
|
*/
|
2011-10-25 16:09:32 +00:00
|
|
|
|
function isFunction(value){return typeof value == 'function';}
|
2010-11-25 16:19:14 +00:00
|
|
|
|
|
|
|
|
|
|
|
2011-01-10 07:21:48 +00:00
|
|
|
|
/**
|
|
|
|
|
|
* Checks if `obj` is a window object.
|
|
|
|
|
|
*
|
|
|
|
|
|
* @private
|
|
|
|
|
|
* @param {*} obj Object to check
|
|
|
|
|
|
* @returns {boolean} True if `obj` is a window obj.
|
|
|
|
|
|
*/
|
|
|
|
|
|
function isWindow(obj) {
|
|
|
|
|
|
return obj && obj.document && obj.location && obj.alert && obj.setInterval;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2011-10-25 16:09:32 +00:00
|
|
|
|
function isBoolean(value) {return typeof value == $boolean;}
|
|
|
|
|
|
function isTextNode(node) {return nodeName_(node) == '#text';}
|
2011-08-19 00:41:57 +00:00
|
|
|
|
|
|
|
|
|
|
function trim(value) {
|
|
|
|
|
|
return isString(value) ? value.replace(/^\s*/, '').replace(/\s*$/, '') : value;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-04-12 21:28:15 +00:00
|
|
|
|
function isElement(node) {
|
2011-02-10 19:20:49 +00:00
|
|
|
|
return node &&
|
|
|
|
|
|
(node.nodeName // we are a direct element
|
|
|
|
|
|
|| (node.bind && node.find)); // we have a bind and find method part of jQuery API
|
2010-04-23 00:11:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2011-04-21 23:32:05 +00:00
|
|
|
|
/**
|
|
|
|
|
|
* @param str 'key1,key2,...'
|
|
|
|
|
|
* @returns {object} in the form of {key1:true, key2:true, ...}
|
|
|
|
|
|
*/
|
|
|
|
|
|
function makeMap(str){
|
|
|
|
|
|
var obj = {}, items = str.split(","), i;
|
|
|
|
|
|
for ( i = 0; i < items.length; i++ )
|
|
|
|
|
|
obj[ items[i] ] = true;
|
|
|
|
|
|
return obj;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2010-10-19 04:20:47 +00:00
|
|
|
|
/**
|
2011-08-19 00:41:57 +00:00
|
|
|
|
* HTML class which is the only class which can be used in ng:bind to inline HTML for security
|
|
|
|
|
|
* reasons.
|
|
|
|
|
|
*
|
2010-10-19 04:20:47 +00:00
|
|
|
|
* @constructor
|
|
|
|
|
|
* @param html raw (unsafe) html
|
2011-08-19 00:41:57 +00:00
|
|
|
|
* @param {string=} option If set to 'usafe', get method will return raw (unsafe/unsanitized) html
|
2010-10-19 04:20:47 +00:00
|
|
|
|
*/
|
|
|
|
|
|
function HTML(html, option) {
|
2010-04-23 00:11:56 +00:00
|
|
|
|
this.html = html;
|
2011-02-12 16:58:11 +00:00
|
|
|
|
this.get = lowercase(option) == 'unsafe'
|
|
|
|
|
|
? valueFn(html)
|
|
|
|
|
|
: function htmlSanitize() {
|
|
|
|
|
|
var buf = [];
|
|
|
|
|
|
htmlParser(html, htmlSanitizeWriter(buf));
|
|
|
|
|
|
return buf.join('');
|
|
|
|
|
|
};
|
2010-04-12 21:28:15 +00:00
|
|
|
|
}
|
2010-04-08 20:43:40 +00:00
|
|
|
|
|
2011-04-07 21:36:41 +00:00
|
|
|
|
if (msie < 9) {
|
2011-01-06 07:56:57 +00:00
|
|
|
|
nodeName_ = function(element) {
|
2010-10-19 22:34:58 +00:00
|
|
|
|
element = element.nodeName ? element : element[0];
|
2011-08-19 00:41:57 +00:00
|
|
|
|
return (element.scopeName && element.scopeName != 'HTML')
|
|
|
|
|
|
? uppercase(element.scopeName + ':' + element.nodeName) : element.nodeName;
|
2010-04-21 19:50:05 +00:00
|
|
|
|
};
|
|
|
|
|
|
} else {
|
2011-01-06 07:56:57 +00:00
|
|
|
|
nodeName_ = function(element) {
|
2010-10-19 22:34:58 +00:00
|
|
|
|
return element.nodeName ? element.nodeName : element[0].nodeName;
|
2010-04-21 19:50:05 +00:00
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-04-08 20:43:40 +00:00
|
|
|
|
function isVisible(element) {
|
2010-04-19 21:36:41 +00:00
|
|
|
|
var rect = element[0].getBoundingClientRect(),
|
2010-04-19 21:41:36 +00:00
|
|
|
|
width = (rect.width || (rect.right||0 - rect.left||0)),
|
|
|
|
|
|
height = (rect.height || (rect.bottom||0 - rect.top||0));
|
2010-04-19 21:36:41 +00:00
|
|
|
|
return width>0 && height>0;
|
2010-04-08 20:43:40 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2010-03-30 03:25:42 +00:00
|
|
|
|
function map(obj, iterator, context) {
|
|
|
|
|
|
var results = [];
|
2011-01-08 06:02:23 +00:00
|
|
|
|
forEach(obj, function(value, index, list) {
|
2010-03-30 03:25:42 +00:00
|
|
|
|
results.push(iterator.call(context, value, index, list));
|
|
|
|
|
|
});
|
|
|
|
|
|
return results;
|
2010-04-04 00:04:36 +00:00
|
|
|
|
}
|
2010-11-25 01:21:37 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @ngdoc function
|
|
|
|
|
|
* @name angular.Object.size
|
|
|
|
|
|
* @function
|
|
|
|
|
|
*
|
|
|
|
|
|
* @description
|
2011-08-19 00:41:57 +00:00
|
|
|
|
* Determines the number of elements in an array, the number of properties an object has, or
|
|
|
|
|
|
* the length of a string.
|
2010-11-25 01:21:37 +00:00
|
|
|
|
*
|
2011-08-19 00:41:57 +00:00
|
|
|
|
* Note: This function is used to augment the Object type in Angular expressions. See
|
|
|
|
|
|
* {@link angular.Object} for more information about Angular arrays.
|
2010-11-25 01:21:37 +00:00
|
|
|
|
*
|
2011-08-19 00:41:57 +00:00
|
|
|
|
* @param {Object|Array|string} obj Object, array, or string to inspect.
|
2011-03-27 22:58:24 +00:00
|
|
|
|
* @param {boolean} [ownPropsOnly=false] Count only "own" properties in an object
|
2011-09-01 07:06:09 +00:00
|
|
|
|
* @returns {number} The size of `obj` or `0` if `obj` is neither an object nor an array.
|
2010-11-25 01:21:37 +00:00
|
|
|
|
*
|
|
|
|
|
|
* @example
|
2011-02-01 00:21:29 +00:00
|
|
|
|
* <doc:example>
|
|
|
|
|
|
* <doc:source>
|
2011-08-19 00:41:57 +00:00
|
|
|
|
* <script>
|
|
|
|
|
|
* function SizeCtrl() {
|
|
|
|
|
|
* this.fooStringLength = angular.Object.size('foo');
|
|
|
|
|
|
* }
|
|
|
|
|
|
* </script>
|
|
|
|
|
|
* <div ng:controller="SizeCtrl">
|
|
|
|
|
|
* Number of items in array: {{ [1,2].$size() }}<br/>
|
|
|
|
|
|
* Number of items in object: {{ {a:1, b:2, c:3}.$size() }}<br/>
|
|
|
|
|
|
* String length: {{fooStringLength}}
|
|
|
|
|
|
* </div>
|
2011-02-01 00:21:29 +00:00
|
|
|
|
* </doc:source>
|
|
|
|
|
|
* <doc:scenario>
|
|
|
|
|
|
* it('should print correct sizes for an array and an object', function() {
|
|
|
|
|
|
* expect(binding('[1,2].$size()')).toBe('2');
|
|
|
|
|
|
* expect(binding('{a:1, b:2, c:3}.$size()')).toBe('3');
|
2011-08-19 00:41:57 +00:00
|
|
|
|
* expect(binding('fooStringLength')).toBe('3');
|
2011-02-01 00:21:29 +00:00
|
|
|
|
* });
|
|
|
|
|
|
* </doc:scenario>
|
|
|
|
|
|
* </doc:example>
|
2010-11-25 01:21:37 +00:00
|
|
|
|
*/
|
2011-03-27 22:58:24 +00:00
|
|
|
|
function size(obj, ownPropsOnly) {
|
2011-01-18 21:50:52 +00:00
|
|
|
|
var size = 0, key;
|
2011-03-27 23:19:03 +00:00
|
|
|
|
|
|
|
|
|
|
if (isArray(obj) || isString(obj)) {
|
|
|
|
|
|
return obj.length;
|
|
|
|
|
|
} else if (isObject(obj)){
|
|
|
|
|
|
for (key in obj)
|
|
|
|
|
|
if (!ownPropsOnly || obj.hasOwnProperty(key))
|
|
|
|
|
|
size++;
|
2010-03-30 03:25:42 +00:00
|
|
|
|
}
|
2011-03-27 23:19:03 +00:00
|
|
|
|
|
2010-03-30 03:25:42 +00:00
|
|
|
|
return size;
|
|
|
|
|
|
}
|
2011-03-27 23:19:03 +00:00
|
|
|
|
|
|
|
|
|
|
|
2010-03-26 23:27:18 +00:00
|
|
|
|
function includes(array, obj) {
|
|
|
|
|
|
for ( var i = 0; i < array.length; i++) {
|
|
|
|
|
|
if (obj === array[i]) return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
2010-03-20 05:18:39 +00:00
|
|
|
|
|
2010-03-30 03:25:42 +00:00
|
|
|
|
function indexOf(array, obj) {
|
|
|
|
|
|
for ( var i = 0; i < array.length; i++) {
|
|
|
|
|
|
if (obj === array[i]) return i;
|
|
|
|
|
|
}
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2011-11-04 04:14:04 +00:00
|
|
|
|
function arrayRemove(array, value) {
|
|
|
|
|
|
var index = indexOf(array, value);
|
|
|
|
|
|
if (index >=0)
|
|
|
|
|
|
array.splice(index, 1);
|
|
|
|
|
|
return value;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-01-12 00:15:12 +00:00
|
|
|
|
function isLeafNode (node) {
|
2010-03-23 21:57:11 +00:00
|
|
|
|
if (node) {
|
|
|
|
|
|
switch (node.nodeName) {
|
|
|
|
|
|
case "OPTION":
|
|
|
|
|
|
case "PRE":
|
|
|
|
|
|
case "TITLE":
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
2010-01-06 00:36:58 +00:00
|
|
|
|
}
|
2010-03-23 21:57:11 +00:00
|
|
|
|
return false;
|
2010-01-12 00:15:12 +00:00
|
|
|
|
}
|
2010-01-06 00:36:58 +00:00
|
|
|
|
|
2011-03-23 16:33:29 +00:00
|
|
|
|
/**
|
|
|
|
|
|
* @ngdoc function
|
|
|
|
|
|
* @name angular.copy
|
|
|
|
|
|
* @function
|
|
|
|
|
|
*
|
|
|
|
|
|
* @description
|
|
|
|
|
|
* Alias for {@link angular.Object.copy}
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
2010-09-21 16:55:09 +00:00
|
|
|
|
/**
|
2010-11-25 01:32:04 +00:00
|
|
|
|
* @ngdoc function
|
|
|
|
|
|
* @name angular.Object.copy
|
|
|
|
|
|
* @function
|
2010-09-21 16:55:09 +00:00
|
|
|
|
*
|
2010-11-25 01:32:04 +00:00
|
|
|
|
* @description
|
2011-08-19 00:41:57 +00:00
|
|
|
|
* Creates a deep copy of `source`, which should be an object or an array.
|
2010-09-21 16:55:09 +00:00
|
|
|
|
*
|
2011-08-19 00:41:57 +00:00
|
|
|
|
* * If no destination is supplied, a copy of the object or array is created.
|
|
|
|
|
|
* * If a destination is provided, all of its elements (for array) or properties (for objects)
|
|
|
|
|
|
* are deleted and then all elements/properties from the source are copied to it.
|
|
|
|
|
|
* * If `source` is not an object or array, `source` is returned.
|
2011-01-18 21:50:52 +00:00
|
|
|
|
*
|
2011-08-19 00:41:57 +00:00
|
|
|
|
* Note: this function is used to augment the Object type in Angular expressions. See
|
|
|
|
|
|
* {@link angular.Array} for more information about Angular arrays.
|
2010-09-21 16:55:09 +00:00
|
|
|
|
*
|
2011-08-19 00:41:57 +00:00
|
|
|
|
* @param {*} source The source that will be used to make a copy.
|
|
|
|
|
|
* Can be any type, including primitives, `null`, and `undefined`.
|
|
|
|
|
|
* @param {(Object|Array)=} destination Destination into which the source is copied. If
|
2011-04-07 19:48:14 +00:00
|
|
|
|
* provided, must be of the same type as `source`.
|
2011-08-19 00:41:57 +00:00
|
|
|
|
* @returns {*} The copy or updated `destination`, if `destination` was specified.
|
2010-11-25 01:32:04 +00:00
|
|
|
|
*
|
|
|
|
|
|
* @example
|
2011-02-01 00:21:29 +00:00
|
|
|
|
* <doc:example>
|
|
|
|
|
|
* <doc:source>
|
2011-09-08 20:56:29 +00:00
|
|
|
|
<script>
|
2011-10-07 18:27:49 +00:00
|
|
|
|
function Ctrl() {
|
2011-09-08 20:56:29 +00:00
|
|
|
|
this.master = {
|
|
|
|
|
|
salutation: 'Hello',
|
|
|
|
|
|
name: 'world'
|
|
|
|
|
|
};
|
2011-10-07 18:27:49 +00:00
|
|
|
|
this.copy = function() {
|
2011-09-08 20:56:29 +00:00
|
|
|
|
this.form = angular.copy(this.master);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
</script>
|
|
|
|
|
|
<div ng:controller="Ctrl">
|
|
|
|
|
|
Salutation: <input type="text" ng:model="master.salutation" ><br/>
|
|
|
|
|
|
Name: <input type="text" ng:model="master.name"><br/>
|
|
|
|
|
|
<button ng:click="copy()">copy</button>
|
|
|
|
|
|
<hr/>
|
|
|
|
|
|
|
|
|
|
|
|
The master object is <span ng:hide="master.$equals(form)">NOT</span> equal to the form object.
|
|
|
|
|
|
|
|
|
|
|
|
<pre>master={{master}}</pre>
|
|
|
|
|
|
<pre>form={{form}}</pre>
|
|
|
|
|
|
</div>
|
2011-02-01 00:21:29 +00:00
|
|
|
|
* </doc:source>
|
|
|
|
|
|
* <doc:scenario>
|
2011-01-18 21:50:52 +00:00
|
|
|
|
it('should print that initialy the form object is NOT equal to master', function() {
|
2011-09-08 20:56:29 +00:00
|
|
|
|
expect(element('.doc-example-live input[ng\\:model="master.salutation"]').val()).toBe('Hello');
|
|
|
|
|
|
expect(element('.doc-example-live input[ng\\:model="master.name"]').val()).toBe('world');
|
2011-03-03 17:52:35 +00:00
|
|
|
|
expect(element('.doc-example-live span').css('display')).toBe('inline');
|
2011-01-18 21:50:52 +00:00
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
it('should make form and master equal when the copy button is clicked', function() {
|
2011-03-03 17:52:35 +00:00
|
|
|
|
element('.doc-example-live button').click();
|
|
|
|
|
|
expect(element('.doc-example-live span').css('display')).toBe('none');
|
2011-01-18 21:50:52 +00:00
|
|
|
|
});
|
2011-02-01 00:21:29 +00:00
|
|
|
|
* </doc:scenario>
|
|
|
|
|
|
* </doc:example>
|
2010-09-21 16:55:09 +00:00
|
|
|
|
*/
|
2010-03-15 21:36:50 +00:00
|
|
|
|
function copy(source, destination){
|
|
|
|
|
|
if (!destination) {
|
2010-10-13 19:47:10 +00:00
|
|
|
|
destination = source;
|
2010-05-07 19:09:14 +00:00
|
|
|
|
if (source) {
|
|
|
|
|
|
if (isArray(source)) {
|
2010-10-13 19:47:10 +00:00
|
|
|
|
destination = copy(source, []);
|
2010-11-07 06:50:04 +00:00
|
|
|
|
} else if (isDate(source)) {
|
2010-10-13 19:47:10 +00:00
|
|
|
|
destination = new Date(source.getTime());
|
2010-05-07 19:09:14 +00:00
|
|
|
|
} else if (isObject(source)) {
|
2010-10-13 19:47:10 +00:00
|
|
|
|
destination = copy(source, {});
|
2010-05-07 19:09:14 +00:00
|
|
|
|
}
|
2010-03-15 21:36:50 +00:00
|
|
|
|
}
|
|
|
|
|
|
} else {
|
2010-03-26 23:27:18 +00:00
|
|
|
|
if (isArray(source)) {
|
2010-03-15 21:36:50 +00:00
|
|
|
|
while(destination.length) {
|
|
|
|
|
|
destination.pop();
|
|
|
|
|
|
}
|
2010-05-31 03:21:40 +00:00
|
|
|
|
for ( var i = 0; i < source.length; i++) {
|
|
|
|
|
|
destination.push(copy(source[i]));
|
|
|
|
|
|
}
|
2010-03-15 21:36:50 +00:00
|
|
|
|
} else {
|
2011-01-08 06:02:23 +00:00
|
|
|
|
forEach(destination, function(value, key){
|
2010-03-15 21:36:50 +00:00
|
|
|
|
delete destination[key];
|
|
|
|
|
|
});
|
2010-05-31 03:21:40 +00:00
|
|
|
|
for ( var key in source) {
|
|
|
|
|
|
destination[key] = copy(source[key]);
|
|
|
|
|
|
}
|
2010-03-15 21:36:50 +00:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2010-10-13 19:47:10 +00:00
|
|
|
|
return destination;
|
2010-04-04 00:04:36 +00:00
|
|
|
|
}
|
2010-03-15 21:36:50 +00:00
|
|
|
|
|
2011-03-23 16:33:29 +00:00
|
|
|
|
/**
|
|
|
|
|
|
* @ngdoc function
|
|
|
|
|
|
* @name angular.equals
|
|
|
|
|
|
* @function
|
|
|
|
|
|
*
|
|
|
|
|
|
* @description
|
|
|
|
|
|
* Alias for {@link angular.Object.equals}
|
|
|
|
|
|
*/
|
2010-11-25 00:55:44 +00:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @ngdoc function
|
|
|
|
|
|
* @name angular.Object.equals
|
|
|
|
|
|
* @function
|
|
|
|
|
|
*
|
|
|
|
|
|
* @description
|
2011-08-19 00:41:57 +00:00
|
|
|
|
* Determines if two objects or two values are equivalent. Supports value types, arrays and
|
|
|
|
|
|
* objects.
|
2010-11-25 00:55:44 +00:00
|
|
|
|
*
|
2011-08-19 00:41:57 +00:00
|
|
|
|
* Two objects or values are considered equivalent if at least one of the following is true:
|
2010-11-25 00:55:44 +00:00
|
|
|
|
*
|
2011-08-19 00:41:57 +00:00
|
|
|
|
* * Both objects or values pass `===` comparison.
|
|
|
|
|
|
* * Both objects or values are of the same type and all of their properties pass `===` comparison.
|
2010-11-25 00:55:44 +00:00
|
|
|
|
*
|
2011-08-19 00:41:57 +00:00
|
|
|
|
* During a property comparision, properties of `function` type and properties with names
|
|
|
|
|
|
* that begin with `$` are ignored.
|
|
|
|
|
|
*
|
|
|
|
|
|
* Note: This function is used to augment the Object type in Angular expressions. See
|
|
|
|
|
|
* {@link angular.Array} for more information about Angular arrays.
|
2010-11-25 01:21:37 +00:00
|
|
|
|
*
|
2010-11-25 00:55:44 +00:00
|
|
|
|
* @param {*} o1 Object or value to compare.
|
|
|
|
|
|
* @param {*} o2 Object or value to compare.
|
|
|
|
|
|
* @returns {boolean} True if arguments are equal.
|
|
|
|
|
|
*
|
|
|
|
|
|
* @example
|
2011-02-01 00:21:29 +00:00
|
|
|
|
* <doc:example>
|
|
|
|
|
|
* <doc:source>
|
2011-09-08 20:56:29 +00:00
|
|
|
|
<script>
|
2011-10-07 18:27:49 +00:00
|
|
|
|
function Ctrl() {
|
2011-09-08 20:56:29 +00:00
|
|
|
|
this.master = {
|
|
|
|
|
|
salutation: 'Hello',
|
|
|
|
|
|
name: 'world'
|
|
|
|
|
|
};
|
|
|
|
|
|
this.greeting = angular.copy(this.master);
|
|
|
|
|
|
}
|
|
|
|
|
|
</script>
|
|
|
|
|
|
<div ng:controller="Ctrl">
|
|
|
|
|
|
Salutation: <input type="text" ng:model="greeting.salutation"><br/>
|
|
|
|
|
|
Name: <input type="text" ng:model="greeting.name"><br/>
|
|
|
|
|
|
<hr/>
|
|
|
|
|
|
|
|
|
|
|
|
The <code>greeting</code> object is
|
|
|
|
|
|
<span ng:hide="greeting.$equals(master)">NOT</span> equal to
|
|
|
|
|
|
<code>{salutation:'Hello', name:'world'}</code>.
|
|
|
|
|
|
|
|
|
|
|
|
<pre>greeting={{greeting}}</pre>
|
|
|
|
|
|
</div>
|
2011-02-01 00:21:29 +00:00
|
|
|
|
* </doc:source>
|
|
|
|
|
|
* <doc:scenario>
|
|
|
|
|
|
it('should print that initialy greeting is equal to the hardcoded value object', function() {
|
2011-09-08 20:56:29 +00:00
|
|
|
|
expect(element('.doc-example-live input[ng\\:model="greeting.salutation"]').val()).toBe('Hello');
|
|
|
|
|
|
expect(element('.doc-example-live input[ng\\:model="greeting.name"]').val()).toBe('world');
|
2011-03-03 17:52:35 +00:00
|
|
|
|
expect(element('.doc-example-live span').css('display')).toBe('none');
|
2011-02-01 00:21:29 +00:00
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
it('should say that the objects are not equal when the form is modified', function() {
|
|
|
|
|
|
input('greeting.name').enter('kitty');
|
2011-03-03 17:52:35 +00:00
|
|
|
|
expect(element('.doc-example-live span').css('display')).toBe('inline');
|
2011-02-01 00:21:29 +00:00
|
|
|
|
});
|
|
|
|
|
|
* </doc:scenario>
|
|
|
|
|
|
* </doc:example>
|
2010-11-25 00:55:44 +00:00
|
|
|
|
*/
|
2010-07-19 19:29:24 +00:00
|
|
|
|
function equals(o1, o2) {
|
2011-03-23 16:33:29 +00:00
|
|
|
|
if (o1 === o2) return true;
|
2011-01-13 15:55:31 +00:00
|
|
|
|
if (o1 === null || o2 === null) return false;
|
2010-07-19 19:29:24 +00:00
|
|
|
|
var t1 = typeof o1, t2 = typeof o2, length, key, keySet;
|
|
|
|
|
|
if (t1 == t2 && t1 == 'object') {
|
|
|
|
|
|
if (o1 instanceof Array) {
|
|
|
|
|
|
if ((length = o1.length) == o2.length) {
|
|
|
|
|
|
for(key=0; key<length; key++) {
|
|
|
|
|
|
if (!equals(o1[key], o2[key])) return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
keySet = {};
|
|
|
|
|
|
for(key in o1) {
|
2011-08-19 00:41:57 +00:00
|
|
|
|
if (key.charAt(0) !== '$' && !isFunction(o1[key]) && !equals(o1[key], o2[key])) {
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
2010-07-19 19:29:24 +00:00
|
|
|
|
keySet[key] = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
for(key in o2) {
|
2010-10-08 23:43:40 +00:00
|
|
|
|
if (!keySet[key] && key.charAt(0) !== '$' && !isFunction(o2[key])) return false;
|
2010-07-19 19:29:24 +00:00
|
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-01-12 00:15:12 +00:00
|
|
|
|
function setHtml(node, html) {
|
2010-01-09 23:02:43 +00:00
|
|
|
|
if (isLeafNode(node)) {
|
|
|
|
|
|
if (msie) {
|
2010-01-06 00:36:58 +00:00
|
|
|
|
node.innerText = html;
|
|
|
|
|
|
} else {
|
|
|
|
|
|
node.textContent = html;
|
|
|
|
|
|
}
|
|
|
|
|
|
} else {
|
|
|
|
|
|
node.innerHTML = html;
|
|
|
|
|
|
}
|
2010-01-12 00:15:12 +00:00
|
|
|
|
}
|
2010-01-06 00:36:58 +00:00
|
|
|
|
|
Introduced injector and $new to scope, and injection into link methods and controllers
- added angular.injector(scope, services, instanceCache) which returns inject
- inject method can return, instance, or call function which have $inject
property
- initialize services with $creation=[eager|eager-publish] this means that
only some of the services are now globally accessible
- upgraded $become on scope to use injector hence respect the $inject property
for injection
- $become should not be run multiple times and will most likely be removed
in future version
- added $new on scope to create a child scope
- $inject is respected on constructor function
- simplified scopes so that they no longer have separate __proto__ for
parent, api, behavior and instance this should speed up execution since
scope will now create one __proto__ chain per scope (not three).
BACKWARD COMPATIBILITY WARNING:
- services now need to have $inject instead of inject property for proper
injection this breaks backward compatibility
- not all services are now published into root scope
(only: $location, $cookie, $window)
- if you have widget/directive which uses services on scope
(such as this.$xhr), you will now have to inject that service in
(as it is not published on the root scope anymore)
2010-10-09 00:30:13 +00:00
|
|
|
|
function concat(array1, array2, index) {
|
2011-08-02 05:15:33 +00:00
|
|
|
|
return array1.concat(slice.call(array2, index));
|
Introduced injector and $new to scope, and injection into link methods and controllers
- added angular.injector(scope, services, instanceCache) which returns inject
- inject method can return, instance, or call function which have $inject
property
- initialize services with $creation=[eager|eager-publish] this means that
only some of the services are now globally accessible
- upgraded $become on scope to use injector hence respect the $inject property
for injection
- $become should not be run multiple times and will most likely be removed
in future version
- added $new on scope to create a child scope
- $inject is respected on constructor function
- simplified scopes so that they no longer have separate __proto__ for
parent, api, behavior and instance this should speed up execution since
scope will now create one __proto__ chain per scope (not three).
BACKWARD COMPATIBILITY WARNING:
- services now need to have $inject instead of inject property for proper
injection this breaks backward compatibility
- not all services are now published into root scope
(only: $location, $cookie, $window)
- if you have widget/directive which uses services on scope
(such as this.$xhr), you will now have to inject that service in
(as it is not published on the root scope anymore)
2010-10-09 00:30:13 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2011-03-23 16:33:29 +00:00
|
|
|
|
function sliceArgs(args, startIndex) {
|
2011-08-02 05:15:33 +00:00
|
|
|
|
return slice.call(args, startIndex || 0);
|
2011-03-23 16:33:29 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2010-11-25 06:33:40 +00:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @ngdoc function
|
|
|
|
|
|
* @name angular.bind
|
|
|
|
|
|
* @function
|
|
|
|
|
|
*
|
|
|
|
|
|
* @description
|
2011-09-01 07:06:09 +00:00
|
|
|
|
* Returns a function which calls function `fn` bound to `self` (`self` becomes the `this` for
|
|
|
|
|
|
* `fn`). You can supply optional `args` that are are prebound to the function. This feature is also
|
|
|
|
|
|
* known as [function currying](http://en.wikipedia.org/wiki/Currying).
|
2010-11-25 06:33:40 +00:00
|
|
|
|
*
|
2011-02-14 18:17:04 +00:00
|
|
|
|
* @param {Object} self Context which `fn` should be evaluated in.
|
2010-11-25 06:33:40 +00:00
|
|
|
|
* @param {function()} fn Function to be bound.
|
2010-12-08 00:06:31 +00:00
|
|
|
|
* @param {...*} args Optional arguments to be prebound to the `fn` function call.
|
2010-11-25 06:33:40 +00:00
|
|
|
|
* @returns {function()} Function that wraps the `fn` with all the specified bindings.
|
|
|
|
|
|
*/
|
2010-08-11 18:44:12 +00:00
|
|
|
|
function bind(self, fn) {
|
2011-03-23 16:33:29 +00:00
|
|
|
|
var curryArgs = arguments.length > 2 ? sliceArgs(arguments, 2) : [];
|
2011-08-05 23:24:12 +00:00
|
|
|
|
if (isFunction(fn) && !(fn instanceof RegExp)) {
|
2011-03-23 16:29:20 +00:00
|
|
|
|
return curryArgs.length
|
|
|
|
|
|
? function() {
|
|
|
|
|
|
return arguments.length
|
2011-08-02 05:15:33 +00:00
|
|
|
|
? fn.apply(self, curryArgs.concat(slice.call(arguments, 0)))
|
2011-03-23 16:29:20 +00:00
|
|
|
|
: fn.apply(self, curryArgs);
|
|
|
|
|
|
}
|
|
|
|
|
|
: function() {
|
|
|
|
|
|
return arguments.length
|
|
|
|
|
|
? fn.apply(self, arguments)
|
|
|
|
|
|
: fn.call(self);
|
|
|
|
|
|
};
|
2010-07-27 23:53:23 +00:00
|
|
|
|
} else {
|
2011-09-01 07:06:09 +00:00
|
|
|
|
// in IE, native methods are not functions so they cannot be bound (note: they don't need to be)
|
2010-08-11 18:44:12 +00:00
|
|
|
|
return fn;
|
2010-07-27 23:53:23 +00:00
|
|
|
|
}
|
2010-01-12 00:15:12 +00:00
|
|
|
|
}
|
2010-01-06 00:36:58 +00:00
|
|
|
|
|
2010-01-12 00:15:12 +00:00
|
|
|
|
function toBoolean(value) {
|
2010-03-30 21:55:04 +00:00
|
|
|
|
if (value && value.length !== 0) {
|
|
|
|
|
|
var v = lowercase("" + value);
|
2010-07-19 19:29:24 +00:00
|
|
|
|
value = !(v == 'f' || v == '0' || v == 'false' || v == 'no' || v == 'n' || v == '[]');
|
2010-03-30 21:55:04 +00:00
|
|
|
|
} else {
|
2010-01-06 00:36:58 +00:00
|
|
|
|
value = false;
|
2010-03-30 21:55:04 +00:00
|
|
|
|
}
|
|
|
|
|
|
return value;
|
2010-01-12 00:15:12 +00:00
|
|
|
|
}
|
2010-01-06 00:36:58 +00:00
|
|
|
|
|
2010-11-25 03:14:34 +00:00
|
|
|
|
|
2010-04-01 00:56:16 +00:00
|
|
|
|
/////////////////////////////////////////////////
|
|
|
|
|
|
|
2010-09-27 23:00:05 +00:00
|
|
|
|
/**
|
|
|
|
|
|
* Parses an escaped url query string into key-value pairs.
|
2010-10-27 22:31:10 +00:00
|
|
|
|
* @returns Object.<(string|boolean)>
|
2010-09-27 23:00:05 +00:00
|
|
|
|
*/
|
|
|
|
|
|
function parseKeyValue(/**string*/keyValue) {
|
2010-04-01 21:10:28 +00:00
|
|
|
|
var obj = {}, key_value, key;
|
2011-01-08 06:02:23 +00:00
|
|
|
|
forEach((keyValue || "").split('&'), function(keyValue){
|
2010-04-01 21:10:28 +00:00
|
|
|
|
if (keyValue) {
|
|
|
|
|
|
key_value = keyValue.split('=');
|
2011-09-02 20:28:52 +00:00
|
|
|
|
key = decodeURIComponent(key_value[0]);
|
|
|
|
|
|
obj[key] = isDefined(key_value[1]) ? decodeURIComponent(key_value[1]) : true;
|
2010-04-01 21:10:28 +00:00
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
return obj;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2010-04-02 18:10:36 +00:00
|
|
|
|
function toKeyValue(obj) {
|
|
|
|
|
|
var parts = [];
|
2011-01-08 06:02:23 +00:00
|
|
|
|
forEach(obj, function(value, key) {
|
2011-09-02 20:28:52 +00:00
|
|
|
|
parts.push(encodeUriQuery(key, true) + (value === true ? '' : '=' + encodeUriQuery(value, true)));
|
2010-04-02 18:10:36 +00:00
|
|
|
|
});
|
|
|
|
|
|
return parts.length ? parts.join('&') : '';
|
2010-04-04 00:04:36 +00:00
|
|
|
|
}
|
2010-04-02 18:10:36 +00:00
|
|
|
|
|
2011-02-17 00:48:21 +00:00
|
|
|
|
|
|
|
|
|
|
/**
|
2011-07-30 01:42:16 +00:00
|
|
|
|
* We need our custom mehtod because encodeURIComponent is too agressive and doesn't follow
|
2011-04-01 04:45:28 +00:00
|
|
|
|
* http://www.ietf.org/rfc/rfc3986.txt with regards to the character set (pchar) allowed in path
|
|
|
|
|
|
* segments:
|
|
|
|
|
|
* segment = *pchar
|
|
|
|
|
|
* pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
|
|
|
|
|
|
* pct-encoded = "%" HEXDIG HEXDIG
|
|
|
|
|
|
* unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
|
|
|
|
|
|
* sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
|
|
|
|
|
|
* / "*" / "+" / "," / ";" / "="
|
2011-02-17 00:48:21 +00:00
|
|
|
|
*/
|
|
|
|
|
|
function encodeUriSegment(val) {
|
2011-04-01 04:45:28 +00:00
|
|
|
|
return encodeUriQuery(val, true).
|
|
|
|
|
|
replace(/%26/gi, '&').
|
|
|
|
|
|
replace(/%3D/gi, '=').
|
|
|
|
|
|
replace(/%2B/gi, '+');
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* This method is intended for encoding *key* or *value* parts of query component. We need a custom
|
|
|
|
|
|
* method becuase encodeURIComponent is too agressive and encodes stuff that doesn't have to be
|
|
|
|
|
|
* encoded per http://tools.ietf.org/html/rfc3986:
|
|
|
|
|
|
* query = *( pchar / "/" / "?" )
|
|
|
|
|
|
* pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
|
|
|
|
|
|
* unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
|
|
|
|
|
|
* pct-encoded = "%" HEXDIG HEXDIG
|
|
|
|
|
|
* sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
|
|
|
|
|
|
* / "*" / "+" / "," / ";" / "="
|
|
|
|
|
|
*/
|
|
|
|
|
|
function encodeUriQuery(val, pctEncodeSpaces) {
|
2011-02-17 00:48:21 +00:00
|
|
|
|
return encodeURIComponent(val).
|
|
|
|
|
|
replace(/%40/gi, '@').
|
|
|
|
|
|
replace(/%3A/gi, ':').
|
|
|
|
|
|
replace(/%24/g, '$').
|
2011-04-01 04:45:28 +00:00
|
|
|
|
replace(/%2C/gi, ',').
|
|
|
|
|
|
replace((pctEncodeSpaces ? null : /%20/g), '+');
|
2011-02-17 00:48:21 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2011-04-01 04:45:28 +00:00
|
|
|
|
|
2010-11-12 23:16:33 +00:00
|
|
|
|
/**
|
|
|
|
|
|
* @ngdoc directive
|
|
|
|
|
|
* @name angular.directive.ng:autobind
|
|
|
|
|
|
* @element script
|
|
|
|
|
|
*
|
2010-11-18 05:23:23 +00:00
|
|
|
|
* @TODO ng:autobind is not a directive!! it should be documented as bootstrap parameter in a
|
|
|
|
|
|
* separate bootstrap section.
|
|
|
|
|
|
* @TODO rename to ng:autobind to ng:autoboot
|
|
|
|
|
|
*
|
2010-11-12 23:16:33 +00:00
|
|
|
|
* @description
|
2011-08-19 00:41:57 +00:00
|
|
|
|
* Technically, ng:autobind is not a directive; it is an Angular bootstrap parameter that can act
|
|
|
|
|
|
* as a directive. It must exist in the script used to boot Angular and can be used only one time.
|
|
|
|
|
|
* For details on bootstrapping Angular, see {@link guide/dev_guide.bootstrap Initializing Angular}
|
|
|
|
|
|
* in the Angular Developer Guide.
|
2010-11-18 05:23:23 +00:00
|
|
|
|
*
|
2011-08-19 00:41:57 +00:00
|
|
|
|
* `ng:autobind` with no parameters tells Angular to compile and manage the whole page.
|
2011-04-08 23:03:39 +00:00
|
|
|
|
*
|
2011-08-19 00:41:57 +00:00
|
|
|
|
* `ng:autobind="[root element ID]"` tells Angular to compile and manage part of the document,
|
2011-06-06 22:00:54 +00:00
|
|
|
|
* starting at "root element ID".
|
2011-01-19 20:16:38 +00:00
|
|
|
|
*
|
2011-08-19 00:41:57 +00:00
|
|
|
|
|
2010-11-12 23:16:33 +00:00
|
|
|
|
*/
|
2011-03-10 22:26:22 +00:00
|
|
|
|
function angularInit(config, document){
|
|
|
|
|
|
var autobind = config.autobind;
|
2011-11-02 04:09:54 +00:00
|
|
|
|
|
2011-03-10 22:26:22 +00:00
|
|
|
|
if (autobind) {
|
2011-11-02 04:09:54 +00:00
|
|
|
|
var modules = [ngModule];
|
|
|
|
|
|
forEach((config.modules || '').split(','), function(module){
|
|
|
|
|
|
module = trim(module);
|
|
|
|
|
|
if (module) {
|
|
|
|
|
|
modules.push(module);
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
2011-11-02 23:32:46 +00:00
|
|
|
|
createInjector(modules, angularModule)(['$rootScope', '$compile', '$injector', function(scope, compile, injector){
|
2011-11-02 04:09:54 +00:00
|
|
|
|
scope.$apply(function(){
|
|
|
|
|
|
compile(isString(autobind) ? document.getElementById(autobind) : document)(scope);
|
|
|
|
|
|
});
|
|
|
|
|
|
}]);
|
2010-04-01 21:10:28 +00:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2010-04-07 17:17:15 +00:00
|
|
|
|
|
2011-09-08 20:56:29 +00:00
|
|
|
|
function angularJsConfig(document) {
|
2011-02-05 00:42:21 +00:00
|
|
|
|
bindJQuery();
|
2011-10-25 15:47:02 +00:00
|
|
|
|
var scripts = document.getElementsByTagName('script'),
|
|
|
|
|
|
script = scripts[scripts.length-1],
|
|
|
|
|
|
scriptSrc = script.src,
|
2011-09-08 20:56:29 +00:00
|
|
|
|
config = {},
|
2011-10-25 15:47:02 +00:00
|
|
|
|
hashPos;
|
|
|
|
|
|
|
|
|
|
|
|
hashPos = scriptSrc.indexOf('#');
|
|
|
|
|
|
if (hashPos != -1) extend(config, parseKeyValue(scriptSrc.substr(hashPos+1)));
|
|
|
|
|
|
|
|
|
|
|
|
eachAttribute(jqLite(script), function(value, name){
|
|
|
|
|
|
if (/^ng:/.exec(name)) {
|
|
|
|
|
|
name = name.substring(3).replace(/-/g, '_');
|
|
|
|
|
|
value = value || true;
|
|
|
|
|
|
config[name] = value;
|
2010-04-07 17:17:15 +00:00
|
|
|
|
}
|
2011-10-25 15:47:02 +00:00
|
|
|
|
});
|
|
|
|
|
|
|
2010-07-29 22:26:10 +00:00
|
|
|
|
return config;
|
2010-04-07 17:17:15 +00:00
|
|
|
|
}
|
2011-02-05 00:42:21 +00:00
|
|
|
|
|
2011-10-07 18:27:49 +00:00
|
|
|
|
function bindJQuery() {
|
2011-02-05 00:42:21 +00:00
|
|
|
|
// bind to jQuery if present;
|
|
|
|
|
|
jQuery = window.jQuery;
|
2011-02-07 21:28:42 +00:00
|
|
|
|
// reset to jQuery or default to us.
|
2011-02-10 19:20:49 +00:00
|
|
|
|
if (jQuery) {
|
|
|
|
|
|
jqLite = jQuery;
|
|
|
|
|
|
extend(jQuery.fn, {
|
2011-07-26 19:06:14 +00:00
|
|
|
|
scope: JQLitePrototype.scope,
|
|
|
|
|
|
inheritedData: JQLitePrototype.inheritedData
|
2011-02-12 18:12:10 +00:00
|
|
|
|
});
|
2011-07-26 19:06:14 +00:00
|
|
|
|
JQLitePatchJQueryRemove('remove', true);
|
|
|
|
|
|
JQLitePatchJQueryRemove('empty');
|
|
|
|
|
|
JQLitePatchJQueryRemove('html');
|
2011-02-07 21:28:42 +00:00
|
|
|
|
} else {
|
|
|
|
|
|
jqLite = jqLiteWrap;
|
|
|
|
|
|
}
|
|
|
|
|
|
angular.element = jqLite;
|
2011-02-05 00:42:21 +00:00
|
|
|
|
}
|
2011-02-12 18:12:10 +00:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* throw error of the argument is falsy.
|
|
|
|
|
|
*/
|
2011-02-17 00:18:35 +00:00
|
|
|
|
function assertArg(arg, name, reason) {
|
2011-02-12 18:12:10 +00:00
|
|
|
|
if (!arg) {
|
2011-02-17 00:18:35 +00:00
|
|
|
|
var error = new Error("Argument '" + (name||'?') + "' is " +
|
|
|
|
|
|
(reason || "required"));
|
2011-02-12 18:12:10 +00:00
|
|
|
|
throw error;
|
|
|
|
|
|
}
|
2011-09-08 20:56:29 +00:00
|
|
|
|
return arg;
|
2011-03-29 06:15:28 +00:00
|
|
|
|
}
|
2011-02-17 00:18:35 +00:00
|
|
|
|
|
|
|
|
|
|
function assertArgFn(arg, name) {
|
2011-09-08 20:56:29 +00:00
|
|
|
|
assertArg(isFunction(arg), name, 'not a function, got ' +
|
2011-03-23 16:33:29 +00:00
|
|
|
|
(typeof arg == 'object' ? arg.constructor.name : typeof arg));
|
2011-09-08 20:56:29 +00:00
|
|
|
|
return arg;
|
2011-03-29 06:15:28 +00:00
|
|
|
|
}
|
2011-07-12 00:31:29 +00:00
|
|
|
|
|
2011-11-01 21:27:22 +00:00
|
|
|
|
function publishExternalAPI(angular){
|
|
|
|
|
|
extend(angular, {
|
|
|
|
|
|
'copy': copy,
|
|
|
|
|
|
'extend': extend,
|
|
|
|
|
|
'equals': equals,
|
|
|
|
|
|
'forEach': forEach,
|
2011-11-02 23:32:46 +00:00
|
|
|
|
'injector': function(){ return createInjector(arguments, angularModule); },
|
2011-11-01 21:27:22 +00:00
|
|
|
|
'noop':noop,
|
|
|
|
|
|
'bind':bind,
|
|
|
|
|
|
'toJson': toJson,
|
|
|
|
|
|
'fromJson': fromJson,
|
|
|
|
|
|
'identity':identity,
|
|
|
|
|
|
'isUndefined': isUndefined,
|
|
|
|
|
|
'isDefined': isDefined,
|
|
|
|
|
|
'isString': isString,
|
|
|
|
|
|
'isFunction': isFunction,
|
|
|
|
|
|
'isObject': isObject,
|
|
|
|
|
|
'isNumber': isNumber,
|
|
|
|
|
|
'isArray': isArray,
|
|
|
|
|
|
'version': version,
|
|
|
|
|
|
'isDate': isDate,
|
|
|
|
|
|
'lowercase': lowercase,
|
|
|
|
|
|
'uppercase': uppercase
|
|
|
|
|
|
});
|
2011-11-02 04:09:54 +00:00
|
|
|
|
|
2011-11-02 23:32:46 +00:00
|
|
|
|
angularModule.NG = ngModule;
|
2011-11-02 04:09:54 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2011-11-02 23:32:46 +00:00
|
|
|
|
ngModule.$inject = ['$provide', '$injector'];
|
|
|
|
|
|
function ngModule($provide, $injector) {
|
|
|
|
|
|
// TODO(misko): temporary services to get the compiler working;
|
|
|
|
|
|
$provide.value('$textMarkup', angularTextMarkup);
|
|
|
|
|
|
$provide.value('$attrMarkup', angularAttrMarkup);
|
|
|
|
|
|
$provide.value('$directive', angularDirective);
|
|
|
|
|
|
$provide.value('$widget', angularWidget);
|
|
|
|
|
|
|
|
|
|
|
|
$provide.service('$browser', $BrowserProvider);
|
|
|
|
|
|
$provide.service('$compile', $CompileProvider);
|
|
|
|
|
|
$provide.service('$cookies', $CookiesProvider);
|
|
|
|
|
|
$provide.service('$cookieStore', $CookieStoreProvider);
|
|
|
|
|
|
$provide.service('$defer', $DeferProvider);
|
|
|
|
|
|
$provide.service('$document', $DocumentProvider);
|
|
|
|
|
|
$provide.service('$exceptionHandler', $ExceptionHandlerProvider);
|
2011-11-03 22:59:18 +00:00
|
|
|
|
$provide.service('$filter', $FilterProvider);
|
2011-11-02 23:32:46 +00:00
|
|
|
|
$provide.service('$formFactory', $FormFactoryProvider);
|
|
|
|
|
|
$provide.service('$locale', $LocaleProvider);
|
|
|
|
|
|
$provide.service('$location', $LocationProvider);
|
|
|
|
|
|
$provide.service('$locationConfig', $LocationConfigProvider);
|
|
|
|
|
|
$provide.service('$log', $LogProvider);
|
2011-11-03 20:53:37 +00:00
|
|
|
|
$provide.service('$parse', $ParseProvider);
|
2011-11-02 23:32:46 +00:00
|
|
|
|
$provide.service('$resource', $ResourceProvider);
|
|
|
|
|
|
$provide.service('$route', $RouteProvider);
|
|
|
|
|
|
$provide.service('$routeParams', $RouteParamsProvider);
|
|
|
|
|
|
$provide.service('$rootScope', $RootScopeProvider);
|
|
|
|
|
|
$provide.service('$sniffer', $SnifferProvider);
|
|
|
|
|
|
$provide.service('$window', $WindowProvider);
|
|
|
|
|
|
$provide.service('$xhr.bulk', $XhrBulkProvider);
|
|
|
|
|
|
$provide.service('$xhr.cache', $XhrCacheProvider);
|
|
|
|
|
|
$provide.service('$xhr.error', $XhrErrorProvider);
|
|
|
|
|
|
$provide.service('$xhr', $XhrProvider);
|
2011-11-01 21:27:22 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
2011-07-12 00:31:29 +00:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* @ngdoc property
|
|
|
|
|
|
* @name angular.version
|
|
|
|
|
|
* @description
|
2011-09-01 07:06:09 +00:00
|
|
|
|
* An object that contains information about the current AngularJS version. This object has the
|
|
|
|
|
|
* following properties:
|
2011-07-12 00:31:29 +00:00
|
|
|
|
*
|
2011-09-01 07:06:09 +00:00
|
|
|
|
* - `full` – `{string}` – Full version string, such as "0.9.18".
|
|
|
|
|
|
* - `major` – `{number}` – Major version number, such as "0".
|
|
|
|
|
|
* - `minor` – `{number}` – Minor version number, such as "9".
|
|
|
|
|
|
* - `dot` – `{number}` – Dot version number, such as "18".
|
|
|
|
|
|
* - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat".
|
2011-07-12 00:31:29 +00:00
|
|
|
|
*/
|
|
|
|
|
|
var version = {
|
|
|
|
|
|
full: '"NG_VERSION_FULL"', // all of these placeholder strings will be replaced by rake's
|
|
|
|
|
|
major: "NG_VERSION_MAJOR", // compile task
|
|
|
|
|
|
minor: "NG_VERSION_MINOR",
|
|
|
|
|
|
dot: "NG_VERSION_DOT",
|
|
|
|
|
|
codeName: '"NG_VERSION_CODENAME"'
|
2011-07-27 20:24:07 +00:00
|
|
|
|
};
|