Skip to content

Commit f90de74

Browse files
authored
Merge branch '9.1.x' into ibarakov/issue7350-9.1.x
2 parents 0ec4a30 + 77a6047 commit f90de74

File tree

8 files changed

+95
-25
lines changed

8 files changed

+95
-25
lines changed

projects/igniteui-angular/src/lib/grids/cell.component.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -588,14 +588,12 @@ export class IgxGridCellComponent implements OnInit, OnChanges, OnDestroy {
588588

589589
private addPointerListeners(selection) {
590590
if (selection !== GridSelectionMode.multiple) { return; }
591-
this.nativeElement.addEventListener('pointerdown', this.pointerdown);
592591
this.nativeElement.addEventListener('pointerenter', this.pointerenter);
593592
this.nativeElement.addEventListener('pointerup', this.pointerup);
594593
}
595594

596595
private removePointerListeners(selection) {
597596
if (selection !== GridSelectionMode.multiple) { return; }
598-
this.nativeElement.removeEventListener('pointerdown', this.pointerdown);
599597
this.nativeElement.removeEventListener('pointerenter', this.pointerenter);
600598
this.nativeElement.removeEventListener('pointerup', this.pointerup);
601599
}
@@ -606,6 +604,7 @@ export class IgxGridCellComponent implements OnInit, OnChanges, OnDestroy {
606604
*/
607605
ngOnInit() {
608606
this.zone.runOutsideAngular(() => {
607+
this.nativeElement.addEventListener('pointerdown', this.pointerdown);
609608
this.addPointerListeners(this.cellSelectionMode);
610609
// IE 11 workarounds
611610
if (isIE()) {
@@ -629,6 +628,7 @@ export class IgxGridCellComponent implements OnInit, OnChanges, OnDestroy {
629628
*/
630629
ngOnDestroy() {
631630
this.zone.runOutsideAngular(() => {
631+
this.nativeElement.removeEventListener('pointerdown', this.pointerdown);
632632
this.removePointerListeners(this.cellSelectionMode);
633633
if (isIE()) {
634634
this.nativeElement.removeEventListener('compositionstart', this.compositionStartHandler);
@@ -755,6 +755,10 @@ export class IgxGridCellComponent implements OnInit, OnChanges, OnDestroy {
755755
* @internal
756756
*/
757757
pointerdown = (event: PointerEvent) => {
758+
if (this.cellSelectionMode !== GridSelectionMode.multiple) {
759+
this.activate(event);
760+
return;
761+
}
758762
if (!isLeftClick(event)) {
759763
this.selectionService.addKeyboardRange();
760764
this.selectionService.initKeyboardState();
@@ -816,9 +820,6 @@ export class IgxGridCellComponent implements OnInit, OnChanges, OnDestroy {
816820
*/
817821
@HostListener('click', ['$event'])
818822
public onClick(event: MouseEvent) {
819-
if (this.cellSelectionMode !== GridSelectionMode.multiple) {
820-
this.activate(event);
821-
}
822823
this.grid.onCellClick.emit({
823824
cell: this,
824825
event

projects/igniteui-angular/src/lib/grids/columns/column-group.component.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -239,9 +239,9 @@ export class IgxColumnGroupComponent extends IgxColumnComponent implements After
239239
}
240240

241241
/**
242-
* Enables/Disables the column group selection.
243-
* ```html
244-
* <igx-column [selected] = "true"></igx-column>
242+
* Select/deselect the column group.
243+
* ```typescript
244+
* this.columnGroup.selected = true;
245245
* ```
246246
* @memberof IgxColumnGroupComponent
247247
*/

projects/igniteui-angular/src/lib/grids/columns/column.component.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -294,10 +294,10 @@ export class IgxColumnComponent implements AfterContentInit {
294294
}
295295

296296
/**
297-
* Enables/Disables column selection.
297+
* Select/deselect a column.
298298
* Default value is `false`.
299-
* ```html
300-
* <igx-column [selected] = "true"></igx-column>
299+
* ```typescript
300+
* this.column.selected = true;
301301
* ```
302302
* @memberof IgxColumnComponent
303303
*/

projects/igniteui-angular/src/lib/grids/grid/grid-keyBoardNav.spec.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -663,7 +663,7 @@ describe('IgxGrid - Keyboard navigation #grid', () => {
663663
it('should toggle expand/collapse state of group row with ArrowRight/ArrowLeft key.', () => {
664664
const gRow = grid.groupsRowList.toArray()[0];
665665
const gRowElement = GridFunctions.getGroupedRows(fix)[0];
666-
gRowElement.triggerEventHandler('click', {});
666+
gRowElement.triggerEventHandler('pointerdown', {});
667667
fix.detectChanges();
668668
expect(gRow.expanded).toBe(true);
669669

@@ -680,7 +680,7 @@ describe('IgxGrid - Keyboard navigation #grid', () => {
680680
it('should toggle expand/collapse state of group row with ArrowUp/ArrowDown key.', () => {
681681
const gRow = grid.groupsRowList.toArray()[0];
682682
const gRowElement = GridFunctions.getGroupedRows(fix)[0];
683-
gRowElement.triggerEventHandler('click', {});
683+
gRowElement.triggerEventHandler('pointerdown', {});
684684
fix.detectChanges();
685685

686686
expect(gRow.expanded).toBe(true);
@@ -704,7 +704,7 @@ describe('IgxGrid - Keyboard navigation #grid', () => {
704704
let groupedRowsCount = grid.groupsRowList.length;
705705
let groupRow = grid.groupsRowList.toArray()[groupedRowsCount - 1];
706706
const groupRowElement = GridFunctions.getGroupedRows(fix)[groupedRowsCount - 1];
707-
groupRowElement.triggerEventHandler('click', null);
707+
groupRowElement.triggerEventHandler('pointerdown', null);
708708
fix.detectChanges();
709709

710710
GridFunctions.verifyGroupRowIsFocused(groupRow);
@@ -737,7 +737,7 @@ describe('IgxGrid - Keyboard navigation #grid', () => {
737737
expect(grid.groupsRowList.last.expanded).toBeTruthy();
738738

739739
const groupRowIndex = grid.groupsRowList.last.index;
740-
grid.groupsRowList.last.nativeElement.dispatchEvent(new Event('click'));
740+
grid.groupsRowList.last.nativeElement.dispatchEvent(new Event('pointerdown'));
741741
await wait();
742742
fix.detectChanges();
743743
UIInteractions.triggerEventHandlerKeyDown('arrowDown', gridContent);
@@ -762,7 +762,7 @@ describe('IgxGrid - Keyboard navigation #grid', () => {
762762
fix.detectChanges();
763763

764764
let row = grid.getRowByIndex(1);
765-
row.nativeElement.dispatchEvent(new Event('click'));
765+
row.nativeElement.dispatchEvent(new Event('pointerdown'));
766766
await wait();
767767
fix.detectChanges();
768768

@@ -916,7 +916,7 @@ describe('IgxGrid - Keyboard navigation #grid', () => {
916916
await wait(DEBOUNCETIME);
917917
fix.detectChanges();
918918

919-
grid.navigateTo(9, -1, (args) => { args.target.nativeElement.click(); });
919+
grid.navigateTo(9, -1, (args) => { args.target.nativeElement.dispatchEvent(new Event('pointerdown')); });
920920
await wait(100);
921921
fix.detectChanges();
922922
await wait(100);

projects/igniteui-angular/src/lib/grids/grid/groupby-row.component.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ export class IgxGridGroupByRowComponent {
160160
}
161161

162162

163-
@HostListener('click')
163+
@HostListener('pointerdown')
164164
public activate() {
165165
this.grid.navigation.activeNode ? this.grid.navigation.activeNode.row = this.index :
166166
this.grid.navigation.activeNode = {row: this.index};

projects/igniteui-angular/src/lib/icon/icon.component.ts

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
import { Component, ElementRef, HostBinding, Input, OnInit, TemplateRef, ViewChild } from '@angular/core';
1+
import { Component, ElementRef, HostBinding, Input, OnInit, TemplateRef, ViewChild, ChangeDetectorRef, OnDestroy } from '@angular/core';
22
import { IgxIconService } from './icon.service';
3+
import { first, takeUntil } from 'rxjs/operators';
4+
import { Subject } from 'rxjs';
35

46
/**
57
* Icon provides a way to include material icons to markup
@@ -29,8 +31,7 @@ let NEXT_ID = 0;
2931
selector: 'igx-icon',
3032
templateUrl: 'icon.component.html'
3133
})
32-
33-
export class IgxIconComponent implements OnInit {
34+
export class IgxIconComponent implements OnInit, OnDestroy {
3435
@ViewChild('noLigature', { read: TemplateRef, static: true })
3536
private noLigature: TemplateRef<HTMLElement>;
3637

@@ -40,6 +41,8 @@ export class IgxIconComponent implements OnInit {
4041
@ViewChild('svgImage', { read: TemplateRef, static: true })
4142
private svgImage: TemplateRef<HTMLElement>;
4243

44+
private destroy$ = new Subject<void>();
45+
4346
/**
4447
* This allows you to change the value of `class.igx-icon`. By default it's `igx-icon`.
4548
*
@@ -120,10 +123,18 @@ export class IgxIconComponent implements OnInit {
120123
*/
121124
public el: ElementRef;
122125

123-
constructor(private _el: ElementRef, private iconService: IgxIconService) {
126+
constructor(
127+
private _el: ElementRef,
128+
private iconService: IgxIconService,
129+
private ref: ChangeDetectorRef) {
124130
this.el = _el;
125131
this.font = this.iconService.defaultFontSet;
126132
this.iconService.registerFontSetAlias('material', 'material-icons');
133+
this.iconService.iconLoaded.pipe(
134+
first(e => e.name === this.iconName && e.fontSet === this.font),
135+
takeUntil(this.destroy$)
136+
)
137+
.subscribe(_ => this.ref.detectChanges());
127138
}
128139

129140
/**
@@ -135,7 +146,16 @@ export class IgxIconComponent implements OnInit {
135146
}
136147

137148
/**
138-
* An accessor that returns the value of the font property.
149+
* @hidden
150+
* @internal
151+
*/
152+
ngOnDestroy() {
153+
this.destroy$.next();
154+
this.destroy$.complete();
155+
}
156+
157+
/**
158+
* An accessor that returns the value of the font property.
139159
* @example
140160
* ```typescript
141161
* @ViewChild("MyIcon")

projects/igniteui-angular/src/lib/icon/icon.service.spec.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { IgxIconService } from './icon.service';
33
import { DOCUMENT } from '@angular/common';
44

55
import { configureTestSuite } from '../test-utils/configure-suite';
6+
import { first } from 'rxjs/operators';
67

78
describe('Icon Service', () => {
89
configureTestSuite();
@@ -86,4 +87,28 @@ describe('Icon Service', () => {
8687
const svgElement = document.querySelector(`svg[id='${iconKey}']`);
8788
expect(svgElement).toBeDefined();
8889
});
90+
91+
it('should emit loading event for a custom svg icon from url', done => {
92+
const iconService = TestBed.inject(IgxIconService) as IgxIconService;
93+
94+
iconService.iconLoaded.pipe(first()).subscribe(event => {
95+
expect(event.name).toMatch('test');
96+
expect(event.fontSet).toMatch('svg-icons');
97+
done();
98+
});
99+
100+
const iconName = 'test';
101+
const fontSet = 'svg-icons';
102+
103+
spyOn(XMLHttpRequest.prototype, 'open').and.callThrough();
104+
spyOn(XMLHttpRequest.prototype, 'send').and.callFake(() => {
105+
(iconService as any)._iconLoaded.next({
106+
name: iconName,
107+
value: svgText,
108+
fontSet: fontSet
109+
});
110+
});
111+
112+
iconService.addSvgIcon(iconName, 'test.svg', fontSet);
113+
});
89114
});

projects/igniteui-angular/src/lib/icon/icon.service.ts

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,20 @@
11
import { Injectable, SecurityContext, Inject } from '@angular/core';
22
import { DomSanitizer } from '@angular/platform-browser';
33
import { DOCUMENT } from '@angular/common';
4+
import { Subject } from 'rxjs';
5+
6+
/**
7+
* Event emitted when a SVG icon is loaded through
8+
* a HTTP request.
9+
*/
10+
export interface IgxIconLoadedEvent {
11+
/** Name of the icon */
12+
name: string;
13+
/** The actual SVG text */
14+
value: string;
15+
/** The fontSet for the icon. Defaults to material. */
16+
fontSet: string;
17+
}
418

519
/**
620
* **Ignite UI for Angular Icon Service** -
@@ -14,16 +28,25 @@ import { DOCUMENT } from '@angular/common';
1428
* this.iconService.addSvgIcon('aruba', '/assets/svg/country_flags/aruba.svg', 'svg-flags');
1529
* ```
1630
*/
17-
1831
@Injectable({
1932
providedIn: 'root'
2033
})
21-
2234
export class IgxIconService {
2335
private _fontSet = 'material-icons';
2436
private _fontSetAliases = new Map<string, string>();
2537
private _svgContainer: HTMLElement;
2638
private _cachedSvgIcons: Set<string> = new Set<string>();
39+
private _iconLoaded = new Subject<IgxIconLoadedEvent>();
40+
41+
/**
42+
* Observable that emits when an icon is successfully loaded
43+
* through a HTTP request.
44+
* @example
45+
* ```typescript
46+
* this.service.iconLoaded.subscribe((ev: IgxIconLoadedEvent) => ...);
47+
* ```
48+
*/
49+
public iconLoaded = this._iconLoaded.asObservable();
2750

2851
constructor(private _sanitizer: DomSanitizer, @Inject(DOCUMENT) private _document: any) { }
2952

@@ -143,6 +166,7 @@ export class IgxIconService {
143166
const request = event.target as XMLHttpRequest;
144167
if (request.status === 200) {
145168
instance.cacheSvgIcon(iconName, request.responseText, fontSet);
169+
instance._iconLoaded.next({ name: iconName, value: request.responseText, fontSet });
146170
} else {
147171
throw new Error(`Could not fetch SVG from url: ${url}; error: ${request.status} (${request.statusText})`);
148172
}

0 commit comments

Comments
 (0)