mirror of
https://github.com/angular/angular
synced 2026-05-24 09:28:37 +00:00
docs(docs-infra): Handle additional description format
Ex: https://angular.dev/api/router/withExperimentalPlatformNavigation
This commit is contained in:
parent
b885851cbe
commit
f0b1061791
8 changed files with 268 additions and 222 deletions
|
|
@ -22,6 +22,10 @@ export interface HasJsDocTags {
|
|||
jsdocTags: JsDocTagEntry[];
|
||||
}
|
||||
|
||||
export interface MaybeJsDocTags {
|
||||
jsdocTags?: JsDocTagEntry[];
|
||||
}
|
||||
|
||||
export interface HasAdditionalLinks {
|
||||
additionalLinks: LinkEntryRenderable[];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -73,13 +73,14 @@ export function FunctionReference(entry: FunctionEntryRenderable) {
|
|||
<DeprecationWarning entry={entry} />
|
||||
<SectionApi entry={entry} />
|
||||
<div className={REFERENCE_MEMBERS}>
|
||||
{entry.signatures.map((s, i) =>
|
||||
signatureCard(s.name, getFunctionMetadataRenderable(s, entry.moduleName, entry.repo), {
|
||||
id: `${s.name}_${i}`,
|
||||
printSignaturesAsHeader,
|
||||
hideUsageNotes: true,
|
||||
}),
|
||||
)}
|
||||
{entry.signatures.length > 1 &&
|
||||
entry.signatures.map((s, i) =>
|
||||
signatureCard(s.name, getFunctionMetadataRenderable(s, entry.moduleName, entry.repo), {
|
||||
id: `${s.name}_${i}`,
|
||||
printSignaturesAsHeader,
|
||||
hideUsageNotes: true,
|
||||
}),
|
||||
)}
|
||||
</div>
|
||||
|
||||
<SectionDescription entry={entry} />
|
||||
|
|
|
|||
|
|
@ -8,12 +8,12 @@
|
|||
|
||||
import {readFile} from 'fs/promises';
|
||||
import {JSDOM} from 'jsdom';
|
||||
import {getRenderable} from '../processing.mjs';
|
||||
import {renderEntry} from '../rendering.mjs';
|
||||
import {setSymbols} from '../symbol-context.mjs';
|
||||
import {resolve} from 'path';
|
||||
import {initHighlighter} from '../../../shared/shiki.mjs';
|
||||
import {getRenderable} from '../processing.mjs';
|
||||
import {renderEntry} from '../rendering.mjs';
|
||||
import {setHighlighterInstance} from '../shiki/shiki.mjs';
|
||||
import {setSymbols} from '../symbol-context.mjs';
|
||||
|
||||
// Note: The tests will probably break if the schema of the api extraction changes.
|
||||
// All entries in the fake-entries are extracted from Angular's api.
|
||||
|
|
@ -69,7 +69,7 @@ describe('markdown to html', () => {
|
|||
it('should render multiple {@link} blocks', () => {
|
||||
const provideClientHydrationEntry = entries.get('provideClientHydration')!;
|
||||
expect(provideClientHydrationEntry).toBeDefined();
|
||||
const cardItem = provideClientHydrationEntry.querySelector('.docs-reference-card-item')!;
|
||||
const cardItem = provideClientHydrationEntry.querySelector('.docs-api')!;
|
||||
expect(cardItem.innerHTML).not.toContain('@link');
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -17,204 +17,207 @@ import {
|
|||
|
||||
// @ts-ignore This compiles fine, but Webstorm doesn't like the ESM import in a CJS context.
|
||||
describe('jsdoc transforms', () => {
|
||||
it('should transform links', () => {
|
||||
setCurrentSymbol('Router');
|
||||
setSymbols(
|
||||
Object.fromEntries([
|
||||
['Route', 'test'],
|
||||
['Router', 'test'],
|
||||
['Router.someMethod', 'test'],
|
||||
['Router.someMethodWithParenthesis', 'test'],
|
||||
['FormGroup', 'test'],
|
||||
['FormGroup.someMethod', 'test'],
|
||||
]),
|
||||
);
|
||||
describe('addHtmlAdditionalLinks', () => {
|
||||
it('should transform links', () => {
|
||||
setCurrentSymbol('Router');
|
||||
setSymbols(
|
||||
Object.fromEntries([
|
||||
['Route', 'test'],
|
||||
['Router', 'test'],
|
||||
['Router.someMethod', 'test'],
|
||||
['Router.someMethodWithParenthesis', 'test'],
|
||||
['FormGroup', 'test'],
|
||||
['FormGroup.someMethod', 'test'],
|
||||
]),
|
||||
);
|
||||
|
||||
const entry = addHtmlAdditionalLinks({
|
||||
jsdocTags: [
|
||||
{
|
||||
name: 'see',
|
||||
comment: '[Angular](https://angular.io)',
|
||||
},
|
||||
{
|
||||
name: 'see',
|
||||
comment: '[Angular](https://angular.io "Angular")',
|
||||
},
|
||||
{
|
||||
name: 'see',
|
||||
comment: '{@link Route}',
|
||||
},
|
||||
{
|
||||
name: 'see',
|
||||
comment: '{@link Route Something else}',
|
||||
},
|
||||
{
|
||||
name: 'see',
|
||||
comment: '{@link #someMethod}',
|
||||
},
|
||||
{
|
||||
name: 'see',
|
||||
comment: '{@link #someMethodWithParenthesis()}',
|
||||
},
|
||||
{
|
||||
name: 'see',
|
||||
comment: '{@link someMethod()}',
|
||||
},
|
||||
{
|
||||
name: 'see',
|
||||
comment: '{@link FormGroup.someMethod()}',
|
||||
},
|
||||
{
|
||||
name: 'see',
|
||||
comment: '{@link https://angular.dev/api/core/ApplicationRef}',
|
||||
},
|
||||
{
|
||||
name: 'see',
|
||||
comment: '{@link https://angular.dev}',
|
||||
},
|
||||
{
|
||||
name: 'see',
|
||||
comment: '{@link /cli/build ng build}',
|
||||
},
|
||||
{
|
||||
name: 'see',
|
||||
comment: '{@link /ecosystem/rxjs-interop/output-interop Output Interop}',
|
||||
},
|
||||
],
|
||||
moduleName: 'test',
|
||||
});
|
||||
|
||||
expect(entry.additionalLinks[0]).toEqual({
|
||||
label: 'Angular',
|
||||
url: 'https://angular.io',
|
||||
title: undefined,
|
||||
});
|
||||
|
||||
expect(entry.additionalLinks[1]).toEqual({
|
||||
label: 'Angular',
|
||||
url: 'https://angular.io',
|
||||
title: 'Angular',
|
||||
});
|
||||
|
||||
expect(entry.additionalLinks[2]).toEqual({
|
||||
label: 'Route',
|
||||
url: '/api/test/Route',
|
||||
});
|
||||
|
||||
expect(entry.additionalLinks[3]).toEqual({
|
||||
label: 'Something else',
|
||||
url: '/api/test/Route',
|
||||
});
|
||||
|
||||
expect(entry.additionalLinks[4]).toEqual({
|
||||
label: 'someMethod',
|
||||
url: '/api/test/Router#someMethod',
|
||||
});
|
||||
expect(entry.additionalLinks[5]).toEqual({
|
||||
label: 'someMethodWithParenthesis()',
|
||||
url: '/api/test/Router#someMethodWithParenthesis',
|
||||
});
|
||||
expect(entry.additionalLinks[6]).toEqual({
|
||||
label: 'someMethod()',
|
||||
url: '/api/test/Router#someMethod',
|
||||
});
|
||||
expect(entry.additionalLinks[7]).toEqual({
|
||||
label: 'FormGroup.someMethod()',
|
||||
url: '/api/test/FormGroup#someMethod',
|
||||
});
|
||||
|
||||
expect(entry.additionalLinks[8]).toEqual({
|
||||
label: 'ApplicationRef',
|
||||
url: 'https://angular.dev/api/core/ApplicationRef',
|
||||
});
|
||||
expect(entry.additionalLinks[9]).toEqual({
|
||||
label: 'angular.dev',
|
||||
url: 'https://angular.dev',
|
||||
});
|
||||
|
||||
expect(entry.additionalLinks[10]).toEqual({
|
||||
label: 'ng build',
|
||||
url: '/cli/build',
|
||||
});
|
||||
|
||||
expect(entry.additionalLinks[11]).toEqual({
|
||||
label: 'Output Interop',
|
||||
url: '/ecosystem/rxjs-interop/output-interop',
|
||||
});
|
||||
});
|
||||
|
||||
it('should convert backticks to code tags in markdown links', () => {
|
||||
const entry = addHtmlAdditionalLinks({
|
||||
jsdocTags: [
|
||||
{
|
||||
name: 'see',
|
||||
comment:
|
||||
'[Host view using `ViewContainerRef.createComponent`](guide/components/programmatic-rendering#host-view-using-viewcontainerrefcreatecomponent)',
|
||||
},
|
||||
{
|
||||
name: 'see',
|
||||
comment:
|
||||
'[Popup attached to `document.body` with `createComponent` + `hostElement`](guide/components/programmatic-rendering#popup-attached-to-documentbody-with-createcomponent--hostelement)',
|
||||
},
|
||||
{
|
||||
name: 'see',
|
||||
comment: '[Method with `backticks` in title](https://example.com "Title with `code`")',
|
||||
},
|
||||
],
|
||||
moduleName: 'test',
|
||||
});
|
||||
|
||||
expect(entry.additionalLinks[0]).toEqual({
|
||||
label: 'Host view using <code>ViewContainerRef.createComponent</code>',
|
||||
url: 'guide/components/programmatic-rendering#host-view-using-viewcontainerrefcreatecomponent',
|
||||
title: undefined,
|
||||
});
|
||||
|
||||
expect(entry.additionalLinks[1]).toEqual({
|
||||
label:
|
||||
'Popup attached to <code>document.body</code> with <code>createComponent</code> + <code>hostElement</code>',
|
||||
url: 'guide/components/programmatic-rendering#popup-attached-to-documentbody-with-createcomponent--hostelement',
|
||||
title: undefined,
|
||||
});
|
||||
|
||||
expect(entry.additionalLinks[2]).toEqual({
|
||||
label: 'Method with <code>backticks</code> in title',
|
||||
url: 'https://example.com',
|
||||
title: 'Title with `code`',
|
||||
});
|
||||
});
|
||||
|
||||
it('should throw on invalid relatie @link', () => {
|
||||
const entryFn = () =>
|
||||
addHtmlAdditionalLinks({
|
||||
const entry = addHtmlAdditionalLinks({
|
||||
jsdocTags: [
|
||||
{
|
||||
name: 'see',
|
||||
comment: '{@link cli/build ng build}',
|
||||
comment: '[Angular](https://angular.io)',
|
||||
},
|
||||
{
|
||||
name: 'see',
|
||||
comment: '[Angular](https://angular.io "Angular")',
|
||||
},
|
||||
{
|
||||
name: 'see',
|
||||
comment: '{@link Route}',
|
||||
},
|
||||
{
|
||||
name: 'see',
|
||||
comment: '{@link Route Something else}',
|
||||
},
|
||||
{
|
||||
name: 'see',
|
||||
comment: '{@link #someMethod}',
|
||||
},
|
||||
{
|
||||
name: 'see',
|
||||
comment: '{@link #someMethodWithParenthesis()}',
|
||||
},
|
||||
{
|
||||
name: 'see',
|
||||
comment: '{@link someMethod()}',
|
||||
},
|
||||
{
|
||||
name: 'see',
|
||||
comment: '{@link FormGroup.someMethod()}',
|
||||
},
|
||||
{
|
||||
name: 'see',
|
||||
comment: '{@link https://angular.dev/api/core/ApplicationRef}',
|
||||
},
|
||||
{
|
||||
name: 'see',
|
||||
comment: '{@link https://angular.dev}',
|
||||
},
|
||||
{
|
||||
name: 'see',
|
||||
comment: '{@link /cli/build ng build}',
|
||||
},
|
||||
{
|
||||
name: 'see',
|
||||
comment: '{@link /ecosystem/rxjs-interop/output-interop Output Interop}',
|
||||
},
|
||||
],
|
||||
moduleName: 'test',
|
||||
});
|
||||
|
||||
expect(entryFn).toThrowError(/Forbidden relative link: cli\/build ng build/);
|
||||
expect(entry.additionalLinks[0]).toEqual({
|
||||
label: 'Angular',
|
||||
url: 'https://angular.io',
|
||||
title: undefined,
|
||||
});
|
||||
|
||||
expect(entry.additionalLinks[1]).toEqual({
|
||||
label: 'Angular',
|
||||
url: 'https://angular.io',
|
||||
title: 'Angular',
|
||||
});
|
||||
|
||||
expect(entry.additionalLinks[2]).toEqual({
|
||||
label: 'Route',
|
||||
url: '/api/test/Route',
|
||||
});
|
||||
|
||||
expect(entry.additionalLinks[3]).toEqual({
|
||||
label: 'Something else',
|
||||
url: '/api/test/Route',
|
||||
});
|
||||
|
||||
expect(entry.additionalLinks[4]).toEqual({
|
||||
label: 'someMethod',
|
||||
url: '/api/test/Router#someMethod',
|
||||
});
|
||||
expect(entry.additionalLinks[5]).toEqual({
|
||||
label: 'someMethodWithParenthesis()',
|
||||
url: '/api/test/Router#someMethodWithParenthesis',
|
||||
});
|
||||
expect(entry.additionalLinks[6]).toEqual({
|
||||
label: 'someMethod()',
|
||||
url: '/api/test/Router#someMethod',
|
||||
});
|
||||
expect(entry.additionalLinks[7]).toEqual({
|
||||
label: 'FormGroup.someMethod()',
|
||||
url: '/api/test/FormGroup#someMethod',
|
||||
});
|
||||
|
||||
expect(entry.additionalLinks[8]).toEqual({
|
||||
label: 'ApplicationRef',
|
||||
url: 'https://angular.dev/api/core/ApplicationRef',
|
||||
});
|
||||
expect(entry.additionalLinks[9]).toEqual({
|
||||
label: 'angular.dev',
|
||||
url: 'https://angular.dev',
|
||||
});
|
||||
|
||||
expect(entry.additionalLinks[10]).toEqual({
|
||||
label: 'ng build',
|
||||
url: '/cli/build',
|
||||
});
|
||||
|
||||
expect(entry.additionalLinks[11]).toEqual({
|
||||
label: 'Output Interop',
|
||||
url: '/ecosystem/rxjs-interop/output-interop',
|
||||
});
|
||||
});
|
||||
|
||||
it('should convert backticks to code tags in markdown links', () => {
|
||||
const entry = addHtmlAdditionalLinks({
|
||||
jsdocTags: [
|
||||
{
|
||||
name: 'see',
|
||||
comment:
|
||||
'[Host view using `ViewContainerRef.createComponent`](guide/components/programmatic-rendering#host-view-using-viewcontainerrefcreatecomponent)',
|
||||
},
|
||||
{
|
||||
name: 'see',
|
||||
comment:
|
||||
'[Popup attached to `document.body` with `createComponent` + `hostElement`](guide/components/programmatic-rendering#popup-attached-to-documentbody-with-createcomponent--hostelement)',
|
||||
},
|
||||
{
|
||||
name: 'see',
|
||||
comment: '[Method with `backticks` in title](https://example.com "Title with `code`")',
|
||||
},
|
||||
],
|
||||
moduleName: 'test',
|
||||
});
|
||||
|
||||
expect(entry.additionalLinks[0]).toEqual({
|
||||
label: 'Host view using <code>ViewContainerRef.createComponent</code>',
|
||||
url: 'guide/components/programmatic-rendering#host-view-using-viewcontainerrefcreatecomponent',
|
||||
title: undefined,
|
||||
});
|
||||
|
||||
expect(entry.additionalLinks[1]).toEqual({
|
||||
label:
|
||||
'Popup attached to <code>document.body</code> with <code>createComponent</code> + <code>hostElement</code>',
|
||||
url: 'guide/components/programmatic-rendering#popup-attached-to-documentbody-with-createcomponent--hostelement',
|
||||
title: undefined,
|
||||
});
|
||||
|
||||
expect(entry.additionalLinks[2]).toEqual({
|
||||
label: 'Method with <code>backticks</code> in title',
|
||||
url: 'https://example.com',
|
||||
title: 'Title with `code`',
|
||||
});
|
||||
});
|
||||
|
||||
it('should throw on invalid relatie @link', () => {
|
||||
const entryFn = () =>
|
||||
addHtmlAdditionalLinks({
|
||||
jsdocTags: [
|
||||
{
|
||||
name: 'see',
|
||||
comment: '{@link cli/build ng build}',
|
||||
},
|
||||
],
|
||||
moduleName: 'test',
|
||||
});
|
||||
|
||||
expect(entryFn).toThrowError(/Forbidden relative link: cli\/build ng build/);
|
||||
});
|
||||
});
|
||||
|
||||
it('should parse markdown in descriptions', async () => {
|
||||
setHighlighterInstance(await initHighlighter());
|
||||
describe('addHtmlDescription', () => {
|
||||
it('should parse markdown in descriptions', async () => {
|
||||
setHighlighterInstance(await initHighlighter());
|
||||
|
||||
setSymbols(
|
||||
Object.fromEntries([
|
||||
['Route', 'test'],
|
||||
['Router', 'angular/router'],
|
||||
['Router.someMethod', 'test'],
|
||||
['Router.someMethodWithParenthesis', 'test'],
|
||||
['FormGroup', 'test'],
|
||||
['FormGroup.someMethod', 'test'],
|
||||
]),
|
||||
);
|
||||
setSymbols(
|
||||
Object.fromEntries([
|
||||
['Route', 'test'],
|
||||
['Router', 'angular/router'],
|
||||
['Router.someMethod', 'test'],
|
||||
['Router.someMethodWithParenthesis', 'test'],
|
||||
['FormGroup', 'test'],
|
||||
['FormGroup.someMethod', 'test'],
|
||||
]),
|
||||
);
|
||||
|
||||
const entry = addHtmlDescription({
|
||||
description: `
|
||||
const entry = addHtmlDescription({
|
||||
description: `
|
||||
\`\`\`angular-ts
|
||||
import { Router } from '@angular/router';
|
||||
|
||||
|
|
@ -223,16 +226,36 @@ function setupRouter() {
|
|||
}
|
||||
\`\`\`
|
||||
`,
|
||||
moduleName: 'test',
|
||||
moduleName: 'test',
|
||||
});
|
||||
|
||||
// Should have some shiki variables (meaning the description was highlighted).
|
||||
expect(entry.htmlDescription).toContain('--shiki');
|
||||
|
||||
// Having docs-code means that the description was parsed and formatted correctly (by the shared marked renderer)
|
||||
expect(entry.htmlDescription).toContain('class="docs-code"');
|
||||
|
||||
expect(entry.htmlDescription).toContain('/api/angular/router/Router');
|
||||
});
|
||||
|
||||
// Should have some shiki variables (meaning the description was highlighted).
|
||||
expect(entry.htmlDescription).toContain('--shiki');
|
||||
it('should transform entry with different description & description tag', () => {
|
||||
const entry = addHtmlDescription({
|
||||
'description':
|
||||
"Enables interop with the browser's `Navigation` API for router navigations.",
|
||||
'jsdocTags': [
|
||||
{
|
||||
'name': 'description',
|
||||
'comment': 'This feature is _highly_ experimental ...',
|
||||
},
|
||||
],
|
||||
'moduleName': 'platform-browser',
|
||||
});
|
||||
|
||||
// Having docs-code means that the description was parsed and formatted correctly (by the shared marked renderer)
|
||||
expect(entry.htmlDescription).toContain('class="docs-code"');
|
||||
|
||||
expect(entry.htmlDescription).toContain('/api/angular/router/Router');
|
||||
expect(entry.htmlDescription).toBe(`<p>This feature is <em>highly</em> experimental ...</p>`);
|
||||
expect(entry.shortHtmlDescription).toBe(
|
||||
`<p>Enables interop with the browser's <code>Navigation</code> API for router navigations.</p>`,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('should only mark as deprecated if all overloads are deprecated', () => {
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ export async function getFunctionRenderable(
|
|||
moduleName: string,
|
||||
repo: string,
|
||||
): Promise<FunctionEntryRenderable> {
|
||||
return setEntryFlags(
|
||||
const a = setEntryFlags(
|
||||
await addRenderableCodeToc(
|
||||
addHtmlAdditionalLinks(
|
||||
addHtmlUsageNotes(
|
||||
|
|
@ -42,6 +42,11 @@ export async function getFunctionRenderable(
|
|||
),
|
||||
),
|
||||
);
|
||||
if (entry.name === 'withExperimentalPlatformNavigation') {
|
||||
console.warn('**************', a);
|
||||
}
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
export function getFunctionMetadataRenderable(
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import {
|
|||
HasModuleName,
|
||||
HasRenderableJsDocTags,
|
||||
HasStableFlag,
|
||||
MaybeJsDocTags,
|
||||
} from '../entities/traits.mjs';
|
||||
|
||||
import {parseMarkdown} from '../../../shared/marked/parse.mjs';
|
||||
|
|
@ -43,7 +44,7 @@ const jsDoclinkRegex = /\{\s*@link\s+([^}]+)\s*\}/;
|
|||
const jsDoclinkRegexGlobal = new RegExp(jsDoclinkRegex.source, 'g');
|
||||
|
||||
/** Given an entity with a description, gets the entity augmented with an `htmlDescription`. */
|
||||
export function addHtmlDescription<T extends HasDescription & HasModuleName>(
|
||||
export function addHtmlDescription<T extends HasDescription & HasModuleName & MaybeJsDocTags>(
|
||||
entry: T,
|
||||
): T & HasHtmlDescription {
|
||||
const firstParagraphRule = /(.*?)(?:\n\n|$)/s;
|
||||
|
|
@ -56,10 +57,17 @@ export function addHtmlDescription<T extends HasDescription & HasModuleName>(
|
|||
?.comment ?? '';
|
||||
}
|
||||
|
||||
const description = !!entry.description ? entry.description : jsDocDescription;
|
||||
const shortTextMatch = description.match(firstParagraphRule);
|
||||
let description = entry.description || jsDocDescription;
|
||||
let shortDescription = description.match(firstParagraphRule)?.[0] ?? '';
|
||||
|
||||
// For the cases where the @description tag is after a short description
|
||||
if (jsDocDescription && description !== jsDocDescription) {
|
||||
shortDescription = entry.description;
|
||||
description = jsDocDescription;
|
||||
}
|
||||
|
||||
const htmlDescription = getHtmlForJsDocText(description).trim();
|
||||
const shortHtmlDescription = getHtmlForJsDocText(shortTextMatch ? shortTextMatch[0] : '').trim();
|
||||
const shortHtmlDescription = getHtmlForJsDocText(shortDescription).trim();
|
||||
|
||||
return {...entry, htmlDescription, shortHtmlDescription};
|
||||
}
|
||||
|
|
@ -137,6 +145,9 @@ function getHtmlAdditionalLinks<T extends HasJsDocTags>(entry: T): LinkEntryRend
|
|||
.filter((tag) => tag.name === JS_DOC_SEE_TAG)
|
||||
.map((tag) => tag.comment)
|
||||
.map((comment) => {
|
||||
// TODO: Throw when the comment is an absolute link.
|
||||
// With TS 5.9 this is not possible as the ts api that extracts comments from tags strips the "http" part of links.
|
||||
|
||||
const markdownLinkMatch = comment.match(markdownLinkRule);
|
||||
|
||||
if (markdownLinkMatch) {
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@ export function extractJsDocTags(node: ts.HasJSDoc): JsDocTagEntry[] {
|
|||
return ts.getJSDocTags(escapedNode).map((t) => {
|
||||
return {
|
||||
name: t.tagName.getText(),
|
||||
// In TS 5.9, ts.getTextOfJSDocComment still strips "http" from comments breaking any absolute links in @see blocks.
|
||||
// eg: @see https://angular.dev
|
||||
comment: unescapeAngularDecorators(ts.getTextOfJSDocComment(t.comment) ?? ''),
|
||||
};
|
||||
});
|
||||
|
|
|
|||
|
|
@ -8,10 +8,10 @@
|
|||
|
||||
import {
|
||||
HashLocationStrategy,
|
||||
Location,
|
||||
LOCATION_INITIALIZED,
|
||||
LocationStrategy,
|
||||
ViewportScroller,
|
||||
Location,
|
||||
ɵNavigationAdapterForLocation,
|
||||
} from '@angular/common';
|
||||
import {
|
||||
|
|
@ -23,15 +23,15 @@ import {
|
|||
inject,
|
||||
InjectionToken,
|
||||
Injector,
|
||||
ɵIS_ENABLED_BLOCKING_INITIAL_NAVIGATION as IS_ENABLED_BLOCKING_INITIAL_NAVIGATION,
|
||||
makeEnvironmentProviders,
|
||||
ɵperformanceMarkFeature as performanceMarkFeature,
|
||||
provideAppInitializer,
|
||||
provideEnvironmentInitializer,
|
||||
Provider,
|
||||
runInInjectionContext,
|
||||
ɵperformanceMarkFeature as performanceMarkFeature,
|
||||
ɵIS_ENABLED_BLOCKING_INITIAL_NAVIGATION as IS_ENABLED_BLOCKING_INITIAL_NAVIGATION,
|
||||
ɵpublishExternalGlobalUtil,
|
||||
provideEnvironmentInitializer,
|
||||
Type,
|
||||
ɵpublishExternalGlobalUtil,
|
||||
} from '@angular/core';
|
||||
import {of, Subject} from 'rxjs';
|
||||
|
||||
|
|
@ -39,15 +39,18 @@ import {INPUT_BINDER, RoutedComponentInputBinder} from './directives/router_outl
|
|||
import {Event, NavigationError, stringifyEvent} from './events';
|
||||
import {RedirectCommand, Routes} from './models';
|
||||
import {NAVIGATION_ERROR_HANDLER, NavigationTransitions} from './navigation_transition';
|
||||
import {ROUTE_INJECTOR_CLEANUP, routeInjectorCleanup} from './route_injector_cleanup';
|
||||
import {Router} from './router';
|
||||
import {InMemoryScrollingOptions, ROUTER_CONFIGURATION, RouterConfigOptions} from './router_config';
|
||||
import {ROUTES} from './router_config_loader';
|
||||
import {PreloadingStrategy, RouterPreloader} from './router_preloader';
|
||||
import {routeInjectorCleanup, ROUTE_INJECTOR_CLEANUP} from './route_injector_cleanup';
|
||||
|
||||
import {ROUTER_SCROLLER, RouterScroller} from './router_scroller';
|
||||
|
||||
import {getLoadedRoutes, getRouterInstance, navigateByUrl} from './router_devtools';
|
||||
import {ActivatedRoute} from './router_state';
|
||||
import {NavigationStateManager} from './statemanager/navigation_state_manager';
|
||||
import {StateManager} from './statemanager/state_manager';
|
||||
import {afterNextNavigation} from './utils/navigations';
|
||||
import {
|
||||
CREATE_VIEW_TRANSITION,
|
||||
|
|
@ -55,9 +58,6 @@ import {
|
|||
VIEW_TRANSITION_OPTIONS,
|
||||
ViewTransitionsFeatureOptions,
|
||||
} from './utils/view_transition';
|
||||
import {getLoadedRoutes, getRouterInstance, navigateByUrl} from './router_devtools';
|
||||
import {StateManager} from './statemanager/state_manager';
|
||||
import {NavigationStateManager} from './statemanager/navigation_state_manager';
|
||||
|
||||
/**
|
||||
* Sets up providers necessary to enable `Router` functionality for the application.
|
||||
|
|
@ -282,9 +282,9 @@ export type ExperimentalPlatformNavigationFeature =
|
|||
* });
|
||||
* ```
|
||||
*
|
||||
* @see https://github.com/WICG/navigation-api?tab=readme-ov-file#problem-statement
|
||||
* @see https://developer.chrome.com/docs/web-platform/navigation-api/
|
||||
* @see https://developer.mozilla.org/en-US/docs/Web/API/Navigation_API
|
||||
* @see [Navigation API on WICG](https://github.com/WICG/navigation-api?tab=readme-ov-file#problem-statement)
|
||||
* @see [Navigation API on Chrome from developers](https://developer.chrome.com/docs/web-platform/navigation-api/)
|
||||
* @see [Navigation API on MDN](https://developer.mozilla.org/en-US/docs/Web/API/Navigation_API)
|
||||
*
|
||||
* @experimental 21.1
|
||||
* @returns A `RouterFeature` that enables the platform navigation.
|
||||
|
|
@ -899,8 +899,8 @@ export function withComponentInputBinding(): ComponentInputBindingFeature {
|
|||
* ```
|
||||
*
|
||||
* @returns A set of providers for use with `provideRouter`.
|
||||
* @see https://developer.chrome.com/docs/web-platform/view-transitions/
|
||||
* @see https://developer.mozilla.org/en-US/docs/Web/API/View_Transitions_API
|
||||
* @see [View Transitions on MDN](https://developer.chrome.com/docs/web-platform/view-transitions/)
|
||||
* @see [View Transitions API on MDN](https://developer.mozilla.org/en-US/docs/Web/API/View_Transitions_API)
|
||||
* @see [Route transition animations](guide/routing/route-transition-animations)
|
||||
* @developerPreview 19.0
|
||||
*/
|
||||
|
|
|
|||
Loading…
Reference in a new issue