mirror of
https://github.com/Hopiu/angular.js.git
synced 2026-03-20 16:30:26 +00:00
242 lines
7.9 KiB
JavaScript
242 lines
7.9 KiB
JavaScript
'use strict';
|
|
|
|
var $interpolateMinErr = minErr('$interpolate');
|
|
|
|
/**
|
|
* @ngdoc object
|
|
* @name ng.$interpolateProvider
|
|
* @function
|
|
*
|
|
* @description
|
|
*
|
|
* Used for configuring the interpolation markup. Defaults to `{{` and `}}`.
|
|
*
|
|
* @example
|
|
<doc:example module="customInterpolationApp">
|
|
<doc:source>
|
|
<script>
|
|
var customInterpolationApp = angular.module('customInterpolationApp', []);
|
|
|
|
customInterpolationApp.config(function($interpolateProvider) {
|
|
$interpolateProvider.startSymbol('//');
|
|
$interpolateProvider.endSymbol('//');
|
|
});
|
|
|
|
|
|
customInterpolationApp.controller('DemoController', function DemoController() {
|
|
this.label = "This binding is brought you by // interpolation symbols.";
|
|
});
|
|
</script>
|
|
<div ng-app="App" ng-controller="DemoController as demo">
|
|
//demo.label//
|
|
</div>
|
|
</doc:source>
|
|
<doc:scenario>
|
|
it('should interpolate binding with custom symbols', function() {
|
|
expect(binding('demo.label')).toBe('This binding is brought you by // interpolation symbols.');
|
|
});
|
|
</doc:scenario>
|
|
</doc:example>
|
|
*/
|
|
function $InterpolateProvider() {
|
|
var startSymbol = '{{';
|
|
var endSymbol = '}}';
|
|
|
|
/**
|
|
* @ngdoc method
|
|
* @name ng.$interpolateProvider#startSymbol
|
|
* @methodOf ng.$interpolateProvider
|
|
* @description
|
|
* Symbol to denote start of expression in the interpolated string. Defaults to `{{`.
|
|
*
|
|
* @param {string=} value new value to set the starting symbol to.
|
|
* @returns {string|self} Returns the symbol when used as getter and self if used as setter.
|
|
*/
|
|
this.startSymbol = function(value){
|
|
if (value) {
|
|
startSymbol = value;
|
|
return this;
|
|
} else {
|
|
return startSymbol;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* @ngdoc method
|
|
* @name ng.$interpolateProvider#endSymbol
|
|
* @methodOf ng.$interpolateProvider
|
|
* @description
|
|
* Symbol to denote the end of expression in the interpolated string. Defaults to `}}`.
|
|
*
|
|
* @param {string=} value new value to set the ending symbol to.
|
|
* @returns {string|self} Returns the symbol when used as getter and self if used as setter.
|
|
*/
|
|
this.endSymbol = function(value){
|
|
if (value) {
|
|
endSymbol = value;
|
|
return this;
|
|
} else {
|
|
return endSymbol;
|
|
}
|
|
};
|
|
|
|
|
|
this.$get = ['$parse', '$exceptionHandler', '$sce', function($parse, $exceptionHandler, $sce) {
|
|
var startSymbolLength = startSymbol.length,
|
|
endSymbolLength = endSymbol.length;
|
|
|
|
/**
|
|
* @ngdoc function
|
|
* @name ng.$interpolate
|
|
* @function
|
|
*
|
|
* @requires $parse
|
|
* @requires $sce
|
|
*
|
|
* @description
|
|
*
|
|
* Compiles a string with markup into an interpolation function. This service is used by the
|
|
* HTML {@link ng.$compile $compile} service for data binding. See
|
|
* {@link ng.$interpolateProvider $interpolateProvider} for configuring the
|
|
* interpolation markup.
|
|
*
|
|
*
|
|
<pre>
|
|
var $interpolate = ...; // injected
|
|
var exp = $interpolate('Hello {{name | uppercase}}!');
|
|
expect(exp({name:'Angular'}).toEqual('Hello ANGULAR!');
|
|
</pre>
|
|
*
|
|
*
|
|
* @param {string} text The text with markup to interpolate.
|
|
* @param {boolean=} mustHaveExpression if set to true then the interpolation string must have
|
|
* embedded expression in order to return an interpolation function. Strings with no
|
|
* embedded expression will return null for the interpolation function.
|
|
* @param {string=} trustedContext when provided, the returned function passes the interpolated
|
|
* result through {@link ng.$sce#methods_getTrusted $sce.getTrusted(interpolatedResult,
|
|
* trustedContext)} before returning it. Refer to the {@link ng.$sce $sce} service that
|
|
* provides Strict Contextual Escaping for details.
|
|
* @returns {function(context)} an interpolation function which is used to compute the
|
|
* interpolated string. The function has these parameters:
|
|
*
|
|
* * `context`: an object against which any expressions embedded in the strings are evaluated
|
|
* against.
|
|
*
|
|
*/
|
|
function $interpolate(text, mustHaveExpression, trustedContext) {
|
|
var startIndex,
|
|
endIndex,
|
|
index = 0,
|
|
parts = [],
|
|
length = text.length,
|
|
hasInterpolation = false,
|
|
fn,
|
|
exp,
|
|
concat = [];
|
|
|
|
while(index < length) {
|
|
if ( ((startIndex = text.indexOf(startSymbol, index)) != -1) &&
|
|
((endIndex = text.indexOf(endSymbol, startIndex + startSymbolLength)) != -1) ) {
|
|
(index != startIndex) && parts.push(text.substring(index, startIndex));
|
|
parts.push(fn = $parse(exp = text.substring(startIndex + startSymbolLength, endIndex)));
|
|
fn.exp = exp;
|
|
index = endIndex + endSymbolLength;
|
|
hasInterpolation = true;
|
|
} else {
|
|
// we did not find anything, so we have to add the remainder to the parts array
|
|
(index != length) && parts.push(text.substring(index));
|
|
index = length;
|
|
}
|
|
}
|
|
|
|
if (!(length = parts.length)) {
|
|
// we added, nothing, must have been an empty string.
|
|
parts.push('');
|
|
length = 1;
|
|
}
|
|
|
|
// Concatenating expressions makes it hard to reason about whether some combination of
|
|
// concatenated values are unsafe to use and could easily lead to XSS. By requiring that a
|
|
// single expression be used for iframe[src], object[src], etc., we ensure that the value
|
|
// that's used is assigned or constructed by some JS code somewhere that is more testable or
|
|
// make it obvious that you bound the value to some user controlled value. This helps reduce
|
|
// the load when auditing for XSS issues.
|
|
if (trustedContext && parts.length > 1) {
|
|
throw $interpolateMinErr('noconcat',
|
|
"Error while interpolating: {0}\nStrict Contextual Escaping disallows " +
|
|
"interpolations that concatenate multiple expressions when a trusted value is " +
|
|
"required. See http://docs.angularjs.org/api/ng.$sce", text);
|
|
}
|
|
|
|
if (!mustHaveExpression || hasInterpolation) {
|
|
concat.length = length;
|
|
fn = function(context) {
|
|
try {
|
|
for(var i = 0, ii = length, part; i<ii; i++) {
|
|
if (typeof (part = parts[i]) == 'function') {
|
|
part = part(context);
|
|
if (trustedContext) {
|
|
part = $sce.getTrusted(trustedContext, part);
|
|
} else {
|
|
part = $sce.valueOf(part);
|
|
}
|
|
if (part === null || isUndefined(part)) {
|
|
part = '';
|
|
} else if (typeof part != 'string') {
|
|
part = toJson(part);
|
|
}
|
|
}
|
|
concat[i] = part;
|
|
}
|
|
return concat.join('');
|
|
}
|
|
catch(err) {
|
|
var newErr = $interpolateMinErr('interr', "Can't interpolate: {0}\n{1}", text,
|
|
err.toString());
|
|
$exceptionHandler(newErr);
|
|
}
|
|
};
|
|
fn.exp = text;
|
|
fn.parts = parts;
|
|
return fn;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* @ngdoc method
|
|
* @name ng.$interpolate#startSymbol
|
|
* @methodOf ng.$interpolate
|
|
* @description
|
|
* Symbol to denote the start of expression in the interpolated string. Defaults to `{{`.
|
|
*
|
|
* Use {@link ng.$interpolateProvider#startSymbol $interpolateProvider#startSymbol} to change
|
|
* the symbol.
|
|
*
|
|
* @returns {string} start symbol.
|
|
*/
|
|
$interpolate.startSymbol = function() {
|
|
return startSymbol;
|
|
};
|
|
|
|
|
|
/**
|
|
* @ngdoc method
|
|
* @name ng.$interpolate#endSymbol
|
|
* @methodOf ng.$interpolate
|
|
* @description
|
|
* Symbol to denote the end of expression in the interpolated string. Defaults to `}}`.
|
|
*
|
|
* Use {@link ng.$interpolateProvider#endSymbol $interpolateProvider#endSymbol} to change
|
|
* the symbol.
|
|
*
|
|
* @returns {string} start symbol.
|
|
*/
|
|
$interpolate.endSymbol = function() {
|
|
return endSymbol;
|
|
};
|
|
|
|
return $interpolate;
|
|
}];
|
|
}
|
|
|