* @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)
| 8758 | * |
| 8759 | */ |
| 8760 | function $interpolate(text, mustHaveExpression, trustedContext) { |
| 8761 | var startIndex, |
| 8762 | endIndex, |
| 8763 | index = 0, |
| 8764 | parts = [], |
| 8765 | length = text.length, |
| 8766 | hasInterpolation = false, |
| 8767 | fn, |
| 8768 | exp, |
| 8769 | concat = []; |
| 8770 | |
| 8771 | while(index < length) { |
| 8772 | if ( ((startIndex = text.indexOf(startSymbol, index)) != -1) && |
| 8773 | ((endIndex = text.indexOf(endSymbol, startIndex + startSymbolLength)) != -1) ) { |
| 8774 | (index != startIndex) && parts.push(text.substring(index, startIndex)); |
| 8775 | parts.push(fn = $parse(exp = text.substring(startIndex + startSymbolLength, endIndex))); |
| 8776 | fn.exp = exp; |
| 8777 | index = endIndex + endSymbolLength; |
| 8778 | hasInterpolation = true; |
| 8779 | } else { |
| 8780 | // we did not find anything, so we have to add the remainder to the parts array |
| 8781 | (index != length) && parts.push(text.substring(index)); |
| 8782 | index = length; |
| 8783 | } |
| 8784 | } |
| 8785 | |
| 8786 | if (!(length = parts.length)) { |
| 8787 | // we added, nothing, must have been an empty string. |
| 8788 | parts.push(''); |
| 8789 | length = 1; |
| 8790 | } |
| 8791 | |
| 8792 | // Concatenating expressions makes it hard to reason about whether some combination of |
| 8793 | // concatenated values are unsafe to use and could easily lead to XSS. By requiring that a |
| 8794 | // single expression be used for iframe[src], object[src], etc., we ensure that the value |
| 8795 | // that's used is assigned or constructed by some JS code somewhere that is more testable or |
| 8796 | // make it obvious that you bound the value to some user controlled value. This helps reduce |
| 8797 | // the load when auditing for XSS issues. |
| 8798 | if (trustedContext && parts.length > 1) { |
| 8799 | throw $interpolateMinErr('noconcat', |
| 8800 | "Error while interpolating: {0}\nStrict Contextual Escaping disallows " + |
| 8801 | "interpolations that concatenate multiple expressions when a trusted value is " + |
| 8802 | "required. See http://docs.angularjs.org/api/ng.$sce", text); |
| 8803 | } |
| 8804 | |
| 8805 | if (!mustHaveExpression || hasInterpolation) { |
| 8806 | concat.length = length; |
| 8807 | fn = function(context) { |
| 8808 | try { |
| 8809 | for(var i = 0, ii = length, part; i<ii; i++) { |
| 8810 | if (typeof (part = parts[i]) == 'function') { |
| 8811 | part = part(context); |
| 8812 | if (trustedContext) { |
| 8813 | part = $sce.getTrusted(trustedContext, part); |
| 8814 | } else { |
| 8815 | part = $sce.valueOf(part); |
| 8816 | } |
| 8817 | if (part == null) { // null || undefined |
no test coverage detected