diff options
| author | Misko Hevery | 2011-11-17 12:49:15 -0800 |
|---|---|---|
| committer | Igor Minar | 2011-11-30 14:49:36 -0500 |
| commit | 0e1fa2aefe34fe9ba5c957efde9ae4a82df54e11 (patch) | |
| tree | 88463996139a1f8433802e49c35d6b649fafb7f4 | |
| parent | 3d0ce0ebe9ce26f54ce0527ece7a7950bc2e8368 (diff) | |
| download | angular.js-0e1fa2aefe34fe9ba5c957efde9ae4a82df54e11.tar.bz2 | |
feat($interpolate): string interpolation function
| -rw-r--r-- | angularFiles.js | 1 | ||||
| -rw-r--r-- | src/AngularPublic.js | 1 | ||||
| -rw-r--r-- | src/directives.js | 39 | ||||
| -rw-r--r-- | src/markups.js | 28 | ||||
| -rw-r--r-- | src/service/interpolate.js | 82 | ||||
| -rw-r--r-- | test/service/interpolateSpec.js | 21 |
6 files changed, 105 insertions, 67 deletions
diff --git a/angularFiles.js b/angularFiles.js index 4f7da92b..0f0b4509 100644 --- a/angularFiles.js +++ b/angularFiles.js @@ -24,6 +24,7 @@ angularFiles = { 'src/service/filter/limitTo.js', 'src/service/filter/orderBy.js', 'src/service/formFactory.js', + 'src/service/interpolate.js', 'src/service/location.js', 'src/service/log.js', 'src/service/resource.js', diff --git a/src/AngularPublic.js b/src/AngularPublic.js index 7839ea63..e5c70a8b 100644 --- a/src/AngularPublic.js +++ b/src/AngularPublic.js @@ -76,6 +76,7 @@ function ngModule($provide, $injector) { $provide.service('$document', $DocumentProvider); $provide.service('$exceptionHandler', $ExceptionHandlerProvider); $provide.service('$filter', $FilterProvider); + $provide.service('$interpolate', $InterpolateProvider); $provide.service('$formFactory', $FormFactoryProvider); $provide.service('$http', $HttpProvider); $provide.service('$httpBackend', $HttpBackendProvider); diff --git a/src/directives.js b/src/directives.js index 41fbac16..ea09fc06 100644 --- a/src/directives.js +++ b/src/directives.js @@ -282,45 +282,6 @@ angularDirective("ng:bind", function(expression, element){ }]; }); -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; - - // 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 directive diff --git a/src/markups.js b/src/markups.js index b7761857..f6f2143a 100644 --- a/src/markups.js +++ b/src/markups.js @@ -51,34 +51,6 @@ * Understanding Angular Markup} in the Angular Developer Guide. */ -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; - - index = string.indexOf('}}', index); - index = index < 0 ? string.length : index + 2; - - 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; -} - -function binding(string) { - var binding = string.replace(/\n/gm, ' ').match(/^\{\{(.*)\}\}$/); - return binding ? binding[1] : null; -} - -function hasBindings(bindings) { - return bindings.length > 1 || binding(bindings[0]) !== null; -} angularTextMarkup('{{}}', function(text, textNode, parentElement) { var bindings = parseBindings(text), diff --git a/src/service/interpolate.js b/src/service/interpolate.js new file mode 100644 index 00000000..03692824 --- /dev/null +++ b/src/service/interpolate.js @@ -0,0 +1,82 @@ +'use strict'; + +function $InterpolateProvider(){ + this.$get = ['$parse', function($parse){ + return function(text, templateOnly) { + var bindings = parseBindings(text); + if (hasBindings(bindings) || !templateOnly) { + return compileBindTemplate(text); + } + }; + }]; +} + +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; + + // 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; +} + + +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; + + index = string.indexOf('}}', index); + index = index < 0 ? string.length : index + 2; + + 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; +} + +function binding(string) { + var binding = string.replace(/\n/gm, ' ').match(/^\{\{(.*)\}\}$/); + return binding ? binding[1] : null; +} + +function hasBindings(bindings) { + return bindings.length > 1 || binding(bindings[0]) !== null; +} diff --git a/test/service/interpolateSpec.js b/test/service/interpolateSpec.js new file mode 100644 index 00000000..8644ee0a --- /dev/null +++ b/test/service/interpolateSpec.js @@ -0,0 +1,21 @@ +'use strict'; + +describe('$interpolate', function() { + + it('should return a function when there are no bindings and textOnly is undefined', + inject(function($interpolate) { + expect(typeof $interpolate('some text')).toBe('function'); + })); + + + it('should return undefined when there are no bindings and textOnly is set to true', + inject(function($interpolate) { + expect($interpolate('some text', true)).toBeUndefined(); + })); + + + it('should return interpolation function', inject(function($interpolate, $rootScope) { + $rootScope.name = 'Misko'; + expect($interpolate('Hello {{name}}!')($rootScope)).toEqual('Hello Misko!'); + })); +}); |
