diff --git a/src/language-html/utils.js b/src/language-html/utils.js
index ed3fe227e..724dd2495 100644
--- a/src/language-html/utils.js
+++ b/src/language-html/utils.js
@@ -137,6 +137,14 @@ function isLeadingSpaceSensitiveNode(node) {
return false;
}
+ if (
+ (node.type === "text" || node.type === "interpolation") &&
+ node.prev &&
+ (node.prev.type === "text" || node.prev.type === "interpolation")
+ ) {
+ return true;
+ }
+
if (!node.parent || node.parent.cssDisplay === "none") {
return false;
}
@@ -177,6 +185,14 @@ function isTrailingSpaceSensitiveNode(node) {
return false;
}
+ if (
+ (node.type === "text" || node.type === "interpolation") &&
+ node.next &&
+ (node.next.type === "text" || node.next.type === "interpolation")
+ ) {
+ return true;
+ }
+
if (!node.parent || node.parent.cssDisplay === "none") {
return false;
}
diff --git a/tests/html_angular/__snapshots__/jsfmt.spec.js.snap b/tests/html_angular/__snapshots__/jsfmt.spec.js.snap
index 40ea17733..01880bc25 100644
--- a/tests/html_angular/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/html_angular/__snapshots__/jsfmt.spec.js.snap
@@ -816,6 +816,195 @@ exports[`attributes.component.html - angular-verify 3`] = `
`;
+exports[`attributes.component.html - angular-verify 4`] = `
+
{{
@@ -1533,6 +1797,158 @@ exports[`interpolation.component.html - angular-verify 3`] = `
}}
+
+ {{
+ aNormalValue
+ | aPipe
+ }}:
+ {{
+ aReallyReallySuperLongValue
+ | andASuperLongPipeJustToBreakThis
+ }}
+
+
+`;
+
+exports[`interpolation.component.html - angular-verify 4`] = `
+
{{ a | b : c }}
+
{{ 0 - 1 }}
+
{{ - 1 }}
+
{{ a ? 1 : 2 }}
+
{{ a ( 1 ) ( 2 ) }}
+
{{ a [ b ] }}
+
{{ [ 1 ] }}
+
{{ { 'a' : 1 } }}
+
{{ { a : 1 } }}
+
{{ true }}
+
{{ undefined }}
+
{{ null }}
+
{{ ( 1 ) }}
+
{{ 1 }}
+
{{ 'hello' }}
+
{{ a ( 1 , 2 ) }}
+
{{ a . b ( 1 , 2 ) }}
+
{{ x ! }}
+
{{ ! x }}
+
{{ ( ( a ) ) }}
+
{{ a }}
+
{{ a // hello }}
+
{{ a . b }}
+
{{ a ?. b ( ) }}
+
{{ a ?. b }}
+
{{ a // hello }}
+
{{
+"SearchSelection.transmissionLayoutRadioButton" | localize:localizationSection
+}}
+
{{
+"SearchSelection.transmissionLayoutRadioButton" | localize:localizationSection
+}}
+
{{
+"SearchSelection.transmissionLayoutRadioButton" | localize:localizationSection
+}}
+
{{
+"SearchSelection.transmissionLayoutRadioButton" | localize:localizationSection
+}}
+
{{
+"SearchSelection.transmissionLayoutRadioButton" | localize:localizationSection
+}}
+
{{copyTypes[options.copyType]}}
+{{listRow.NextScheduledSendStatus == 1 || listRow.NextScheduledSendStatus == 2 || listRow.NextScheduledSendStatus == 3}}
+
{{a}} {{b}}
+
+ {{ aNormalValue | aPipe }}:
+ {{ aReallyReallySuperLongValue | andASuperLongPipeJustToBreakThis }}
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
{{ a | b: c }}
+
{{ 0 - 1 }}
+
{{ -1 }}
+
{{ a ? 1 : 2 }}
+
{{ a(1)(2) }}
+
{{ a[b] }}
+
{{ [1] }}
+
{{ { a: 1 } }}
+
{{ { a: 1 } }}
+
{{ true }}
+
{{ undefined }}
+
{{ null }}
+
{{ 1 }}
+
{{ 1 }}
+
{{ "hello" }}
+
{{ a(1, 2) }}
+
{{ a.b(1, 2) }}
+
{{ x! }}
+
{{ !x }}
+
{{ a }}
+
{{ a }}
+
{{ a // hello }}
+
{{ a.b }}
+
{{ a?.b() }}
+
{{ a?.b }}
+
{{ a // hello }}
+
+ {{
+ "SearchSelection.transmissionLayoutRadioButton"
+ | localize: localizationSection
+ }}
+
+
+ {{
+ "SearchSelection.transmissionLayoutRadioButton"
+ | localize: localizationSection
+ }}
+
+
+ {{
+ "SearchSelection.transmissionLayoutRadioButton"
+ | localize: localizationSection
+ }}
+
+
+ {{
+ "SearchSelection.transmissionLayoutRadioButton"
+ | localize: localizationSection
+ }}
+
+
+ {{
+ "SearchSelection.transmissionLayoutRadioButton"
+ | localize: localizationSection
+ }}
+
+
+ {{ copyTypes[options.copyType] }}
+
+{{
+ listRow.NextScheduledSendStatus == 1 ||
+ listRow.NextScheduledSendStatus == 2 ||
+ listRow.NextScheduledSendStatus == 3
+}}
+
+
+ {{ a }}
+
+ {{ b }}
+
+
+
+ {{ aNormalValue | aPipe }}:
+
+ {{ aReallyReallySuperLongValue | andASuperLongPipeJustToBreakThis }}
+
+
`;
@@ -8044,3 +8460,1654 @@ bindon-ngModel
-->
`;
+
+exports[`real-world.component.html - angular-verify 4`] = `
+
+
+
+
Template Syntax
+
Interpolation
+
Expression context
+
Statement context
+
Mental Model
+
Buttons
+
Properties vs. Attributes
+
+
Property Binding
+
+
+
Event Binding
+
Two-way Binding
+
+
Directives
+
+
+
Template reference variables
+
Inputs and outputs
+
Pipes
+
Safe navigation operator ?.
+
Non-null assertion operator !.
+
Enums
+
+
+
Interpolation
+
+
My current hero is {{currentHero.name}}
+
+
+ {{title}}
+
+
+
+
+
The sum of 1 + 1 is {{1 + 1}}
+
+
+
The sum of 1 + 1 is not {{1 + 1 + getVal()}}
+
+
top
+
+
Expression context
+
+
Component expression context ({{title}}, [hidden]="isUnchanged")
+
+ {{title}}
+ changed
+
+
+
+
Template input variable expression context (let hero)
+
+
+ {{hero.name}}
+
+
+
Template reference variable expression context (#heroInput)
+
+ Type something:
+ {{heroInput.value}}
+
+
+
top
+
+
Statement context
+
+
Component statement context ( (click)="onSave() )
+
+ Delete hero
+
+
+
Template $event statement context
+
+ Save
+
+
+
Template input variable statement context (let hero)
+
+
+ {{hero.name}}
+
+
+
Template reference variable statement context (#heroForm)
+
+
+
+
+
top
+
+
+
New Mental Model
+
+
+
+
Mental Model
+
+
Save
+
+
+
+
+
+
+
+ Save
+
+
+
+
+
+
+
+
+
+
+
Save
+
+
click me
+{{clicked}}
+
+
+
+ Hero Name:
+
+ {{name}}
+
+
+
+
help
+
+
+
Special
+
+
+
+button
+
+
top
+
+
+
Property vs. Attribute (img examples)
+
+
+
+
+
+
+
+
+
+
top
+
+
+
+
+
Enabled (but does nothing)
+
Disabled
+
Still disabled
+
+
disabled by attribute
+
disabled by property binding
+
+
Disabled Cancel
+
Enabled Save
+
+
top
+
+
+
Property Binding
+
+
+
Cancel is disabled
+
[ngClass] binding to the classes property
+
+
+
+
+
+
+
+
is the interpolated image.
+
is the property bound image.
+
+
"{{title}}" is the interpolated title.
+
" " is the property bound title.
+
+
+
"{{evilTitle}}" is the interpolated evil title.
+
" " is the property bound evil title.
+
+
top
+
+
+
Attribute Binding
+
+
+
+
+ One-Two
+
+
+
+ Five Six
+
+
+
+
+
{{actionName}} with Aria
+
+
+
+
+
+ Disabled
+
+ Disabled as well
+
+
+ Enabled (but inert)
+
+
+
top
+
+
+
Class Binding
+
+
+
Bad curly special
+
+
+
Bad curly
+
+
+
The class binding is special
+
+
+
This one is not so special
+
+
This class binding is special too
+
+
top
+
+
+
Style Binding
+
+
Red
+
Save
+
+
Big
+
Small
+
+
top
+
+
+
Event Binding
+
+
Save
+
+
On Save
+
+
+
+
click with myClick
+{{clickMessage}}
+
+
+
+
+
+
+
+
+
+
+
Click me
+
Click me too!
+
+
+
+
+ Save, no propagation
+
+
+
+
+ Save w/ propagation
+
+
+
top
+
+
Two-way Binding
+
+
+
Resizable Text
+
FontSize (px):
+
+
+
+
De-sugared two-way binding
+
+
+
+
top
+
+
+
NgModel (two-way) Binding
+
+
Result: {{currentHero.name}}
+
+
+without NgModel
+
+
+[(ngModel)]
+
+
+bindon-ngModel
+
+
+(ngModelChange)="...name=$event"
+
+
+(ngModelChange)="setUppercaseName($event)"
+
+
top
+
+
+
NgClass Binding
+
+
currentClasses is {{currentClasses | json}}
+
This div is initially saveable, unchanged, and special
+
+
+
+
saveable |
+
modified: |
+
special:
+
Refresh currentClasses
+
+
+ This div should be {{ canSave ? "": "not"}} saveable,
+ {{ isUnchanged ? "unchanged" : "modified" }} and,
+ {{ isSpecial ? "": "not"}} special after clicking "Refresh".
+
+
+
This div is special
+
+
Bad curly special
+
Curly special
+
+
top
+
+
+
NgStyle Binding
+
+
+ This div is x-large or smaller.
+
+
+
[ngStyle] binding to currentStyles - CSS property names
+
currentStyles is {{currentStyles | json}}
+
+ This div is initially italic, normal weight, and extra large (24px).
+
+
+
+
+
italic: |
+
normal: |
+
xlarge:
+
Refresh currentStyles
+
+
+ This div should be {{ canSave ? "italic": "plain"}},
+ {{ isUnchanged ? "normal weight" : "bold" }} and,
+ {{ isSpecial ? "extra large": "normal size"}} after clicking "Refresh".
+
+
top
+
+
+
NgIf Binding
+
+
+
+
Hello, {{currentHero.name}}
+
Hello, {{nullHero.name}}
+
+
+
+
Add {{currentHero.name}} with template
+
+
+
Hero Detail removed from DOM (via template) because isActive is false
+
+
+
+
+
+
Show with class
+
Hide with class
+
+
+
+
+
Show with style
+
Hide with style
+
+
top
+
+
+
NgFor Binding
+
+
+
+
+
+
+
top
+
+
*ngFor with index
+
with semi-colon separator
+
+
{{i + 1}} - {{hero.name}}
+
+
+
with comma separator
+
+
+
{{i + 1}} - {{hero.name}}
+
+
+
top
+
+
*ngFor trackBy
+
Reset heroes
+
Change ids
+
Clear counts
+
+
without trackBy
+
+
({{hero.id}}) {{hero.name}}
+
+
+ Hero DOM elements change #{{heroesNoTrackByCount}} without trackBy
+
+
+
+
with trackBy
+
+
({{hero.id}}) {{hero.name}}
+
+
+ Hero DOM elements change #{{heroesWithTrackByCount}} with trackBy
+
+
+
+
+
+
with trackBy and semi-colon separator
+
+
+ ({{hero.id}}) {{hero.name}}
+
+
+
+
with trackBy and comma separator
+
+
({{hero.id}}) {{hero.name}}
+
+
+
with trackBy and space separator
+
+
({{hero.id}}) {{hero.name}}
+
+
+
with generic trackById function
+
+
({{hero.id}}) {{hero.name}}
+
+
+
top
+
+
+
NgSwitch Binding
+
+
Pick your favorite hero
+
+
+ {{h.name}}
+
+
+
+
+
+
+
+
Are you as confused as {{currentHero.name}}?
+
+
+
+
top
+
+
+
Template reference variables
+
+
+
+
+
+
+
Call
+
+
+
Fax
+
+
+
+
+
Example Form
+
+
+
top
+
+
+
+
+
+
Save
+
+
+
+
+
myClick2
+{{clickMessage2}}
+
+
top
+
+
+
Pipes
+
+
Title through uppercase pipe: {{title | uppercase}}
+
+
+
+ Title through a pipe chain:
+ {{title | uppercase | lowercase}}
+
+
+
+
Birthdate: {{currentHero?.birthdate | date:'longDate'}}
+
+
{{currentHero | json}}
+
+
Birthdate: {{(currentHero?.birthdate | date:'longDate') | uppercase}}
+
+
+
+ Price: {{product.price | currency:'USD':true}}
+
+
+
top
+
+
+
Safe navigation operator ?.
+
+
+ The title is {{title}}
+
+
+
+ The current hero's name is {{currentHero?.name}}
+
+
+
+ The current hero's name is {{currentHero.name}}
+
+
+
+
+
+
+
The null hero's name is {{nullHero.name}}
+
+
+The null hero's name is {{nullHero && nullHero.name}}
+
+
+
+
+ The null hero's name is {{nullHero?.name}}
+
+
+
+
top
+
+
+
Non-null assertion operator !.
+
+
+
+
+ The hero's name is {{hero!.name}}
+
+
+
+
top
+
+
+
$any type cast function $any( ) .
+
+
+
+
+ The hero's marker is {{$any(hero).marker}}
+
+
+
+
+
+
+ Undeclared members is {{$any(this).member}}
+
+
+
+
top
+
+
+
+
Enums in binding
+
+
+ The name of the Color.Red enum is {{Color[Color.Red]}}.
+ The current color is {{Color[color]}} and its number is {{color}}.
+ Enum Toggle
+
+
+
top
+
+
+
+
+
+
+
+
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+
+
Template Syntax
+
Interpolation
+
+
Expression context
+
+
Statement context
+
+
Mental Model
+
+
Buttons
+
+
Properties vs. Attributes
+
+
+
Property Binding
+
+
+
+
Event Binding
+
+
Two-way Binding
+
+
+
Directives
+
+
+
Template reference variables
+
+
Inputs and outputs
+
+
Pipes
+
+
+ Safe navigation operator
+ ?.
+
+
+
+ Non-null assertion operator
+ !.
+
+
+
Enums
+
+
+
+
+
Interpolation
+
+
My current hero is {{ currentHero.name }}
+
+
+ {{ title }}
+
+
+
+
+
The sum of 1 + 1 is {{ 1 + 1 }}
+
+
+
The sum of 1 + 1 is not {{ 1 + 1 + getVal() }}
+
+
top
+
+
+
Expression context
+
+
+ Component expression context ({{title}},
+ [hidden]="isUnchanged")
+
+
+ {{ title }}
+ changed
+
+
+
Template input variable expression context (let hero)
+
+
+ {{ hero.name }}
+
+
+
Template reference variable expression context (#heroInput)
+
+ Type something:
+
+ {{ heroInput.value }}
+
+
+
top
+
+
+
Statement context
+
+
Component statement context ( (click)="onSave() )
+
Delete hero
+
+
Template $event statement context
+
Save
+
+
Template input variable statement context (let hero)
+
+
+
+ {{ hero.name }}
+
+
+
+
Template reference variable statement context (#heroForm)
+
+
+
+
+
top
+
+
+
+
New Mental Model
+
+
+
+
Mental Model
+
+
Save
+
+
+
+
+
+
+
+
+
+ Save
+
+
+
+
+
+
+
+
+
+
+
+
+
Save
+
+
click me
+{{ clicked }}
+
+
+
+
+ Hero Name:
+
+ {{ name }}
+
+
+
+
+
help
+
+
+
+
Special
+
+
+
+
button
+
+
top
+
+
+
+
Property vs. Attribute (img examples)
+
+
+
+
+
+
+
+
+
+
+
top
+
+
+
+
+
+
Enabled (but does nothing)
+
Disabled
+
Still disabled
+
+
+
disabled by attribute
+
disabled by property binding
+
+
+
+ Disabled Cancel
+
+
Enabled Save
+
+
top
+
+
+
+
Property Binding
+
+
+
Cancel is disabled
+
[ngClass] binding to the classes property
+
+
+
+
+
+
+
+
+
+ is the
+ interpolated
+ image.
+
+
+
+ is the
+ property bound
+ image.
+
+
+
+
+ "{{ title }}" is the
+ interpolated
+ title.
+
+
+
+ "
+
+ " is the
+ property bound
+ title.
+
+
+
+
+
+ "{{ evilTitle }}" is the
+ interpolated
+ evil title.
+
+
+
+ "
+
+ " is the
+ property bound
+ evil title.
+
+
+
top
+
+
+
+
Attribute Binding
+
+
+
+
+ One-Two
+
+
+
+
+ Five
+ Six
+
+
+
+
+
+
{{ actionName }} with Aria
+
+
+
+
+
+
+ Disabled
+
+ Disabled as well
+
+
+ Enabled (but inert)
+
+
+
top
+
+
+
+
Class Binding
+
+
+
Bad curly special
+
+
+
Bad curly
+
+
+
The class binding is special
+
+
+
+ This one is not so special
+
+
+
This class binding is special too
+
+
top
+
+
+
+
Style Binding
+
+
Red
+
Save
+
+
Big
+
Small
+
+
top
+
+
+
+
Event Binding
+
+
Save
+
+
On Save
+
+
+
+
click with myClick
+ {{ clickMessage }}
+
+
+
+
+
+
+
+
+
+ Click me
+
Click me too!
+
+
+
+
+ Save, no propagation
+
+
+
+
+ Save w/ propagation
+
+
+
top
+
+
+
Two-way Binding
+
+
+
Resizable Text
+
+ FontSize (px):
+
+
+
+
+
+
De-sugared two-way binding
+
+
+
+
top
+
+
+
+
NgModel (two-way) Binding
+
+
Result: {{ currentHero.name }}
+
+
+without NgModel
+
+
+[(ngModel)]
+
+
+bindon-ngModel
+
+
+(ngModelChange)="...name=$event"
+
+
+(ngModelChange)="setUppercaseName($event)"
+
+
top
+
+
+
+
NgClass Binding
+
+
currentClasses is {{ currentClasses | json }}
+
+ This div is initially saveable, unchanged, and special
+
+
+
+
+
+ saveable
+
+
+|
+
+ modified:
+
+
+|
+
+ special:
+
+
+
Refresh currentClasses
+
+
+
+ This div should be {{ canSave ? "" : "not" }} saveable,
+ {{ isUnchanged ? "unchanged" : "modified" }} and,
+ {{ isSpecial ? "" : "not" }} special after clicking "Refresh".
+
+
+
+
+
This div is special
+
+
Bad curly special
+
Curly special
+
+
top
+
+
+
+
NgStyle Binding
+
+
+ This div is x-large or smaller.
+
+
+
[ngStyle] binding to currentStyles - CSS property names
+
currentStyles is {{ currentStyles | json }}
+
+ This div is initially italic, normal weight, and extra large (24px).
+
+
+
+
+
+ italic:
+
+
+|
+
+ normal:
+
+
+|
+
+ xlarge:
+
+
+
Refresh currentStyles
+
+
+
+ This div should be {{ canSave ? "italic" : "plain" }},
+ {{ isUnchanged ? "normal weight" : "bold" }} and,
+ {{ isSpecial ? "extra large" : "normal size" }} after clicking "Refresh".
+
+
+
top
+
+
+
+
NgIf Binding
+
+
+
+
Hello, {{ currentHero.name }}
+
Hello, {{ nullHero.name }}
+
+
+
+
+ Add {{ currentHero.name }} with template
+
+
+
+
Hero Detail removed from DOM (via template) because isActive is false
+
+
+
+
Show with class
+
Hide with class
+
+
+
+
+
Show with style
+
Hide with style
+
+
top
+
+
+
+
NgFor Binding
+
+
+
+
+
+
+
top
+
+
*ngFor with index
+
+ with
+ semi-colon
+ separator
+
+
+
+ {{ i + 1 }} - {{ hero.name }}
+
+
+
+
+ with
+ comma
+ separator
+
+
+
+
+ {{ i + 1 }} - {{ hero.name }}
+
+
+
+
top
+
+
*ngFor trackBy
+
Reset heroes
+
Change ids
+
Clear counts
+
+
+ without
+ trackBy
+
+
+
+ ({{ hero.id }}) {{ hero.name }}
+
+
+
+ Hero DOM elements change #{{ heroesNoTrackByCount }} without trackBy
+
+
+
+
with trackBy
+
+
+ ({{ hero.id }}) {{ hero.name }}
+
+
+
+ Hero DOM elements change #{{ heroesWithTrackByCount }} with trackBy
+
+
+
+
+
+
+
+
+ with trackBy and
+ semi-colon
+ separator
+
+
+
+ ({{ hero.id }}) {{ hero.name }}
+
+
+
+
+ with trackBy and
+ comma
+ separator
+
+
+
+ ({{ hero.id }}) {{ hero.name }}
+
+
+
+
+ with trackBy and
+ space
+ separator
+
+
+
+ ({{ hero.id }}) {{ hero.name }}
+
+
+
+
+ with
+ generic
+ trackById function
+
+
+
+ ({{ hero.id }}) {{ hero.name }}
+
+
+
+
top
+
+
+
+
NgSwitch Binding
+
+
Pick your favorite hero
+
+
+
+ {{ h.name }}
+
+
+
+
+
+
+
+
+ Are you as confused as {{ currentHero.name }}?
+
+
+
+
+
top
+
+
+
+
Template reference variables
+
+
+
+
+
+
+
Call
+
+
+
Fax
+
+
+
+
+
Example Form
+
+
+
top
+
+
+
+
+
+
+
Save
+
+
+
+
myClick2
+{{ clickMessage2 }}
+
+
top
+
+
+
+
Pipes
+
+
Title through uppercase pipe: {{ title | uppercase }}
+
+
+
Title through a pipe chain: {{ title | uppercase | lowercase }}
+
+
+
Birthdate: {{ currentHero?.birthdate | date: "longDate" }}
+
+
{{ currentHero | json }}
+
+
+ Birthdate: {{ currentHero?.birthdate | date: "longDate" | uppercase }}
+
+
+
+
+ Price:
+ {{ product.price | currency: "USD":true }}
+
+
+
top
+
+
+
+
+ Safe navigation operator
+ ?.
+
+
+
The title is {{ title }}
+
+
The current hero's name is {{ currentHero?.name }}
+
+
The current hero's name is {{ currentHero.name }}
+
+
+
+
+
The null hero's name is {{ nullHero.name }}
+
+
The null hero's name is {{ nullHero && nullHero.name }}
+
+
+
+ The null hero's name is {{ nullHero?.name }}
+
+
+
top
+
+
+
+
+ Non-null assertion operator
+ !.
+
+
+
+
+
The hero's name is {{ hero!.name }}
+
+
+
top
+
+
+
+
+ $any type cast function
+ $any( )
+ .
+
+
+
+
+
The hero's marker is {{ $any(hero).marker }}
+
+
+
+
+
Undeclared members is {{$any(this).member}}
+
+
+
top
+
+
+
+
+
Enums in binding
+
+
+ The name of the Color.Red enum is {{ Color[Color.Red] }}.
+
+ The current color is {{ Color[color] }} and its number is {{ color }}.
+
+
+ Enum Toggle
+
+
+
+
top
+
+
+
+
+
+
+
+`;
diff --git a/tests/html_angular/interpolation.component.html b/tests/html_angular/interpolation.component.html
index d8021e80d..134c8f934 100644
--- a/tests/html_angular/interpolation.component.html
+++ b/tests/html_angular/interpolation.component.html
@@ -50,3 +50,7 @@
>{{b}}
+
+ {{ aNormalValue | aPipe }}:
+ {{ aReallyReallySuperLongValue | andASuperLongPipeJustToBreakThis }}
+
diff --git a/tests/html_angular/jsfmt.spec.js b/tests/html_angular/jsfmt.spec.js
index d491f09bd..b3183c499 100644
--- a/tests/html_angular/jsfmt.spec.js
+++ b/tests/html_angular/jsfmt.spec.js
@@ -1,3 +1,4 @@
run_spec(__dirname, ["angular"]);
run_spec(__dirname, ["angular"], { trailingComma: "es5" });
run_spec(__dirname, ["angular"], { printWidth: 1 });
+run_spec(__dirname, ["angular"], { htmlWhitespaceSensitivity: "ignore" });