diff --git a/aio/src/app/app.component.html b/aio/src/app/app.component.html
index 6ecd5b23eb..92fe8e1db0 100644
--- a/aio/src/app/app.component.html
+++ b/aio/src/app/app.component.html
@@ -1,7 +1,7 @@
-
+
@@ -13,7 +13,7 @@
diff --git a/aio/src/app/app.component.spec.ts b/aio/src/app/app.component.spec.ts
index a668074a44..f8c9312d54 100644
--- a/aio/src/app/app.component.spec.ts
+++ b/aio/src/app/app.component.spec.ts
@@ -1,9 +1,12 @@
import { async, inject, ComponentFixture, TestBed } from '@angular/core/testing';
import { APP_BASE_HREF } from '@angular/common';
+import { By } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { AppModule } from './app.module';
import { GaService } from 'app/shared/ga.service';
import { SearchService } from 'app/search/search.service';
+import { SearchResultsComponent } from 'app/search/search-results/search-results.component';
+import { SearchBoxComponent } from 'app/search/search-box/search-box.component';
import { MockSearchService } from 'testing/search.service';
import { LocationService } from 'app/shared/location.service';
import { MockLocationService } from 'testing/location.service';
@@ -84,6 +87,27 @@ describe('AppComponent', () => {
anchorElement.click();
expect(location.handleAnchorClick).toHaveBeenCalledWith(anchorElement, 0, false, false);
}));
+
+ 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 docViewer = fixture.debugElement.query(By.css('aio-doc-viewer'));
+ spyOn(searchResults, 'hideResults');
+ docViewer.nativeElement.click();
+ expect(searchResults.hideResults).toHaveBeenCalled();
+ });
+
+ it('should not intercept clicks on any of the search elements', () => {
+ const searchResults = fixture.debugElement.query(By.directive(SearchResultsComponent));
+ const searchResultsComponent: SearchResultsComponent = searchResults.componentInstance;
+ const searchBox = fixture.debugElement.query(By.directive(SearchBoxComponent));
+ spyOn(searchResultsComponent, 'hideResults');
+
+ searchResults.nativeElement.click();
+ expect(searchResultsComponent.hideResults).not.toHaveBeenCalled();
+
+ searchBox.nativeElement.click();
+ expect(searchResultsComponent.hideResults).not.toHaveBeenCalled();
+ });
});
});
diff --git a/aio/src/app/app.component.ts b/aio/src/app/app.component.ts
index 874fdf24d6..4f131a3f8d 100644
--- a/aio/src/app/app.component.ts
+++ b/aio/src/app/app.component.ts
@@ -1,4 +1,4 @@
-import { Component, HostListener, ViewChild, OnInit } from '@angular/core';
+import { Component, ElementRef, HostListener, OnInit, QueryList, ViewChild, ViewChildren } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { GaService } from 'app/shared/ga.service';
@@ -6,6 +6,7 @@ import { LocationService } from 'app/shared/location.service';
import { DocumentService, DocumentContents } from 'app/documents/document.service';
import { NavigationService, NavigationViews, NavigationNode } from 'app/navigation/navigation.service';
import { SearchService } from 'app/search/search.service';
+import { SearchResultsComponent } from 'app/search/search-results/search-results.component';
@Component({
selector: 'aio-shell',
@@ -23,13 +24,18 @@ export class AppComponent implements OnInit {
navigationViews: Observable;
selectedNodes: Observable;
- constructor(
- documentService: DocumentService,
- gaService: GaService,
- private locationService: LocationService,
- navigationService: NavigationService,
- private searchService: SearchService) {
+ @ViewChildren('searchBox, searchResults', { read: ElementRef })
+ searchElements: QueryList;
+ @ViewChild(SearchResultsComponent)
+ searchResults: SearchResultsComponent;
+
+ constructor(
+ documentService: DocumentService,
+ gaService: GaService,
+ private locationService: LocationService,
+ navigationService: NavigationService,
+ private searchService: SearchService) {
this.currentDocument = documentService.currentDocument;
locationService.currentUrl.subscribe(url => gaService.locationChanged(url));
this.navigationViews = navigationService.navigationViews;
@@ -50,6 +56,16 @@ export class AppComponent implements OnInit {
@HostListener('click', ['$event.target', '$event.button', '$event.ctrlKey', '$event.metaKey'])
onClick(eventTarget: HTMLElement, button: number, ctrlKey: boolean, metaKey: boolean): boolean {
+
+ // Hide the search results if we clicked outside both the search box and the search results
+ if (this.searchResults) {
+ const hits = this.searchElements.filter(element => element.nativeElement.contains(eventTarget));
+ if (hits.length === 0) {
+ this.searchResults.hideResults();
+ }
+ }
+
+ // Deal with anchor clicks
if (eventTarget instanceof HTMLAnchorElement) {
return this.locationService.handleAnchorClick(eventTarget, button, ctrlKey, metaKey);
}