-
Notifications
You must be signed in to change notification settings - Fork 27.3k
fix($compile): correctly denormalize templates that do not use standard interpolation symbols #14610
Conversation
…rd interpolation symbols In order to support third party modules that do not use the same interpolation symbols as the main app, we implemented denormalization (see dfe9983). This required that 3rd party modules always used the standad `{{` and `}}` interpolation symbols, so that we could correctly denormalise them to the current app's symbols. The problem with this became apparent when an app template using new symbols inadvertently contained one of the standard interpolation symbols. E.g. `<div data-context='{"context":{"id":3,"type":"page"}}">` The double closing curly braces were being incorrectly denormalised. This commit fixes this by allowing the compiler to be configured to know what symbols are being used in templates from a given module. Now modules can specify that what interpolation symbols they use and the compiler will denormalize appropriately. Closes angular#6493 Closes angular#6453
}); | ||
|
||
module('symbol-test', function($interpolateProvider, $compileProvider) { | ||
$interpolateProvider.startSymbol('##'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these two lines should not be there, as with them, the test makes no sense.
I see this as a feature. @petebacondarwin would it be possible to know why you think it is a fix? |
To clarify this a bit more. If I change my interpolation symbols (in my app) to
to output
But it doesn’t. See http://plnkr.co/edit/s9KVOZ9srU0JfkQYPrCf?p=preview |
Ok, but then I think that should be true in the test even without the On Saturday, May 14, 2016, Pete Bacon Darwin notifications@github.com
|
Without the changes to the interpolate provider then no denormalisation occurs so the bug doesn't occur in the same way. If we have not changed the symbols when we accept that we should escape |
Agree, but then |
Ahah! @lgalfaso so what you are saying is that we have another issue: |
implementation details a side, yes, the issue is the one stated. |
@lgalfaso here are better tests: it('should denormalise interpolation symbols in templates correctly, if different to the current symbols', function() {
angular.module('symbol-test', [])
.directive('myDirective', function() {
return {
template: '<span foo=\'{"ctx":{"id":3}}\'>[[1 + 2]]</span>'
};
});
module('symbol-test', function($compileProvider) {
$compileProvider.moduleSymbols('symbol-test', '[[', ']]');
});
inject(function($compile) {
element = $compile('<div><div my-directive></div></div>')($rootScope);
expect(element.children('div').children('span').attr('foo')).toBe('{"ctx":{"id":3}}');
expect(element.text()).toEqual('{{1 + 2}}');
$rootScope.$apply();
expect(element.text()).toEqual('3');
});
});
it('should escape the current interpolation symbols in templates, before denormalising, if the template module symbols are different', function() {
angular.module('symbol-test', [])
.directive('myDirective', function() {
return {
template: '<span>{[1 + 2]}[[3 + 4]]</span>'
};
});
module('symbol-test', function($interpolateProvider, $compileProvider) {
$interpolateProvider.startSymbol('{[');
$interpolateProvider.endSymbol(']}');
$compileProvider.moduleSymbols('symbol-test', '[[', ']]');
});
inject(function($compile) {
element = $compile('<div><div my-directive></div></div>')($rootScope);
expect(element.text()).toEqual('\\{\\[1 + 2\\]\\}{[3 + 4]}');
$rootScope.$apply();
expect(element.text()).toEqual('3');
});
}); The second one fails at the moment. |
…rd interpolation symbols In order to support third party modules that do not use the same interpolation symbols as the main app, we implemented denormalization (see dfe9983). This required that 3rd party modules always used the standad `{{` and `}}` interpolation symbols, so that we could correctly denormalise them to the current app's symbols. The problem with this became apparent when an app template using new symbols inadvertently contained one of the standard interpolation symbols. E.g. `<div data-context='{"context":{"id":3,"type":"page"}}">` The double closing curly braces were being incorrectly denormalised. This commit fixes this by allowing the compiler to be configured to know what symbols are being used in templates from a given module. Now modules can specify that what interpolation symbols they use and the compiler will denormalize appropriately. Closes angular#6493 Closes angular#6453
I added these tests and updated the code to make them pass. |
@petebacondarwin I think that the solution will have to be somehow more complex. Eg it('this works', function() {
angular.module('symbol-test', [])
.directive('myDirective', function() {
return {
template: '<span foo=\'{"ctx":{"id":3}}\'>Hi</span>'
};
});
module('symbol-test');
inject(function($compile) {
element = $compile('<div><div my-directive></div></div>')($rootScope);
$rootScope.$apply();
expect(element.find('span').attr('foo')).toEqual('{"ctx":{"id":3}}');
});
});
it('so this should work too', function() {
angular.module('symbol-test', [])
.directive('myDirective', function() {
return {
template: '<span foo=\'{"ctx":{"id":3}}\'>Hi</span>'
};
})
.config(function($compileProvider) {
$compileProvider.moduleSymbols('symbol-test', '[[', ']]');
});
module('symbol-test');
inject(function($compile) {
element = $compile('<div><div my-directive></div></div>')($rootScope);
$rootScope.$apply();
expect(element.find('span').attr('foo')).toEqual('{"ctx":{"id":3}}');
});
}); |
I just realized there is another issue with template denormalization: We are not taking |
expect(element.children('div').children('span').attr('foo')).toBe('{"ctx":{"id":3\\}\\}'); | ||
expect(element.text()).toEqual('{{1 + 2}}'); | ||
$rootScope.$apply(); | ||
expect(element.text()).toEqual('3'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about .attr('foo')
? I believe it is still escaped and I think this is not what we want...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is what @lgalfaso was referring to in his test: #14610 (comment)
:-(
Hmm looks like this could be more painful than it is worth... |
yep |
Perhaps another one for the "known issues" pile? |
More like "a couple more" 😛 |
What kind of change does this PR introduce? (Bug fix, feature, docs update, ...)
FIX
What is the current behavior? (You can also link to an open issue here)
See #6493
What is the new behavior (if this is a feature change)?
Fixed
Does this PR introduce a breaking change?
No
Please check if the PR fulfills these requirements
Other information:
** STILL NEED TO ADD DOCS **
In order to support third party modules that do not use the same interpolation
symbols as the main app, we implemented denormalization (see dfe9983).
This required that 3rd party modules always used the standad
{{
and}}
interpolation symbols, so that we could correctly denormalise them to the
current app's symbols.
The problem with this became apparent when an app template using new symbols
inadvertently contained one of the standard interpolation symbols.
E.g.
<div data-context='{"context":{"id":3,"type":"page"}}">
The double closing curly braces were being incorrectly denormalised.
This commit fixes this by allowing the compiler to be configured to know
what symbols are being used in templates from a given module.
Now modules can specify that what interpolation symbols they use and the
compiler will denormalize appropriately.
Closes #6493
Closes #6453