fix(aio): handle clicks deep within anchor tags

This commit is contained in:
Ward Bell 2017-04-18 12:13:13 -07:00 committed by Pete Bacon Darwin
parent 745731e1a3
commit f90258162a
2 changed files with 32 additions and 8 deletions

View File

@ -308,13 +308,35 @@ describe('AppComponent', () => {
describe('click intercepting', () => { describe('click intercepting', () => {
it('should intercept clicks on anchors and call `location.handleAnchorClick()`', it('should intercept clicks on anchors and call `location.handleAnchorClick()`',
inject([LocationService], (location: LocationService) => { inject([LocationService], (location: LocationService) => {
const anchorElement: HTMLAnchorElement = document.createElement('a');
anchorElement.href = 'some/local/url'; const el = fixture.nativeElement as Element;
fixture.nativeElement.append(anchorElement); el.innerHTML = '<a href="some/local/url">click me</a>';
const anchorElement = el.getElementsByTagName('a')[0];
anchorElement.click(); anchorElement.click();
expect(location.handleAnchorClick).toHaveBeenCalledWith(anchorElement, 0, false, false); expect(location.handleAnchorClick).toHaveBeenCalledWith(anchorElement, 0, false, false);
})); }));
it('should intercept clicks on elements deep within an anchor tag',
inject([LocationService], (location: LocationService) => {
const el = fixture.nativeElement as Element;
el.innerHTML = '<a href="some/local/url"><div><img></div></a>';
const imageElement = el.getElementsByTagName('img')[0];
const anchorElement = el.getElementsByTagName('a')[0];
imageElement.click();
expect(location.handleAnchorClick).toHaveBeenCalledWith(anchorElement, 0, false, false);
}));
it('should ignore clicks on elements without an anchor ancestor',
inject([LocationService], (location: LocationService) => {
const el = fixture.nativeElement as Element;
el.innerHTML = '<div><p><div><img></div></p></div>';
const imageElement = el.getElementsByTagName('img')[0];
imageElement.click();
expect(location.handleAnchorClick).not.toHaveBeenCalled();
}));
it('should intercept clicks not on the search elements and hide the search results', () => { it('should intercept clicks not on the search elements and hide the search results', () => {
const searchResults: SearchResultsComponent = fixture.debugElement.query(By.directive(SearchResultsComponent)).componentInstance; const searchResults: SearchResultsComponent = fixture.debugElement.query(By.directive(SearchResultsComponent)).componentInstance;
spyOn(searchResults, 'hideResults'); spyOn(searchResults, 'hideResults');

View File

@ -133,14 +133,16 @@ export class AppComponent implements OnInit {
if (eventTarget.tagName === 'FOOTER' && metaKey && altKey) { if (eventTarget.tagName === 'FOOTER' && metaKey && altKey) {
this.dtOn = !this.dtOn; this.dtOn = !this.dtOn;
return false;
} }
// Deal with anchor clicks // Deal with anchor clicks; climb DOM tree until anchor found (or null)
if (eventTarget instanceof HTMLImageElement) { let target = eventTarget;
eventTarget = eventTarget.parentElement; // assume image wrapped in Anchor while (target && !(target instanceof HTMLAnchorElement)) {
target = target.parentElement;
} }
if (eventTarget instanceof HTMLAnchorElement) { if (target) {
return this.locationService.handleAnchorClick(eventTarget, button, ctrlKey, metaKey); return this.locationService.handleAnchorClick(target as HTMLAnchorElement, button, ctrlKey, metaKey);
} }
return true; return true;
} }