diff --git a/aio/.eslintrc.json b/aio/.eslintrc.json index 2f94590cd8a..e11d637a7fc 100644 --- a/aio/.eslintrc.json +++ b/aio/.eslintrc.json @@ -27,6 +27,7 @@ "style": "kebab-case" } ], + "max-len": ["error" , 120], "@angular-eslint/directive-selector": [ "error", { diff --git a/aio/src/app/app.component.spec.ts b/aio/src/app/app.component.spec.ts index 65f3434a80f..9ea8ab9315b 100644 --- a/aio/src/app/app.component.spec.ts +++ b/aio/src/app/app.component.spec.ts @@ -431,8 +431,14 @@ describe('AppComponent', () => { await setupSelectorForTesting(); locationService.urlSubject.next('docs#section-1'); const versionWithoutSlashIndex = component.docVersions.length; - const versionWithoutSlashUrl = component.docVersions[versionWithoutSlashIndex] = { url: 'https://next.angular.io', title: 'foo' }; - selectElement.triggerEventHandler('change', { option: versionWithoutSlashUrl, index: versionWithoutSlashIndex }); + const versionWithoutSlashUrl = (component.docVersions[versionWithoutSlashIndex] = { + url: 'https://next.angular.io', + title: 'foo', + }); + selectElement.triggerEventHandler('change', { + option: versionWithoutSlashUrl, + index: versionWithoutSlashIndex, + }); expect(locationService.go).toHaveBeenCalledWith('https://next.angular.io/docs#section-1'); }); }); @@ -589,7 +595,10 @@ describe('AppComponent', () => { }); describe('restrainScrolling()', () => { - const preventedScrolling = (currentTarget: { scrollTop: number, scrollHeight?: number, clientHeight?: number }, deltaY: number) => { + const preventedScrolling = ( + currentTarget: {scrollTop: number, scrollHeight?: number, clientHeight?: number}, + deltaY: number + ) => { const evt = { deltaY, currentTarget, @@ -780,15 +789,20 @@ describe('AppComponent', () => { describe('keyup handling', () => { it('should grab focus when the / key is pressed', () => { - const searchBox: SearchBoxComponent = fixture.debugElement.query(By.directive(SearchBoxComponent)).componentInstance; + const searchBox: SearchBoxComponent = fixture.debugElement.query( + By.directive(SearchBoxComponent) + ).componentInstance; spyOn(searchBox, 'focus'); window.document.dispatchEvent(new KeyboardEvent('keyup', { key: '/' })); fixture.detectChanges(); expect(searchBox.focus).toHaveBeenCalled(); }); + // eslint-disable-next-line max-len it('should set focus back to the search box when the search results are displayed and the escape key is pressed', () => { - const searchBox: SearchBoxComponent = fixture.debugElement.query(By.directive(SearchBoxComponent)).componentInstance; + const searchBox: SearchBoxComponent = fixture.debugElement.query( + By.directive(SearchBoxComponent) + ).componentInstance; spyOn(searchBox, 'focus'); component.showSearchResults = true; window.document.dispatchEvent(new KeyboardEvent('keyup', { key: 'Escape' })); @@ -809,7 +823,15 @@ describe('AppComponent', () => { const searchService = TestBed.inject(SearchService) as Partial as MockSearchService; const results = [ - { path: 'news', title: 'News', type: 'marketing', keywords: '', titleWords: '', deprecated: false, topics: '' } + { + path: 'news', + title: 'News', + type: 'marketing', + keywords: '', + titleWords: '', + deprecated: false, + topics: '', + }, ]; searchService.searchResults.next({ query: 'something', results }); diff --git a/aio/src/app/app.component.ts b/aio/src/app/app.component.ts index 58ba84c18fd..d37e88e9101 100644 --- a/aio/src/app/app.component.ts +++ b/aio/src/app/app.component.ts @@ -1,4 +1,13 @@ -import { Component, ElementRef, HostBinding, HostListener, OnInit, QueryList, ViewChild, ViewChildren } from '@angular/core'; +import { + Component, + ElementRef, + HostBinding, + HostListener, + OnInit, + QueryList, + ViewChild, + ViewChildren, +} from '@angular/core'; import { MatSidenav } from '@angular/material/sidenav'; import { DocumentContents, DocumentService } from 'app/documents/document.service'; import { NotificationComponent } from 'app/layout/notification/notification.component'; diff --git a/aio/src/app/custom-elements/contributor/contributor.component.ts b/aio/src/app/custom-elements/contributor/contributor.component.ts index e02f73cb818..95e9c144a85 100644 --- a/aio/src/app/custom-elements/contributor/contributor.component.ts +++ b/aio/src/app/custom-elements/contributor/contributor.component.ts @@ -11,20 +11,22 @@ import { CONTENT_URL_PREFIX } from 'app/documents/document.service';

{{person.name}}

- diff --git a/aio/src/app/custom-elements/element-registry.ts b/aio/src/app/custom-elements/element-registry.ts index 776a60d1653..1d1d8afa0fc 100644 --- a/aio/src/app/custom-elements/element-registry.ts +++ b/aio/src/app/custom-elements/element-registry.ts @@ -60,7 +60,9 @@ export interface WithCustomElementComponent { } /** Injection token to provide the element path modules. */ -export const ELEMENT_MODULE_LOAD_CALLBACKS_TOKEN = new InjectionToken>('aio/elements-map'); +export const ELEMENT_MODULE_LOAD_CALLBACKS_TOKEN = new InjectionToken< + Map +>('aio/elements-map'); /** Map of possible custom element selectors to their lazy-loadable module paths. */ export const ELEMENT_MODULE_LOAD_CALLBACKS = new Map(); diff --git a/aio/src/app/custom-elements/elements-loader.ts b/aio/src/app/custom-elements/elements-loader.ts index 73b1c105226..9dc8eb8a5a4 100644 --- a/aio/src/app/custom-elements/elements-loader.ts +++ b/aio/src/app/custom-elements/elements-loader.ts @@ -52,7 +52,7 @@ export class ElementsLoader { // Load and register the custom element (for the first time). const modulePathLoader = this.elementsToLoad.get(selector) as LoadChildrenCallback; const loadedAndRegistered = - (modulePathLoader() as Promise | Type>) + (modulePathLoader() as Promise | Type>) .then(elementModuleOrFactory => { /** * With View Engine, the NgModule factory is created and provided when loaded. diff --git a/aio/src/app/custom-elements/toc/toc.component.spec.ts b/aio/src/app/custom-elements/toc/toc.component.spec.ts index e869d8f950f..a9a86e2af9d 100644 --- a/aio/src/app/custom-elements/toc/toc.component.spec.ts +++ b/aio/src/app/custom-elements/toc/toc.component.spec.ts @@ -110,7 +110,9 @@ describe('TocComponent', () => { describe('when fewer than `maxPrimary` TocItems', () => { beforeEach(() => { - tocService.tocList.next([tocItem('Heading A'), tocItem('Heading B'), tocItem('Heading C'), tocItem('Heading D')]); + tocService.tocList.next( + [ tocItem('Heading A'), tocItem('Heading B'), tocItem('Heading C'), tocItem('Heading D') ] + ); fixture.detectChanges(); page = setPage(); }); diff --git a/aio/src/app/custom-elements/toc/toc.component.ts b/aio/src/app/custom-elements/toc/toc.component.ts index 9883ffb4410..d7a0dfe06c6 100644 --- a/aio/src/app/custom-elements/toc/toc.component.ts +++ b/aio/src/app/custom-elements/toc/toc.component.ts @@ -51,7 +51,8 @@ export class TocComponent implements OnInit, AfterViewInit, OnDestroy { if (!this.isEmbedded) { // We use the `asap` scheduler because updates to `activeItemIndex` are triggered by DOM changes, // which, in turn, are caused by the rendering that happened due to a ChangeDetection. - // Without asap, we would be updating the model while still in a ChangeDetection handler, which is disallowed by Angular. + // Without asap, we would be updating the model while still in a ChangeDetection handler, + // which is disallowed by Angular. combineLatest([ this.tocService.activeItemIndex.pipe(subscribeOn(asapScheduler)), this.items.changes.pipe(startWith(this.items)), diff --git a/aio/src/app/documents/document.service.spec.ts b/aio/src/app/documents/document.service.spec.ts index 1a7628953ad..84af677806a 100644 --- a/aio/src/app/documents/document.service.spec.ts +++ b/aio/src/app/documents/document.service.spec.ts @@ -135,12 +135,17 @@ describe('DocumentService', () => { httpMock.expectOne({}).flush(null, {status: 500, statusText: 'Server Error'}); expect(latestDocument.id).toBe(FETCHING_ERROR_ID); - expect(latestDocument.contents?.toString()).toContain('We are unable to retrieve the "initial/doc" page at this time.'); + expect( + latestDocument.contents?.toString() + ).toContain('We are unable to retrieve the "initial/doc" page at this time.'); expect(logger.output.error).toEqual([ [jasmine.any(Error)] ]); expect(logger.output.error[0][0].message) - .toEqual("Error fetching document 'initial/doc': (Http failure response for generated/docs/initial/doc.json: 500 Server Error)"); + .toEqual( + 'Error fetching document \'initial/doc\': ' + + '(Http failure response for generated/docs/initial/doc.json: 500 Server Error)' + ); locationService.go('new/doc'); httpMock.expectOne({}).flush(doc1); diff --git a/aio/src/app/layout/doc-viewer/doc-viewer.component.ts b/aio/src/app/layout/doc-viewer/doc-viewer.component.ts index 69c8ead8a8d..6b03d81363d 100644 --- a/aio/src/app/layout/doc-viewer/doc-viewer.component.ts +++ b/aio/src/app/layout/doc-viewer/doc-viewer.component.ts @@ -212,8 +212,12 @@ export class DocViewerComponent implements OnDestroy { // Some properties are not assignable and thus cannot be animated. // Example methods, readonly and CSS properties: // "length", "parentRule", "getPropertyPriority", "getPropertyValue", "item", "removeProperty", "setProperty" - type StringValueCSSStyleDeclaration - = Exclude<{ [K in keyof CSSStyleDeclaration]: CSSStyleDeclaration[K] extends string ? K : never }[keyof CSSStyleDeclaration], number>; + type StringValueCSSStyleDeclaration = Exclude< + { + [K in keyof CSSStyleDeclaration]: CSSStyleDeclaration[K] extends string ? K : never; + }[keyof CSSStyleDeclaration], + number + >; const animateProp = (elem: HTMLElement, prop: StringValueCSSStyleDeclaration, from: string, to: string, duration = 200) => { const animationsDisabled = !DocViewerComponent.animationsEnabled diff --git a/aio/src/app/layout/mode-banner/mode-banner.component.ts b/aio/src/app/layout/mode-banner/mode-banner.component.ts index 759dcc5c381..5e7d31c132f 100644 --- a/aio/src/app/layout/mode-banner/mode-banner.component.ts +++ b/aio/src/app/layout/mode-banner/mode-banner.component.ts @@ -4,11 +4,13 @@ import { VersionInfo } from 'app/navigation/navigation.service'; @Component({ selector: 'aio-mode-banner', template: ` -
-

This is the archived documentation for Angular v{{version?.major}}. - Please visit angular.io to see documentation for the current version of Angular.

-
- ` +
+

+ This is the archived documentation for Angular v{{ version?.major }}. Please visit + angular.io to see documentation for the current version of Angular. +

+
+ `, }) export class ModeBannerComponent { @Input() mode: string; diff --git a/aio/src/app/navigation/navigation.service.ts b/aio/src/app/navigation/navigation.service.ts index bf3e08a71b5..7bfcd7ed88d 100644 --- a/aio/src/app/navigation/navigation.service.ts +++ b/aio/src/app/navigation/navigation.service.ts @@ -9,7 +9,14 @@ import { CONTENT_URL_PREFIX } from 'app/documents/document.service'; // Import and re-export the Navigation model types import { CurrentNodes, NavigationNode, NavigationResponse, NavigationViews, VersionInfo } from './navigation.model'; -export { CurrentNodes, CurrentNode, NavigationNode, NavigationResponse, NavigationViews, VersionInfo } from './navigation.model'; +export { + CurrentNodes, + CurrentNode, + NavigationNode, + NavigationResponse, + NavigationViews, + VersionInfo, +} from './navigation.model'; export const navigationPath = CONTENT_URL_PREFIX + 'navigation.json'; @@ -46,8 +53,8 @@ export class NavigationService { * We create an observable by calling `http.get` but then publish it to share the result * among multiple subscribers, without triggering new requests. * We use `publishLast` because once the http request is complete the request observable completes. - * If you use `publish` here then the completed request observable will cause the subscribed observables to complete too. - * We `connect` to the published observable to trigger the request immediately. + * If you use `publish` here then the completed request observable will cause the subscribed + * observables to complete too. We `connect` to the published observable to trigger the request immediately. * We could use `.refCount` here but then if the subscribers went from 1 -> 0 -> 1 then you would get * another request to the server. * We are not storing the subscription from connecting as we do not expect this service to be destroyed. diff --git a/aio/src/app/shared/location.service.spec.ts b/aio/src/app/shared/location.service.spec.ts index e5435f58e21..a42844bb85e 100644 --- a/aio/src/app/shared/location.service.spec.ts +++ b/aio/src/app/shared/location.service.spec.ts @@ -389,7 +389,9 @@ describe('LocationService', () => { it('should convert the params to a query string', () => { const params = { foo: 'bar', moo: 'car' }; service.setSearch('Some label', params); - expect(platformLocation.replaceState).toHaveBeenCalledWith(jasmine.any(Object), 'Some label', jasmine.any(String)); + expect(platformLocation.replaceState).toHaveBeenCalledWith( + jasmine.any(Object),'Some label', jasmine.any(String) + ); const [path, query] = platformLocation.replaceState.calls.mostRecent().args[2].split('?'); expect(path).toEqual('a/b/c'); expect(query).toContain('foo=bar'); diff --git a/aio/src/app/shared/scroll-spy.service.spec.ts b/aio/src/app/shared/scroll-spy.service.spec.ts index 1cc9956fcc4..b17e279fc32 100644 --- a/aio/src/app/shared/scroll-spy.service.spec.ts +++ b/aio/src/app/shared/scroll-spy.service.spec.ts @@ -3,7 +3,12 @@ import { fakeAsync, tick } from '@angular/core/testing'; import { DOCUMENT } from '@angular/common'; import { ScrollService } from 'app/shared/scroll.service'; -import { ScrollItem, ScrollSpiedElement, ScrollSpiedElementGroup, ScrollSpyService } from 'app/shared/scroll-spy.service'; +import { + ScrollItem, + ScrollSpiedElement, + ScrollSpiedElementGroup, + ScrollSpyService, +} from 'app/shared/scroll-spy.service'; describe('ScrollSpiedElement', () => { diff --git a/aio/src/app/shared/search-results/search-results.component.spec.ts b/aio/src/app/shared/search-results/search-results.component.spec.ts index af32de5b886..c52c9f7ba17 100644 --- a/aio/src/app/shared/search-results/search-results.component.spec.ts +++ b/aio/src/app/shared/search-results/search-results.component.spec.ts @@ -37,6 +37,7 @@ describe('SearchResultsComponent', () => { /** Get a full set of test results. "Take" what you need */ beforeEach(() => { + /* eslint-disable max-len */ apiD = { path: 'api/d', title: 'API D', deprecated: false, keywords: '', titleWords: '', type: '', topics: '' }; apiC = { path: 'api/c', title: 'API C', deprecated: false, keywords: '', titleWords: '', type: '', topics: '' }; guideA = { path: 'guide/a', title: 'Guide A', deprecated: false, keywords: '', titleWords: '', type: '', topics: '' }; @@ -52,9 +53,24 @@ describe('SearchResultsComponent', () => { guideL = { path: 'guide/l', title: 'Guide l', deprecated: false, keywords: '', titleWords: '', type: '', topics: '' }; guideM = { path: 'guide/m', title: 'Guide m', deprecated: false, keywords: '', titleWords: '', type: '', topics: '' }; guideN = { path: 'guide/n', title: 'Guide n', deprecated: false, keywords: '', titleWords: '', type: '', topics: '' }; + /* eslint-enable max-len */ standardResults = [ - guideA, apiD, guideB, guideAC, apiC, guideN, guideM, guideL, guideK, guideJ, guideI, guideH, guideG, guideF, guideE, + guideA, + apiD, + guideB, + guideAC, + apiC, + guideN, + guideM, + guideL, + guideK, + guideJ, + guideI, + guideH, + guideG, + guideF, + guideE, ]; }); @@ -71,8 +87,24 @@ describe('SearchResultsComponent', () => { }); it('should map the search results into groups based on their containing folder', () => { - const startA = { path: 'start/a', title: 'Start A', deprecated: false, keywords: '', titleWords: '', type: '', topics: '' }; - const tutorialA = { path: 'tutorial/a', title: 'Tutorial A', deprecated: false, keywords: '', titleWords: '', type: '', topics: '' }; + const startA = { + path: 'start/a', + title: 'Start A', + deprecated: false, + keywords: '', + titleWords: '', + type: '', + topics: '', + }; + const tutorialA = { + path: 'tutorial/a', + title: 'Tutorial A', + deprecated: false, + keywords: '', + titleWords: '', + type: '', + topics: '', + }; setSearchResults('', [guideA, apiD, guideB, startA, tutorialA]); expect(component.searchAreas).toEqual([ @@ -84,20 +116,92 @@ describe('SearchResultsComponent', () => { it('should special case results that are top level folders', () => { setSearchResults('', [ - { path: 'docs', title: 'Docs introduction', type: '', keywords: '', titleWords: '', deprecated: false, topics: '' }, - { path: 'start', title: 'Getting started', type: '', keywords: '', titleWords: '', deprecated: false, topics: '' }, - { path: 'tutorial', title: 'Tutorial index', type: '', keywords: '', titleWords: '', deprecated: false, topics: '' }, - { path: 'tutorial/toh-pt1', title: 'Tutorial - part 1', type: '', keywords: '', titleWords: '', deprecated: false, topics: '' }, + { + path: 'docs', + title: 'Docs introduction', + type: '', + keywords: '', + titleWords: '', + deprecated: false, + topics: '', + }, + { + path: 'start', + title: 'Getting started', + type: '', + keywords: '', + titleWords: '', + deprecated: false, + topics: '', + }, + { + path: 'tutorial', + title: 'Tutorial index', + type: '', + keywords: '', + titleWords: '', + deprecated: false, + topics: '', + }, + { + path: 'tutorial/toh-pt1', + title: 'Tutorial - part 1', + type: '', + keywords: '', + titleWords: '', + deprecated: false, + topics: '', + }, ]); expect(component.searchAreas).toEqual([ - { name: 'guides', priorityPages: [ - { path: 'docs', title: 'Docs introduction', type: '', keywords: '', titleWords: '', deprecated: false, topics: '' }, - ], pages: [] }, - { name: 'tutorials', priorityPages: [ - { path: 'start', title: 'Getting started', type: '', keywords: '', titleWords: '', deprecated: false, topics: '' }, - { path: 'tutorial', title: 'Tutorial index', type: '', keywords: '', titleWords: '', deprecated: false, topics: '' }, - { path: 'tutorial/toh-pt1', title: 'Tutorial - part 1', type: '', keywords: '', titleWords: '', deprecated: false, topics: '' }, - ], pages: [] }, + { + name: 'guides', + priorityPages: [ + { + path: 'docs', + title: 'Docs introduction', + type: '', + keywords: '', + titleWords: '', + deprecated: false, + topics: '', + }, + ], + pages: [], + }, + { + name: 'tutorials', + priorityPages: [ + { + path: 'start', + title: 'Getting started', + type: '', + keywords: '', + titleWords: '', + deprecated: false, + topics: '', + }, + { + path: 'tutorial', + title: 'Tutorial index', + type: '', + keywords: '', + titleWords: '', + deprecated: false, + topics: '', + }, + { + path: 'tutorial/toh-pt1', + title: 'Tutorial - part 1', + type: '', + keywords: '', + titleWords: '', + deprecated: false, + topics: '', + }, + ], + pages: [], + }, ]); }); @@ -154,6 +258,7 @@ describe('SearchResultsComponent', () => { guideE.deprecated = true; setSearchResults('something', standardResults); }); + // eslint-disable-next-line max-len it('should include deprecated items in priority pages unless there are fewer than 5 non-deprecated priority pages', () => { // Priority pages do not include deprecated items: expect(component.searchAreas[1].priorityPages).not.toContain(guideAC); @@ -195,7 +300,15 @@ describe('SearchResultsComponent', () => { component.resultSelected.subscribe((result: SearchResult) => selected = result); selected = null; - searchResult = { path: 'news', title: 'News', type: 'marketing', keywords: '', titleWords: '', deprecated: false, topics: '' }; + searchResult = { + path: 'news', + title: 'News', + type: 'marketing', + keywords: '', + titleWords: '', + deprecated: false, + topics: '', + }; setSearchResults('something', [searchResult]); fixture.detectChanges(); diff --git a/aio/src/app/shared/toc.service.ts b/aio/src/app/shared/toc.service.ts index bf191d5776e..e27e637beab 100644 --- a/aio/src/app/shared/toc.service.ts +++ b/aio/src/app/shared/toc.service.ts @@ -130,8 +130,14 @@ export class TocService { } // Helpers -function querySelectorAll(parent: Element, selector: K): HTMLElementTagNameMap[K][]; -function querySelectorAll(parent: Element, selector: K): SVGElementTagNameMap[K][]; +function querySelectorAll( + parent: Element, + selector: K +): HTMLElementTagNameMap[K][]; +function querySelectorAll( + parent: Element, + selector: K +): SVGElementTagNameMap[K][]; function querySelectorAll(parent: Element, selector: string): E[]; function querySelectorAll(parent: Element, selector: string) { // Wrap the `NodeList` as a regular `Array` to have access to array methods. diff --git a/aio/tests/e2e/src/onerror.e2e-spec.ts b/aio/tests/e2e/src/onerror.e2e-spec.ts index f1168a09f83..52b55bc83f3 100644 --- a/aio/tests/e2e/src/onerror.e2e-spec.ts +++ b/aio/tests/e2e/src/onerror.e2e-spec.ts @@ -1,7 +1,7 @@ import { browser } from 'protractor'; import { SitePage } from './app.po'; -/* tslint:disable:max-line-length */ +/* eslint-disable max-len */ describe('onerror handler', () => { let page: SitePage; diff --git a/aio/tools/firebase-test-utils/.eslintrc.json b/aio/tools/firebase-test-utils/.eslintrc.json index 6d720c8a5cb..d86e9bca8bb 100644 --- a/aio/tools/firebase-test-utils/.eslintrc.json +++ b/aio/tools/firebase-test-utils/.eslintrc.json @@ -1,4 +1,5 @@ { + "root": true, "extends": "../../.eslintrc.json", "overrides": [ { diff --git a/aio/tools/firebase-test-utils/FirebaseRedirect.ts b/aio/tools/firebase-test-utils/FirebaseRedirect.ts index 8c32367043d..71b5837bed3 100644 --- a/aio/tools/firebase-test-utils/FirebaseRedirect.ts +++ b/aio/tools/firebase-test-utils/FirebaseRedirect.ts @@ -20,8 +20,14 @@ export class FirebaseRedirect { return undefined; } - const namedReplacers = this.source.namedGroups.map<[RegExp, string]>(name => [ XRegExp(`:${name}`, 'g'), match[name] ]); - const restReplacers = this.source.restNamedGroups.map<[RegExp, string]>(name => [ XRegExp(`:${name}\\*`, 'g'), match[name] ]); + const namedReplacers = this.source.namedGroups.map<[RegExp, string]>((name) => [ + XRegExp(`:${name}`, 'g'), + match[name], + ]); + const restReplacers = this.source.restNamedGroups.map<[RegExp, string]>((name) => [ + XRegExp(`:${name}\\*`, 'g'), + match[name], + ]); return XRegExp.replaceEach(this.destination, [...namedReplacers, ...restReplacers]); } } diff --git a/aio/tools/ng-packages-installer/.eslintrc.js b/aio/tools/ng-packages-installer/.eslintrc.js index e7de9e6e5a7..95fcef6b503 100644 --- a/aio/tools/ng-packages-installer/.eslintrc.js +++ b/aio/tools/ng-packages-installer/.eslintrc.js @@ -1,4 +1,5 @@ module.exports = { + root: true, extends: [ 'eslint:recommended', 'plugin:jasmine/recommended', diff --git a/aio/tools/transforms/.eslintrc.js b/aio/tools/transforms/.eslintrc.js index 473f5a49da6..11fb3926608 100644 --- a/aio/tools/transforms/.eslintrc.js +++ b/aio/tools/transforms/.eslintrc.js @@ -1,4 +1,5 @@ module.exports = { + 'root': true, 'env': { 'es6': true, 'jasmine': true,