@@ -24,6 +24,7 @@ import { MENU_DEFAULTS } from './defaults/menu-defaults';
2424import { STYLE_STATE_DEFAULTS } from './defaults/style-state-defaults' ;
2525import { TOOLBAR_ACTION_DEFAULTS } from './defaults/toolbar-action-defaults' ;
2626import { TextEditorFixtureComponent } from './fixtures/text-editor.component.fixture' ;
27+ import { SkyTextEditorAdapterService } from './services/text-editor-adapter.service' ;
2728import { SkyTextEditorComponent } from './text-editor.component' ;
2829import { SkyTextEditorModule } from './text-editor.module' ;
2930import { SkyTextEditorStyleState } from './types/style-state' ;
@@ -274,6 +275,18 @@ describe('Text editor', () => {
274275 fixture . detectChanges ( ) ;
275276 }
276277
278+ function insertMergeField ( index : number ) : void {
279+ openDropdown ( '.sky-text-editor-menu-merge-field' ) ;
280+ expect ( document . querySelector ( '.sky-dropdown-item' ) ) . toBeTruthy ( ) ;
281+
282+ iframeDocument . body . focus ( ) ;
283+ const mergeFieldOption = document . querySelectorAll (
284+ '.sky-dropdown-item button'
285+ ) [ index ] ;
286+ SkyAppTestUtility . fireDomEvent ( mergeFieldOption , 'click' ) ;
287+ fixture . detectChanges ( ) ;
288+ }
289+
277290 function getFontPicker ( ) : HTMLElement {
278291 return fixture . nativeElement . querySelector (
279292 '.sky-text-editor-toolbar .sky-text-editor-font-picker'
@@ -653,26 +666,48 @@ describe('Text editor', () => {
653666 tick ( ) ;
654667 fixture . detectChanges ( ) ;
655668
656- openDropdown ( '.sky-text-editor-menu-merge-field' ) ;
657- expect ( document . querySelector ( '.sky-dropdown-item' ) ) . toBeTruthy ( ) ;
658-
659- iframeDocument . body . focus ( ) ;
660- const mergeFieldOption = document . querySelectorAll (
661- '.sky-dropdown-item button'
662- ) [ 2 ] ;
663- SkyAppTestUtility . fireDomEvent ( mergeFieldOption , 'click' ) ;
664- fixture . detectChanges ( ) ;
665- tick ( ) ;
666- fixture . detectChanges ( ) ;
667- tick ( ) ;
668- fixture . detectChanges ( ) ;
669+ insertMergeField ( 2 ) ;
669670
670671 expect ( testComponent . value ) . toContain ( 'data-fieldid="2"' ) ;
671672 expect ( testComponent . value ) . toContain (
672673 'data-fielddisplay="A field that is really too long for its own good"'
673674 ) ;
674675 } ) ) ;
675676
677+ it ( 'should escape merge field attribute values' , fakeAsync ( ( ) => {
678+ testComponent . mergeFields = [
679+ {
680+ id : '"><' ,
681+ name : '"><' ,
682+ } ,
683+ ] ;
684+
685+ fixture . detectChanges ( ) ;
686+
687+ const adapterSvc = fixture . debugElement
688+ . query ( By . css ( 'sky-text-editor' ) )
689+ . injector . get ( SkyTextEditorAdapterService ) ;
690+
691+ spyOn ( adapterSvc , 'execCommand' ) . and . callThrough ( ) ;
692+
693+ insertMergeField ( 0 ) ;
694+
695+ expect ( adapterSvc . execCommand ) . toHaveBeenCalledOnceWith ( {
696+ command : 'insertHTML' ,
697+ value : jasmine . stringContaining ( 'data-fieldid=""><' ) ,
698+ } ) ;
699+
700+ expect ( adapterSvc . execCommand ) . toHaveBeenCalledOnceWith ( {
701+ command : 'insertHTML' ,
702+ value : jasmine . stringContaining ( 'data-fielddisplay=""><' ) ,
703+ } ) ;
704+
705+ // The browser converts the escaped angle brackets back to their unescaped
706+ // versions since they appear within quotes in an attribute value.
707+ expect ( testComponent . value ) . toContain ( 'data-fieldid=""><' ) ;
708+ expect ( testComponent . value ) . toContain ( 'data-fielddisplay=""><"' ) ;
709+ } ) ) ;
710+
676711 it ( 'Toolbar values should update based on selection' , fakeAsync ( ( ) => {
677712 testComponent . value =
678713 '<font style="font-size: 16px" face="Arial" color="#c14040">' +
0 commit comments