Created
July 8, 2014 22:42
-
-
Save sudodoki/506630db640a87b5433f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function minErr(module) { | |
return function () { | |
var code = arguments[0], | |
prefix = '[' + (module ? module + ':' : '') + code + '] ', | |
template = arguments[1], | |
templateArgs = arguments, | |
stringify = function (obj) { | |
if (typeof obj === 'function') { | |
return obj.toString().replace(/ \{[\s\S]*$/, ''); | |
} else if (typeof obj === 'undefined') { | |
return 'undefined'; | |
} else if (typeof obj !== 'string') { | |
return JSON.stringify(obj); | |
} | |
return obj; | |
}, | |
message, i; | |
message = prefix + template.replace(/\{\d+\}/g, function (match) { | |
var index = +match.slice(1, -1), arg; | |
if (index + 2 < templateArgs.length) { | |
arg = templateArgs[index + 2]; | |
if (typeof arg === 'function') { | |
return arg.toString().replace(/ ?\{[\s\S]*$/, ''); | |
} else if (typeof arg === 'undefined') { | |
return 'undefined'; | |
} else if (typeof arg !== 'string') { | |
return toJson(arg); | |
} | |
return arg; | |
} | |
return match; | |
}); | |
message = message + '\nhttp://errors.angularjs.org/1.2.17/' + | |
(module ? module + '/' : '') + code; | |
for (i = 2; i < arguments.length; i++) { | |
message = message + (i == 2 ? '?' : '&') + 'p' + (i-2) + '=' + | |
encodeURIComponent(stringify(arguments[i])); | |
} | |
return new Error(message); | |
}; | |
} | |
var $interpolateMinErr = minErr('$interpolate'); | |
function $InterpolateProvider() { | |
var startSymbol = '{{'; | |
var endSymbol = '}}'; | |
/** | |
* @ngdoc method | |
* @name $interpolateProvider#startSymbol | |
* @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 $interpolateProvider#endSymbol | |
* @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 service | |
* @name $interpolate | |
* @kind 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. | |
* | |
* | |
* ```js | |
* var $interpolate = ...; // injected | |
* var exp = $interpolate('Hello {{name | uppercase}}!'); | |
* expect(exp({name:'Angular'}).toEqual('Hello ANGULAR!'); | |
* ``` | |
* | |
* | |
* @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#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') { | |
var oldPart = part; | |
part = part(context); | |
if (part === undefined) { | |
console.log('part.ext === ', part, oldPart.exp, context) | |
var newErr = $interpolateMinErr('undinterr', "Interpolation of {0} on scope {1} returned undefined\n", oldPart.exp, context.$id); | |
$exceptionHandler(newErr); | |
} | |
if (trustedContext) { | |
part = $sce.getTrusted(trustedContext, part); | |
} else { | |
part = $sce.valueOf(part); | |
} | |
if (part == null) { // null || undefined | |
part = ''; | |
} else { | |
switch (typeof part) { | |
case 'string': | |
{ | |
break; | |
} | |
case 'number': | |
{ | |
part = '' + part; | |
break; | |
} | |
default: | |
{ | |
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 $interpolate#startSymbol | |
* @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 $interpolate#endSymbol | |
* @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} end symbol. | |
*/ | |
$interpolate.endSymbol = function() { | |
return endSymbol; | |
}; | |
return $interpolate; | |
}]; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment