mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
refactor(docs-infra): introduce max-len 120 eslint rule (#43439)
add the max-len rule to the aio eslintrc and fix what code breaks such rule PR Close #43439
This commit is contained in:
committed by
Andrew Kushnir
parent
4ef9d247b6
commit
66c6dbdc79
@@ -27,6 +27,7 @@
|
||||
"style": "kebab-case"
|
||||
}
|
||||
],
|
||||
"max-len": ["error" , 120],
|
||||
"@angular-eslint/directive-selector": [
|
||||
"error",
|
||||
{
|
||||
|
||||
@@ -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<SearchService> 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 });
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -11,20 +11,22 @@ import { CONTENT_URL_PREFIX } from 'app/documents/document.service';
|
||||
<div class="card-front" (click)="flipCard(person)" (keyup.enter)="flipCard(person)">
|
||||
<h3>{{person.name}}</h3>
|
||||
|
||||
<div class="contributor-image" [style.background-image]="'url('+pictureBase+(person.picture || noPicture)+')'">
|
||||
<div class="contributor-info">
|
||||
<a *ngIf="person.bio" mat-button class="info-item">
|
||||
View Bio
|
||||
</a>
|
||||
<a *ngIf="person.twitter" mat-icon-button class="info-item icon"
|
||||
href="https://twitter.com/{{person.twitter}}" target="_blank" (click)="$event.stopPropagation()">
|
||||
<mat-icon svgIcon="logos:twitter"></mat-icon>
|
||||
</a>
|
||||
<a *ngIf="person.website" mat-icon-button class="info-item icon"
|
||||
href="{{person.website}}" target="_blank" (click)="$event.stopPropagation()">
|
||||
<mat-icon class="link-icon">link</mat-icon>
|
||||
</a>
|
||||
</div>
|
||||
<div class="contributor-image"
|
||||
[style.background-image]="'url('+pictureBase+(person.picture || noPicture)+')'">
|
||||
<div class="contributor-info">
|
||||
<a *ngIf="person.bio" mat-button class="info-item">
|
||||
View Bio
|
||||
</a>
|
||||
<a *ngIf="person.twitter" mat-icon-button class="info-item icon"
|
||||
href="https://twitter.com/{{person.twitter}}"
|
||||
target="_blank" (click)="$event.stopPropagation()">
|
||||
<mat-icon svgIcon="logos:twitter"></mat-icon>
|
||||
</a>
|
||||
<a *ngIf="person.website" mat-icon-button class="info-item icon"
|
||||
href="{{person.website}}" target="_blank" (click)="$event.stopPropagation()">
|
||||
<mat-icon class="link-icon">link</mat-icon>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -60,7 +60,9 @@ export interface WithCustomElementComponent {
|
||||
}
|
||||
|
||||
/** Injection token to provide the element path modules. */
|
||||
export const ELEMENT_MODULE_LOAD_CALLBACKS_TOKEN = new InjectionToken<Map<string, LoadChildrenCallback>>('aio/elements-map');
|
||||
export const ELEMENT_MODULE_LOAD_CALLBACKS_TOKEN = new InjectionToken<
|
||||
Map<string, LoadChildrenCallback>
|
||||
>('aio/elements-map');
|
||||
|
||||
/** Map of possible custom element selectors to their lazy-loadable module paths. */
|
||||
export const ELEMENT_MODULE_LOAD_CALLBACKS = new Map<string, LoadChildrenCallback>();
|
||||
|
||||
@@ -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<NgModuleFactory<WithCustomElementComponent> | Type<WithCustomElementComponent>>)
|
||||
(modulePathLoader() as Promise<NgModuleFactory<WithCustomElementComponent> | Type<WithCustomElementComponent>>)
|
||||
.then(elementModuleOrFactory => {
|
||||
/**
|
||||
* With View Engine, the NgModule factory is created and provided when loaded.
|
||||
|
||||
@@ -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();
|
||||
});
|
||||
|
||||
@@ -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)),
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -4,11 +4,13 @@ import { VersionInfo } from 'app/navigation/navigation.service';
|
||||
@Component({
|
||||
selector: 'aio-mode-banner',
|
||||
template: `
|
||||
<div *ngIf="mode === 'archive'" class="mode-banner alert archive-warning">
|
||||
<p>This is the <strong>archived documentation for Angular v{{version?.major}}.</strong>
|
||||
Please visit <a href="https://angular.io/">angular.io</a> to see documentation for the current version of Angular.</p>
|
||||
</div>
|
||||
`
|
||||
<div *ngIf="mode === 'archive'" class="mode-banner alert archive-warning">
|
||||
<p>
|
||||
This is the <strong>archived documentation for Angular v{{ version?.major }}.</strong> Please visit
|
||||
<a href="https://angular.io/">angular.io</a> to see documentation for the current version of Angular.
|
||||
</p>
|
||||
</div>
|
||||
`,
|
||||
})
|
||||
export class ModeBannerComponent {
|
||||
@Input() mode: string;
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -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', () => {
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -130,8 +130,14 @@ export class TocService {
|
||||
}
|
||||
|
||||
// Helpers
|
||||
function querySelectorAll<K extends keyof HTMLElementTagNameMap>(parent: Element, selector: K): HTMLElementTagNameMap[K][];
|
||||
function querySelectorAll<K extends keyof SVGElementTagNameMap>(parent: Element, selector: K): SVGElementTagNameMap[K][];
|
||||
function querySelectorAll<K extends keyof HTMLElementTagNameMap>(
|
||||
parent: Element,
|
||||
selector: K
|
||||
): HTMLElementTagNameMap[K][];
|
||||
function querySelectorAll<K extends keyof SVGElementTagNameMap>(
|
||||
parent: Element,
|
||||
selector: K
|
||||
): SVGElementTagNameMap[K][];
|
||||
function querySelectorAll<E extends Element = Element>(parent: Element, selector: string): E[];
|
||||
function querySelectorAll(parent: Element, selector: string) {
|
||||
// Wrap the `NodeList` as a regular `Array` to have access to array methods.
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
{
|
||||
"root": true,
|
||||
"extends": "../../.eslintrc.json",
|
||||
"overrides": [
|
||||
{
|
||||
|
||||
@@ -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]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
module.exports = {
|
||||
root: true,
|
||||
extends: [
|
||||
'eslint:recommended',
|
||||
'plugin:jasmine/recommended',
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
module.exports = {
|
||||
'root': true,
|
||||
'env': {
|
||||
'es6': true,
|
||||
'jasmine': true,
|
||||
|
||||
Reference in New Issue
Block a user