@ng-doc/app 22.0.0-beta.2 → 22.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -29
- package/fesm2022/ng-doc-app-classes-content-anchor-controller.mjs +363 -0
- package/fesm2022/ng-doc-app-classes-content-anchor-controller.mjs.map +1 -0
- package/fesm2022/ng-doc-app-classes-content-controller.mjs +299 -0
- package/fesm2022/ng-doc-app-classes-content-controller.mjs.map +1 -0
- package/fesm2022/ng-doc-app-classes-default-search-engine.mjs +51 -35
- package/fesm2022/ng-doc-app-classes-default-search-engine.mjs.map +1 -1
- package/fesm2022/ng-doc-app-classes-root-page.mjs.map +1 -1
- package/fesm2022/ng-doc-app-classes-search-engine.mjs.map +1 -1
- package/fesm2022/ng-doc-app-classes.mjs +2 -0
- package/fesm2022/ng-doc-app-classes.mjs.map +1 -1
- package/fesm2022/ng-doc-app-components-api-list.mjs +173 -69
- package/fesm2022/ng-doc-app-components-api-list.mjs.map +1 -1
- package/fesm2022/ng-doc-app-components-breadcrumb.mjs +13 -10
- package/fesm2022/ng-doc-app-components-breadcrumb.mjs.map +1 -1
- package/fesm2022/ng-doc-app-components-code.mjs +152 -25
- package/fesm2022/ng-doc-app-components-code.mjs.map +1 -1
- package/fesm2022/ng-doc-app-components-command-palette.mjs +498 -0
- package/fesm2022/ng-doc-app-components-command-palette.mjs.map +1 -0
- package/fesm2022/ng-doc-app-components-copy-button.mjs +38 -21
- package/fesm2022/ng-doc-app-components-copy-button.mjs.map +1 -1
- package/fesm2022/ng-doc-app-components-demo-displayer.mjs +36 -29
- package/fesm2022/ng-doc-app-components-demo-displayer.mjs.map +1 -1
- package/fesm2022/ng-doc-app-components-demo-frame.mjs +96 -0
- package/fesm2022/ng-doc-app-components-demo-frame.mjs.map +1 -0
- package/fesm2022/ng-doc-app-components-demo-pane.mjs +39 -36
- package/fesm2022/ng-doc-app-components-demo-pane.mjs.map +1 -1
- package/fesm2022/ng-doc-app-components-demo.mjs +175 -44
- package/fesm2022/ng-doc-app-components-demo.mjs.map +1 -1
- package/fesm2022/ng-doc-app-components-fullscreen-button.mjs +12 -9
- package/fesm2022/ng-doc-app-components-fullscreen-button.mjs.map +1 -1
- package/fesm2022/ng-doc-app-components-fullscreen-toggle.mjs +79 -0
- package/fesm2022/ng-doc-app-components-fullscreen-toggle.mjs.map +1 -0
- package/fesm2022/ng-doc-app-components-heading-anchor.mjs +54 -21
- package/fesm2022/ng-doc-app-components-heading-anchor.mjs.map +1 -1
- package/fesm2022/ng-doc-app-components-image-viewer.mjs +183 -89
- package/fesm2022/ng-doc-app-components-image-viewer.mjs.map +1 -1
- package/fesm2022/ng-doc-app-components-kind-icon.mjs +42 -25
- package/fesm2022/ng-doc-app-components-kind-icon.mjs.map +1 -1
- package/fesm2022/ng-doc-app-components-link.mjs +12 -9
- package/fesm2022/ng-doc-app-components-link.mjs.map +1 -1
- package/fesm2022/ng-doc-app-components-members.mjs +30 -0
- package/fesm2022/ng-doc-app-components-members.mjs.map +1 -0
- package/fesm2022/ng-doc-app-components-mermaid-viewer.mjs +61 -20
- package/fesm2022/ng-doc-app-components-mermaid-viewer.mjs.map +1 -1
- package/fesm2022/ng-doc-app-components-navbar.mjs +39 -49
- package/fesm2022/ng-doc-app-components-navbar.mjs.map +1 -1
- package/fesm2022/ng-doc-app-components-page-header.mjs +73 -10
- package/fesm2022/ng-doc-app-components-page-header.mjs.map +1 -1
- package/fesm2022/ng-doc-app-components-page-link.mjs +123 -31
- package/fesm2022/ng-doc-app-components-page-link.mjs.map +1 -1
- package/fesm2022/ng-doc-app-components-page-navigation.mjs +17 -19
- package/fesm2022/ng-doc-app-components-page-navigation.mjs.map +1 -1
- package/fesm2022/ng-doc-app-components-page-wrapper.mjs +56 -35
- package/fesm2022/ng-doc-app-components-page-wrapper.mjs.map +1 -1
- package/fesm2022/ng-doc-app-components-page.mjs +168 -24
- package/fesm2022/ng-doc-app-components-page.mjs.map +1 -1
- package/fesm2022/ng-doc-app-components-playground.mjs +477 -286
- package/fesm2022/ng-doc-app-components-playground.mjs.map +1 -1
- package/fesm2022/ng-doc-app-components-root.mjs +48 -31
- package/fesm2022/ng-doc-app-components-root.mjs.map +1 -1
- package/fesm2022/ng-doc-app-components-search-result.mjs +22 -21
- package/fesm2022/ng-doc-app-components-search-result.mjs.map +1 -1
- package/fesm2022/ng-doc-app-components-search.mjs +64 -33
- package/fesm2022/ng-doc-app-components-search.mjs.map +1 -1
- package/fesm2022/ng-doc-app-components-sidebar.mjs +86 -61
- package/fesm2022/ng-doc-app-components-sidebar.mjs.map +1 -1
- package/fesm2022/ng-doc-app-components-tabs.mjs +35 -11
- package/fesm2022/ng-doc-app-components-tabs.mjs.map +1 -1
- package/fesm2022/ng-doc-app-components-theme-toggle.mjs +33 -21
- package/fesm2022/ng-doc-app-components-theme-toggle.mjs.map +1 -1
- package/fesm2022/ng-doc-app-components-toc.mjs +267 -90
- package/fesm2022/ng-doc-app-components-toc.mjs.map +1 -1
- package/fesm2022/ng-doc-app-components.mjs +4 -1
- package/fesm2022/ng-doc-app-components.mjs.map +1 -1
- package/fesm2022/ng-doc-app-defaults-default-processors.mjs +2 -1
- package/fesm2022/ng-doc-app-defaults-default-processors.mjs.map +1 -1
- package/fesm2022/ng-doc-app-demo-app.mjs +176 -0
- package/fesm2022/ng-doc-app-demo-app.mjs.map +1 -0
- package/fesm2022/ng-doc-app-directives-code-highlighter.mjs +11 -5
- package/fesm2022/ng-doc-app-directives-code-highlighter.mjs.map +1 -1
- package/fesm2022/ng-doc-app-directives-members-filter.mjs +276 -0
- package/fesm2022/ng-doc-app-directives-members-filter.mjs.map +1 -0
- package/fesm2022/ng-doc-app-directives-route-active.mjs +34 -30
- package/fesm2022/ng-doc-app-directives-route-active.mjs.map +1 -1
- package/fesm2022/ng-doc-app-directives.mjs +1 -0
- package/fesm2022/ng-doc-app-directives.mjs.map +1 -1
- package/fesm2022/ng-doc-app-helpers.mjs +307 -2
- package/fesm2022/ng-doc-app-helpers.mjs.map +1 -1
- package/fesm2022/ng-doc-app-pipes-decode-uri-component.mjs +6 -4
- package/fesm2022/ng-doc-app-pipes-decode-uri-component.mjs.map +1 -1
- package/fesm2022/ng-doc-app-pipes-extract-value.mjs +6 -4
- package/fesm2022/ng-doc-app-pipes-extract-value.mjs.map +1 -1
- package/fesm2022/ng-doc-app-pipes-filter-by-text.mjs +7 -4
- package/fesm2022/ng-doc-app-pipes-filter-by-text.mjs.map +1 -1
- package/fesm2022/ng-doc-app-pipes-sanitize-html.mjs +8 -5
- package/fesm2022/ng-doc-app-pipes-sanitize-html.mjs.map +1 -1
- package/fesm2022/ng-doc-app-processors-page-processor.mjs +86 -23
- package/fesm2022/ng-doc-app-processors-page-processor.mjs.map +1 -1
- package/fesm2022/ng-doc-app-processors-processors-tooltip.mjs +26 -25
- package/fesm2022/ng-doc-app-processors-processors-tooltip.mjs.map +1 -1
- package/fesm2022/ng-doc-app-processors-processors.mjs +42 -10
- package/fesm2022/ng-doc-app-processors-processors.mjs.map +1 -1
- package/fesm2022/ng-doc-app-providers-ng-doc-app.mjs +31 -2
- package/fesm2022/ng-doc-app-providers-ng-doc-app.mjs.map +1 -1
- package/fesm2022/ng-doc-app-providers-title.mjs +129 -0
- package/fesm2022/ng-doc-app-providers-title.mjs.map +1 -0
- package/fesm2022/ng-doc-app-providers.mjs +1 -0
- package/fesm2022/ng-doc-app-providers.mjs.map +1 -1
- package/fesm2022/ng-doc-app-services-content-scroll-intent.mjs +122 -0
- package/fesm2022/ng-doc-app-services-content-scroll-intent.mjs.map +1 -0
- package/fesm2022/ng-doc-app-services-content-state.mjs +57 -0
- package/fesm2022/ng-doc-app-services-content-state.mjs.map +1 -0
- package/fesm2022/ng-doc-app-services-fullscreen-route.mjs +74 -0
- package/fesm2022/ng-doc-app-services-fullscreen-route.mjs.map +1 -0
- package/fesm2022/ng-doc-app-services-highlighter.mjs +90 -17
- package/fesm2022/ng-doc-app-services-highlighter.mjs.map +1 -1
- package/fesm2022/ng-doc-app-services-route-preloader.mjs +384 -0
- package/fesm2022/ng-doc-app-services-route-preloader.mjs.map +1 -0
- package/fesm2022/ng-doc-app-services-shortcuts.mjs +214 -0
- package/fesm2022/ng-doc-app-services-shortcuts.mjs.map +1 -0
- package/fesm2022/ng-doc-app-services-sidebar.mjs +59 -25
- package/fesm2022/ng-doc-app-services-sidebar.mjs.map +1 -1
- package/fesm2022/ng-doc-app-services-store.mjs +8 -8
- package/fesm2022/ng-doc-app-services-store.mjs.map +1 -1
- package/fesm2022/ng-doc-app-services-theme.mjs +32 -12
- package/fesm2022/ng-doc-app-services-theme.mjs.map +1 -1
- package/fesm2022/ng-doc-app-services.mjs +143 -0
- package/fesm2022/ng-doc-app-services.mjs.map +1 -1
- package/fesm2022/ng-doc-app-tokens.mjs +7 -28
- package/fesm2022/ng-doc-app-tokens.mjs.map +1 -1
- package/fesm2022/ng-doc-app-type-controls-boolean-control.mjs +18 -9
- package/fesm2022/ng-doc-app-type-controls-boolean-control.mjs.map +1 -1
- package/fesm2022/ng-doc-app-type-controls-number-control.mjs +12 -9
- package/fesm2022/ng-doc-app-type-controls-number-control.mjs.map +1 -1
- package/fesm2022/ng-doc-app-type-controls-string-control.mjs +12 -9
- package/fesm2022/ng-doc-app-type-controls-string-control.mjs.map +1 -1
- package/fesm2022/ng-doc-app-type-controls-type-alias-control.mjs +59 -18
- package/fesm2022/ng-doc-app-type-controls-type-alias-control.mjs.map +1 -1
- package/package.json +82 -28
- package/styles/global.css +1128 -201
- package/styles/main.css +1128 -201
- package/styles/themes/dark.css +88 -56
- package/types/ng-doc-app-classes-content-anchor-controller.d.ts +54 -0
- package/types/ng-doc-app-classes-content-controller.d.ts +94 -0
- package/types/ng-doc-app-classes-default-search-engine.d.ts +9 -1
- package/types/ng-doc-app-classes-root-page.d.ts +14 -1
- package/types/ng-doc-app-classes-search-engine.d.ts +5 -0
- package/types/ng-doc-app-classes.d.ts +2 -0
- package/types/ng-doc-app-components-api-list.d.ts +69 -20
- package/types/ng-doc-app-components-breadcrumb.d.ts +8 -3
- package/types/ng-doc-app-components-code.d.ts +46 -12
- package/types/ng-doc-app-components-command-palette.d.ts +147 -0
- package/types/ng-doc-app-components-copy-button.d.ts +18 -6
- package/types/ng-doc-app-components-demo-displayer.d.ts +23 -10
- package/types/ng-doc-app-components-demo-frame.d.ts +48 -0
- package/types/ng-doc-app-components-demo-pane.d.ts +19 -15
- package/types/ng-doc-app-components-demo.d.ts +80 -15
- package/types/ng-doc-app-components-fullscreen-button.d.ts +4 -2
- package/types/ng-doc-app-components-fullscreen-toggle.d.ts +24 -0
- package/types/ng-doc-app-components-heading-anchor.d.ts +26 -7
- package/types/ng-doc-app-components-image-viewer.d.ts +71 -7
- package/types/ng-doc-app-components-kind-icon.d.ts +28 -7
- package/types/ng-doc-app-components-link.d.ts +6 -2
- package/types/ng-doc-app-components-members.d.ts +13 -0
- package/types/ng-doc-app-components-mermaid-viewer.d.ts +21 -6
- package/types/ng-doc-app-components-navbar.d.ts +25 -15
- package/types/ng-doc-app-components-page-header.d.ts +28 -4
- package/types/ng-doc-app-components-page-link.d.ts +34 -15
- package/types/ng-doc-app-components-page-navigation.d.ts +10 -5
- package/types/ng-doc-app-components-page-wrapper.d.ts +35 -11
- package/types/ng-doc-app-components-page.d.ts +57 -6
- package/types/ng-doc-app-components-playground.d.ts +167 -78
- package/types/ng-doc-app-components-root.d.ts +28 -7
- package/types/ng-doc-app-components-search-result.d.ts +14 -6
- package/types/ng-doc-app-components-search.d.ts +19 -7
- package/types/ng-doc-app-components-tabs.d.ts +24 -5
- package/types/ng-doc-app-components-theme-toggle.d.ts +18 -5
- package/types/ng-doc-app-components-toc.d.ts +76 -29
- package/types/ng-doc-app-components.d.ts +4 -1
- package/types/ng-doc-app-demo-app.d.ts +89 -0
- package/types/ng-doc-app-directives-code-highlighter.d.ts +8 -4
- package/types/ng-doc-app-directives-members-filter.d.ts +61 -0
- package/types/ng-doc-app-directives-route-active.d.ts +21 -7
- package/types/ng-doc-app-directives.d.ts +1 -0
- package/types/ng-doc-app-helpers.d.ts +142 -3
- package/types/ng-doc-app-interfaces.d.ts +62 -31
- package/types/ng-doc-app-pipes-decode-uri-component.d.ts +3 -0
- package/types/ng-doc-app-pipes-extract-value.d.ts +3 -0
- package/types/ng-doc-app-pipes-filter-by-text.d.ts +4 -0
- package/types/ng-doc-app-pipes-sanitize-html.d.ts +4 -2
- package/types/ng-doc-app-processors-page-processor.d.ts +39 -10
- package/types/ng-doc-app-processors-processors-tooltip.d.ts +11 -10
- package/types/ng-doc-app-processors-processors.d.ts +10 -1
- package/types/ng-doc-app-providers-ng-doc-app.d.ts +18 -1
- package/types/ng-doc-app-providers-title.d.ts +59 -0
- package/types/ng-doc-app-providers.d.ts +1 -0
- package/types/ng-doc-app-services-content-scroll-intent.d.ts +52 -0
- package/types/ng-doc-app-services-content-state.d.ts +40 -0
- package/types/ng-doc-app-services-fullscreen-route.d.ts +35 -0
- package/types/ng-doc-app-services-highlighter.d.ts +47 -5
- package/types/ng-doc-app-services-route-preloader.d.ts +121 -0
- package/types/ng-doc-app-services-shortcuts.d.ts +96 -0
- package/types/ng-doc-app-services-sidebar.d.ts +24 -4
- package/types/ng-doc-app-services-store.d.ts +24 -1
- package/types/ng-doc-app-services-theme.d.ts +19 -3
- package/types/ng-doc-app-services.d.ts +77 -0
- package/types/ng-doc-app-tokens.d.ts +10 -30
- package/types/ng-doc-app-type-controls-boolean-control.d.ts +11 -6
- package/types/ng-doc-app-type-controls-number-control.d.ts +5 -3
- package/types/ng-doc-app-type-controls-string-control.d.ts +5 -3
- package/types/ng-doc-app-type-controls-type-alias-control.d.ts +35 -6
- package/fesm2022/ng-doc-app-components-search-dialog.mjs +0 -78
- package/fesm2022/ng-doc-app-components-search-dialog.mjs.map +0 -1
- package/types/ng-doc-app-components-search-dialog.d.ts +0 -28
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ng-doc-app-directives-members-filter.mjs","sources":["../../../../libs/app/directives/members-filter/members-filter.directive.ts","../../../../libs/app/directives/members-filter/ng-doc-app-directives-members-filter.ts"],"sourcesContent":["import {\n afterNextRender,\n ApplicationRef,\n ComponentRef,\n createComponent,\n DestroyRef,\n Directive,\n DOCUMENT,\n ElementRef,\n EnvironmentInjector,\n inject,\n Injector,\n NgZone,\n Signal,\n signal,\n untracked,\n} from '@angular/core';\nimport { NgDocShortcutsService } from '@ng-doc/app/services/shortcuts';\nimport {\n NgDocSelectionComponent,\n NgDocSelectionHostDirective,\n} from '@ng-doc/ui-kit/components/selection';\n\nconst TAB = '[data-ng-doc-members-tab]';\nconst FILTER = 'input[data-ng-doc-members-filter]';\nconst MEMBER = '.ng-doc-member[data-group]';\nconst GROUP = '.ng-doc-members-group[data-group]';\nconst EXPAND = '.ng-doc-member-expand[aria-controls]';\nconst COUNT = '.ng-doc-members-count';\nconst EMPTY = '.ng-doc-members-empty';\nconst ALL = 'all';\nconst INHERITED = 'inherited';\n\n/**\n * Adds the member tabs, the name filter and the expandable method rows to the members table of\n * an API page. The page renders every member, so the table reads well without it (on the server\n * and before hydration); the directive only hides rows.\n *\n * It reads this markup inside its host: tab buttons with a data-ng-doc-members-tab attribute\n * (\"all\", \"inherited\" or a group name, each with an optional .ng-doc-members-count), a text input\n * with a data-ng-doc-members-filter attribute, group rows (.ng-doc-members-group with data-group)\n * and member rows (.ng-doc-member with data-group, data-name and, for inherited members,\n * data-inherited). A .ng-doc-member-expand button in a member row shows and hides the detail row\n * its aria-controls names, and an optional .ng-doc-members-empty element shows when no member\n * matches. F focuses the filter while single-key shortcuts are on.\n *\n * In the browser it inserts an `ng-doc-selection` as the first child of the row of tabs, the\n * highlight that slides to the selected tab as in the code-block tabs. Until it is placed, the\n * selected tab draws its own background, so the server-rendered page looks the same.\n */\n@Directive({\n selector: '[ngDocMembersFilter]',\n host: {\n '(click)': 'onClick($event)',\n '(input)': 'onInput($event)',\n '(keydown)': 'onKeydown($event)',\n },\n})\nexport class NgDocMembersFilterDirective {\n private readonly host: HTMLElement = inject(ElementRef).nativeElement;\n // The tabs are plain HTML, so no element can carry ngDocSelectionOrigin: the directive selects\n // the tab on the host of the highlight itself.\n private readonly selectionInjector = Injector.create({\n providers: [NgDocSelectionHostDirective],\n parent: inject(Injector),\n });\n private readonly selection = this.selectionInjector.get(NgDocSelectionHostDirective);\n private readonly selectedTab = signal(ALL);\n private readonly filterQuery = signal('');\n private ready = false;\n\n /** The selected tab: \"all\", \"inherited\" or a group name. */\n readonly tab: Signal<string> = this.selectedTab.asReadonly();\n /** The text the member names are filtered by. */\n readonly query: Signal<string> = this.filterQuery.asReadonly();\n\n constructor() {\n const destroyRef = inject(DestroyRef);\n const ngZone = inject(NgZone);\n const window = inject(DOCUMENT).defaultView;\n const removeShortcut = inject(NgDocShortcutsService).register({\n key: 'f',\n handler: () => this.host.querySelector<HTMLInputElement>(FILTER)?.focus(),\n });\n\n destroyRef.onDestroy(removeShortcut);\n\n // The markup is rendered by the page, so the directive only starts working in the browser.\n afterNextRender(() => {\n this.ready = true;\n // The counts change the width of the tabs, so they are final before the highlight measures.\n this.countTabs();\n\n const highlight = this.createHighlight();\n\n destroyRef.onDestroy(() => {\n highlight?.destroy();\n highlight?.location.nativeElement.remove();\n });\n\n const selected = this.tabs().find(\n (tab: HTMLElement) => tab.getAttribute('aria-selected') === 'true',\n );\n\n this.select(selected?.dataset['ngDocMembersTab'] ?? ALL);\n\n // Rows of tabs that scroll inside themselves fade on the edge that still hides tabs.\n const fade = () => this.fade();\n const onScroll = (event: Event) => {\n if (event.target instanceof Element && event.target.querySelector(TAB)) {\n this.fade();\n }\n };\n\n ngZone.runOutsideAngular(() => {\n this.host.addEventListener('scroll', onScroll, true);\n window?.addEventListener('resize', fade);\n });\n destroyRef.onDestroy(() => {\n this.host.removeEventListener('scroll', onScroll, true);\n window?.removeEventListener('resize', fade);\n });\n this.fade();\n });\n }\n\n /**\n * Shows the members of a tab.\n * @param tab - \"all\", \"inherited\" or a group name.\n */\n select(tab: string): void {\n untracked(() => {\n this.selectedTab.set(tab);\n\n const button = this.tabs().find(\n (candidate: HTMLElement) => candidate.dataset['ngDocMembersTab'] === tab,\n );\n\n for (const candidate of this.tabs()) {\n candidate.setAttribute('aria-selected', String(candidate === button));\n candidate.tabIndex = candidate === button ? 0 : -1;\n }\n\n this.selection.select(button);\n\n this.apply();\n });\n }\n\n /**\n * Shows the members whose name contains the text.\n * @param query - The text; case is ignored.\n */\n filter(query: string): void {\n untracked(() => {\n this.filterQuery.set(query);\n\n const input = this.host.querySelector<HTMLInputElement>(FILTER);\n\n if (input && input.value !== query) {\n input.value = query;\n }\n\n this.apply();\n });\n }\n\n protected onClick(event: MouseEvent): void {\n const target = event.target instanceof Element ? event.target : null;\n const tab = target?.closest<HTMLElement>(TAB);\n const expand = target?.closest<HTMLElement>(EXPAND);\n\n if (tab && this.host.contains(tab) && !tab.hasAttribute('disabled')) {\n this.select(tab.dataset['ngDocMembersTab'] ?? ALL);\n } else if (expand && this.host.contains(expand)) {\n expand.setAttribute('aria-expanded', String(expand.getAttribute('aria-expanded') !== 'true'));\n this.apply();\n }\n }\n\n protected onInput(event: Event): void {\n if (event.target instanceof HTMLInputElement && event.target.matches(FILTER)) {\n this.filter(event.target.value);\n }\n }\n\n protected onKeydown(event: KeyboardEvent): void {\n const tab = event.target instanceof Element ? event.target.closest<HTMLElement>(TAB) : null;\n\n if (!tab) {\n return;\n }\n\n const tabs = this.tabs().filter((button: HTMLElement) => !button.hasAttribute('disabled'));\n const index = tabs.indexOf(tab);\n const next =\n event.key === 'ArrowRight'\n ? tabs[(index + 1) % tabs.length]\n : event.key === 'ArrowLeft'\n ? tabs[(index - 1 + tabs.length) % tabs.length]\n : event.key === 'Home'\n ? tabs[0]\n : event.key === 'End'\n ? tabs[tabs.length - 1]\n : undefined;\n\n if (next) {\n event.preventDefault();\n next.focus();\n this.select(next.dataset['ngDocMembersTab'] ?? ALL);\n }\n }\n\n /**\n * Inserts the highlight of the selected tab into the row of tabs. It is the same component as in\n * the code-block tabs, so it measures, follows resizes and animates the same way; the row is its\n * offset parent, so it scrolls with the tabs.\n */\n private createHighlight(): ComponentRef<NgDocSelectionComponent> | undefined {\n const row = this.tabs()[0]?.parentElement;\n\n if (!row) {\n return undefined;\n }\n\n const hostElement = this.host.ownerDocument.createElement('ng-doc-selection');\n\n row.prepend(hostElement);\n\n const highlight = createComponent(NgDocSelectionComponent, {\n environmentInjector: this.selectionInjector.get(EnvironmentInjector),\n elementInjector: this.selectionInjector,\n hostElement,\n });\n\n highlight.setInput('align', null);\n this.selectionInjector.get(ApplicationRef).attachView(highlight.hostView);\n\n return highlight;\n }\n\n private tabs(): HTMLElement[] {\n return Array.from(this.host.querySelectorAll<HTMLElement>(TAB));\n }\n\n private members(): HTMLElement[] {\n return Array.from(this.host.querySelectorAll<HTMLElement>(MEMBER));\n }\n\n private countTabs(): void {\n const members = this.members();\n\n for (const button of this.tabs()) {\n const tab = button.dataset['ngDocMembersTab'] ?? ALL;\n const count = members.filter((member: HTMLElement) => inTab(member, tab)).length;\n const counter = button.querySelector(COUNT);\n\n if (counter) {\n counter.textContent = String(count);\n }\n\n button.toggleAttribute('disabled', tab !== ALL && count === 0);\n }\n }\n\n private apply(): void {\n if (!this.ready) {\n return;\n }\n\n const tab = this.selectedTab();\n const query = this.filterQuery().trim().toLowerCase();\n const visible = new Map<string, number>();\n\n for (const member of this.members()) {\n const group = member.dataset['group'] ?? '';\n const name = (member.dataset['name'] ?? member.textContent ?? '').toLowerCase();\n const shown = inTab(member, tab) && (!query || name.includes(query));\n\n member.hidden = !shown;\n visible.set(group, (visible.get(group) ?? 0) + (shown ? 1 : 0));\n\n for (const expand of Array.from(member.querySelectorAll<HTMLElement>(EXPAND))) {\n const detail = this.host.ownerDocument.getElementById(\n expand.getAttribute('aria-controls') ?? '',\n );\n\n if (detail && this.host.contains(detail)) {\n detail.hidden = !shown || expand.getAttribute('aria-expanded') !== 'true';\n }\n }\n }\n\n for (const group of Array.from(this.host.querySelectorAll<HTMLElement>(GROUP))) {\n const count = visible.get(group.dataset['group'] ?? '') ?? 0;\n const counter = group.querySelector(COUNT);\n\n group.hidden = count === 0;\n\n if (counter) {\n counter.textContent = String(count);\n }\n }\n\n const empty = this.host.querySelector<HTMLElement>(EMPTY);\n\n if (empty) {\n empty.hidden = this.members().some((member: HTMLElement) => !member.hidden);\n }\n }\n\n private fade(): void {\n const list = this.tabs()[0]?.parentElement;\n\n if (!list) {\n return;\n }\n\n const max = list.scrollWidth - list.clientWidth;\n const edges = [\n ...(max > 1 && list.scrollLeft > 1 ? ['start'] : []),\n ...(max > 1 && list.scrollLeft < max - 1 ? ['end'] : []),\n ];\n\n if (edges.length) {\n list.dataset['fade'] = edges.join(' ');\n } else {\n delete list.dataset['fade'];\n }\n }\n}\n\n/**\n * Whether a member row belongs to a tab.\n * @param member - The member row.\n * @param tab - \"all\", \"inherited\" or a group name.\n */\nfunction inTab(member: HTMLElement, tab: string): boolean {\n return (\n tab === ALL ||\n (tab === INHERITED ? member.hasAttribute('data-inherited') : member.dataset['group'] === tab)\n );\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
@@ -1,48 +1,52 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { Router, NavigationEnd } from '@angular/router';
|
|
2
|
+
import { input, inject, computed, Directive } from '@angular/core';
|
|
3
|
+
import { Router, isActive } from '@angular/router';
|
|
5
4
|
import { asArray } from '@ng-doc/core/helpers/as-array';
|
|
6
|
-
import { filter, map, distinctUntilChanged } from 'rxjs/operators';
|
|
7
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Adds classes to its host element while the router URL matches a link.
|
|
8
|
+
*
|
|
9
|
+
* ```html
|
|
10
|
+
* <a [ngDocRouteActive]="'/docs/getting-started'" activeClass="active">Getting started</a>
|
|
11
|
+
* ```
|
|
12
|
+
*/
|
|
8
13
|
class NgDocRouteActiveDirective {
|
|
9
14
|
constructor() {
|
|
10
|
-
|
|
11
|
-
this.
|
|
12
|
-
|
|
15
|
+
/** The link to match against the router URL. */
|
|
16
|
+
this.link = input('', { ...(ngDevMode ? { debugName: "link" } : /* istanbul ignore next */ {}), alias: 'ngDocRouteActive' });
|
|
17
|
+
/** Class or classes to add while the link is active. */
|
|
18
|
+
this.activeClass = input([], /* @ts-ignore */
|
|
19
|
+
...(ngDevMode ? [{ debugName: "activeClass" }] : /* istanbul ignore next */ []));
|
|
20
|
+
/** How the link is matched against the router URL. */
|
|
21
|
+
this.matchOptions = input({
|
|
13
22
|
fragment: 'exact',
|
|
14
23
|
paths: 'subset',
|
|
15
24
|
queryParams: 'exact',
|
|
16
25
|
matrixParams: 'exact',
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
router.
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
});
|
|
26
|
+
}, /* @ts-ignore */
|
|
27
|
+
...(ngDevMode ? [{ debugName: "matchOptions" }] : /* istanbul ignore next */ []));
|
|
28
|
+
this.router = inject(Router);
|
|
29
|
+
// One router signal per link and options; it follows the URL the router has committed.
|
|
30
|
+
this.active = computed(() => isActive(this.link(), this.router, this.matchOptions()), /* @ts-ignore */
|
|
31
|
+
...(ngDevMode ? [{ debugName: "active" }] : /* istanbul ignore next */ []));
|
|
32
|
+
/** Whether the link is active. */
|
|
33
|
+
this.isActive = computed(() => this.active()(), /* @ts-ignore */
|
|
34
|
+
...(ngDevMode ? [{ debugName: "isActive" }] : /* istanbul ignore next */ []));
|
|
35
|
+
this.classes = computed(() => (this.isActive() ? asArray(this.activeClass()) : []), /* @ts-ignore */
|
|
36
|
+
...(ngDevMode ? [{ debugName: "classes" }] : /* istanbul ignore next */ []));
|
|
28
37
|
}
|
|
29
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.
|
|
30
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "
|
|
38
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.2.1", ngImport: i0, type: NgDocRouteActiveDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
39
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.2.1", type: NgDocRouteActiveDirective, isStandalone: true, selector: "[ngDocRouteActive]", inputs: { link: { classPropertyName: "link", publicName: "ngDocRouteActive", isSignal: true, isRequired: false, transformFunction: null }, activeClass: { classPropertyName: "activeClass", publicName: "activeClass", isSignal: true, isRequired: false, transformFunction: null }, matchOptions: { classPropertyName: "matchOptions", publicName: "matchOptions", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "classes()" } }, ngImport: i0 }); }
|
|
31
40
|
}
|
|
32
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.
|
|
41
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.1", ngImport: i0, type: NgDocRouteActiveDirective, decorators: [{
|
|
33
42
|
type: Directive,
|
|
34
43
|
args: [{
|
|
35
44
|
selector: '[ngDocRouteActive]',
|
|
36
|
-
|
|
45
|
+
host: {
|
|
46
|
+
'[class]': 'classes()',
|
|
47
|
+
},
|
|
37
48
|
}]
|
|
38
|
-
}],
|
|
39
|
-
type: Input,
|
|
40
|
-
args: ['ngDocRouteActive']
|
|
41
|
-
}], activeClass: [{
|
|
42
|
-
type: Input
|
|
43
|
-
}], matchOptions: [{
|
|
44
|
-
type: Input
|
|
45
|
-
}] } });
|
|
49
|
+
}], propDecorators: { link: [{ type: i0.Input, args: [{ isSignal: true, alias: "ngDocRouteActive", required: false }] }], activeClass: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeClass", required: false }] }], matchOptions: [{ type: i0.Input, args: [{ isSignal: true, alias: "matchOptions", required: false }] }] } });
|
|
46
50
|
|
|
47
51
|
/**
|
|
48
52
|
* Generated bundle index. Do not edit.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ng-doc-app-directives-route-active.mjs","sources":["../../../../libs/app/directives/route-active/route-active.directive.ts","../../../../libs/app/directives/route-active/ng-doc-app-directives-route-active.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"ng-doc-app-directives-route-active.mjs","sources":["../../../../libs/app/directives/route-active/route-active.directive.ts","../../../../libs/app/directives/route-active/ng-doc-app-directives-route-active.ts"],"sourcesContent":["import { computed, Directive, inject, input } from '@angular/core';\nimport { isActive, IsActiveMatchOptions, Router } from '@angular/router';\nimport { asArray } from '@ng-doc/core/helpers/as-array';\n\n/**\n * Adds classes to its host element while the router URL matches a link.\n *\n * ```html\n * <a [ngDocRouteActive]=\"'/docs/getting-started'\" activeClass=\"active\">Getting started</a>\n * ```\n */\n@Directive({\n selector: '[ngDocRouteActive]',\n host: {\n '[class]': 'classes()',\n },\n})\nexport class NgDocRouteActiveDirective {\n /** The link to match against the router URL. */\n readonly link = input<string>('', { alias: 'ngDocRouteActive' });\n\n /** Class or classes to add while the link is active. */\n readonly activeClass = input<string | string[]>([]);\n\n /** How the link is matched against the router URL. */\n readonly matchOptions = input<IsActiveMatchOptions>({\n fragment: 'exact',\n paths: 'subset',\n queryParams: 'exact',\n matrixParams: 'exact',\n });\n\n private readonly router = inject(Router);\n\n // One router signal per link and options; it follows the URL the router has committed.\n private readonly active = computed(() => isActive(this.link(), this.router, this.matchOptions()));\n\n /** Whether the link is active. */\n readonly isActive = computed(() => this.active()());\n\n protected readonly classes = computed(() => (this.isActive() ? asArray(this.activeClass()) : []));\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;AAIA;;;;;;AAMG;MAOU,yBAAyB,CAAA;AANtC,IAAA,WAAA,GAAA;;QAQW,IAAA,CAAA,IAAI,GAAG,KAAK,CAAS,EAAE,4EAAI,KAAK,EAAE,kBAAkB,EAAA,CAAG;;QAGvD,IAAA,CAAA,WAAW,GAAG,KAAK,CAAoB,EAAE;wFAAC;;QAG1C,IAAA,CAAA,YAAY,GAAG,KAAK,CAAuB;AAClD,YAAA,QAAQ,EAAE,OAAO;AACjB,YAAA,KAAK,EAAE,QAAQ;AACf,YAAA,WAAW,EAAE,OAAO;AACpB,YAAA,YAAY,EAAE,OAAO;AACtB,SAAA;yFAAC;AAEe,QAAA,IAAA,CAAA,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;;QAGvB,IAAA,CAAA,MAAM,GAAG,QAAQ,CAAC,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,YAAY,EAAE,CAAC;mFAAC;;QAGxF,IAAA,CAAA,QAAQ,GAAG,QAAQ,CAAC,MAAM,IAAI,CAAC,MAAM,EAAE,EAAE;qFAAC;QAEhC,IAAA,CAAA,OAAO,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,QAAQ,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,GAAG,EAAE,CAAC;oFAAC;AAClG,IAAA;8GAxBY,yBAAyB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;kGAAzB,yBAAyB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,oBAAA,EAAA,MAAA,EAAA,EAAA,IAAA,EAAA,EAAA,iBAAA,EAAA,MAAA,EAAA,UAAA,EAAA,kBAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,WAAA,EAAA,EAAA,iBAAA,EAAA,aAAA,EAAA,UAAA,EAAA,aAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,YAAA,EAAA,EAAA,iBAAA,EAAA,cAAA,EAAA,UAAA,EAAA,cAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAA,EAAA,KAAA,EAAA,iBAAA,EAAA,IAAA,EAAA,EAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,OAAA,EAAA,WAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,CAAA,CAAA;;2FAAzB,yBAAyB,EAAA,UAAA,EAAA,CAAA;kBANrC,SAAS;AAAC,YAAA,IAAA,EAAA,CAAA;AACT,oBAAA,QAAQ,EAAE,oBAAoB;AAC9B,oBAAA,IAAI,EAAE;AACJ,wBAAA,SAAS,EAAE,WAAW;AACvB,qBAAA;AACF,iBAAA;;;AChBD;;AAEG;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ng-doc-app-directives.mjs","sources":["../../../../libs/app/directives/ng-doc-app-directives.ts"],"sourcesContent":["/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"ng-doc-app-directives.mjs","sources":["../../../../libs/app/directives/ng-doc-app-directives.ts"],"sourcesContent":["/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;AAAA;;AAEG"}
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
import { InjectionToken, inject } from '@angular/core';
|
|
2
|
+
import { NgDocContentState } from '@ng-doc/app/services/content-state';
|
|
1
3
|
import { asArray } from '@ng-doc/core/helpers/as-array';
|
|
2
4
|
import { objectKeys } from '@ng-doc/core/helpers/object-keys';
|
|
5
|
+
import { extractValueOrThrow } from '@ng-doc/core/helpers/extract-value';
|
|
3
6
|
|
|
4
7
|
/**
|
|
5
8
|
*
|
|
@@ -16,6 +19,172 @@ function asBoolean(value) {
|
|
|
16
19
|
return !!value;
|
|
17
20
|
}
|
|
18
21
|
|
|
22
|
+
/** The key of the resolver that `ɵwithNgDocContent` adds to a generated page route. */
|
|
23
|
+
const RESOLVE_KEY = 'ɵngDocContent';
|
|
24
|
+
/** The loads started for each content source, so a source loads once however often it is asked. */
|
|
25
|
+
const preloads = new WeakMap();
|
|
26
|
+
/**
|
|
27
|
+
* The content source of each resolver made by `ɵwithNgDocContent`. The router copies route
|
|
28
|
+
* objects when it loads them, but it keeps their `resolve` maps and functions, so the source is
|
|
29
|
+
* found through the resolver.
|
|
30
|
+
*/
|
|
31
|
+
const routeSources = new WeakMap();
|
|
32
|
+
/** The wait of each navigation, by its root snapshot. */
|
|
33
|
+
const navigationWaits = new WeakMap();
|
|
34
|
+
/**
|
|
35
|
+
* How long the router waits for the content of a page before it shows the page anyway, in
|
|
36
|
+
* milliseconds. A stalled load must not freeze navigation: after this, the page opens and its
|
|
37
|
+
* content renders when it arrives, as without the wait.
|
|
38
|
+
* @internal
|
|
39
|
+
*/
|
|
40
|
+
const ɵNG_DOC_CONTENT_WAIT = new InjectionToken('ɵNG_DOC_CONTENT_WAIT', {
|
|
41
|
+
factory: () => 8000,
|
|
42
|
+
});
|
|
43
|
+
/**
|
|
44
|
+
* Loads a content source once and keeps its payload, so a page that renders it later shows it in
|
|
45
|
+
* its first render. A failed load is forgotten, so the next request tries again.
|
|
46
|
+
* @param source - The content source.
|
|
47
|
+
* @returns The loaded payload.
|
|
48
|
+
* @internal
|
|
49
|
+
*/
|
|
50
|
+
function ɵpreloadNgDocContent(source) {
|
|
51
|
+
const existing = preloads.get(source);
|
|
52
|
+
if (existing)
|
|
53
|
+
return existing.promise;
|
|
54
|
+
// Preloads are shared between navigations, so no navigation may abort them.
|
|
55
|
+
const promise = Promise.resolve()
|
|
56
|
+
.then(() => source.load(new AbortController().signal))
|
|
57
|
+
.then((payload) => {
|
|
58
|
+
if (preloads.get(source) === entry)
|
|
59
|
+
entry.payload = payload;
|
|
60
|
+
return payload;
|
|
61
|
+
}, (error) => {
|
|
62
|
+
if (preloads.get(source) === entry)
|
|
63
|
+
preloads.delete(source);
|
|
64
|
+
throw error;
|
|
65
|
+
});
|
|
66
|
+
const entry = { promise };
|
|
67
|
+
preloads.set(source, entry);
|
|
68
|
+
return promise;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Returns the payload of a source that `ɵpreloadNgDocContent` has loaded, without waiting.
|
|
72
|
+
* @param source - The content source.
|
|
73
|
+
* @returns The payload, or `undefined` when the source has not finished loading.
|
|
74
|
+
* @internal
|
|
75
|
+
*/
|
|
76
|
+
function ɵpeekNgDocContent(source) {
|
|
77
|
+
return preloads.get(source)?.payload;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Returns the load of a source that `ɵpreloadNgDocContent` started and that has not finished,
|
|
81
|
+
* so a page that opens before it finishes waits for the same load instead of starting another.
|
|
82
|
+
* @param source - The content source.
|
|
83
|
+
* @returns The pending load, or `undefined`.
|
|
84
|
+
* @internal
|
|
85
|
+
*/
|
|
86
|
+
function ɵpendingNgDocContent(source) {
|
|
87
|
+
const entry = preloads.get(source);
|
|
88
|
+
return entry && !entry.payload ? entry.promise : undefined;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Drops the preloaded payload of a source, for a source that reports a new revision.
|
|
92
|
+
* @param source - The content source.
|
|
93
|
+
* @internal
|
|
94
|
+
*/
|
|
95
|
+
function ɵforgetNgDocContent(source) {
|
|
96
|
+
preloads.delete(source);
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Makes the router wait for the content of a generated page before it shows the page. Without
|
|
100
|
+
* it, the router removes the previous page as soon as the page's code has loaded, and an empty
|
|
101
|
+
* page shows until its content arrives.
|
|
102
|
+
*
|
|
103
|
+
* The resolver loads the content of every route of the navigation that has some, all at once,
|
|
104
|
+
* because the router runs the resolvers of nested routes one after another. A load that fails
|
|
105
|
+
* still lets the navigation finish: the page shows the error. A load that takes longer than
|
|
106
|
+
* `ɵNG_DOC_CONTENT_WAIT` lets it finish too: the page then renders its content when it arrives.
|
|
107
|
+
* @param route - The route of the page.
|
|
108
|
+
* @param source - The content source of the route's component.
|
|
109
|
+
* @returns A copy of the route with the resolver added.
|
|
110
|
+
* @internal
|
|
111
|
+
*/
|
|
112
|
+
function ɵwithNgDocContent(route, source) {
|
|
113
|
+
const resolver = async (snapshot) => {
|
|
114
|
+
// The resolvers of one navigation share its root snapshot, and with it one wait: nested
|
|
115
|
+
// resolvers run one after another, and each must not start a wait of its own.
|
|
116
|
+
let wait = navigationWaits.get(snapshot.root);
|
|
117
|
+
if (!wait) {
|
|
118
|
+
const sources = new Set();
|
|
119
|
+
const add = (item) => {
|
|
120
|
+
ɵngDocRouteContentSources(item.routeConfig).forEach((found) => sources.add(found));
|
|
121
|
+
};
|
|
122
|
+
snapshot.pathFromRoot.forEach(add);
|
|
123
|
+
for (let child = snapshot.firstChild; child; child = child.firstChild)
|
|
124
|
+
add(child);
|
|
125
|
+
wait = waitFor([...sources], inject(ɵNG_DOC_CONTENT_WAIT));
|
|
126
|
+
navigationWaits.set(snapshot.root, wait);
|
|
127
|
+
}
|
|
128
|
+
await wait;
|
|
129
|
+
return true;
|
|
130
|
+
};
|
|
131
|
+
routeSources.set(resolver, source);
|
|
132
|
+
return { ...route, resolve: { ...route.resolve, [RESOLVE_KEY]: resolver } };
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Waits until the sources have loaded or failed, or for at most `limit` milliseconds.
|
|
136
|
+
* @param sources - The content sources.
|
|
137
|
+
* @param limit - The longest wait, in milliseconds.
|
|
138
|
+
* @returns A promise that settles when the wait is over; it never rejects.
|
|
139
|
+
*/
|
|
140
|
+
async function waitFor(sources, limit) {
|
|
141
|
+
let timer;
|
|
142
|
+
try {
|
|
143
|
+
await Promise.race([
|
|
144
|
+
Promise.all(sources.map((item) => ɵpreloadNgDocContent(item).catch(() => undefined))),
|
|
145
|
+
// The timer is cleared as soon as the content is in, so it never keeps a server render or
|
|
146
|
+
// a zone application from becoming stable.
|
|
147
|
+
new Promise((resolve) => (timer = setTimeout(resolve, limit))),
|
|
148
|
+
]);
|
|
149
|
+
}
|
|
150
|
+
finally {
|
|
151
|
+
clearTimeout(timer);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Returns the content sources that `ɵwithNgDocContent` attached to a route.
|
|
156
|
+
* @param route - The route, as declared or as the router copied it.
|
|
157
|
+
* @returns The content sources of the route.
|
|
158
|
+
* @internal
|
|
159
|
+
*/
|
|
160
|
+
function ɵngDocRouteContentSources(route) {
|
|
161
|
+
return Object.values(route?.resolve ?? {})
|
|
162
|
+
.map((resolver) => routeSources.get(resolver))
|
|
163
|
+
.filter((source) => source !== undefined);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/** Waits for content loading and processing before returning an SSR application. */
|
|
167
|
+
function withNgDocContentReady(bootstrap) {
|
|
168
|
+
return async (...arguments_) => {
|
|
169
|
+
let application;
|
|
170
|
+
try {
|
|
171
|
+
application = await bootstrap(...arguments_);
|
|
172
|
+
await application.whenStable();
|
|
173
|
+
application.injector.get(NgDocContentState).throwIfFailed();
|
|
174
|
+
return application;
|
|
175
|
+
}
|
|
176
|
+
catch (error) {
|
|
177
|
+
try {
|
|
178
|
+
application?.destroy();
|
|
179
|
+
}
|
|
180
|
+
catch {
|
|
181
|
+
// Preserve the load, processing, stability, or bootstrap failure.
|
|
182
|
+
}
|
|
183
|
+
throw error;
|
|
184
|
+
}
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
|
|
19
188
|
/**
|
|
20
189
|
*
|
|
21
190
|
* @param viewContainer
|
|
@@ -55,7 +224,10 @@ async function formatHtml(html) {
|
|
|
55
224
|
*/
|
|
56
225
|
function generateToc(container) {
|
|
57
226
|
const headings = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'];
|
|
58
|
-
const headingElements = Array.from(container.querySelectorAll(headings.join(', ')))
|
|
227
|
+
const headingElements = Array.from(container.querySelectorAll(headings.join(', ')))
|
|
228
|
+
// Only the open tab of a tab group is on the page, so the headings inside tabs would come and
|
|
229
|
+
// go with it; they stay out of the table of contents.
|
|
230
|
+
.filter((heading) => heading.id && !heading.closest('ng-doc-tabs'));
|
|
59
231
|
const levels = asArray(new Set(headingElements.map(levelFromTagName).sort()));
|
|
60
232
|
return headingElements.reduce((map, heading) => {
|
|
61
233
|
const headingLevel = levelFromTagName(heading);
|
|
@@ -80,6 +252,77 @@ function levelFromTagName(heading) {
|
|
|
80
252
|
return Number(heading.tagName.toLowerCase().replace(/[a-z]*/g, '') || 1);
|
|
81
253
|
}
|
|
82
254
|
|
|
255
|
+
/**
|
|
256
|
+
* The host attribute with which a component tells that its content loads asynchronously. The
|
|
257
|
+
* server renders it, so only such hosts are copied: a page with inline content costs nothing.
|
|
258
|
+
* @internal
|
|
259
|
+
*/
|
|
260
|
+
const ɵNG_DOC_ASYNC_CONTENT_ATTRIBUTE = 'data-ng-doc-async-content';
|
|
261
|
+
/** The NgDoc hosts that skip hydration and whose content loads asynchronously. */
|
|
262
|
+
const SKIPPED_ASYNC_HOSTS = ['ng-doc-page', 'ng-doc-page-header']
|
|
263
|
+
.map((tag) => `${tag}[ngskiphydration][${ɵNG_DOC_ASYNC_CONTENT_ATTRIBUTE}]`)
|
|
264
|
+
.join(', ');
|
|
265
|
+
/** The class of the element that holds a server-rendered copy. */
|
|
266
|
+
const SNAPSHOT_CLASS = 'ng-doc-hydration-snapshot';
|
|
267
|
+
/** The host attribute that hides the host's own content while the copy is shown. */
|
|
268
|
+
const SNAPSHOT_ATTRIBUTE = 'data-ng-doc-hydration-snapshot';
|
|
269
|
+
const snapshots = new WeakMap();
|
|
270
|
+
/**
|
|
271
|
+
* Copies the server-rendered content of the NgDoc hosts that skip hydration and load their
|
|
272
|
+
* content asynchronously.
|
|
273
|
+
*
|
|
274
|
+
* Angular empties such a host when it creates its component in the browser, and the page would
|
|
275
|
+
* stay blank until the content arrives, so the component shows this copy until its own content
|
|
276
|
+
* renders (`ɵrestoreNgDocHydrationSnapshot`). Call it in the browser before the application
|
|
277
|
+
* renders.
|
|
278
|
+
* @param document - The document that holds the server-rendered application.
|
|
279
|
+
* @internal
|
|
280
|
+
*/
|
|
281
|
+
function ɵcaptureNgDocHydrationSnapshots(document) {
|
|
282
|
+
for (const host of Array.from(document.querySelectorAll(SKIPPED_ASYNC_HOSTS))) {
|
|
283
|
+
if (!host.childNodes.length || snapshots.has(host))
|
|
284
|
+
continue;
|
|
285
|
+
const copy = document.createDocumentFragment();
|
|
286
|
+
host.childNodes.forEach((node) => copy.appendChild(node.cloneNode(true)));
|
|
287
|
+
snapshots.set(host, copy);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Shows the server-rendered copy of a host's content, taken by
|
|
292
|
+
* `ɵcaptureNgDocHydrationSnapshots`, in place of the host's own content until the returned
|
|
293
|
+
* function is called. Each copy is shown once; without one, nothing changes. The copy is inert
|
|
294
|
+
* and the host is busy while it is shown.
|
|
295
|
+
* @param host - The host element of the component.
|
|
296
|
+
* @returns A function that removes the copy and shows the host's own content; later calls do
|
|
297
|
+
* nothing.
|
|
298
|
+
* @internal
|
|
299
|
+
*/
|
|
300
|
+
function ɵrestoreNgDocHydrationSnapshot(host) {
|
|
301
|
+
const copy = snapshots.get(host);
|
|
302
|
+
if (!copy)
|
|
303
|
+
return () => undefined;
|
|
304
|
+
snapshots.delete(host);
|
|
305
|
+
let wrapper = host.ownerDocument.createElement('div');
|
|
306
|
+
wrapper.className = SNAPSHOT_CLASS;
|
|
307
|
+
// The copied nodes lay out as the host's own children did. Inline, because the wrapper has no
|
|
308
|
+
// encapsulation attribute for a component style to match.
|
|
309
|
+
wrapper.style.display = 'contents';
|
|
310
|
+
// A static copy: its demos, buttons and links do nothing until the real content replaces it.
|
|
311
|
+
wrapper.setAttribute('inert', '');
|
|
312
|
+
wrapper.appendChild(copy);
|
|
313
|
+
host.insertBefore(wrapper, host.firstChild);
|
|
314
|
+
host.setAttribute(SNAPSHOT_ATTRIBUTE, '');
|
|
315
|
+
host.setAttribute('aria-busy', 'true');
|
|
316
|
+
return () => {
|
|
317
|
+
if (!wrapper)
|
|
318
|
+
return;
|
|
319
|
+
wrapper.remove();
|
|
320
|
+
wrapper = undefined;
|
|
321
|
+
host.removeAttribute(SNAPSHOT_ATTRIBUTE);
|
|
322
|
+
host.removeAttribute('aria-busy');
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
|
|
83
326
|
/**
|
|
84
327
|
* Check if the OS theme is dark
|
|
85
328
|
*/
|
|
@@ -105,9 +348,71 @@ function isPlaygroundProperty(obj) {
|
|
|
105
348
|
return objectKeys(obj).includes('type');
|
|
106
349
|
}
|
|
107
350
|
|
|
351
|
+
/**
|
|
352
|
+
* Returns the current route as an absolute URL in path form: the route's path, query and fragment
|
|
353
|
+
* on the document's origin.
|
|
354
|
+
*
|
|
355
|
+
* With `PathLocationStrategy`, the default, it is the document's own URL. With
|
|
356
|
+
* `HashLocationStrategy` the route lives in the document's fragment (`/#/docs/page#section`), so
|
|
357
|
+
* `location.hash` and links resolved against `location.href` see the wrong part of the URL. This
|
|
358
|
+
* URL carries the route's own fragment, and relative links resolve against the route.
|
|
359
|
+
* @param locationStrategy - The location strategy of the application.
|
|
360
|
+
* @param documentUrl - The URL of the document, `location.href`.
|
|
361
|
+
* @returns The URL of the route.
|
|
362
|
+
* @internal
|
|
363
|
+
*/
|
|
364
|
+
function ɵngDocRouteUrl(locationStrategy, documentUrl) {
|
|
365
|
+
// A path that starts with `//` would be read as another host.
|
|
366
|
+
return new URL(locationStrategy.path(true).replace(/^\/*/, '/'), documentUrl);
|
|
367
|
+
}
|
|
368
|
+
/**
|
|
369
|
+
* Returns the absolute URL of the current page, without its query, as the reader shares it: the
|
|
370
|
+
* route in the form the location strategy shows it (`/docs/page` or `/#/docs/page`).
|
|
371
|
+
* @param locationStrategy - The location strategy of the application.
|
|
372
|
+
* @param location - The location of the document.
|
|
373
|
+
* @param fragment - The fragment to link to, without `#`.
|
|
374
|
+
* @returns The URL of the page.
|
|
375
|
+
* @internal
|
|
376
|
+
*/
|
|
377
|
+
function ɵngDocPageUrl(locationStrategy, location, fragment) {
|
|
378
|
+
const route = ɵngDocRouteUrl(locationStrategy, location.href);
|
|
379
|
+
// `path()` includes the base href and `prepareExternalUrl()` adds it, so it is removed in
|
|
380
|
+
// between; the round trip gives back the document's own path with `PathLocationStrategy`.
|
|
381
|
+
const base = new URL(locationStrategy.getBaseHref() || '/', route).pathname.replace(/\/+$/, '');
|
|
382
|
+
const path = base && (route.pathname === base || route.pathname.startsWith(`${base}/`))
|
|
383
|
+
? route.pathname.slice(base.length) || '/'
|
|
384
|
+
: route.pathname;
|
|
385
|
+
const external = locationStrategy.prepareExternalUrl(fragment ? `${path}#${fragment}` : path);
|
|
386
|
+
if (external.startsWith('#')) {
|
|
387
|
+
// The route is the document's fragment: it follows the document's path, without its query.
|
|
388
|
+
return `${location.origin}${location.pathname}${external}`;
|
|
389
|
+
}
|
|
390
|
+
if (external.startsWith('/') && !external.startsWith('//')) {
|
|
391
|
+
return `${location.origin}${external}`;
|
|
392
|
+
}
|
|
393
|
+
return new URL(external, location.href).href;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
/**
|
|
397
|
+
* Resolves an option of a playground property. A named option (an enum member) carries its
|
|
398
|
+
* value; a plain value from the playground's `controls` is the value itself; any other option is
|
|
399
|
+
* the source text of a union member, such as `'small'`, and is evaluated; it throws when that
|
|
400
|
+
* text can't be evaluated.
|
|
401
|
+
* @param option - The option.
|
|
402
|
+
* @param isManual - Whether the options come from the playground's `controls`.
|
|
403
|
+
* @returns The value of the option and the text that shows it.
|
|
404
|
+
*/
|
|
405
|
+
function resolvePlaygroundOption(option, isManual) {
|
|
406
|
+
if (typeof option !== 'string') {
|
|
407
|
+
return { label: option.label, value: option.value };
|
|
408
|
+
}
|
|
409
|
+
const value = isManual ? option : extractValueOrThrow(option);
|
|
410
|
+
return { label: String(value), value };
|
|
411
|
+
}
|
|
412
|
+
|
|
108
413
|
/**
|
|
109
414
|
* Generated bundle index. Do not edit.
|
|
110
415
|
*/
|
|
111
416
|
|
|
112
|
-
export { asBoolean, createComponent, formatHtml, generateToc, isDarkOsTheme, isExternalLink, isPlaygroundProperty };
|
|
417
|
+
export { asBoolean, createComponent, formatHtml, generateToc, isDarkOsTheme, isExternalLink, isPlaygroundProperty, resolvePlaygroundOption, withNgDocContentReady, ɵNG_DOC_ASYNC_CONTENT_ATTRIBUTE, ɵNG_DOC_CONTENT_WAIT, ɵcaptureNgDocHydrationSnapshots, ɵforgetNgDocContent, ɵngDocPageUrl, ɵngDocRouteContentSources, ɵngDocRouteUrl, ɵpeekNgDocContent, ɵpendingNgDocContent, ɵpreloadNgDocContent, ɵrestoreNgDocHydrationSnapshot, ɵwithNgDocContent };
|
|
113
418
|
//# sourceMappingURL=ng-doc-app-helpers.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ng-doc-app-helpers.mjs","sources":["../../../../libs/app/helpers/as-boolean.ts","../../../../libs/app/helpers/create-component.ts","../../../../libs/app/helpers/format-html.ts","../../../../libs/app/helpers/generate-toc.ts","../../../../libs/app/helpers/is-dark-os-theme.ts","../../../../libs/app/helpers/is-external-link.ts","../../../../libs/app/helpers/is-playground-property.ts","../../../../libs/app/helpers/ng-doc-app-helpers.ts"],"sourcesContent":["/**\n *\n * @param value\n */\nexport function asBoolean(value: unknown): boolean {\n if (typeof value === 'string') {\n return value.toLowerCase() === 'true'\n ? true\n : value.toLowerCase() === 'false'\n ? false\n : !!value;\n }\n return !!value;\n}\n","import { Type, ViewContainerRef } from '@angular/core';\n\n/**\n *\n * @param viewContainer\n * @param component\n * @param inputs\n */\nexport function createComponent<T>(\n viewContainer: ViewContainerRef,\n component: Type<T>,\n inputs?: object,\n): void {\n viewContainer.clear();\n\n const componentRef = viewContainer.createComponent(component);\n\n if (inputs) {\n Object.entries(inputs).forEach(([key, value]) => {\n componentRef.setInput(key, value);\n });\n }\n}\n","/**\n *\n * @param html\n */\nexport async function formatHtml(html: string): Promise<string> {\n\t// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n\t// @ts-ignore\n\tconst formatter = await import('esthetic');\n\n\treturn formatter.default.html(html.trim(), {\n\t\twrap: 50,\n\t\tmarkup: {\n\t\t\tforceIndent: true,\n\t\t},\n\t});\n}\n","import { NgDocTocItem } from '@ng-doc/app/interfaces';\nimport { asArray } from '@ng-doc/core/helpers/as-array';\nimport { NgDocHeading } from '@ng-doc/core/types';\n\n/**\n * Generate table of contents, only for headings with id\n * @param container\n * @param headings\n */\nexport function generateToc(container: HTMLElement): NgDocTocItem[] {\n const headings: NgDocHeading[] = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'];\n\n const headingElements: HTMLHeadingElement[] = Array.from(\n container.querySelectorAll<HTMLHeadingElement>(headings.join(', ')),\n ).filter((heading: HTMLHeadingElement) => heading.id);\n\n const levels: number[] = asArray(new Set(headingElements.map(levelFromTagName).sort()));\n\n return headingElements.reduce((map: NgDocTocItem[], heading: HTMLHeadingElement) => {\n const headingLevel: number = levelFromTagName(heading);\n const isHeadingLink = heading.getAttribute('headingLink') === 'true';\n\n if (isHeadingLink) {\n map.push({\n title: heading.textContent?.trim() ?? '',\n element: heading,\n path: heading.getAttribute('href') ?? '',\n hash: heading.id,\n level: levels.indexOf(headingLevel) + 1,\n });\n }\n\n return map;\n }, []);\n}\n\n/**\n *\n * @param heading\n */\nfunction levelFromTagName(heading: HTMLHeadingElement): number {\n return Number(heading.tagName.toLowerCase().replace(/[a-z]*/g, '') || 1);\n}\n","/**\n * Check if the OS theme is dark\n */\nexport function isDarkOsTheme(): boolean {\n\treturn window.matchMedia('(prefers-color-scheme: dark)').matches;\n}\n","/**\n *\n * @param url\n */\nexport function isExternalLink(url: string): boolean {\n\tconst anchorElement: HTMLAnchorElement = document.createElement('a');\n\n\tanchorElement.href = url;\n\n\treturn anchorElement.host !== window.location.host;\n}\n","import { objectKeys } from '@ng-doc/core/helpers/object-keys';\nimport { NgDocPlaygroundProperty } from '@ng-doc/core/interfaces';\n\n/**\n *\n * @param obj\n */\nexport function isPlaygroundProperty(obj: Record<string, any>): obj is NgDocPlaygroundProperty {\n return objectKeys(obj).includes('type');\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ng-doc-app-helpers.mjs","sources":["../../../../libs/app/helpers/as-boolean.ts","../../../../libs/app/helpers/content-preload.ts","../../../../libs/app/helpers/content-ready.ts","../../../../libs/app/helpers/create-component.ts","../../../../libs/app/helpers/format-html.ts","../../../../libs/app/helpers/generate-toc.ts","../../../../libs/app/helpers/hydration-snapshot.ts","../../../../libs/app/helpers/is-dark-os-theme.ts","../../../../libs/app/helpers/is-external-link.ts","../../../../libs/app/helpers/is-playground-property.ts","../../../../libs/app/helpers/page-url.ts","../../../../libs/app/helpers/playground-option.ts","../../../../libs/app/helpers/ng-doc-app-helpers.ts"],"sourcesContent":["/**\n *\n * @param value\n */\nexport function asBoolean(value: unknown): boolean {\n if (typeof value === 'string') {\n return value.toLowerCase() === 'true'\n ? true\n : value.toLowerCase() === 'false'\n ? false\n : !!value;\n }\n return !!value;\n}\n","import { inject, InjectionToken } from '@angular/core';\nimport type { ActivatedRouteSnapshot, ResolveFn, Route } from '@angular/router';\nimport type { NgDocContentModule, NgDocContentSource } from '@ng-doc/core/interfaces';\n\n/** The key of the resolver that `ɵwithNgDocContent` adds to a generated page route. */\nconst RESOLVE_KEY = 'ɵngDocContent';\n\ninterface PreloadEntry {\n readonly promise: Promise<NgDocContentModule>;\n payload?: NgDocContentModule;\n}\n\n/** The loads started for each content source, so a source loads once however often it is asked. */\nconst preloads = new WeakMap<NgDocContentSource, PreloadEntry>();\n\n/**\n * The content source of each resolver made by `ɵwithNgDocContent`. The router copies route\n * objects when it loads them, but it keeps their `resolve` maps and functions, so the source is\n * found through the resolver.\n */\nconst routeSources = new WeakMap<ResolveFn<unknown>, NgDocContentSource>();\n\n/** The wait of each navigation, by its root snapshot. */\nconst navigationWaits = new WeakMap<ActivatedRouteSnapshot, Promise<void>>();\n\n/**\n * How long the router waits for the content of a page before it shows the page anyway, in\n * milliseconds. A stalled load must not freeze navigation: after this, the page opens and its\n * content renders when it arrives, as without the wait.\n * @internal\n */\nexport const ɵNG_DOC_CONTENT_WAIT = new InjectionToken<number>('ɵNG_DOC_CONTENT_WAIT', {\n factory: () => 8000,\n});\n\n/**\n * Loads a content source once and keeps its payload, so a page that renders it later shows it in\n * its first render. A failed load is forgotten, so the next request tries again.\n * @param source - The content source.\n * @returns The loaded payload.\n * @internal\n */\nexport function ɵpreloadNgDocContent(source: NgDocContentSource): Promise<NgDocContentModule> {\n const existing = preloads.get(source);\n\n if (existing) return existing.promise;\n\n // Preloads are shared between navigations, so no navigation may abort them.\n const promise = Promise.resolve()\n .then(() => source.load(new AbortController().signal))\n .then(\n (payload: NgDocContentModule) => {\n if (preloads.get(source) === entry) entry.payload = payload;\n return payload;\n },\n (error: unknown) => {\n if (preloads.get(source) === entry) preloads.delete(source);\n throw error;\n },\n );\n const entry: PreloadEntry = { promise };\n\n preloads.set(source, entry);\n\n return promise;\n}\n\n/**\n * Returns the payload of a source that `ɵpreloadNgDocContent` has loaded, without waiting.\n * @param source - The content source.\n * @returns The payload, or `undefined` when the source has not finished loading.\n * @internal\n */\nexport function ɵpeekNgDocContent(source: NgDocContentSource): NgDocContentModule | undefined {\n return preloads.get(source)?.payload;\n}\n\n/**\n * Returns the load of a source that `ɵpreloadNgDocContent` started and that has not finished,\n * so a page that opens before it finishes waits for the same load instead of starting another.\n * @param source - The content source.\n * @returns The pending load, or `undefined`.\n * @internal\n */\nexport function ɵpendingNgDocContent(\n source: NgDocContentSource,\n): Promise<NgDocContentModule> | undefined {\n const entry = preloads.get(source);\n\n return entry && !entry.payload ? entry.promise : undefined;\n}\n\n/**\n * Drops the preloaded payload of a source, for a source that reports a new revision.\n * @param source - The content source.\n * @internal\n */\nexport function ɵforgetNgDocContent(source: NgDocContentSource): void {\n preloads.delete(source);\n}\n\n/**\n * Makes the router wait for the content of a generated page before it shows the page. Without\n * it, the router removes the previous page as soon as the page's code has loaded, and an empty\n * page shows until its content arrives.\n *\n * The resolver loads the content of every route of the navigation that has some, all at once,\n * because the router runs the resolvers of nested routes one after another. A load that fails\n * still lets the navigation finish: the page shows the error. A load that takes longer than\n * `ɵNG_DOC_CONTENT_WAIT` lets it finish too: the page then renders its content when it arrives.\n * @param route - The route of the page.\n * @param source - The content source of the route's component.\n * @returns A copy of the route with the resolver added.\n * @internal\n */\nexport function ɵwithNgDocContent(route: Route, source: NgDocContentSource): Route {\n const resolver: ResolveFn<boolean> = async (snapshot: ActivatedRouteSnapshot) => {\n // The resolvers of one navigation share its root snapshot, and with it one wait: nested\n // resolvers run one after another, and each must not start a wait of its own.\n let wait = navigationWaits.get(snapshot.root);\n\n if (!wait) {\n const sources = new Set<NgDocContentSource>();\n const add = (item: ActivatedRouteSnapshot): void => {\n ɵngDocRouteContentSources(item.routeConfig).forEach((found) => sources.add(found));\n };\n\n snapshot.pathFromRoot.forEach(add);\n for (let child = snapshot.firstChild; child; child = child.firstChild) add(child);\n wait = waitFor([...sources], inject(ɵNG_DOC_CONTENT_WAIT));\n navigationWaits.set(snapshot.root, wait);\n }\n await wait;\n\n return true;\n };\n\n routeSources.set(resolver, source);\n\n return { ...route, resolve: { ...route.resolve, [RESOLVE_KEY]: resolver } };\n}\n\n/**\n * Waits until the sources have loaded or failed, or for at most `limit` milliseconds.\n * @param sources - The content sources.\n * @param limit - The longest wait, in milliseconds.\n * @returns A promise that settles when the wait is over; it never rejects.\n */\nasync function waitFor(sources: NgDocContentSource[], limit: number): Promise<void> {\n let timer: ReturnType<typeof setTimeout> | undefined;\n\n try {\n await Promise.race([\n Promise.all(sources.map((item) => ɵpreloadNgDocContent(item).catch(() => undefined))),\n // The timer is cleared as soon as the content is in, so it never keeps a server render or\n // a zone application from becoming stable.\n new Promise<void>((resolve) => (timer = setTimeout(resolve, limit))),\n ]);\n } finally {\n clearTimeout(timer);\n }\n}\n\n/**\n * Returns the content sources that `ɵwithNgDocContent` attached to a route.\n * @param route - The route, as declared or as the router copied it.\n * @returns The content sources of the route.\n * @internal\n */\nexport function ɵngDocRouteContentSources(route: Route | null | undefined): NgDocContentSource[] {\n return Object.values(route?.resolve ?? {})\n .map((resolver: unknown) => routeSources.get(resolver as ResolveFn<unknown>))\n .filter((source): source is NgDocContentSource => source !== undefined);\n}\n","import { ApplicationRef } from '@angular/core';\nimport { NgDocContentState } from '@ng-doc/app/services/content-state';\n\nexport type NgDocBootstrap<\n TArguments extends unknown[],\n TApplication extends ApplicationRef = ApplicationRef,\n> = (...arguments_: TArguments) => Promise<TApplication>;\n\n/** Waits for content loading and processing before returning an SSR application. */\nexport function withNgDocContentReady<\n TArguments extends unknown[],\n TApplication extends ApplicationRef = ApplicationRef,\n>(bootstrap: NgDocBootstrap<TArguments, TApplication>): NgDocBootstrap<TArguments, TApplication> {\n return async (...arguments_: TArguments): Promise<TApplication> => {\n let application: TApplication | undefined;\n try {\n application = await bootstrap(...arguments_);\n await application.whenStable();\n application.injector.get(NgDocContentState).throwIfFailed();\n return application;\n } catch (error) {\n try {\n application?.destroy();\n } catch {\n // Preserve the load, processing, stability, or bootstrap failure.\n }\n throw error;\n }\n };\n}\n","import { Type, ViewContainerRef } from '@angular/core';\n\n/**\n *\n * @param viewContainer\n * @param component\n * @param inputs\n */\nexport function createComponent<T>(\n viewContainer: ViewContainerRef,\n component: Type<T>,\n inputs?: object,\n): void {\n viewContainer.clear();\n\n const componentRef = viewContainer.createComponent(component);\n\n if (inputs) {\n Object.entries(inputs).forEach(([key, value]) => {\n componentRef.setInput(key, value);\n });\n }\n}\n","/**\n *\n * @param html\n */\nexport async function formatHtml(html: string): Promise<string> {\n\t// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n\t// @ts-ignore\n\tconst formatter = await import('esthetic');\n\n\treturn formatter.default.html(html.trim(), {\n\t\twrap: 50,\n\t\tmarkup: {\n\t\t\tforceIndent: true,\n\t\t},\n\t});\n}\n","import { NgDocTocItem } from '@ng-doc/app/interfaces';\nimport { asArray } from '@ng-doc/core/helpers/as-array';\nimport { NgDocHeading } from '@ng-doc/core/types';\n\n/**\n * Generate table of contents, only for headings with id\n * @param container\n * @param headings\n */\nexport function generateToc(container: HTMLElement): NgDocTocItem[] {\n const headings: NgDocHeading[] = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'];\n\n const headingElements: HTMLHeadingElement[] = Array.from(\n container.querySelectorAll<HTMLHeadingElement>(headings.join(', ')),\n )\n // Only the open tab of a tab group is on the page, so the headings inside tabs would come and\n // go with it; they stay out of the table of contents.\n .filter((heading: HTMLHeadingElement) => heading.id && !heading.closest('ng-doc-tabs'));\n\n const levels: number[] = asArray(new Set(headingElements.map(levelFromTagName).sort()));\n\n return headingElements.reduce((map: NgDocTocItem[], heading: HTMLHeadingElement) => {\n const headingLevel: number = levelFromTagName(heading);\n const isHeadingLink = heading.getAttribute('headingLink') === 'true';\n\n if (isHeadingLink) {\n map.push({\n title: heading.textContent?.trim() ?? '',\n element: heading,\n path: heading.getAttribute('href') ?? '',\n hash: heading.id,\n level: levels.indexOf(headingLevel) + 1,\n });\n }\n\n return map;\n }, []);\n}\n\n/**\n *\n * @param heading\n */\nfunction levelFromTagName(heading: HTMLHeadingElement): number {\n return Number(heading.tagName.toLowerCase().replace(/[a-z]*/g, '') || 1);\n}\n","/**\n * The host attribute with which a component tells that its content loads asynchronously. The\n * server renders it, so only such hosts are copied: a page with inline content costs nothing.\n * @internal\n */\nexport const ɵNG_DOC_ASYNC_CONTENT_ATTRIBUTE = 'data-ng-doc-async-content';\n\n/** The NgDoc hosts that skip hydration and whose content loads asynchronously. */\nconst SKIPPED_ASYNC_HOSTS = ['ng-doc-page', 'ng-doc-page-header']\n .map((tag: string) => `${tag}[ngskiphydration][${ɵNG_DOC_ASYNC_CONTENT_ATTRIBUTE}]`)\n .join(', ');\n/** The class of the element that holds a server-rendered copy. */\nconst SNAPSHOT_CLASS = 'ng-doc-hydration-snapshot';\n/** The host attribute that hides the host's own content while the copy is shown. */\nconst SNAPSHOT_ATTRIBUTE = 'data-ng-doc-hydration-snapshot';\n\nconst snapshots = new WeakMap<Element, DocumentFragment>();\n\n/**\n * Copies the server-rendered content of the NgDoc hosts that skip hydration and load their\n * content asynchronously.\n *\n * Angular empties such a host when it creates its component in the browser, and the page would\n * stay blank until the content arrives, so the component shows this copy until its own content\n * renders (`ɵrestoreNgDocHydrationSnapshot`). Call it in the browser before the application\n * renders.\n * @param document - The document that holds the server-rendered application.\n * @internal\n */\nexport function ɵcaptureNgDocHydrationSnapshots(document: Document): void {\n for (const host of Array.from(document.querySelectorAll(SKIPPED_ASYNC_HOSTS))) {\n if (!host.childNodes.length || snapshots.has(host)) continue;\n\n const copy = document.createDocumentFragment();\n\n host.childNodes.forEach((node: ChildNode) => copy.appendChild(node.cloneNode(true)));\n snapshots.set(host, copy);\n }\n}\n\n/**\n * Shows the server-rendered copy of a host's content, taken by\n * `ɵcaptureNgDocHydrationSnapshots`, in place of the host's own content until the returned\n * function is called. Each copy is shown once; without one, nothing changes. The copy is inert\n * and the host is busy while it is shown.\n * @param host - The host element of the component.\n * @returns A function that removes the copy and shows the host's own content; later calls do\n * nothing.\n * @internal\n */\nexport function ɵrestoreNgDocHydrationSnapshot(host: Element): () => void {\n const copy = snapshots.get(host);\n\n if (!copy) return () => undefined;\n\n snapshots.delete(host);\n\n let wrapper: HTMLElement | undefined = host.ownerDocument.createElement('div');\n\n wrapper.className = SNAPSHOT_CLASS;\n // The copied nodes lay out as the host's own children did. Inline, because the wrapper has no\n // encapsulation attribute for a component style to match.\n wrapper.style.display = 'contents';\n // A static copy: its demos, buttons and links do nothing until the real content replaces it.\n wrapper.setAttribute('inert', '');\n wrapper.appendChild(copy);\n host.insertBefore(wrapper, host.firstChild);\n host.setAttribute(SNAPSHOT_ATTRIBUTE, '');\n host.setAttribute('aria-busy', 'true');\n\n return () => {\n if (!wrapper) return;\n wrapper.remove();\n wrapper = undefined;\n host.removeAttribute(SNAPSHOT_ATTRIBUTE);\n host.removeAttribute('aria-busy');\n };\n}\n","/**\n * Check if the OS theme is dark\n */\nexport function isDarkOsTheme(): boolean {\n\treturn window.matchMedia('(prefers-color-scheme: dark)').matches;\n}\n","/**\n *\n * @param url\n */\nexport function isExternalLink(url: string): boolean {\n\tconst anchorElement: HTMLAnchorElement = document.createElement('a');\n\n\tanchorElement.href = url;\n\n\treturn anchorElement.host !== window.location.host;\n}\n","import { objectKeys } from '@ng-doc/core/helpers/object-keys';\nimport { NgDocPlaygroundProperty } from '@ng-doc/core/interfaces';\n\n/**\n *\n * @param obj\n */\nexport function isPlaygroundProperty(obj: Record<string, any>): obj is NgDocPlaygroundProperty {\n return objectKeys(obj).includes('type');\n}\n","import type { LocationStrategy } from '@angular/common';\n\n/**\n * Returns the current route as an absolute URL in path form: the route's path, query and fragment\n * on the document's origin.\n *\n * With `PathLocationStrategy`, the default, it is the document's own URL. With\n * `HashLocationStrategy` the route lives in the document's fragment (`/#/docs/page#section`), so\n * `location.hash` and links resolved against `location.href` see the wrong part of the URL. This\n * URL carries the route's own fragment, and relative links resolve against the route.\n * @param locationStrategy - The location strategy of the application.\n * @param documentUrl - The URL of the document, `location.href`.\n * @returns The URL of the route.\n * @internal\n */\nexport function ɵngDocRouteUrl(locationStrategy: LocationStrategy, documentUrl: string): URL {\n // A path that starts with `//` would be read as another host.\n return new URL(locationStrategy.path(true).replace(/^\\/*/, '/'), documentUrl);\n}\n\n/**\n * Returns the absolute URL of the current page, without its query, as the reader shares it: the\n * route in the form the location strategy shows it (`/docs/page` or `/#/docs/page`).\n * @param locationStrategy - The location strategy of the application.\n * @param location - The location of the document.\n * @param fragment - The fragment to link to, without `#`.\n * @returns The URL of the page.\n * @internal\n */\nexport function ɵngDocPageUrl(\n locationStrategy: LocationStrategy,\n location: Pick<Location, 'href' | 'origin' | 'pathname'>,\n fragment?: string,\n): string {\n const route = ɵngDocRouteUrl(locationStrategy, location.href);\n // `path()` includes the base href and `prepareExternalUrl()` adds it, so it is removed in\n // between; the round trip gives back the document's own path with `PathLocationStrategy`.\n const base = new URL(locationStrategy.getBaseHref() || '/', route).pathname.replace(/\\/+$/, '');\n const path =\n base && (route.pathname === base || route.pathname.startsWith(`${base}/`))\n ? route.pathname.slice(base.length) || '/'\n : route.pathname;\n const external = locationStrategy.prepareExternalUrl(fragment ? `${path}#${fragment}` : path);\n\n if (external.startsWith('#')) {\n // The route is the document's fragment: it follows the document's path, without its query.\n return `${location.origin}${location.pathname}${external}`;\n }\n\n if (external.startsWith('/') && !external.startsWith('//')) {\n return `${location.origin}${external}`;\n }\n\n return new URL(external, location.href).href;\n}\n","import { extractValueOrThrow } from '@ng-doc/core/helpers/extract-value';\nimport { NgDocPlaygroundOption } from '@ng-doc/core/interfaces';\n\n/** An option of a playground property, resolved to the value it sets and the text it shows. */\nexport interface NgDocResolvedPlaygroundOption {\n /** The text shown for the option. */\n label: string;\n /** The value the option sets. */\n value: unknown;\n}\n\n/**\n * Resolves an option of a playground property. A named option (an enum member) carries its\n * value; a plain value from the playground's `controls` is the value itself; any other option is\n * the source text of a union member, such as `'small'`, and is evaluated; it throws when that\n * text can't be evaluated.\n * @param option - The option.\n * @param isManual - Whether the options come from the playground's `controls`.\n * @returns The value of the option and the text that shows it.\n */\nexport function resolvePlaygroundOption(\n option: string | NgDocPlaygroundOption,\n isManual?: boolean,\n): NgDocResolvedPlaygroundOption {\n if (typeof option !== 'string') {\n return { label: option.label, value: option.value };\n }\n\n const value: unknown = isManual ? option : extractValueOrThrow(option);\n\n return { label: String(value), value };\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|