/** * @ngdoc overview * @name angular * @namespace Namespace for angular. * @description * Hello world! * * @example */ //////////////////////////////////// if (typeof document.getAttribute == $undefined) document.getAttribute = function() {}; /** * @ngdoc * @name angular.lowercase * @function * * @description Converts string to lowercase * @param {string} value * @returns {string} Lowercased string. */ var lowercase = function (value){ return isString(value) ? value.toLowerCase() : value; }; /** * @ngdoc * @name angular.uppercase * @function * * @description Converts string to uppercase. * @param {string} value * @returns {string} Uppercased string. */ var uppercase = function (value){ return isString(value) ? value.toUpperCase() : value; }; var manualLowercase = function (s) { return isString(s) ? s.replace(/[A-Z]/g, function (ch) {return fromCharCode(ch.charCodeAt(0) | 32); }) : s; }; var manualUppercase = function (s) { return isString(s) ? s.replace(/[a-z]/g, function (ch) {return fromCharCode(ch.charCodeAt(0) & ~32); }) : s; }; // String#toLowerCase and String#toUpperCase don't produce correct results in browsers with Turkish // locale, for this reason we need to detect this case and redefine lowercase/uppercase methods with // correct but slower alternatives. if ('i' !== 'I'.toLowerCase()) { lowercase = manualLowercase; uppercase = manualUppercase; } function fromCharCode(code) { return String.fromCharCode(code); } var _undefined = undefined, _null = null, $$element = '$element', $angular = 'angular', $array = 'array', $boolean = 'boolean', $console = 'console', $date = 'date', $display = 'display', $element = 'element', $function = 'function', $length = 'length', $name = 'name', $none = 'none', $noop = 'noop', $null = 'null', $number = 'number', $object = 'object', $string = 'string', $undefined = 'undefined', NG_EXCEPTION = 'ng-exception', NG_VALIDATION_ERROR = 'ng-validation-error', NOOP = 'noop', PRIORITY_FIRST = -99999, PRIORITY_WATCH = -1000, PRIORITY_LAST = 99999, PRIORITY = {'FIRST': PRIORITY_FIRST, 'LAST': PRIORITY_LAST, 'WATCH':PRIORITY_WATCH}, jQuery = window['jQuery'] || window['$'], // weirdness to make IE happy _ = window['_'], /** holds major version number for IE or NaN for real browsers */ msie = parseInt((/msie (\d+)/.exec(lowercase(navigator.userAgent)) || [])[1], 10), jqLite = jQuery || jqLiteWrap, slice = Array.prototype.slice, push = Array.prototype.push, error = window[$console] ? bind(window[$console], window[$console]['error'] || noop) : noop, /** * @name angular * @namespace The exported angular namespace. */ angular = window[$angular] || (window[$angular] = {}), angularTextMarkup = extensionMap(angular, 'markup'), angularAttrMarkup = extensionMap(angular, 'attrMarkup'), /** * @ngdoc overview * @name angular.directive * @namespace Namespace for all directives. * @description * A directive is an XML attribute that you can use in an existing HTML * element type or in a DOM element type that you create using * `angular.widget`, to modify that element's properties. You can use * any number of directives per element. * * For example, you can add the ng:bind directive as an attribute of an * HTML span element, as in ``. * How does this work? The compiler passes the attribute value `1+2` * to the ng:bind extension, which in turn tells the Scope to watch * that expression and report changes. On any change it sets the span * text to the expression value. * * Here's how to define ng:bind: *
angular.directive('ng:bind', function(expression, compiledElement) {
var compiler = this;
return function(linkElement) {
var currentScope = this;
currentScope.$watch(expression, function(value) {
linkElement.text(value);
});
};
});
*
*
* ## Directive vs. Attribute Widget
* Both attribute widgets and directives can compile a DOM element
* attribute. So why have two different ways to do the same thing?
* The answer is that order matters, but you have no control over
* the order in which attributes are read. To solve this we
* apply attribute widget before the directive.
*
* For example, consider this piece of HTML, which uses the
* directives `ng:repeat`, `ng:init`, and `ng:bind`:
*
* <my:watch exp="name"/>
*
*
* You can implement `my:watch` like this:
*
* angular.widget('my:watch', function(compileElement) {
* var compiler = this;
* var exp = compileElement.attr('exp');
* return function(linkElement) {
* var currentScope = this;
* currentScope.$watch(exp, function(value){
* alert(value);
* }};
* };
* });
*
*
* # Attribute Widget
* Let's implement the same widget, but this time as an attribute
* that can be added to any existing DOM element.
*
* <div my-watch="name">text</div>
*
* You can implement `my:watch` attribute like this:
*
* angular.widget('@my:watch', function(expression, compileElement) {
* var compiler = this;
* return function(linkElement) {
* var currentScope = this;
* currentScope.$watch(expression, function(value){
* alert(value);
* });
* };
* });
*
*
* @example
*
*
* function reverse(text) {
* var reversed = [];
* for (var i = 0; i < text.length; i++) {
* reversed.unshift(text.charAt(i));
* }
* return reversed.join('');
* }
*
* angular.formatter('reverse', {
* parse: function(value){
* return reverse(value||'').toUpperCase();
* },
* format: function(value){
* return reverse(value||'').toLowerCase();
* }
* });
*
*
* @example
*
*
* Formatted:
*
* {{data}}
*
*
* @scenario
* it('should store reverse', function(){
* expect(element('.doc-example input:first').val()).toEqual('angular');
* expect(element('.doc-example input:last').val()).toEqual('RALUGNA');
*
* this.addFutureAction('change to XYZ', function($window, $document, done){
* $document.elements('.doc-example input:last').val('XYZ').trigger('change');
* done();
* });
* expect(element('.doc-example input:first').val()).toEqual('zyx');
* });
*/
angularFormatter = extensionMap(angular, 'formatter'),
/**
* @ngdoc overview
* @name angular.service
*
* @description
* # Overview
* Services are substituable objects, which are wired together using dependency injection.
* Each service could have dependencies (other services), which are passed in constructor.
* Because JS is dynamicaly typed language, dependency injection can not use static types
* to satisfy these dependencies, so each service must explicitely define its dependencies.
* This is done by $inject property.
*
* For now, life time of all services is the same as the life time of page.
*
*
* # Standard services
* The Angular framework provides a standard set of services for common operations.
* You can write your own services and rewrite these standard services as well.
* Like other core angular variables, standard services always start with $.
*
* * `angular.service.$window`
* * `angular.service.$document`
* * `angular.service.$location`
* * `angular.service.$log`
* * `angular.service.$exceptionHandler`
* * `angular.service.$hover`
* * `angular.service.$invalidWidgets`
* * `angular.service.$route`
* * `angular.service.$xhr`
* * `angular.service.$xhr.error`
* * `angular.service.$xhr.bulk`
* * `angular.service.$xhr.cache`
* * `angular.service.$resource`
* * `angular.service.$cookies`
* * `angular.service.$cookieStore`
*
* # Writing your own services
*
* angular.service('notify', function(location) {
* this.one = function() {
* }
* }, {$inject: ['$location']});
*
*
* # Using services in controller
*/
angularService = extensionMap(angular, 'service'),
angularCallbacks = extensionMap(angular, 'callbacks'),
nodeName,
rngScript = /^(|.*\/)angular(-.*?)?(\.min)?.js(\?[^#]*)?(#(.*))?$/;
function foreach(obj, iterator, context) {
var key;
if (obj) {
if (isFunction(obj)){
for (key in obj) {
if (key != 'prototype' && key != $length && key != $name && obj.hasOwnProperty(key)) {
iterator.call(context, obj[key], key);
}
}
} else if (obj.forEach) {
obj.forEach(iterator, context);
} else if (isObject(obj) && isNumber(obj.length)) {
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;
}
function foreachSorted(obj, iterator, context) {
var keys = [];
for (var key in obj) keys.push(key);
keys.sort();
for ( var i = 0; i < keys.length; i++) {
iterator.call(context, obj[keys[i]], keys[i]);
}
return keys;
}
function extend(dst) {
foreach(arguments, function(obj){
if (obj !== dst) {
foreach(obj, function(value, key){
dst[key] = value;
});
}
});
return dst;
}
function inherit(parent, extra) {
return extend(new (extend(function(){}, {prototype:parent}))(), extra);
}
function noop() {}
function identity($) {return $;}
function valueFn(value) {return function(){ return value; };}
function extensionMap(angular, name, transform) {
var extPoint;
return angular[name] || (extPoint = angular[name] = function (name, fn, prop){
name = (transform || identity)(name);
if (isDefined(fn)) {
if (isDefined(extPoint[name])) {
foreach(extPoint[name], function(property, key) {
if (key.charAt(0) == '$' && isUndefined(fn[key]))
fn[key] = property;
});
}
extPoint[name] = extend(fn, prop || {});
}
return extPoint[name];
});
}
function jqLiteWrap(element) {
// for some reasons the parentNode of an orphan looks like _null but its typeof is object.
if (element) {
if (isString(element)) {
var div = document.createElement('div');
div.innerHTML = element;
element = new JQLite(div.childNodes);
} else if (!(element instanceof JQLite) && isElement(element)) {
element = new JQLite(element);
}
}
return element;
}
function isUndefined(value){ return typeof value == $undefined; }
function isDefined(value){ return typeof value != $undefined; }
function isObject(value){ return value!=_null && typeof value == $object;}
function isString(value){ return typeof value == $string;}
function isNumber(value){ return typeof value == $number;}
function isDate(value){ return value instanceof Date; }
function isArray(value) { return value instanceof Array; }
function isFunction(value){ return typeof value == $function;}
function isBoolean(value) { return typeof value == $boolean;}
function isTextNode(node) { return nodeName(node) == '#text'; }
function trim(value) { return isString(value) ? value.replace(/^\s*/, '').replace(/\s*$/, '') : value; }
function isElement(node) {
return node && (node.nodeName || node instanceof JQLite || (jQuery && node instanceof jQuery));
}
/**
* HTML class which is the only class which can be used in ng:bind to inline HTML for security reasons.
* @constructor
* @param html raw (unsafe) html
* @param {string=} option if set to 'usafe' then get method will return raw (unsafe/unsanitized) html
*/
function HTML(html, option) {
this.html = html;
this.get = lowercase(option) == 'unsafe' ?
valueFn(html) :
function htmlSanitize() {
var buf = [];
htmlParser(html, htmlSanitizeWriter(buf));
return buf.join('');
};
}
if (msie) {
nodeName = function(element) {
element = element.nodeName ? element : element[0];
return (element.scopeName && element.scopeName != 'HTML' ) ? uppercase(element.scopeName + ':' + element.nodeName) : element.nodeName;
};
} else {
nodeName = function(element) {
return element.nodeName ? element.nodeName : element[0].nodeName;
};
}
function quickClone(element) {
return jqLite(element[0].cloneNode(true));
}
function isVisible(element) {
var rect = element[0].getBoundingClientRect(),
width = (rect.width || (rect.right||0 - rect.left||0)),
height = (rect.height || (rect.bottom||0 - rect.top||0));
return width>0 && height>0;
}
function map(obj, iterator, context) {
var results = [];
foreach(obj, function(value, index, list) {
results.push(iterator.call(context, value, index, list));
});
return results;
}
function size(obj) {
var size = 0;
if (obj) {
if (isNumber(obj.length)) {
return obj.length;
} else if (isObject(obj)){
for (key in obj)
size++;
}
}
return size;
}
function includes(array, obj) {
for ( var i = 0; i < array.length; i++) {
if (obj === array[i]) return true;
}
return false;
}
function indexOf(array, obj) {
for ( var i = 0; i < array.length; i++) {
if (obj === array[i]) return i;
}
return -1;
}
function isLeafNode (node) {
if (node) {
switch (node.nodeName) {
case "OPTION":
case "PRE":
case "TITLE":
return true;
}
}
return false;
}
/**
* Copies stuff.
*
* If destination is not provided and source is an object or an array, a copy is created & returned,
* otherwise the source is returned.
*
* If destination is provided, all of its properties will be deleted and if source is an object or
* an array, all of its members will be copied into the destination object. Finally the destination
* is returned just for kicks.
*
* @param {*} source The source to be used during copy.
* Can be any type including primitives, null and undefined.
* @param {(Object|Array)=} destination Optional destination into which the source is copied
* @returns {*}
*/
function copy(source, destination){
if (!destination) {
destination = source;
if (source) {
if (isArray(source)) {
destination = copy(source, []);
} else if (isDate(source)) {
destination = new Date(source.getTime());
} else if (isObject(source)) {
destination = copy(source, {});
}
}
} else {
if (isArray(source)) {
while(destination.length) {
destination.pop();
}
for ( var i = 0; i < source.length; i++) {
destination.push(copy(source[i]));
}
} else {
foreach(destination, function(value, key){
delete destination[key];
});
for ( var key in source) {
destination[key] = copy(source[key]);
}
}
}
return destination;
}
function equals(o1, o2) {
if (o1 == o2) return true;
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
<!doctype html>
<html xmlns:ng="http://angularjs.org">
<head>
<script type="text/javascript" ng:autobind
src="http://code.angularjs.org/angular-0.9.3.min.js"></script>
</head>
<body>
Hello {{'world'}}!
</body>
</html>
*
*
* The `ng:autobind` attribute tells
<!doctype html>
<html xmlns:ng="http://angularjs.org">
<head>
<script type="text/javascript" ng:autobind
src="http://code.angularjs.org/angular-0.9.3.min.js"></script>
<script type="text/javascript">
(function(window, previousOnLoad){
window.onload = function(){
try { (previousOnLoad||angular.noop)(); } catch(e) {}
angular.compile(window.document).$init();
};
})(window, window.onload);
</script>
</head>
<body>
Hello {{'World'}}!
</body>
</html>
*
*
* This is the sequence that your code should follow if you're writing
* your own manual binding code:
*
* * After the page is loaded, find the root of the HTML template,
* which is typically the root of the document.
* * Run the HTML compiler, which converts the templates into an
* executable, bi-directionally bound application.
*
* #XML Namespace
* *IMPORTANT:* When using * <html xmlns:ng="http://angularjs.org"> ** * # Create your own namespace * If you want to define your own widgets, you must create your own * namespace and use that namespace to form the fully qualified * widget name. For example, you could map the alias `my` to your * domain and create a widget called my:widget. To create your own * namespace, simply add another xmlsn tag to your page, create an * alias, and set it to your unique domain: * *
* <html xmlns:ng="http://angularjs.org" xmlns:my="http://mydomain.com"> ** * # Global Object * The