diff options
Diffstat (limited to 'src/service')
| -rw-r--r-- | src/service/interpolate.js | 205 |
1 files changed, 134 insertions, 71 deletions
diff --git a/src/service/interpolate.js b/src/service/interpolate.js index 03692824..6d3ae868 100644 --- a/src/service/interpolate.js +++ b/src/service/interpolate.js @@ -1,82 +1,145 @@ 'use strict'; -function $InterpolateProvider(){ - this.$get = ['$parse', function($parse){ - return function(text, templateOnly) { - var bindings = parseBindings(text); - if (hasBindings(bindings) || !templateOnly) { - return compileBindTemplate(text); - } - }; - }]; -} +/** + * @ngdoc function + * @name angular.module.ng.$interpolateProvider + * @function + * + * @description + * + * Used for configuring the interpolation markup. Deafults to `{{` and `}}`. + */ +function $InterpolateProvider() { + var startSymbol = '{{'; + var endSymbol = '}}'; -var bindTemplateCache = {}; -function compileBindTemplate(template){ - var fn = bindTemplateCache[template]; - if (!fn) { - var bindings = []; - forEach(parseBindings(template), function(text){ - var exp = binding(text); - bindings.push(exp - ? function(scope, element) { return scope.$eval(exp); } - : function() { return text; }); - }); - bindTemplateCache[template] = fn = function(scope, element, prettyPrintJson) { - var parts = [], - hadOwnElement = scope.hasOwnProperty('$element'), - oldElement = scope.$element; + /** + * @ngdoc method + * @name angular.module.ng.$interpolateProvider#startSymbol + * @methodOf angular.module.ng.$interpolateProvider + * @description + * Symbol to denote start of expression in the interpolated string. Defaults to `{{`. + * + * @prop {string=} value new value to set the starting symbol to. + */ + this.startSymbol = function(value){ + if (value) { + startSymbol = value; + return this; + } else { + return startSymbol; + } + }; - // TODO(misko): get rid of $element - scope.$element = element; - try { - for (var i = 0; i < bindings.length; i++) { - var value = bindings[i](scope, element); - if (isElement(value)) - value = ''; - else if (isObject(value)) - value = toJson(value, prettyPrintJson); - parts.push(value); - } - return parts.join(''); - } finally { - if (hadOwnElement) { - scope.$element = oldElement; - } else { - delete scope.$element; - } - } - }; - } - return fn; -} + /** + * @ngdoc method + * @name angular.module.ng.$interpolateProvider#endSymbol + * @methodOf angular.module.ng.$interpolateProvider + * @description + * Symbol to denote the end of expression in the interpolated string. Defaults to `}}`. + * + * @prop {string=} value new value to set the ending symbol to. + */ + this.endSymbol = function(value){ + if (value) { + endSymbol = value; + return this; + } else { + return startSymbol; + } + }; -function parseBindings(string) { - var results = []; - var lastIndex = 0; - var index; - while((index = string.indexOf('{{', lastIndex)) > -1) { - if (lastIndex < index) - results.push(string.substr(lastIndex, index - lastIndex)); - lastIndex = index; + this.$get = ['$parse', function($parse) { + var startSymbolLength = startSymbol.length, + endSymbolLength = endSymbol.length; - index = string.indexOf('}}', index); - index = index < 0 ? string.length : index + 2; + /** + * @ngdoc function + * @name angular.module.ng.$interpolate + * @function + * + * @requires $parse + * + * @description + * + * Compiles a string with markup into an interpolation function. This service is used by the + * HTML {@link angular.module.ng.$compile $compile} service for data binding. See + * {@link angular.module.ng.$interpolateProvider $interpolateProvider} for configuring the + * interpolation markup. + * + * + <pre> + var $interpolate = ...; // injected + var exp = $interpolate('Hello {{name}}!'); + 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. + * @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. + * + */ + return function(text, mustHaveExpression) { + var startIndex, + endIndex, + index = 0, + parts = [], + length = text.length, + hasInterpolation = false, + fn, + exp, + concat = []; - results.push(string.substr(lastIndex, index - lastIndex)); - lastIndex = index; - } - if (lastIndex != string.length) - results.push(string.substr(lastIndex, string.length - lastIndex)); - return results.length === 0 ? [ string ] : results; -} + 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; + } + } -function binding(string) { - var binding = string.replace(/\n/gm, ' ').match(/^\{\{(.*)\}\}$/); - return binding ? binding[1] : null; -} + if (!(length = parts.length)) { + // we added, nothing, must have been an empty string. + parts.push(''); + length = 1; + } -function hasBindings(bindings) { - return bindings.length > 1 || binding(bindings[0]) !== null; + if (!mustHaveExpression || hasInterpolation) { + concat.length = length; + fn = function(context) { + for(var i = 0, ii = length, part; i<ii; i++) { + if (typeof (part = parts[i]) == 'function') { + part = part(context); + if (part == null || part == undefined) { + part = ''; + } else if (typeof part != 'string') { + part = toJson(part); + } + } + concat[i] = part; + } + return concat.join(''); + }; + fn.exp = text; + fn.parts = parts; + return fn; + } + }; + }]; } + |
