* @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 ng.$compile $compile service fo
(text, mustHaveExpression, trustedContext, allOrNothing)
| 10026 | * - `context`: evaluation context for all expressions embedded in the interpolated text |
| 10027 | */ |
| 10028 | function $interpolate(text, mustHaveExpression, trustedContext, allOrNothing) { |
| 10029 | allOrNothing = !!allOrNothing; |
| 10030 | var startIndex, |
| 10031 | endIndex, |
| 10032 | index = 0, |
| 10033 | expressions = [], |
| 10034 | parseFns = [], |
| 10035 | textLength = text.length, |
| 10036 | exp, |
| 10037 | concat = [], |
| 10038 | expressionPositions = []; |
| 10039 | |
| 10040 | while (index < textLength) { |
| 10041 | if (((startIndex = text.indexOf(startSymbol, index)) != -1) && |
| 10042 | ((endIndex = text.indexOf(endSymbol, startIndex + startSymbolLength)) != -1)) { |
| 10043 | if (index !== startIndex) { |
| 10044 | concat.push(unescapeText(text.substring(index, startIndex))); |
| 10045 | } |
| 10046 | exp = text.substring(startIndex + startSymbolLength, endIndex); |
| 10047 | expressions.push(exp); |
| 10048 | parseFns.push($parse(exp, parseStringifyInterceptor)); |
| 10049 | index = endIndex + endSymbolLength; |
| 10050 | expressionPositions.push(concat.length); |
| 10051 | concat.push(''); |
| 10052 | } else { |
| 10053 | // we did not find an interpolation, so we have to add the remainder to the separators array |
| 10054 | if (index !== textLength) { |
| 10055 | concat.push(unescapeText(text.substring(index))); |
| 10056 | } |
| 10057 | break; |
| 10058 | } |
| 10059 | } |
| 10060 | |
| 10061 | // Concatenating expressions makes it hard to reason about whether some combination of |
| 10062 | // concatenated values are unsafe to use and could easily lead to XSS. By requiring that a |
| 10063 | // single expression be used for iframe[src], object[src], etc., we ensure that the value |
| 10064 | // that's used is assigned or constructed by some JS code somewhere that is more testable or |
| 10065 | // make it obvious that you bound the value to some user controlled value. This helps reduce |
| 10066 | // the load when auditing for XSS issues. |
| 10067 | if (trustedContext && concat.length > 1) { |
| 10068 | throw $interpolateMinErr('noconcat', |
| 10069 | "Error while interpolating: {0}\nStrict Contextual Escaping disallows " + |
| 10070 | "interpolations that concatenate multiple expressions when a trusted value is " + |
| 10071 | "required. See http://docs.angularjs.org/api/ng.$sce", text); |
| 10072 | } |
| 10073 | |
| 10074 | if (!mustHaveExpression || expressions.length) { |
| 10075 | var compute = function(values) { |
| 10076 | for (var i = 0, ii = expressions.length; i < ii; i++) { |
| 10077 | if (allOrNothing && isUndefined(values[i])) return; |
| 10078 | concat[expressionPositions[i]] = values[i]; |
| 10079 | } |
| 10080 | return concat.join(''); |
| 10081 | }; |
| 10082 | |
| 10083 | var getValue = function(value) { |
| 10084 | return trustedContext ? |
| 10085 | $sce.getTrusted(trustedContext, value) : |
no test coverage detected