App-EventStreamr
view release on metacpan or search on metacpan
share/status/app/lib/angular/angular.js view on Meta::CPAN
* // return function postLink( ... ) { ... }
* },
* // or
* // link: {
* // pre: function preLink(scope, iElement, iAttrs, controller) { ... },
* // post: function postLink(scope, iElement, iAttrs, controller) { ... }
* // }
* // or
* // link: function postLink( ... ) { ... }
* };
* return directiveDefinitionObject;
* });
* </pre>
*
* <div class="alert alert-warning">
* **Note:** Any unspecified options will use the default value. You can see the default values below.
* </div>
*
* Therefore the above can be simplified as:
*
* <pre>
* var myModule = angular.module(...);
*
* myModule.directive('directiveName', function factory(injectables) {
* var directiveDefinitionObject = {
* link: function postLink(scope, iElement, iAttrs) { ... }
* };
* return directiveDefinitionObject;
* // or
* // return function postLink(scope, iElement, iAttrs) { ... }
* });
* </pre>
*
*
*
* ### Directive Definition Object
*
* The directive definition object provides instructions to the {@link api/ng.$compile
* compiler}. The attributes are:
*
* #### `priority`
* When there are multiple directives defined on a single DOM element, sometimes it
* is necessary to specify the order in which the directives are applied. The `priority` is used
* to sort the directives before their `compile` functions get called. Priority is defined as a
* number. Directives with greater numerical `priority` are compiled first. Pre-link functions
* are also run in priority order, but post-link functions are run in reverse order. The order
* of directives with the same priority is undefined. The default priority is `0`.
*
* #### `terminal`
* If set to true then the current `priority` will be the last set of directives
* which will execute (any directives at the current priority will still execute
* as the order of execution on same `priority` is undefined).
*
* #### `scope`
* **If set to `true`,** then a new scope will be created for this directive. If multiple directives on the
* same element request a new scope, only one new scope is created. The new scope rule does not
* apply for the root of the template since the root of the template always gets a new scope.
*
* **If set to `{}` (object hash),** then a new "isolate" scope is created. The 'isolate' scope differs from
* normal scope in that it does not prototypically inherit from the parent scope. This is useful
* when creating reusable components, which should not accidentally read or modify data in the
* parent scope.
*
* The 'isolate' scope takes an object hash which defines a set of local scope properties
* derived from the parent scope. These local properties are useful for aliasing values for
* templates. Locals definition is a hash of local scope property to its source:
*
* * `@` or `@attr` - bind a local scope property to the value of DOM attribute. The result is
* always a string since DOM attributes are strings. If no `attr` name is specified then the
* attribute name is assumed to be the same as the local name.
* Given `<widget my-attr="hello {{name}}">` and widget definition
* of `scope: { localName:'@myAttr' }`, then widget scope property `localName` will reflect
* the interpolated value of `hello {{name}}`. As the `name` attribute changes so will the
* `localName` property on the widget scope. The `name` is read from the parent scope (not
* component scope).
*
* * `=` or `=attr` - set up bi-directional binding between a local scope property and the
* parent scope property of name defined via the value of the `attr` attribute. If no `attr`
* name is specified then the attribute name is assumed to be the same as the local name.
* Given `<widget my-attr="parentModel">` and widget definition of
* `scope: { localModel:'=myAttr' }`, then widget scope property `localModel` will reflect the
* value of `parentModel` on the parent scope. Any changes to `parentModel` will be reflected
* in `localModel` and any changes in `localModel` will reflect in `parentModel`. If the parent
* scope property doesn't exist, it will throw a NON_ASSIGNABLE_MODEL_EXPRESSION exception. You
* can avoid this behavior using `=?` or `=?attr` in order to flag the property as optional.
*
* * `&` or `&attr` - provides a way to execute an expression in the context of the parent scope.
* If no `attr` name is specified then the attribute name is assumed to be the same as the
* local name. Given `<widget my-attr="count = count + value">` and widget definition of
* `scope: { localFn:'&myAttr' }`, then isolate scope property `localFn` will point to
* a function wrapper for the `count = count + value` expression. Often it's desirable to
* pass data from the isolated scope via an expression and to the parent scope, this can be
* done by passing a map of local variable names and values into the expression wrapper fn.
* For example, if the expression is `increment(amount)` then we can specify the amount value
* by calling the `localFn` as `localFn({amount: 22})`.
*
*
*
* #### `controller`
* Controller constructor function. The controller is instantiated before the
* pre-linking phase and it is shared with other directives (see
* `require` attribute). This allows the directives to communicate with each other and augment
* each other's behavior. The controller is injectable (and supports bracket notation) with the following locals:
*
* * `$scope` - Current scope associated with the element
* * `$element` - Current element
* * `$attrs` - Current attributes object for the element
* * `$transclude` - A transclude linking function pre-bound to the correct transclusion scope.
* The scope can be overridden by an optional first argument.
* `function([scope], cloneLinkingFn)`.
*
*
* #### `require`
* Require another directive and inject its controller as the fourth argument to the linking function. The
* `require` takes a string name (or array of strings) of the directive(s) to pass in. If an array is used, the
* injected argument will be an array in corresponding order. If no such directive can be
* found, or if the directive does not have a controller, then an error is raised. The name can be prefixed with:
*
* * (no prefix) - Locate the required controller on the current element. Throw an error if not found.
* * `?` - Attempt to locate the required controller or pass `null` to the `link` fn if not found.
* * `^` - Locate the required controller by searching the element's parents. Throw an error if not found.
share/status/app/lib/angular/angular.js view on Meta::CPAN
* @function
*
* @description
* Adds the CSS class value specified by the classVal parameter to the element. If animations
* are enabled then an animation will be triggered for the class addition.
*
* @param {string} classVal The className value that will be added to the element
*/
$addClass : function(classVal) {
if(classVal && classVal.length > 0) {
$animate.addClass(this.$$element, classVal);
}
},
/**
* @ngdoc function
* @name ng.$compile.directive.Attributes#$removeClass
* @methodOf ng.$compile.directive.Attributes
* @function
*
* @description
* Removes the CSS class value specified by the classVal parameter from the element. If
* animations are enabled then an animation will be triggered for the class removal.
*
* @param {string} classVal The className value that will be removed from the element
*/
$removeClass : function(classVal) {
if(classVal && classVal.length > 0) {
$animate.removeClass(this.$$element, classVal);
}
},
/**
* @ngdoc function
* @name ng.$compile.directive.Attributes#$updateClass
* @methodOf ng.$compile.directive.Attributes
* @function
*
* @description
* Adds and removes the appropriate CSS class values to the element based on the difference
* between the new and old CSS class values (specified as newClasses and oldClasses).
*
* @param {string} newClasses The current CSS className value
* @param {string} oldClasses The former CSS className value
*/
$updateClass : function(newClasses, oldClasses) {
this.$removeClass(tokenDifference(oldClasses, newClasses));
this.$addClass(tokenDifference(newClasses, oldClasses));
},
/**
* Set a normalized attribute on the element in a way such that all directives
* can share the attribute. This function properly handles boolean attributes.
* @param {string} key Normalized key. (ie ngAttribute)
* @param {string|boolean} value The value to set. If `null` attribute will be deleted.
* @param {boolean=} writeAttr If false, does not write the value to DOM element attribute.
* Defaults to true.
* @param {string=} attrName Optional none normalized name. Defaults to key.
*/
$set: function(key, value, writeAttr, attrName) {
// TODO: decide whether or not to throw an error if "class"
//is set through this function since it may cause $updateClass to
//become unstable.
var booleanKey = getBooleanAttrName(this.$$element[0], key),
normalizedVal,
nodeName;
if (booleanKey) {
this.$$element.prop(key, value);
attrName = booleanKey;
}
this[key] = value;
// translate normalized key to actual key
if (attrName) {
this.$attr[key] = attrName;
} else {
attrName = this.$attr[key];
if (!attrName) {
this.$attr[key] = attrName = snake_case(key, '-');
}
}
nodeName = nodeName_(this.$$element);
// sanitize a[href] and img[src] values
if ((nodeName === 'A' && key === 'href') ||
(nodeName === 'IMG' && key === 'src')) {
this[key] = value = $$sanitizeUri(value, key === 'src');
}
if (writeAttr !== false) {
if (value === null || value === undefined) {
this.$$element.removeAttr(attrName);
} else {
this.$$element.attr(attrName, value);
}
}
// fire observers
var $$observers = this.$$observers;
$$observers && forEach($$observers[key], function(fn) {
try {
fn(value);
} catch (e) {
$exceptionHandler(e);
}
});
},
/**
* @ngdoc function
* @name ng.$compile.directive.Attributes#$observe
* @methodOf ng.$compile.directive.Attributes
* @function
*
* @description
* Observes an interpolated attribute.
share/status/app/lib/angular/angular.js view on Meta::CPAN
* POST/PUT requests require request data to be provided as well, shortcut methods
* were created:
*
* <pre>
* $http.get('/someUrl').success(successCallback);
* $http.post('/someUrl', data).success(successCallback);
* </pre>
*
* Complete list of shortcut methods:
*
* - {@link ng.$http#methods_get $http.get}
* - {@link ng.$http#methods_head $http.head}
* - {@link ng.$http#methods_post $http.post}
* - {@link ng.$http#methods_put $http.put}
* - {@link ng.$http#methods_delete $http.delete}
* - {@link ng.$http#methods_jsonp $http.jsonp}
*
*
* # Setting HTTP Headers
*
* The $http service will automatically add certain HTTP headers to all requests. These defaults
* can be fully configured by accessing the `$httpProvider.defaults.headers` configuration
* object, which currently contains this default configuration:
*
* - `$httpProvider.defaults.headers.common` (headers that are common for all requests):
* - `Accept: application/json, text/plain, * / *`
* - `$httpProvider.defaults.headers.post`: (header defaults for POST requests)
* - `Content-Type: application/json`
* - `$httpProvider.defaults.headers.put` (header defaults for PUT requests)
* - `Content-Type: application/json`
*
* To add or overwrite these defaults, simply add or remove a property from these configuration
* objects. To add headers for an HTTP method other than POST or PUT, simply add a new object
* with the lowercased HTTP method name as the key, e.g.
* `$httpProvider.defaults.headers.get = { 'My-Header' : 'value' }.
*
* The defaults can also be set at runtime via the `$http.defaults` object in the same
* fashion. In addition, you can supply a `headers` property in the config object passed when
* calling `$http(config)`, which overrides the defaults without changing them globally.
*
*
* # Transforming Requests and Responses
*
* Both requests and responses can be transformed using transform functions. By default, Angular
* applies these transformations:
*
* Request transformations:
*
* - If the `data` property of the request configuration object contains an object, serialize it
* into JSON format.
*
* Response transformations:
*
* - If XSRF prefix is detected, strip it (see Security Considerations section below).
* - If JSON response is detected, deserialize it using a JSON parser.
*
* To globally augment or override the default transforms, modify the
* `$httpProvider.defaults.transformRequest` and `$httpProvider.defaults.transformResponse`
* properties. These properties are by default an array of transform functions, which allows you
* to `push` or `unshift` a new transformation function into the transformation chain. You can
* also decide to completely override any default transformations by assigning your
* transformation functions to these properties directly without the array wrapper.
*
* Similarly, to locally override the request/response transforms, augment the
* `transformRequest` and/or `transformResponse` properties of the configuration object passed
* into `$http`.
*
*
* # Caching
*
* To enable caching, set the request configuration `cache` property to `true` (to use default
* cache) or to a custom cache object (built with {@link ng.$cacheFactory `$cacheFactory`}).
* When the cache is enabled, `$http` stores the response from the server in the specified
* cache. The next time the same request is made, the response is served from the cache without
* sending a request to the server.
*
* Note that even if the response is served from cache, delivery of the data is asynchronous in
* the same way that real requests are.
*
* If there are multiple GET requests for the same URL that should be cached using the same
* cache, but the cache is not populated yet, only one request to the server will be made and
* the remaining requests will be fulfilled using the response from the first request.
*
* You can change the default cache to a new object (built with
* {@link ng.$cacheFactory `$cacheFactory`}) by updating the
* {@link ng.$http#properties_defaults `$http.defaults.cache`} property. All requests who set
* their `cache` property to `true` will now use this cache object.
*
* If you set the default cache to `false` then only requests that specify their own custom
* cache object will be cached.
*
* # Interceptors
*
* Before you start creating interceptors, be sure to understand the
* {@link ng.$q $q and deferred/promise APIs}.
*
* For purposes of global error handling, authentication, or any kind of synchronous or
* asynchronous pre-processing of request or postprocessing of responses, it is desirable to be
* able to intercept requests before they are handed to the server and
* responses before they are handed over to the application code that
* initiated these requests. The interceptors leverage the {@link ng.$q
* promise APIs} to fulfill this need for both synchronous and asynchronous pre-processing.
*
* The interceptors are service factories that are registered with the `$httpProvider` by
* adding them to the `$httpProvider.interceptors` array. The factory is called and
* injected with dependencies (if specified) and returns the interceptor.
*
* There are two kinds of interceptors (and two kinds of rejection interceptors):
*
* * `request`: interceptors get called with http `config` object. The function is free to
* modify the `config` or create a new one. The function needs to return the `config`
* directly or as a promise.
* * `requestError`: interceptor gets called when a previous interceptor threw an error or
* resolved with a rejection.
* * `response`: interceptors get called with http `response` object. The function is free to
* modify the `response` or create a new one. The function needs to return the `response`
* directly or as a promise.
* * `responseError`: interceptor gets called when a previous interceptor threw an error or
* resolved with a rejection.
*
*
share/status/app/lib/angular/angular.js view on Meta::CPAN
var hex = this.text.substring(this.index + 1, this.index + 5);
if (!hex.match(/[\da-f]{4}/i))
this.throwError('Invalid unicode escape [\\u' + hex + ']');
this.index += 4;
string += String.fromCharCode(parseInt(hex, 16));
} else {
var rep = ESCAPE[ch];
if (rep) {
string += rep;
} else {
string += ch;
}
}
escape = false;
} else if (ch === '\\') {
escape = true;
} else if (ch === quote) {
this.index++;
this.tokens.push({
index: start,
text: rawString,
string: string,
json: true,
fn: function() { return string; }
});
return;
} else {
string += ch;
}
this.index++;
}
this.throwError('Unterminated quote', start);
}
};
/**
* @constructor
*/
var Parser = function (lexer, $filter, options) {
this.lexer = lexer;
this.$filter = $filter;
this.options = options;
};
Parser.ZERO = function () { return 0; };
Parser.prototype = {
constructor: Parser,
parse: function (text, json) {
this.text = text;
//TODO(i): strip all the obsolte json stuff from this file
this.json = json;
this.tokens = this.lexer.lex(text);
if (json) {
// The extra level of aliasing is here, just in case the lexer misses something, so that
// we prevent any accidental execution in JSON.
this.assignment = this.logicalOR;
this.functionCall =
this.fieldAccess =
this.objectIndex =
this.filterChain = function() {
this.throwError('is not valid json', {text: text, index: 0});
};
}
var value = json ? this.primary() : this.statements();
if (this.tokens.length !== 0) {
this.throwError('is an unexpected token', this.tokens[0]);
}
value.literal = !!value.literal;
value.constant = !!value.constant;
return value;
},
primary: function () {
var primary;
if (this.expect('(')) {
primary = this.filterChain();
this.consume(')');
} else if (this.expect('[')) {
primary = this.arrayDeclaration();
} else if (this.expect('{')) {
primary = this.object();
} else {
var token = this.expect();
primary = token.fn;
if (!primary) {
this.throwError('not a primary expression', token);
}
if (token.json) {
primary.constant = true;
primary.literal = true;
}
}
var next, context;
while ((next = this.expect('(', '[', '.'))) {
if (next.text === '(') {
primary = this.functionCall(primary, context);
context = null;
} else if (next.text === '[') {
context = primary;
primary = this.objectIndex(primary);
} else if (next.text === '.') {
context = primary;
primary = this.fieldAccess(primary);
} else {
this.throwError('IMPOSSIBLE');
}
}
return primary;
},
share/status/app/lib/angular/angular.js view on Meta::CPAN
expect(child.salutation).toEqual('Hello');
child.salutation = "Welcome";
expect(child.salutation).toEqual('Welcome');
expect(parent.salutation).toEqual('Hello');
* </pre>
*
*
* @param {Object.<string, function()>=} providers Map of service factory which need to be
* provided for the current scope. Defaults to {@link ng}.
* @param {Object.<string, *>=} instanceCache Provides pre-instantiated services which should
* append/override services provided by `providers`. This is handy
* when unit-testing and having the need to override a default
* service.
* @returns {Object} Newly created scope.
*
*/
function Scope() {
this.$id = nextUid();
this.$$phase = this.$parent = this.$$watchers =
this.$$nextSibling = this.$$prevSibling =
this.$$childHead = this.$$childTail = null;
this['this'] = this.$root = this;
this.$$destroyed = false;
this.$$asyncQueue = [];
this.$$postDigestQueue = [];
this.$$listeners = {};
this.$$isolateBindings = {};
}
/**
* @ngdoc property
* @name ng.$rootScope.Scope#$id
* @propertyOf ng.$rootScope.Scope
* @returns {number} Unique scope ID (monotonically increasing alphanumeric sequence) useful for
* debugging.
*/
Scope.prototype = {
constructor: Scope,
/**
* @ngdoc function
* @name ng.$rootScope.Scope#$new
* @methodOf ng.$rootScope.Scope
* @function
*
* @description
* Creates a new child {@link ng.$rootScope.Scope scope}.
*
* The parent scope will propagate the {@link ng.$rootScope.Scope#methods_$digest $digest()} and
* {@link ng.$rootScope.Scope#methods_$digest $digest()} events. The scope can be removed from the
* scope hierarchy using {@link ng.$rootScope.Scope#methods_$destroy $destroy()}.
*
* {@link ng.$rootScope.Scope#methods_$destroy $destroy()} must be called on a scope when it is
* desired for the scope and its child scopes to be permanently detached from the parent and
* thus stop participating in model change detection and listener notification by invoking.
*
* @param {boolean} isolate If true, then the scope does not prototypically inherit from the
* parent scope. The scope is isolated, as it can not see parent scope properties.
* When creating widgets, it is useful for the widget to not accidentally read parent
* state.
*
* @returns {Object} The newly created child scope.
*
*/
$new: function(isolate) {
var ChildScope,
child;
if (isolate) {
child = new Scope();
child.$root = this.$root;
// ensure that there is just one async queue per $rootScope and its children
child.$$asyncQueue = this.$$asyncQueue;
child.$$postDigestQueue = this.$$postDigestQueue;
} else {
ChildScope = function() {}; // should be anonymous; This is so that when the minifier munges
// the name it does not become random set of chars. This will then show up as class
// name in the debugger.
ChildScope.prototype = this;
child = new ChildScope();
child.$id = nextUid();
}
child['this'] = child;
child.$$listeners = {};
child.$parent = this;
child.$$watchers = child.$$nextSibling = child.$$childHead = child.$$childTail = null;
child.$$prevSibling = this.$$childTail;
if (this.$$childHead) {
this.$$childTail.$$nextSibling = child;
this.$$childTail = child;
} else {
this.$$childHead = this.$$childTail = child;
}
return child;
},
/**
* @ngdoc function
* @name ng.$rootScope.Scope#$watch
* @methodOf ng.$rootScope.Scope
* @function
*
* @description
* Registers a `listener` callback to be executed whenever the `watchExpression` changes.
*
* - The `watchExpression` is called on every call to {@link ng.$rootScope.Scope#methods_$digest
* $digest()} and should return the value that will be watched. (Since
* {@link ng.$rootScope.Scope#methods_$digest $digest()} reruns when it detects changes the
* `watchExpression` can execute multiple times per
* {@link ng.$rootScope.Scope#methods_$digest $digest()} and should be idempotent.)
* - The `listener` is called only when the value from the current `watchExpression` and the
* previous call to `watchExpression` are not equal (with the exception of the initial run,
* see below). The inequality is determined according to
* {@link angular.equals} function. To save the value of the object for later comparison,
* the {@link angular.copy} function is used. It also means that watching complex options
* will have adverse memory and performance implications.
* - The watch `listener` may change the model, which may trigger other `listener`s to fire.
* This is achieved by rerunning the watchers until no changes are detected. The rerun
* iteration limit is 10 to prevent an infinite loop deadlock.
share/status/app/lib/angular/angular.js view on Meta::CPAN
/**
* @ngdoc object
* @name ng.$sceProvider
* @description
*
* The $sceProvider provider allows developers to configure the {@link ng.$sce $sce} service.
* - enable/disable Strict Contextual Escaping (SCE) in a module
* - override the default implementation with a custom delegate
*
* Read more about {@link ng.$sce Strict Contextual Escaping (SCE)}.
*/
/* jshint maxlen: false*/
/**
* @ngdoc service
* @name ng.$sce
* @function
*
* @description
*
* `$sce` is a service that provides Strict Contextual Escaping services to AngularJS.
*
* # Strict Contextual Escaping
*
* Strict Contextual Escaping (SCE) is a mode in which AngularJS requires bindings in certain
* contexts to result in a value that is marked as safe to use for that context. One example of
* such a context is binding arbitrary html controlled by the user via `ng-bind-html`. We refer
* to these contexts as privileged or SCE contexts.
*
* As of version 1.2, Angular ships with SCE enabled by default.
*
* Note: When enabled (the default), IE8 in quirks mode is not supported. In this mode, IE8 allows
* one to execute arbitrary javascript by the use of the expression() syntax. Refer
* <http://blogs.msdn.com/b/ie/archive/2008/10/16/ending-expressions.aspx> to learn more about them.
* You can ensure your document is in standards mode and not quirks mode by adding `<!doctype html>`
* to the top of your HTML document.
*
* SCE assists in writing code in way that (a) is secure by default and (b) makes auditing for
* security vulnerabilities such as XSS, clickjacking, etc. a lot easier.
*
* Here's an example of a binding in a privileged context:
*
* <pre class="prettyprint">
* <input ng-model="userHtml">
* <div ng-bind-html="userHtml">
* </pre>
*
* Notice that `ng-bind-html` is bound to `userHtml` controlled by the user. With SCE
* disabled, this application allows the user to render arbitrary HTML into the DIV.
* In a more realistic example, one may be rendering user comments, blog articles, etc. via
* bindings. (HTML is just one example of a context where rendering user controlled input creates
* security vulnerabilities.)
*
* For the case of HTML, you might use a library, either on the client side, or on the server side,
* to sanitize unsafe HTML before binding to the value and rendering it in the document.
*
* How would you ensure that every place that used these types of bindings was bound to a value that
* was sanitized by your library (or returned as safe for rendering by your server?) How can you
* ensure that you didn't accidentally delete the line that sanitized the value, or renamed some
* properties/fields and forgot to update the binding to the sanitized value?
*
* To be secure by default, you want to ensure that any such bindings are disallowed unless you can
* determine that something explicitly says it's safe to use a value for binding in that
* context. You can then audit your code (a simple grep would do) to ensure that this is only done
* for those values that you can easily tell are safe - because they were received from your server,
* sanitized by your library, etc. You can organize your codebase to help with this - perhaps
* allowing only the files in a specific directory to do this. Ensuring that the internal API
* exposed by that code doesn't markup arbitrary values as safe then becomes a more manageable task.
*
* In the case of AngularJS' SCE service, one uses {@link ng.$sce#methods_trustAs $sce.trustAs}
* (and shorthand methods such as {@link ng.$sce#methods_trustAsHtml $sce.trustAsHtml}, etc.) to
* obtain values that will be accepted by SCE / privileged contexts.
*
*
* ## How does it work?
*
* In privileged contexts, directives and code will bind to the result of {@link ng.$sce#methods_getTrusted
* $sce.getTrusted(context, value)} rather than to the value directly. Directives use {@link
* ng.$sce#methods_parse $sce.parseAs} rather than `$parse` to watch attribute bindings, which performs the
* {@link ng.$sce#methods_getTrusted $sce.getTrusted} behind the scenes on non-constant literals.
*
* As an example, {@link ng.directive:ngBindHtml ngBindHtml} uses {@link
* ng.$sce#methods_parseAsHtml $sce.parseAsHtml(binding expression)}. Here's the actual code (slightly
* simplified):
*
* <pre class="prettyprint">
* var ngBindHtmlDirective = ['$sce', function($sce) {
* return function(scope, element, attr) {
* scope.$watch($sce.parseAsHtml(attr.ngBindHtml), function(value) {
* element.html(value || '');
* });
* };
* }];
* </pre>
*
* ## Impact on loading templates
*
* This applies both to the {@link ng.directive:ngInclude `ng-include`} directive as well as
* `templateUrl`'s specified by {@link guide/directive directives}.
*
* By default, Angular only loads templates from the same domain and protocol as the application
* document. This is done by calling {@link ng.$sce#methods_getTrustedResourceUrl
* $sce.getTrustedResourceUrl} on the template URL. To load templates from other domains and/or
* protocols, you may either either {@link ng.$sceDelegateProvider#methods_resourceUrlWhitelist whitelist
* them} or {@link ng.$sce#methods_trustAsResourceUrl wrap it} into a trusted value.
*
* *Please note*:
* The browser's
* {@link https://code.google.com/p/browsersec/wiki/Part2#Same-origin_policy_for_XMLHttpRequest
* Same Origin Policy} and {@link http://www.w3.org/TR/cors/ Cross-Origin Resource Sharing (CORS)}
* policy apply in addition to this and may further restrict whether the template is successfully
* loaded. This means that without the right CORS policy, loading templates from a different domain
* won't work on all browsers. Also, loading templates from `file://` URL does not work on some
* browsers.
*
* ## This feels like too much overhead for the developer?
*
* It's important to remember that SCE only applies to interpolation expressions.
*
* If your expressions are constant literals, they're automatically trusted and you don't need to
* call `$sce.trustAs` on them. (e.g.
* `<div ng-html-bind-unsafe="'<b>implicitly trusted</b>'"></div>`) just works.
*
* Additionally, `a[href]` and `img[src]` automatically sanitize their URLs and do not pass them
* through {@link ng.$sce#methods_getTrusted $sce.getTrusted}. SCE doesn't play a role here.
*
* The included {@link ng.$sceDelegate $sceDelegate} comes with sane defaults to allow you to load
* templates in `ng-include` from your application's domain without having to even know about SCE.
* It blocks loading templates from other domains or loading templates over http from an https
* served document. You can change these by setting your own custom {@link
* ng.$sceDelegateProvider#methods_resourceUrlWhitelist whitelists} and {@link
* ng.$sceDelegateProvider#methods_resourceUrlBlacklist blacklists} for matching such URLs.
*
* This significantly reduces the overhead. It is far easier to pay the small overhead and have an
* application that's secure and can be audited to verify that with much more ease than bolting
* security onto an application later.
*
* <a name="contexts"></a>
* ## What trusted context types are supported?
*
* | Context | Notes |
* |---------------------|----------------|
* | `$sce.HTML` | For HTML that's safe to source into the application. The {@link ng.directive:ngBindHtml ngBindHtml} directive uses this context for bindings. |
* | `$sce.CSS` | For CSS that's safe to source into the application. Currently unused. Feel free to use it in your own directives. |
* | `$sce.URL` | For URLs that are safe to follow as links. Currently unused (`<a href=` and `<img src=` sanitize their urls and don't consititute an SCE context. |
* | `$sce.RESOURCE_URL` | For URLs that are not only safe to follow as links, but whose contens are also safe to include in your application. Examples include `ng-include`, `src` / `ngSrc` bindings for tags other than `IMG` (e.g. `IFRAME`, `OBJECT`...
* | `$sce.JS` | For JavaScript that is safe to execute in your application's context. Currently unused. Feel free to use it in your own directives. |
*
* ## Format of items in {@link ng.$sceDelegateProvider#methods_resourceUrlWhitelist resourceUrlWhitelist}/{@link ng.$sceDelegateProvider#methods_resourceUrlBlacklist Blacklist} <a name="resourceUrlPatternItem"></a>
*
* Each element in these arrays must be one of the following:
*
* - **'self'**
* - The special **string**, `'self'`, can be used to match against all URLs of the **same
* domain** as the application document using the **same protocol**.
* - **String** (except the special value `'self'`)
* - The string is matched against the full *normalized / absolute URL* of the resource
* being tested (substring matches are not good enough.)
* - There are exactly **two wildcard sequences** - `*` and `**`. All other characters
* match themselves.
* - `*`: matches zero or more occurances of any character other than one of the following 6
* characters: '`:`', '`/`', '`.`', '`?`', '`&`' and ';'. It's a useful wildcard for use
* in a whitelist.
* - `**`: matches zero or more occurances of *any* character. As such, it's not
* not appropriate to use in for a scheme, domain, etc. as it would match too much. (e.g.
* http://**.example.com/ would match http://evil.com/?ignore=.example.com/ and that might
* not have been the intention.) It's usage at the very end of the path is ok. (e.g.
* http://foo.example.com/templates/**).
* - **RegExp** (*see caveat below*)
* - *Caveat*: While regular expressions are powerful and offer great flexibility, their syntax
* (and all the inevitable escaping) makes them *harder to maintain*. It's easy to
* accidentally introduce a bug when one updates a complex expression (imho, all regexes should
* have good test coverage.). For instance, the use of `.` in the regex is correct only in a
* small number of cases. A `.` character in the regex used when matching the scheme or a
* subdomain could be matched against a `:` or literal `.` that was likely not intended. It
* is highly recommended to use the string patterns and only fall back to regular expressions
* if they as a last resort.
* - The regular expression must be an instance of RegExp (i.e. not a string.) It is
* matched against the **entire** *normalized / absolute URL* of the resource being tested
* (even when the RegExp did not have the `^` and `$` codes.) In addition, any flags
* present on the RegExp (such as multiline, global, ignoreCase) are ignored.
* - If you are generating your Javascript from some other templating engine (not
* recommended, e.g. in issue [#4006](https://github.com/angular/angular.js/issues/4006)),
* remember to escape your regular expression (and be aware that you might need more than
* one level of escaping depending on your templating engine and the way you interpolated
* the value.) Do make use of your platform's escaping mechanism as it might be good
* enough before coding your own. e.g. Ruby has
* [Regexp.escape(str)](http://www.ruby-doc.org/core-2.0.0/Regexp.html#method-c-escape)
* and Python has [re.escape](http://docs.python.org/library/re.html#re.escape).
* Javascript lacks a similar built in function for escaping. Take a look at Google
* Closure library's [goog.string.regExpEscape(s)](
* http://docs.closure-library.googlecode.com/git/closure_goog_string_string.js.source.html#line962).
*
* Refer {@link ng.$sceDelegateProvider $sceDelegateProvider} for an example.
*
* ## Show me an example using SCE.
*
* @example
<example module="mySceApp">
<file name="index.html">
<div ng-controller="myAppController as myCtrl">
<i ng-bind-html="myCtrl.explicitlyTrustedHtml" id="explicitlyTrustedHtml"></i><br><br>
<b>User comments</b><br>
By default, HTML that isn't explicitly trusted (e.g. Alice's comment) is sanitized when
$sanitize is available. If $sanitize isn't available, this results in an error instead of an
exploit.
<div class="well">
<div ng-repeat="userComment in myCtrl.userComments">
<b>{{userComment.name}}</b>:
<span ng-bind-html="userComment.htmlComment" class="htmlComment"></span>
<br>
</div>
</div>
</div>
</file>
<file name="script.js">
var mySceApp = angular.module('mySceApp', ['ngSanitize']);
mySceApp.controller("myAppController", function myAppController($http, $templateCache, $sce) {
var self = this;
$http.get("test_data.json", {cache: $templateCache}).success(function(userComments) {
self.userComments = userComments;
});
self.explicitlyTrustedHtml = $sce.trustAsHtml(
'<span onmouseover="this.textContent="Explicitly trusted HTML bypasses ' +
'sanitization."">Hover over this text.</span>');
});
</file>
<file name="test_data.json">
[
share/status/app/lib/angular/angular.js view on Meta::CPAN
* {@link http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html
* plural categories} in Angular's default en-US locale: "one" and "other".
*
* While a plural category may match many numbers (for example, in en-US locale, "other" can match
* any number that is not 1), an explicit number rule can only match one number. For example, the
* explicit number rule for "3" matches the number 3. There are examples of plural categories
* and explicit number rules throughout the rest of this documentation.
*
* # Configuring ngPluralize
* You configure ngPluralize by providing 2 attributes: `count` and `when`.
* You can also provide an optional attribute, `offset`.
*
* The value of the `count` attribute can be either a string or an {@link guide/expression
* Angular expression}; these are evaluated on the current scope for its bound value.
*
* The `when` attribute specifies the mappings between plural categories and the actual
* string to be displayed. The value of the attribute should be a JSON object.
*
* The following example shows how to configure ngPluralize:
*
* <pre>
* <ng-pluralize count="personCount"
when="{'0': 'Nobody is viewing.',
* 'one': '1 person is viewing.',
* 'other': '{} people are viewing.'}">
* </ng-pluralize>
*</pre>
*
* In the example, `"0: Nobody is viewing."` is an explicit number rule. If you did not
* specify this rule, 0 would be matched to the "other" category and "0 people are viewing"
* would be shown instead of "Nobody is viewing". You can specify an explicit number rule for
* other numbers, for example 12, so that instead of showing "12 people are viewing", you can
* show "a dozen people are viewing".
*
* You can use a set of closed braces (`{}`) as a placeholder for the number that you want substituted
* into pluralized strings. In the previous example, Angular will replace `{}` with
* <span ng-non-bindable>`{{personCount}}`</span>. The closed braces `{}` is a placeholder
* for <span ng-non-bindable>{{numberExpression}}</span>.
*
* # Configuring ngPluralize with offset
* The `offset` attribute allows further customization of pluralized text, which can result in
* a better user experience. For example, instead of the message "4 people are viewing this document",
* you might display "John, Kate and 2 others are viewing this document".
* The offset attribute allows you to offset a number by any desired value.
* Let's take a look at an example:
*
* <pre>
* <ng-pluralize count="personCount" offset=2
* when="{'0': 'Nobody is viewing.',
* '1': '{{person1}} is viewing.',
* '2': '{{person1}} and {{person2}} are viewing.',
* 'one': '{{person1}}, {{person2}} and one other person are viewing.',
* 'other': '{{person1}}, {{person2}} and {} other people are viewing.'}">
* </ng-pluralize>
* </pre>
*
* Notice that we are still using two plural categories(one, other), but we added
* three explicit number rules 0, 1 and 2.
* When one person, perhaps John, views the document, "John is viewing" will be shown.
* When three people view the document, no explicit number rule is found, so
* an offset of 2 is taken off 3, and Angular uses 1 to decide the plural category.
* In this case, plural category 'one' is matched and "John, Marry and one other person are viewing"
* is shown.
*
* Note that when you specify offsets, you must provide explicit number rules for
* numbers from 0 up to and including the offset. If you use an offset of 3, for example,
* you must provide explicit number rules for 0, 1, 2 and 3. You must also provide plural strings for
* plural categories "one" and "other".
*
* @param {string|expression} count The variable to be bounded to.
* @param {string} when The mapping between plural category to its corresponding strings.
* @param {number=} offset Offset to deduct from the total number.
*
* @example
<doc:example>
<doc:source>
<script>
function Ctrl($scope) {
$scope.person1 = 'Igor';
$scope.person2 = 'Misko';
$scope.personCount = 1;
}
</script>
<div ng-controller="Ctrl">
Person 1:<input type="text" ng-model="person1" value="Igor" /><br/>
Person 2:<input type="text" ng-model="person2" value="Misko" /><br/>
Number of People:<input type="text" ng-model="personCount" value="1" /><br/>
<!--- Example with simple pluralization rules for en locale --->
Without Offset:
<ng-pluralize count="personCount"
when="{'0': 'Nobody is viewing.',
'one': '1 person is viewing.',
'other': '{} people are viewing.'}">
</ng-pluralize><br>
<!--- Example with offset --->
With Offset(2):
<ng-pluralize count="personCount" offset=2
when="{'0': 'Nobody is viewing.',
'1': '{{person1}} is viewing.',
'2': '{{person1}} and {{person2}} are viewing.',
'one': '{{person1}}, {{person2}} and one other person are viewing.',
'other': '{{person1}}, {{person2}} and {} other people are viewing.'}">
</ng-pluralize>
</div>
</doc:source>
<doc:scenario>
it('should show correct pluralized string', function() {
expect(element('.doc-example-live ng-pluralize:first').text()).
toBe('1 person is viewing.');
expect(element('.doc-example-live ng-pluralize:last').text()).
toBe('Igor is viewing.');
using('.doc-example-live').input('personCount').enter('0');
expect(element('.doc-example-live ng-pluralize:first').text()).
toBe('Nobody is viewing.');
expect(element('.doc-example-live ng-pluralize:last').text()).
toBe('Nobody is viewing.');
using('.doc-example-live').input('personCount').enter('2');
( run in 3.555 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )