@ng-doc/app 22.0.0-beta.1 → 22.0.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.
Files changed (205) hide show
  1. package/README.md +20 -29
  2. package/fesm2022/ng-doc-app-classes-content-anchor-controller.mjs +363 -0
  3. package/fesm2022/ng-doc-app-classes-content-anchor-controller.mjs.map +1 -0
  4. package/fesm2022/ng-doc-app-classes-content-controller.mjs +299 -0
  5. package/fesm2022/ng-doc-app-classes-content-controller.mjs.map +1 -0
  6. package/fesm2022/ng-doc-app-classes-default-search-engine.mjs +51 -35
  7. package/fesm2022/ng-doc-app-classes-default-search-engine.mjs.map +1 -1
  8. package/fesm2022/ng-doc-app-classes-root-page.mjs.map +1 -1
  9. package/fesm2022/ng-doc-app-classes-search-engine.mjs.map +1 -1
  10. package/fesm2022/ng-doc-app-classes.mjs +2 -0
  11. package/fesm2022/ng-doc-app-classes.mjs.map +1 -1
  12. package/fesm2022/ng-doc-app-components-api-list.mjs +178 -68
  13. package/fesm2022/ng-doc-app-components-api-list.mjs.map +1 -1
  14. package/fesm2022/ng-doc-app-components-breadcrumb.mjs +13 -10
  15. package/fesm2022/ng-doc-app-components-breadcrumb.mjs.map +1 -1
  16. package/fesm2022/ng-doc-app-components-code.mjs +152 -25
  17. package/fesm2022/ng-doc-app-components-code.mjs.map +1 -1
  18. package/fesm2022/ng-doc-app-components-command-palette.mjs +498 -0
  19. package/fesm2022/ng-doc-app-components-command-palette.mjs.map +1 -0
  20. package/fesm2022/ng-doc-app-components-copy-button.mjs +38 -21
  21. package/fesm2022/ng-doc-app-components-copy-button.mjs.map +1 -1
  22. package/fesm2022/ng-doc-app-components-demo-displayer.mjs +36 -29
  23. package/fesm2022/ng-doc-app-components-demo-displayer.mjs.map +1 -1
  24. package/fesm2022/ng-doc-app-components-demo-pane.mjs +39 -36
  25. package/fesm2022/ng-doc-app-components-demo-pane.mjs.map +1 -1
  26. package/fesm2022/ng-doc-app-components-demo.mjs +129 -44
  27. package/fesm2022/ng-doc-app-components-demo.mjs.map +1 -1
  28. package/fesm2022/ng-doc-app-components-fullscreen-button.mjs +12 -9
  29. package/fesm2022/ng-doc-app-components-fullscreen-button.mjs.map +1 -1
  30. package/fesm2022/ng-doc-app-components-fullscreen-toggle.mjs +79 -0
  31. package/fesm2022/ng-doc-app-components-fullscreen-toggle.mjs.map +1 -0
  32. package/fesm2022/ng-doc-app-components-heading-anchor.mjs +54 -21
  33. package/fesm2022/ng-doc-app-components-heading-anchor.mjs.map +1 -1
  34. package/fesm2022/ng-doc-app-components-image-viewer.mjs +187 -91
  35. package/fesm2022/ng-doc-app-components-image-viewer.mjs.map +1 -1
  36. package/fesm2022/ng-doc-app-components-kind-icon.mjs +42 -25
  37. package/fesm2022/ng-doc-app-components-kind-icon.mjs.map +1 -1
  38. package/fesm2022/ng-doc-app-components-link.mjs +12 -9
  39. package/fesm2022/ng-doc-app-components-link.mjs.map +1 -1
  40. package/fesm2022/ng-doc-app-components-members.mjs +30 -0
  41. package/fesm2022/ng-doc-app-components-members.mjs.map +1 -0
  42. package/fesm2022/ng-doc-app-components-mermaid-viewer.mjs +69 -24
  43. package/fesm2022/ng-doc-app-components-mermaid-viewer.mjs.map +1 -1
  44. package/fesm2022/ng-doc-app-components-navbar.mjs +39 -49
  45. package/fesm2022/ng-doc-app-components-navbar.mjs.map +1 -1
  46. package/fesm2022/ng-doc-app-components-page-header.mjs +73 -10
  47. package/fesm2022/ng-doc-app-components-page-header.mjs.map +1 -1
  48. package/fesm2022/ng-doc-app-components-page-link.mjs +123 -31
  49. package/fesm2022/ng-doc-app-components-page-link.mjs.map +1 -1
  50. package/fesm2022/ng-doc-app-components-page-navigation.mjs +17 -19
  51. package/fesm2022/ng-doc-app-components-page-navigation.mjs.map +1 -1
  52. package/fesm2022/ng-doc-app-components-page-wrapper.mjs +56 -35
  53. package/fesm2022/ng-doc-app-components-page-wrapper.mjs.map +1 -1
  54. package/fesm2022/ng-doc-app-components-page.mjs +168 -24
  55. package/fesm2022/ng-doc-app-components-page.mjs.map +1 -1
  56. package/fesm2022/ng-doc-app-components-playground.mjs +392 -263
  57. package/fesm2022/ng-doc-app-components-playground.mjs.map +1 -1
  58. package/fesm2022/ng-doc-app-components-root.mjs +48 -31
  59. package/fesm2022/ng-doc-app-components-root.mjs.map +1 -1
  60. package/fesm2022/ng-doc-app-components-search-result.mjs +22 -21
  61. package/fesm2022/ng-doc-app-components-search-result.mjs.map +1 -1
  62. package/fesm2022/ng-doc-app-components-search.mjs +64 -33
  63. package/fesm2022/ng-doc-app-components-search.mjs.map +1 -1
  64. package/fesm2022/ng-doc-app-components-sidebar.mjs +90 -63
  65. package/fesm2022/ng-doc-app-components-sidebar.mjs.map +1 -1
  66. package/fesm2022/ng-doc-app-components-tabs.mjs +18 -12
  67. package/fesm2022/ng-doc-app-components-tabs.mjs.map +1 -1
  68. package/fesm2022/ng-doc-app-components-theme-toggle.mjs +33 -21
  69. package/fesm2022/ng-doc-app-components-theme-toggle.mjs.map +1 -1
  70. package/fesm2022/ng-doc-app-components-toc.mjs +268 -90
  71. package/fesm2022/ng-doc-app-components-toc.mjs.map +1 -1
  72. package/fesm2022/ng-doc-app-components.mjs +3 -1
  73. package/fesm2022/ng-doc-app-components.mjs.map +1 -1
  74. package/fesm2022/ng-doc-app-defaults-default-processors.mjs +2 -1
  75. package/fesm2022/ng-doc-app-defaults-default-processors.mjs.map +1 -1
  76. package/fesm2022/ng-doc-app-directives-code-highlighter.mjs +14 -7
  77. package/fesm2022/ng-doc-app-directives-code-highlighter.mjs.map +1 -1
  78. package/fesm2022/ng-doc-app-directives-members-filter.mjs +276 -0
  79. package/fesm2022/ng-doc-app-directives-members-filter.mjs.map +1 -0
  80. package/fesm2022/ng-doc-app-directives-route-active.mjs +34 -30
  81. package/fesm2022/ng-doc-app-directives-route-active.mjs.map +1 -1
  82. package/fesm2022/ng-doc-app-directives.mjs +1 -0
  83. package/fesm2022/ng-doc-app-directives.mjs.map +1 -1
  84. package/fesm2022/ng-doc-app-helpers.mjs +285 -1
  85. package/fesm2022/ng-doc-app-helpers.mjs.map +1 -1
  86. package/fesm2022/ng-doc-app-pipes-decode-uri-component.mjs +6 -4
  87. package/fesm2022/ng-doc-app-pipes-decode-uri-component.mjs.map +1 -1
  88. package/fesm2022/ng-doc-app-pipes-extract-value.mjs +6 -4
  89. package/fesm2022/ng-doc-app-pipes-extract-value.mjs.map +1 -1
  90. package/fesm2022/ng-doc-app-pipes-filter-by-text.mjs +7 -4
  91. package/fesm2022/ng-doc-app-pipes-filter-by-text.mjs.map +1 -1
  92. package/fesm2022/ng-doc-app-pipes-sanitize-html.mjs +8 -5
  93. package/fesm2022/ng-doc-app-pipes-sanitize-html.mjs.map +1 -1
  94. package/fesm2022/ng-doc-app-processors-page-processor.mjs +86 -23
  95. package/fesm2022/ng-doc-app-processors-page-processor.mjs.map +1 -1
  96. package/fesm2022/ng-doc-app-processors-processors-tooltip.mjs +26 -25
  97. package/fesm2022/ng-doc-app-processors-processors-tooltip.mjs.map +1 -1
  98. package/fesm2022/ng-doc-app-processors-processors.mjs +12 -1
  99. package/fesm2022/ng-doc-app-processors-processors.mjs.map +1 -1
  100. package/fesm2022/ng-doc-app-providers-ng-doc-app.mjs +31 -2
  101. package/fesm2022/ng-doc-app-providers-ng-doc-app.mjs.map +1 -1
  102. package/fesm2022/ng-doc-app-services-content-scroll-intent.mjs +122 -0
  103. package/fesm2022/ng-doc-app-services-content-scroll-intent.mjs.map +1 -0
  104. package/fesm2022/ng-doc-app-services-content-state.mjs +57 -0
  105. package/fesm2022/ng-doc-app-services-content-state.mjs.map +1 -0
  106. package/fesm2022/ng-doc-app-services-fullscreen-route.mjs +74 -0
  107. package/fesm2022/ng-doc-app-services-fullscreen-route.mjs.map +1 -0
  108. package/fesm2022/ng-doc-app-services-highlighter.mjs +83 -14
  109. package/fesm2022/ng-doc-app-services-highlighter.mjs.map +1 -1
  110. package/fesm2022/ng-doc-app-services-route-preloader.mjs +360 -0
  111. package/fesm2022/ng-doc-app-services-route-preloader.mjs.map +1 -0
  112. package/fesm2022/ng-doc-app-services-shortcuts.mjs +214 -0
  113. package/fesm2022/ng-doc-app-services-shortcuts.mjs.map +1 -0
  114. package/fesm2022/ng-doc-app-services-sidebar.mjs +59 -25
  115. package/fesm2022/ng-doc-app-services-sidebar.mjs.map +1 -1
  116. package/fesm2022/ng-doc-app-services-store.mjs +8 -8
  117. package/fesm2022/ng-doc-app-services-store.mjs.map +1 -1
  118. package/fesm2022/ng-doc-app-services-theme.mjs +32 -12
  119. package/fesm2022/ng-doc-app-services-theme.mjs.map +1 -1
  120. package/fesm2022/ng-doc-app-services.mjs +143 -0
  121. package/fesm2022/ng-doc-app-services.mjs.map +1 -1
  122. package/fesm2022/ng-doc-app-tokens.mjs +7 -28
  123. package/fesm2022/ng-doc-app-tokens.mjs.map +1 -1
  124. package/fesm2022/ng-doc-app-type-controls-boolean-control.mjs +18 -9
  125. package/fesm2022/ng-doc-app-type-controls-boolean-control.mjs.map +1 -1
  126. package/fesm2022/ng-doc-app-type-controls-number-control.mjs +12 -9
  127. package/fesm2022/ng-doc-app-type-controls-number-control.mjs.map +1 -1
  128. package/fesm2022/ng-doc-app-type-controls-string-control.mjs +12 -9
  129. package/fesm2022/ng-doc-app-type-controls-string-control.mjs.map +1 -1
  130. package/fesm2022/ng-doc-app-type-controls-type-alias-control.mjs +22 -16
  131. package/fesm2022/ng-doc-app-type-controls-type-alias-control.mjs.map +1 -1
  132. package/package.json +74 -32
  133. package/styles/global.css +1129 -205
  134. package/styles/main.css +1129 -205
  135. package/styles/themes/dark.css +78 -56
  136. package/types/ng-doc-app-classes-content-anchor-controller.d.ts +54 -0
  137. package/types/ng-doc-app-classes-content-controller.d.ts +94 -0
  138. package/types/ng-doc-app-classes-default-search-engine.d.ts +9 -1
  139. package/types/ng-doc-app-classes-root-page.d.ts +6 -1
  140. package/types/ng-doc-app-classes-search-engine.d.ts +5 -0
  141. package/types/ng-doc-app-classes.d.ts +2 -0
  142. package/types/ng-doc-app-components-api-list.d.ts +69 -20
  143. package/types/ng-doc-app-components-breadcrumb.d.ts +8 -3
  144. package/types/ng-doc-app-components-code.d.ts +46 -12
  145. package/types/ng-doc-app-components-command-palette.d.ts +147 -0
  146. package/types/ng-doc-app-components-copy-button.d.ts +18 -6
  147. package/types/ng-doc-app-components-demo-displayer.d.ts +23 -10
  148. package/types/ng-doc-app-components-demo-pane.d.ts +19 -15
  149. package/types/ng-doc-app-components-demo.d.ts +62 -15
  150. package/types/ng-doc-app-components-fullscreen-button.d.ts +4 -2
  151. package/types/ng-doc-app-components-fullscreen-toggle.d.ts +24 -0
  152. package/types/ng-doc-app-components-heading-anchor.d.ts +26 -7
  153. package/types/ng-doc-app-components-image-viewer.d.ts +71 -7
  154. package/types/ng-doc-app-components-kind-icon.d.ts +28 -7
  155. package/types/ng-doc-app-components-link.d.ts +6 -2
  156. package/types/ng-doc-app-components-members.d.ts +13 -0
  157. package/types/ng-doc-app-components-mermaid-viewer.d.ts +21 -6
  158. package/types/ng-doc-app-components-navbar.d.ts +25 -15
  159. package/types/ng-doc-app-components-page-header.d.ts +28 -4
  160. package/types/ng-doc-app-components-page-link.d.ts +34 -15
  161. package/types/ng-doc-app-components-page-navigation.d.ts +10 -5
  162. package/types/ng-doc-app-components-page-wrapper.d.ts +35 -11
  163. package/types/ng-doc-app-components-page.d.ts +57 -6
  164. package/types/ng-doc-app-components-playground.d.ts +146 -78
  165. package/types/ng-doc-app-components-root.d.ts +28 -7
  166. package/types/ng-doc-app-components-search-result.d.ts +14 -6
  167. package/types/ng-doc-app-components-search.d.ts +19 -7
  168. package/types/ng-doc-app-components-tabs.d.ts +13 -4
  169. package/types/ng-doc-app-components-theme-toggle.d.ts +18 -5
  170. package/types/ng-doc-app-components-toc.d.ts +76 -29
  171. package/types/ng-doc-app-components.d.ts +3 -1
  172. package/types/ng-doc-app-directives-code-highlighter.d.ts +8 -4
  173. package/types/ng-doc-app-directives-members-filter.d.ts +61 -0
  174. package/types/ng-doc-app-directives-route-active.d.ts +21 -7
  175. package/types/ng-doc-app-directives.d.ts +1 -0
  176. package/types/ng-doc-app-helpers.d.ts +124 -3
  177. package/types/ng-doc-app-interfaces.d.ts +48 -28
  178. package/types/ng-doc-app-pipes-decode-uri-component.d.ts +3 -0
  179. package/types/ng-doc-app-pipes-extract-value.d.ts +3 -0
  180. package/types/ng-doc-app-pipes-filter-by-text.d.ts +4 -0
  181. package/types/ng-doc-app-pipes-sanitize-html.d.ts +4 -2
  182. package/types/ng-doc-app-processors-page-processor.d.ts +39 -10
  183. package/types/ng-doc-app-processors-processors-tooltip.d.ts +11 -10
  184. package/types/ng-doc-app-processors-processors.d.ts +5 -1
  185. package/types/ng-doc-app-providers-ng-doc-app.d.ts +17 -0
  186. package/types/ng-doc-app-providers-playground-demo.d.ts +1 -1
  187. package/types/ng-doc-app-providers-type-control.d.ts +2 -2
  188. package/types/ng-doc-app-services-content-scroll-intent.d.ts +52 -0
  189. package/types/ng-doc-app-services-content-state.d.ts +40 -0
  190. package/types/ng-doc-app-services-fullscreen-route.d.ts +35 -0
  191. package/types/ng-doc-app-services-highlighter.d.ts +40 -5
  192. package/types/ng-doc-app-services-route-preloader.d.ts +109 -0
  193. package/types/ng-doc-app-services-shortcuts.d.ts +96 -0
  194. package/types/ng-doc-app-services-sidebar.d.ts +24 -4
  195. package/types/ng-doc-app-services-store.d.ts +24 -1
  196. package/types/ng-doc-app-services-theme.d.ts +19 -3
  197. package/types/ng-doc-app-services.d.ts +77 -0
  198. package/types/ng-doc-app-tokens.d.ts +10 -30
  199. package/types/ng-doc-app-type-controls-boolean-control.d.ts +11 -6
  200. package/types/ng-doc-app-type-controls-number-control.d.ts +5 -3
  201. package/types/ng-doc-app-type-controls-string-control.d.ts +5 -3
  202. package/types/ng-doc-app-type-controls-type-alias-control.d.ts +13 -6
  203. package/fesm2022/ng-doc-app-components-search-dialog.mjs +0 -78
  204. package/fesm2022/ng-doc-app-components-search-dialog.mjs.map +0 -1
  205. package/types/ng-doc-app-components-search-dialog.d.ts +0 -28
@@ -1,38 +1,77 @@
1
1
  import * as i0 from '@angular/core';
2
- import { inject, ViewContainerRef, ViewChild, Input, ChangeDetectionStrategy, Component } from '@angular/core';
2
+ import { input, booleanAttribute, viewChild, ViewContainerRef, inject, Injector, afterNextRender, ChangeDetectionStrategy, Component } from '@angular/core';
3
3
  import { Router, ActivatedRoute, RouterOutlet, RouterLink, RouterLinkActive } from '@angular/router';
4
4
  import { NgDocPageHeaderComponent } from '@ng-doc/app/components/page-header';
5
5
  import { createComponent } from '@ng-doc/app/helpers';
6
+ import { NgDocFullscreenRouteService } from '@ng-doc/app/services/fullscreen-route';
7
+ import { NgDocRoutePreloader } from '@ng-doc/app/services/route-preloader';
6
8
  import { NG_DOC_PAGE_SKELETON, NG_DOC_CONTEXT } from '@ng-doc/app/tokens';
7
9
  import { isPresent } from '@ng-doc/core/helpers/is-present';
8
10
  import { NgDocTabRouteComponent, NgDocTabRoutesGroupComponent, NgDocIconComponent } from '@ng-doc/ui-kit';
9
11
 
12
+ /**
13
+ * Layout of a generated page: the breadcrumbs, the page header, the tabs of a page with several
14
+ * routes, the page itself, the previous and next page links, and the table of contents beside it.
15
+ *
16
+ * The breadcrumbs, the page links and the table of contents are the page skeleton's components,
17
+ * created in the containers this component exposes.
18
+ *
19
+ * While the page shows one of its fullscreen routes (`NgDocFullscreenRouteService`), only the page
20
+ * is shown.
21
+ */
10
22
  class NgDocPageWrapperComponent {
11
23
  constructor() {
12
- this.hasBreadcrumb = true;
13
- this.pageType = 'guide';
24
+ /** Routes of the page; a page with more than one gets tabs. */
25
+ this.routes = input.required(/* @ts-ignore */
26
+ ...(ngDevMode ? [{ debugName: "routes" }] : /* istanbul ignore next */ []));
27
+ /** HTML of the page header. */
28
+ this.headerContent = input.required(/* @ts-ignore */
29
+ ...(ngDevMode ? [{ debugName: "headerContent" }] : /* istanbul ignore next */ []));
30
+ /** Deferred source of the page header, for generated pages that load it separately. */
31
+ this.headerContentSource = input(/* @ts-ignore */
32
+ ...(ngDevMode ? [undefined, { debugName: "headerContentSource" }] : /* istanbul ignore next */ []));
33
+ /** Whether the page shows breadcrumbs. */
34
+ this.hasBreadcrumb = input(true, { ...(ngDevMode ? { debugName: "hasBreadcrumb" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
35
+ /** Type of the page: guides get previous and next page links, API pages do not. */
36
+ this.pageType = input('guide', /* @ts-ignore */
37
+ ...(ngDevMode ? [{ debugName: "pageType" }] : /* istanbul ignore next */ []));
38
+ /** Container of the breadcrumbs. */
39
+ this.pageBreadcrumbs = viewChild.required('pageBreadcrumbs', { ...(ngDevMode ? { debugName: "pageBreadcrumbs" } : /* istanbul ignore next */ {}), read: ViewContainerRef });
40
+ /** Container of the table of contents. */
41
+ this.pageToc = viewChild.required('pageToc', { ...(ngDevMode ? { debugName: "pageToc" } : /* istanbul ignore next */ {}), read: ViewContainerRef });
42
+ /** Container of the previous and next page links. */
43
+ this.pageNavigation = viewChild.required('pageNavigation', { ...(ngDevMode ? { debugName: "pageNavigation" } : /* istanbul ignore next */ {}), read: ViewContainerRef });
14
44
  this.skeleton = inject(NG_DOC_PAGE_SKELETON);
15
45
  this.router = inject(Router);
16
46
  this.route = inject(ActivatedRoute);
17
47
  this.context = inject(NG_DOC_CONTEXT);
48
+ this.fullscreenRoute = inject(NgDocFullscreenRouteService);
18
49
  this.breadcrumbs = inject(ActivatedRoute)
19
50
  .pathFromRoot.filter((route) => !!route.snapshot.url.length)
20
51
  .map((route) => route.snapshot.title)
21
52
  .filter(isPresent);
53
+ this.preloader = inject(NgDocRoutePreloader);
54
+ this.injector = inject(Injector);
22
55
  }
23
56
  ngOnInit() {
24
- if (this.skeleton.breadcrumbs && this.hasBreadcrumb) {
25
- createComponent(this.pageBreadcrumbs, this.skeleton.breadcrumbs, {
57
+ if (this.skeleton.breadcrumbs && this.hasBreadcrumb()) {
58
+ createComponent(this.pageBreadcrumbs(), this.skeleton.breadcrumbs, {
26
59
  breadcrumbs: this.breadcrumbs,
27
60
  });
28
61
  }
29
- if (this.pageType === 'guide') {
30
- if (this.skeleton.navigation) {
31
- createComponent(this.pageNavigation, this.skeleton.navigation, this.navigationInputs());
32
- }
62
+ if (this.pageType() === 'guide' && this.skeleton.navigation) {
63
+ createComponent(this.pageNavigation(), this.skeleton.navigation, this.adjacentPages());
33
64
  }
65
+ // Readers often go on to the previous or next guide, so both are preloaded once the browser
66
+ // is idle after this one has rendered. Render hooks never run on the server.
67
+ afterNextRender(() => {
68
+ if (this.pageType() !== 'guide')
69
+ return;
70
+ const { prevPage, nextPage } = this.adjacentPages();
71
+ this.preloader.preloadWhenIdle([prevPage?.route, nextPage?.route]);
72
+ }, { injector: this.injector });
34
73
  }
35
- navigationInputs() {
74
+ adjacentPages() {
36
75
  const url = '/' +
37
76
  this.route.pathFromRoot
38
77
  .map((route) => route.snapshot.url)
@@ -47,10 +86,10 @@ class NgDocPageWrapperComponent {
47
86
  nextPage: flatPages[flatPages.findIndex((item) => url === item.route) + 1],
48
87
  };
49
88
  }
50
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NgDocPageWrapperComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
51
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: NgDocPageWrapperComponent, isStandalone: true, selector: "ng-doc-page-wrapper", inputs: { routes: "routes", headerContent: "headerContent", hasBreadcrumb: "hasBreadcrumb", pageType: "pageType" }, host: { properties: { "attr.data-ng-doc-page-tabs": "routes.length > 1" } }, viewQueries: [{ propertyName: "pageBreadcrumbs", first: true, predicate: ["pageBreadcrumbs"], descendants: true, read: ViewContainerRef, static: true }, { propertyName: "pageToc", first: true, predicate: ["pageToc"], descendants: true, read: ViewContainerRef, static: true }, { propertyName: "pageNavigation", first: true, predicate: ["pageNavigation"], descendants: true, read: ViewContainerRef, static: true }], ngImport: i0, template: "<article class=\"ngde\">\n <ng-container #pageBreadcrumbs></ng-container>\n\n <ng-doc-page-header [headerContent]=\"headerContent\" />\n\n @if (routes.length > 1) {\n <ng-doc-tab-routes-group>\n @for (route of routes; track route) {\n <a\n ng-doc-tab-route\n [routerLink]=\"['./' + route.path]\"\n routerLinkActive\n [routerLinkActiveOptions]=\"{ exact: true }\"\n #rla=\"routerLinkActive\"\n [isActive]=\"rla.isActive\">\n @if (route.data?.['icon']; as icon) {\n <ng-doc-icon [customIcon]=\"icon\" />\n }\n {{ route.title }}\n </a>\n }\n </ng-doc-tab-routes-group>\n }\n\n <router-outlet></router-outlet>\n\n <ng-container #pageNavigation></ng-container>\n</article>\n\n<ng-container #pageToc></ng-container>\n", styles: [":host{display:flex;justify-content:space-between;--ng-doc-page-sticky-offset: var(--ng-doc-navbar-height)}:host[data-ng-doc-page-tabs=true]{--ng-doc-page-sticky-offset: calc( var(--ng-doc-navbar-height) + var(--ng-doc-page-wrapper-tabs-height) )}:host{--ng-doc-toc-margin: calc(var(--ng-doc-base-gutter) * 5)}:host article{position:relative;width:var(--ng-doc-article-width, 100%);margin-left:auto;margin-right:auto;min-width:0}:host header ::ng-deep h1{margin-top:0}:host ng-doc-tab-routes-group{position:sticky!important;top:var(--ng-doc-navbar-height);margin:calc(var(--ng-doc-base-gutter) * 2) 0;background:var(--ng-doc-navbar-background);z-index:5;height:var(--ng-doc-page-wrapper-tabs-height)}:host .ng-doc-page-header{margin-bottom:calc(var(--ng-doc-base-gutter) * 3)}\n"], dependencies: [{ kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: NgDocTabRouteComponent, selector: "a[ng-doc-tab-route]", inputs: ["isActive"] }, { kind: "component", type: NgDocTabRoutesGroupComponent, selector: "ng-doc-tab-routes-group" }, { kind: "directive", type: RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }, { kind: "component", type: NgDocIconComponent, selector: "ng-doc-icon", inputs: ["icon", "customIcon", "size"] }, { kind: "component", type: NgDocPageHeaderComponent, selector: "ng-doc-page-header", inputs: ["headerContent"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
89
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.2.1", ngImport: i0, type: NgDocPageWrapperComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
90
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.2.1", type: NgDocPageWrapperComponent, isStandalone: true, selector: "ng-doc-page-wrapper", inputs: { routes: { classPropertyName: "routes", publicName: "routes", isSignal: true, isRequired: true, transformFunction: null }, headerContent: { classPropertyName: "headerContent", publicName: "headerContent", isSignal: true, isRequired: true, transformFunction: null }, headerContentSource: { classPropertyName: "headerContentSource", publicName: "headerContentSource", isSignal: true, isRequired: false, transformFunction: null }, hasBreadcrumb: { classPropertyName: "hasBreadcrumb", publicName: "hasBreadcrumb", isSignal: true, isRequired: false, transformFunction: null }, pageType: { classPropertyName: "pageType", publicName: "pageType", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.data-ng-doc-page-tabs": "routes().length > 1", "attr.data-ng-doc-fullscreen-route": "fullscreenRoute.active()" } }, viewQueries: [{ propertyName: "pageBreadcrumbs", first: true, predicate: ["pageBreadcrumbs"], descendants: true, read: ViewContainerRef, isSignal: true }, { propertyName: "pageToc", first: true, predicate: ["pageToc"], descendants: true, read: ViewContainerRef, isSignal: true }, { propertyName: "pageNavigation", first: true, predicate: ["pageNavigation"], descendants: true, read: ViewContainerRef, isSignal: true }], ngImport: i0, template: "<article class=\"ngde\">\n <ng-container #pageBreadcrumbs></ng-container>\n\n <ng-doc-page-header\n [headerContent]=\"headerContent()\"\n [headerContentSource]=\"headerContentSource()\" />\n\n @if (routes().length > 1) {\n <ng-doc-tab-routes-group>\n @for (route of routes(); track route) {\n <a\n ng-doc-tab-route\n [routerLink]=\"['./' + route.path]\"\n routerLinkActive\n [routerLinkActiveOptions]=\"{ exact: true }\"\n #rla=\"routerLinkActive\"\n [isActive]=\"rla.isActive\">\n @if (route.data?.['icon']; as icon) {\n <ng-doc-icon [customIcon]=\"icon\" />\n }\n {{ route.title }}\n </a>\n }\n </ng-doc-tab-routes-group>\n }\n\n <router-outlet></router-outlet>\n\n <ng-container #pageNavigation></ng-container>\n</article>\n\n<ng-container #pageToc></ng-container>\n", styles: [":host{display:flex;justify-content:space-between;--ng-doc-page-sticky-offset: var(--ng-doc-navbar-height)}:host[data-ng-doc-page-tabs=true]{--ng-doc-page-sticky-offset: calc( var(--ng-doc-navbar-height) + var(--ng-doc-page-wrapper-tabs-height) )}:host{--ng-doc-toc-margin: calc(var(--ng-doc-base-gutter) * 5)}:host article{position:relative;width:var(--ng-doc-article-width, 100%);max-width:var(--ng-doc-article-width, var(--ng-doc-content-max-width));margin-left:auto;margin-right:auto;min-width:0}:host article:has(.ng-doc-page-tags),:host article:has(ng-doc-api-list){max-width:var(--ng-doc-article-width, var(--ng-doc-api-content-max-width))}:host header ::ng-deep h1{margin-top:0}:host ng-doc-tab-routes-group{position:sticky!important;top:var(--ng-doc-navbar-height);margin:calc(var(--ng-doc-base-gutter) * 2) 0;background:var(--ng-doc-navbar-background);z-index:5;height:var(--ng-doc-page-wrapper-tabs-height)}:host .ng-doc-page-header{margin-bottom:calc(var(--ng-doc-base-gutter) * 3)}:host[data-ng-doc-fullscreen-route=true]{display:block}:host[data-ng-doc-fullscreen-route=true] article{width:100%;max-width:none}:host[data-ng-doc-fullscreen-route=true] ::ng-deep>:not(article),:host[data-ng-doc-fullscreen-route=true] ::ng-deep article>:not(router-outlet+*){display:none}\n"], dependencies: [{ kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "browserUrl", "routerLink"] }, { kind: "component", type: NgDocTabRouteComponent, selector: "a[ng-doc-tab-route]", inputs: ["isActive"] }, { kind: "component", type: NgDocTabRoutesGroupComponent, selector: "ng-doc-tab-routes-group" }, { kind: "directive", type: RouterLinkActive, selector: "[routerLinkActive]", inputs: ["routerLinkActiveOptions", "ariaCurrentWhenActive", "routerLinkActive"], outputs: ["isActiveChange"], exportAs: ["routerLinkActive"] }, { kind: "component", type: NgDocIconComponent, selector: "ng-doc-icon", inputs: ["icon", "customIcon", "size"] }, { kind: "component", type: NgDocPageHeaderComponent, selector: "ng-doc-page-header", inputs: ["headerContent", "headerContentSource"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
52
91
  }
53
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NgDocPageWrapperComponent, decorators: [{
92
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.1", ngImport: i0, type: NgDocPageWrapperComponent, decorators: [{
54
93
  type: Component,
55
94
  args: [{ selector: 'ng-doc-page-wrapper', imports: [
56
95
  RouterOutlet,
@@ -61,28 +100,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
61
100
  NgDocIconComponent,
62
101
  NgDocPageHeaderComponent,
63
102
  ], changeDetection: ChangeDetectionStrategy.OnPush, host: {
64
- '[attr.data-ng-doc-page-tabs]': 'routes.length > 1',
65
- }, template: "<article class=\"ngde\">\n <ng-container #pageBreadcrumbs></ng-container>\n\n <ng-doc-page-header [headerContent]=\"headerContent\" />\n\n @if (routes.length > 1) {\n <ng-doc-tab-routes-group>\n @for (route of routes; track route) {\n <a\n ng-doc-tab-route\n [routerLink]=\"['./' + route.path]\"\n routerLinkActive\n [routerLinkActiveOptions]=\"{ exact: true }\"\n #rla=\"routerLinkActive\"\n [isActive]=\"rla.isActive\">\n @if (route.data?.['icon']; as icon) {\n <ng-doc-icon [customIcon]=\"icon\" />\n }\n {{ route.title }}\n </a>\n }\n </ng-doc-tab-routes-group>\n }\n\n <router-outlet></router-outlet>\n\n <ng-container #pageNavigation></ng-container>\n</article>\n\n<ng-container #pageToc></ng-container>\n", styles: [":host{display:flex;justify-content:space-between;--ng-doc-page-sticky-offset: var(--ng-doc-navbar-height)}:host[data-ng-doc-page-tabs=true]{--ng-doc-page-sticky-offset: calc( var(--ng-doc-navbar-height) + var(--ng-doc-page-wrapper-tabs-height) )}:host{--ng-doc-toc-margin: calc(var(--ng-doc-base-gutter) * 5)}:host article{position:relative;width:var(--ng-doc-article-width, 100%);margin-left:auto;margin-right:auto;min-width:0}:host header ::ng-deep h1{margin-top:0}:host ng-doc-tab-routes-group{position:sticky!important;top:var(--ng-doc-navbar-height);margin:calc(var(--ng-doc-base-gutter) * 2) 0;background:var(--ng-doc-navbar-background);z-index:5;height:var(--ng-doc-page-wrapper-tabs-height)}:host .ng-doc-page-header{margin-bottom:calc(var(--ng-doc-base-gutter) * 3)}\n"] }]
66
- }], propDecorators: { routes: [{
67
- type: Input,
68
- args: [{ required: true }]
69
- }], headerContent: [{
70
- type: Input,
71
- args: [{ required: true }]
72
- }], hasBreadcrumb: [{
73
- type: Input
74
- }], pageType: [{
75
- type: Input
76
- }], pageBreadcrumbs: [{
77
- type: ViewChild,
78
- args: ['pageBreadcrumbs', { read: ViewContainerRef, static: true }]
79
- }], pageToc: [{
80
- type: ViewChild,
81
- args: ['pageToc', { read: ViewContainerRef, static: true }]
82
- }], pageNavigation: [{
83
- type: ViewChild,
84
- args: ['pageNavigation', { read: ViewContainerRef, static: true }]
85
- }] } });
103
+ '[attr.data-ng-doc-page-tabs]': 'routes().length > 1',
104
+ '[attr.data-ng-doc-fullscreen-route]': 'fullscreenRoute.active()',
105
+ }, template: "<article class=\"ngde\">\n <ng-container #pageBreadcrumbs></ng-container>\n\n <ng-doc-page-header\n [headerContent]=\"headerContent()\"\n [headerContentSource]=\"headerContentSource()\" />\n\n @if (routes().length > 1) {\n <ng-doc-tab-routes-group>\n @for (route of routes(); track route) {\n <a\n ng-doc-tab-route\n [routerLink]=\"['./' + route.path]\"\n routerLinkActive\n [routerLinkActiveOptions]=\"{ exact: true }\"\n #rla=\"routerLinkActive\"\n [isActive]=\"rla.isActive\">\n @if (route.data?.['icon']; as icon) {\n <ng-doc-icon [customIcon]=\"icon\" />\n }\n {{ route.title }}\n </a>\n }\n </ng-doc-tab-routes-group>\n }\n\n <router-outlet></router-outlet>\n\n <ng-container #pageNavigation></ng-container>\n</article>\n\n<ng-container #pageToc></ng-container>\n", styles: [":host{display:flex;justify-content:space-between;--ng-doc-page-sticky-offset: var(--ng-doc-navbar-height)}:host[data-ng-doc-page-tabs=true]{--ng-doc-page-sticky-offset: calc( var(--ng-doc-navbar-height) + var(--ng-doc-page-wrapper-tabs-height) )}:host{--ng-doc-toc-margin: calc(var(--ng-doc-base-gutter) * 5)}:host article{position:relative;width:var(--ng-doc-article-width, 100%);max-width:var(--ng-doc-article-width, var(--ng-doc-content-max-width));margin-left:auto;margin-right:auto;min-width:0}:host article:has(.ng-doc-page-tags),:host article:has(ng-doc-api-list){max-width:var(--ng-doc-article-width, var(--ng-doc-api-content-max-width))}:host header ::ng-deep h1{margin-top:0}:host ng-doc-tab-routes-group{position:sticky!important;top:var(--ng-doc-navbar-height);margin:calc(var(--ng-doc-base-gutter) * 2) 0;background:var(--ng-doc-navbar-background);z-index:5;height:var(--ng-doc-page-wrapper-tabs-height)}:host .ng-doc-page-header{margin-bottom:calc(var(--ng-doc-base-gutter) * 3)}:host[data-ng-doc-fullscreen-route=true]{display:block}:host[data-ng-doc-fullscreen-route=true] article{width:100%;max-width:none}:host[data-ng-doc-fullscreen-route=true] ::ng-deep>:not(article),:host[data-ng-doc-fullscreen-route=true] ::ng-deep article>:not(router-outlet+*){display:none}\n"] }]
106
+ }], propDecorators: { routes: [{ type: i0.Input, args: [{ isSignal: true, alias: "routes", required: true }] }], headerContent: [{ type: i0.Input, args: [{ isSignal: true, alias: "headerContent", required: true }] }], headerContentSource: [{ type: i0.Input, args: [{ isSignal: true, alias: "headerContentSource", required: false }] }], hasBreadcrumb: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasBreadcrumb", required: false }] }], pageType: [{ type: i0.Input, args: [{ isSignal: true, alias: "pageType", required: false }] }], pageBreadcrumbs: [{ type: i0.ViewChild, args: ['pageBreadcrumbs', { ...{ read: ViewContainerRef }, isSignal: true }] }], pageToc: [{ type: i0.ViewChild, args: ['pageToc', { ...{ read: ViewContainerRef }, isSignal: true }] }], pageNavigation: [{ type: i0.ViewChild, args: ['pageNavigation', { ...{ read: ViewContainerRef }, isSignal: true }] }] } });
86
107
 
87
108
  /**
88
109
  * Generated bundle index. Do not edit.
@@ -1 +1 @@
1
- {"version":3,"file":"ng-doc-app-components-page-wrapper.mjs","sources":["../../../../libs/app/components/page-wrapper/page-wrapper.component.ts","../../../../libs/app/components/page-wrapper/page-wrapper.component.html","../../../../libs/app/components/page-wrapper/ng-doc-app-components-page-wrapper.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n inject,\n Input,\n OnInit,\n ViewChild,\n ViewContainerRef,\n} from '@angular/core';\nimport {\n ActivatedRoute,\n Router,\n RouterLink,\n RouterLinkActive,\n RouterOutlet,\n Routes,\n} from '@angular/router';\nimport { NgDocPageHeaderComponent } from '@ng-doc/app/components/page-header';\nimport { createComponent } from '@ng-doc/app/helpers';\nimport { NgDocNavigation, NgDocPageNavigation } from '@ng-doc/app/interfaces';\nimport { NG_DOC_CONTEXT, NG_DOC_PAGE_SKELETON } from '@ng-doc/app/tokens';\nimport { isPresent } from '@ng-doc/core/helpers/is-present';\nimport { NgDocPageType } from '@ng-doc/core/types';\nimport {\n NgDocIconComponent,\n NgDocTabRouteComponent,\n NgDocTabRoutesGroupComponent,\n} from '@ng-doc/ui-kit';\n\n@Component({\n selector: 'ng-doc-page-wrapper',\n imports: [\n RouterOutlet,\n RouterLink,\n NgDocTabRouteComponent,\n NgDocTabRoutesGroupComponent,\n RouterLinkActive,\n NgDocIconComponent,\n NgDocPageHeaderComponent,\n ],\n templateUrl: './page-wrapper.component.html',\n styleUrl: './page-wrapper.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '[attr.data-ng-doc-page-tabs]': 'routes.length > 1',\n },\n})\nexport class NgDocPageWrapperComponent implements OnInit {\n @Input({ required: true })\n routes!: Routes;\n\n @Input({ required: true })\n headerContent!: string;\n\n @Input()\n hasBreadcrumb = true;\n\n @Input()\n pageType: NgDocPageType = 'guide';\n\n @ViewChild('pageBreadcrumbs', { read: ViewContainerRef, static: true })\n pageBreadcrumbs!: ViewContainerRef;\n\n @ViewChild('pageToc', { read: ViewContainerRef, static: true })\n pageToc?: ViewContainerRef;\n\n @ViewChild('pageNavigation', { read: ViewContainerRef, static: true })\n pageNavigation!: ViewContainerRef;\n\n protected skeleton = inject(NG_DOC_PAGE_SKELETON);\n protected router = inject(Router);\n protected route = inject(ActivatedRoute);\n protected context = inject(NG_DOC_CONTEXT);\n\n private breadcrumbs: string[] = inject(ActivatedRoute)\n .pathFromRoot.filter((route: ActivatedRoute) => !!route.snapshot.url.length)\n .map((route: ActivatedRoute) => route.snapshot.title)\n .filter(isPresent);\n\n ngOnInit(): void {\n if (this.skeleton.breadcrumbs && this.hasBreadcrumb) {\n createComponent(this.pageBreadcrumbs, this.skeleton.breadcrumbs, {\n breadcrumbs: this.breadcrumbs,\n });\n }\n\n if (this.pageType === 'guide') {\n if (this.skeleton.navigation) {\n createComponent(this.pageNavigation, this.skeleton.navigation, this.navigationInputs());\n }\n }\n }\n\n private navigationInputs(): NgDocPageNavigation {\n const url =\n '/' +\n this.route.pathFromRoot\n .map((route: ActivatedRoute) => route.snapshot.url)\n .flat()\n .join('/');\n const flatItems = (items: NgDocNavigation[]): NgDocNavigation[] =>\n items\n .map((item: NgDocNavigation) => [item.children?.length ? flatItems(item.children) : item])\n .flat(2);\n const flatPages: NgDocNavigation[] = flatItems(this.context.navigation);\n\n return {\n prevPage: flatPages[flatPages.findIndex((item: NgDocNavigation) => url === item.route) - 1],\n nextPage: flatPages[flatPages.findIndex((item: NgDocNavigation) => url === item.route) + 1],\n };\n }\n}\n","<article class=\"ngde\">\n <ng-container #pageBreadcrumbs></ng-container>\n\n <ng-doc-page-header [headerContent]=\"headerContent\" />\n\n @if (routes.length > 1) {\n <ng-doc-tab-routes-group>\n @for (route of routes; track route) {\n <a\n ng-doc-tab-route\n [routerLink]=\"['./' + route.path]\"\n routerLinkActive\n [routerLinkActiveOptions]=\"{ exact: true }\"\n #rla=\"routerLinkActive\"\n [isActive]=\"rla.isActive\">\n @if (route.data?.['icon']; as icon) {\n <ng-doc-icon [customIcon]=\"icon\" />\n }\n {{ route.title }}\n </a>\n }\n </ng-doc-tab-routes-group>\n }\n\n <router-outlet></router-outlet>\n\n <ng-container #pageNavigation></ng-container>\n</article>\n\n<ng-container #pageToc></ng-container>\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-components-page-wrapper.mjs","sources":["../../../../libs/app/components/page-wrapper/page-wrapper.component.ts","../../../../libs/app/components/page-wrapper/page-wrapper.component.html","../../../../libs/app/components/page-wrapper/ng-doc-app-components-page-wrapper.ts"],"sourcesContent":["import {\n afterNextRender,\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n inject,\n Injector,\n input,\n OnInit,\n viewChild,\n ViewContainerRef,\n} from '@angular/core';\nimport {\n ActivatedRoute,\n Router,\n RouterLink,\n RouterLinkActive,\n RouterOutlet,\n Routes,\n} from '@angular/router';\nimport { NgDocPageHeaderComponent } from '@ng-doc/app/components/page-header';\nimport { createComponent } from '@ng-doc/app/helpers';\nimport { NgDocNavigation } from '@ng-doc/app/interfaces';\nimport { NgDocFullscreenRouteService } from '@ng-doc/app/services/fullscreen-route';\nimport { NgDocRoutePreloader } from '@ng-doc/app/services/route-preloader';\nimport { NG_DOC_CONTEXT, NG_DOC_PAGE_SKELETON } from '@ng-doc/app/tokens';\nimport { isPresent } from '@ng-doc/core/helpers/is-present';\nimport type { NgDocContentSource } from '@ng-doc/core/interfaces';\nimport { NgDocPageType } from '@ng-doc/core/types';\nimport {\n NgDocIconComponent,\n NgDocTabRouteComponent,\n NgDocTabRoutesGroupComponent,\n} from '@ng-doc/ui-kit';\n\n/**\n * Layout of a generated page: the breadcrumbs, the page header, the tabs of a page with several\n * routes, the page itself, the previous and next page links, and the table of contents beside it.\n *\n * The breadcrumbs, the page links and the table of contents are the page skeleton's components,\n * created in the containers this component exposes.\n *\n * While the page shows one of its fullscreen routes (`NgDocFullscreenRouteService`), only the page\n * is shown.\n */\n@Component({\n selector: 'ng-doc-page-wrapper',\n imports: [\n RouterOutlet,\n RouterLink,\n NgDocTabRouteComponent,\n NgDocTabRoutesGroupComponent,\n RouterLinkActive,\n NgDocIconComponent,\n NgDocPageHeaderComponent,\n ],\n templateUrl: './page-wrapper.component.html',\n styleUrl: './page-wrapper.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush,\n host: {\n '[attr.data-ng-doc-page-tabs]': 'routes().length > 1',\n '[attr.data-ng-doc-fullscreen-route]': 'fullscreenRoute.active()',\n },\n})\nexport class NgDocPageWrapperComponent implements OnInit {\n /** Routes of the page; a page with more than one gets tabs. */\n readonly routes = input.required<Routes>();\n\n /** HTML of the page header. */\n readonly headerContent = input.required<string>();\n\n /** Deferred source of the page header, for generated pages that load it separately. */\n readonly headerContentSource = input<NgDocContentSource>();\n\n /** Whether the page shows breadcrumbs. */\n readonly hasBreadcrumb = input<boolean, unknown>(true, { transform: booleanAttribute });\n\n /** Type of the page: guides get previous and next page links, API pages do not. */\n readonly pageType = input<NgDocPageType>('guide');\n\n /** Container of the breadcrumbs. */\n readonly pageBreadcrumbs = viewChild.required('pageBreadcrumbs', { read: ViewContainerRef });\n\n /** Container of the table of contents. */\n readonly pageToc = viewChild.required('pageToc', { read: ViewContainerRef });\n\n /** Container of the previous and next page links. */\n readonly pageNavigation = viewChild.required('pageNavigation', { read: ViewContainerRef });\n\n protected skeleton = inject(NG_DOC_PAGE_SKELETON);\n protected router = inject(Router);\n protected route = inject(ActivatedRoute);\n protected context = inject(NG_DOC_CONTEXT);\n protected readonly fullscreenRoute = inject(NgDocFullscreenRouteService);\n\n private breadcrumbs: string[] = inject(ActivatedRoute)\n .pathFromRoot.filter((route: ActivatedRoute) => !!route.snapshot.url.length)\n .map((route: ActivatedRoute) => route.snapshot.title)\n .filter(isPresent);\n\n private readonly preloader = inject(NgDocRoutePreloader);\n private readonly injector = inject(Injector);\n\n ngOnInit(): void {\n if (this.skeleton.breadcrumbs && this.hasBreadcrumb()) {\n createComponent(this.pageBreadcrumbs(), this.skeleton.breadcrumbs, {\n breadcrumbs: this.breadcrumbs,\n });\n }\n\n if (this.pageType() === 'guide' && this.skeleton.navigation) {\n createComponent(this.pageNavigation(), this.skeleton.navigation, this.adjacentPages());\n }\n\n // Readers often go on to the previous or next guide, so both are preloaded once the browser\n // is idle after this one has rendered. Render hooks never run on the server.\n afterNextRender(\n () => {\n if (this.pageType() !== 'guide') return;\n\n const { prevPage, nextPage } = this.adjacentPages();\n\n this.preloader.preloadWhenIdle([prevPage?.route, nextPage?.route]);\n },\n { injector: this.injector },\n );\n }\n\n private adjacentPages(): { prevPage?: NgDocNavigation; nextPage?: NgDocNavigation } {\n const url =\n '/' +\n this.route.pathFromRoot\n .map((route: ActivatedRoute) => route.snapshot.url)\n .flat()\n .join('/');\n const flatItems = (items: NgDocNavigation[]): NgDocNavigation[] =>\n items\n .map((item: NgDocNavigation) => [item.children?.length ? flatItems(item.children) : item])\n .flat(2);\n const flatPages: NgDocNavigation[] = flatItems(this.context.navigation);\n\n return {\n prevPage: flatPages[flatPages.findIndex((item: NgDocNavigation) => url === item.route) - 1],\n nextPage: flatPages[flatPages.findIndex((item: NgDocNavigation) => url === item.route) + 1],\n };\n }\n}\n","<article class=\"ngde\">\n <ng-container #pageBreadcrumbs></ng-container>\n\n <ng-doc-page-header\n [headerContent]=\"headerContent()\"\n [headerContentSource]=\"headerContentSource()\" />\n\n @if (routes().length > 1) {\n <ng-doc-tab-routes-group>\n @for (route of routes(); track route) {\n <a\n ng-doc-tab-route\n [routerLink]=\"['./' + route.path]\"\n routerLinkActive\n [routerLinkActiveOptions]=\"{ exact: true }\"\n #rla=\"routerLinkActive\"\n [isActive]=\"rla.isActive\">\n @if (route.data?.['icon']; as icon) {\n <ng-doc-icon [customIcon]=\"icon\" />\n }\n {{ route.title }}\n </a>\n }\n </ng-doc-tab-routes-group>\n }\n\n <router-outlet></router-outlet>\n\n <ng-container #pageNavigation></ng-container>\n</article>\n\n<ng-container #pageToc></ng-container>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
@@ -1,62 +1,206 @@
1
+ import { Clipboard } from '@angular/cdk/clipboard';
2
+ import { LocationStrategy, isPlatformBrowser } from '@angular/common';
1
3
  import * as i0 from '@angular/core';
2
- import { inject, ChangeDetectorRef, ElementRef, ViewChild, ChangeDetectionStrategy, Component } from '@angular/core';
3
- import { RouterOutlet } from '@angular/router';
4
+ import { viewChild, ElementRef, inject, ChangeDetectorRef, signal, NgZone, PLATFORM_ID, effect, untracked, DestroyRef, reflectComponentType, ChangeDetectionStrategy, Component } from '@angular/core';
5
+ import { ActivatedRoute, RouterLink, RouterOutlet } from '@angular/router';
6
+ import { NgDocContentAnchorController } from '@ng-doc/app/classes/content-anchor-controller';
7
+ import { NgDocContentController } from '@ng-doc/app/classes/content-controller';
4
8
  import { NgDocRootPage } from '@ng-doc/app/classes/root-page';
5
9
  import { NgDocPageWrapperComponent } from '@ng-doc/app/components/page-wrapper';
6
- import { createComponent, generateToc } from '@ng-doc/app/helpers';
10
+ import { ɵrestoreNgDocHydrationSnapshot as _restoreNgDocHydrationSnapshot, generateToc, createComponent, ɵngDocPageUrl as _ngDocPageUrl } from '@ng-doc/app/helpers';
7
11
  import { NgDocSanitizeHtmlPipe } from '@ng-doc/app/pipes';
8
12
  import { NgDocPageProcessorComponent } from '@ng-doc/app/processors';
9
13
  import { provideTypeControl } from '@ng-doc/app/providers/type-control';
14
+ import { NgDocFullscreenRouteService } from '@ng-doc/app/services/fullscreen-route';
10
15
  import { NG_DOC_PAGE_SKELETON } from '@ng-doc/app/tokens';
11
16
  import { NgDocTypeAliasControlComponent, NgDocStringControlComponent, NgDocNumberControlComponent, NgDocBooleanControlComponent } from '@ng-doc/app/type-controls';
12
- import { NgDocButtonIconComponent, NgDocTooltipDirective, NgDocIconComponent, DialogOutletComponent } from '@ng-doc/ui-kit';
17
+ import { NgDocButtonIconComponent, NgDocTooltipDirective } from '@ng-doc/ui-kit';
18
+ import { WA_LOCATION } from '@ng-web-apis/common';
13
19
 
20
+ /**
21
+ * A generated page: its rendered content, the page actions (copy link, edit and view the source),
22
+ * the table of contents it fills in, and the outlet of its fullscreen routes.
23
+ *
24
+ * A fullscreen route (a child route of the page, unless the page sets `disableFullscreenRoutes`)
25
+ * replaces the page: it is shown on its own on the canvas of demos, with a link back to the page,
26
+ * and `NgDocFullscreenRouteService` tells the root layout and the page wrapper to hide their
27
+ * chrome.
28
+ */
14
29
  class NgDocPageComponent {
15
30
  constructor() {
31
+ /** The element that holds the rendered page content. */
32
+ this.pageContainer = viewChild('pageContainer', { ...(ngDevMode ? { debugName: "pageContainer" } : /* istanbul ignore next */ {}), read: (ElementRef) });
16
33
  this.rootPage = inject(NgDocRootPage);
17
34
  this.skeleton = inject(NG_DOC_PAGE_SKELETON);
18
35
  this.changeDetectorRef = inject(ChangeDetectorRef);
19
36
  this.pageWrapper = inject(NgDocPageWrapperComponent);
37
+ this.contentController = inject(NgDocContentController);
38
+ /** Whether the link to the page was just copied. */
39
+ this.linkCopied = signal(false, /* @ts-ignore */
40
+ ...(ngDevMode ? [{ debugName: "linkCopied" }] : /* istanbul ignore next */ []));
41
+ /** Whether one of the page's fullscreen routes is shown instead of the page. */
42
+ this.fullscreenRoute = signal(false, /* @ts-ignore */
43
+ ...(ngDevMode ? [{ debugName: "fullscreenRoute" }] : /* istanbul ignore next */ []));
44
+ /** URL of the page, for the link back from a fullscreen route. */
45
+ this.pageUrl = signal('/', /* @ts-ignore */
46
+ ...(ngDevMode ? [{ debugName: "pageUrl" }] : /* istanbul ignore next */ []));
47
+ this.route = inject(ActivatedRoute);
48
+ this.fullscreenRoutes = inject(NgDocFullscreenRouteService);
49
+ this.contentAnchorController = inject(NgDocContentAnchorController);
50
+ this.clipboard = inject(Clipboard);
51
+ this.ngZone = inject(NgZone);
52
+ this.location = inject(WA_LOCATION);
53
+ this.locationStrategy = inject(LocationStrategy);
54
+ // The router state is complete when the page is created, so a fullscreen route opened
55
+ // directly (a new tab) is known before the first render and the page content never renders.
56
+ this.showFullscreenRoute(!!this.route.firstChild);
57
+ const source = this.rootPage.pageContentSource;
58
+ if (source && !this.fullscreenRoute()) {
59
+ // Angular empties this host (it skips hydration) and the content loads asynchronously, so
60
+ // the server-rendered page stays visible until the loaded content renders.
61
+ if (isPlatformBrowser(inject(PLATFORM_ID))) {
62
+ this.snapshot = _restoreNgDocHydrationSnapshot(inject(ElementRef).nativeElement);
63
+ }
64
+ this.connectContent(source);
65
+ }
66
+ // A page opened on a fullscreen route loads its content only when the reader goes back to
67
+ // it, because pending content holds the application unstable until it renders. An effect,
68
+ // so a page that is leaving (its route closes as it is destroyed) loads nothing.
69
+ effect(() => {
70
+ if (source && !this.fullscreenRoute())
71
+ untracked(() => this.connectContent(source));
72
+ });
73
+ // A load that needs no new pass (its content is already rendered, for example an empty body)
74
+ // or that failed settles without `revealLoaded`.
75
+ effect(() => {
76
+ if (this.contentController.settled())
77
+ untracked(() => this.releaseSnapshot());
78
+ });
79
+ effect(() => {
80
+ if (this.contentController.error()) {
81
+ untracked(() => {
82
+ this.releaseSnapshot();
83
+ this.pageWrapper.pageToc().clear();
84
+ this.contentAnchorController.contentFailed();
85
+ });
86
+ }
87
+ });
88
+ inject(DestroyRef).onDestroy(() => {
89
+ clearTimeout(this.linkCopiedTimer);
90
+ this.releaseSnapshot();
91
+ this.fullscreenRoutes.set(this, false);
92
+ });
93
+ }
94
+ /**
95
+ * Shows one of the page's fullscreen routes instead of the page, or the page again. The outlet
96
+ * of the fullscreen routes calls it when a route opens or closes.
97
+ * @param shown - Whether a fullscreen route is shown.
98
+ */
99
+ showFullscreenRoute(shown) {
100
+ // Pages that disable fullscreen routes render their child routes themselves.
101
+ const fullscreen = shown && !this.rootPage.page?.disableFullscreenRoutes;
102
+ if (fullscreen) {
103
+ this.pageUrl.set('/' +
104
+ this.route.pathFromRoot
105
+ .flatMap((route) => route.snapshot.url)
106
+ .map((segment) => segment.path)
107
+ .join('/'));
108
+ }
109
+ this.fullscreenRoute.set(fullscreen);
110
+ this.fullscreenRoutes.set(this, fullscreen);
20
111
  }
112
+ /**
113
+ * Creates the table of contents from the headings of the rendered page.
114
+ */
21
115
  createToc() {
22
- if (this.pageWrapper.pageToc && this.skeleton.toc) {
23
- createComponent(this.pageWrapper.pageToc, this.skeleton.toc, {
24
- tableOfContent: generateToc(this.pageContainer.nativeElement) ?? [],
25
- });
116
+ const container = this.pageContainer();
117
+ const pageToc = this.pageWrapper.pageToc();
118
+ pageToc.clear();
119
+ if (container && this.skeleton.toc) {
120
+ const inputs = {
121
+ tableOfContent: generateToc(container.nativeElement) ?? [],
122
+ };
123
+ // Only components that declare the input get it: a custom table of contents may not.
124
+ const declared = reflectComponentType(this.skeleton.toc)?.inputs ?? [];
125
+ if (declared.some(({ templateName }) => templateName === 'editSourceFileUrl')) {
126
+ inputs['editSourceFileUrl'] = this.rootPage.editSourceFileUrl;
127
+ }
128
+ // API pages carry their symbol details for the rail, hidden in the content.
129
+ const details = container.nativeElement.querySelector('[data-ng-doc-rail-details]');
130
+ if (details && declared.some(({ templateName }) => templateName === 'details')) {
131
+ details.removeAttribute('hidden');
132
+ inputs['details'] = details;
133
+ }
134
+ createComponent(pageToc, this.skeleton.toc, inputs);
26
135
  this.changeDetectorRef.detectChanges();
27
136
  }
137
+ if (this.rootPage.pageContentSource)
138
+ this.contentAnchorController.contentProcessed();
139
+ }
140
+ /**
141
+ * Shows the page's own content in place of the server-rendered copy when a pass of the loaded
142
+ * content is about to render, in the same task, so its components render and measure visible.
143
+ * The pass of the empty content before the source has loaded keeps the copy.
144
+ * @param version - The content version of the pass.
145
+ * @internal
146
+ */
147
+ revealLoaded(version) {
148
+ if (version === this.contentController.loadedVersion())
149
+ this.releaseSnapshot();
150
+ }
151
+ /**
152
+ * Copies the link to the page, without its query and fragment.
153
+ */
154
+ copyLink() {
155
+ this.clipboard.copy(_ngDocPageUrl(this.locationStrategy, this.location));
156
+ this.linkCopied.set(true);
157
+ clearTimeout(this.linkCopiedTimer);
158
+ // The label timer must not hold the application unstable, so it runs outside the zone.
159
+ this.linkCopiedTimer = this.ngZone.runOutsideAngular(() => setTimeout(() => this.linkCopied.set(false), 1400));
160
+ }
161
+ connectContent(source) {
162
+ // Both calls do nothing once the source is connected.
163
+ this.contentAnchorController.activate();
164
+ this.contentController.connect(source);
165
+ }
166
+ releaseSnapshot() {
167
+ const release = this.snapshot;
168
+ this.snapshot = undefined;
169
+ release?.();
28
170
  }
29
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NgDocPageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
30
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: NgDocPageComponent, isStandalone: true, selector: "ng-doc-page", host: { attributes: { "ngSkipHydration": "true" } }, providers: [
171
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.2.1", ngImport: i0, type: NgDocPageComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
172
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.2.1", type: NgDocPageComponent, isStandalone: true, selector: "ng-doc-page", host: { attributes: { "ngSkipHydration": "true" }, properties: { "attr.data-ng-doc-async-content": "rootPage.pageContentSource && !fullscreenRoute() ? \"\" : null" } }, providers: [
173
+ NgDocContentAnchorController,
174
+ NgDocContentController,
31
175
  provideTypeControl('NgDocTypeAlias', NgDocTypeAliasControlComponent, { order: 10 }),
32
176
  provideTypeControl('string', NgDocStringControlComponent, { order: 20 }),
33
177
  provideTypeControl('number', NgDocNumberControlComponent, { order: 30 }),
34
- provideTypeControl('boolean', NgDocBooleanControlComponent, { hideLabel: true, order: 40 }),
35
- ], viewQueries: [{ propertyName: "pageContainer", first: true, predicate: ["pageContainer"], descendants: true, read: ElementRef, static: true }, { propertyName: "childOutlet", first: true, predicate: ["childOutlet"], descendants: true }], ngImport: i0, template: "<div class=\"ng-doc-page-controls\">\n @if (rootPage.editSourceFileUrl) {\n <a\n ng-doc-button-icon\n [href]=\"rootPage.editSourceFileUrl\"\n target=\"_blank\"\n ngDocTooltip=\"Suggest Edits\">\n <ng-doc-icon icon=\"edit-2\"></ng-doc-icon>\n </a>\n }\n @if (rootPage.viewSourceFileUrl) {\n <a\n ng-doc-button-icon\n [href]=\"rootPage.viewSourceFileUrl\"\n target=\"_blank\"\n ngDocTooltip=\"View Source\">\n <ng-doc-icon icon=\"code\"></ng-doc-icon>\n </a>\n }\n</div>\n\n<div\n class=\"ng-doc-page-wrapper\"\n [ngDocPageProcessor]=\"rootPage.pageContent | ngDocSanitizeHtml\"\n (afterRender)=\"createToc()\"\n #pageContainer></div>\n\n@if (!rootPage.page?.disableFullscreenRoutes) {\n <ng-doc-dialog-outlet [config]=\"{ width: '100vw', height: '100vh' }\">\n <div class=\"ng-doc-fullscreen-wrapper\">\n <router-outlet></router-outlet>\n </div>\n </ng-doc-dialog-outlet>\n}\n", styles: [":host{display:flex;flex-direction:column}:host .ng-doc-page-controls{position:absolute;display:flex;grid-gap:var(--ng-doc-base-gutter);top:0;right:0}.ng-doc-fullscreen-wrapper{display:flex;align-items:center;justify-content:center;width:100%;height:100%}\n"], dependencies: [{ kind: "component", type: NgDocButtonIconComponent, selector: "button[ng-doc-button-icon], a[ng-doc-button-icon], button[ng-doc-button-icon-raised], a[ng-doc-button-icon-raised], button[ng-doc-button-icon-transparent], a[ng-doc-button-icon-transparent]", inputs: ["size", "rounded"] }, { kind: "directive", type: NgDocTooltipDirective, selector: "[ngDocTooltip]", inputs: ["ngDocTooltip", "delay", "displayOrigin", "pointerOrigin", "positions", "canOpen", "panelClass", "minHeight", "maxHeight", "height", "minWidth", "maxWidth", "width"], outputs: ["beforeOpen", "afterOpen", "beforeClose", "afterClose"], exportAs: ["ngDocTooltip"] }, { kind: "component", type: NgDocIconComponent, selector: "ng-doc-icon", inputs: ["icon", "customIcon", "size"] }, { kind: "component", type: NgDocPageProcessorComponent, selector: "[ngDocPageProcessor]", inputs: ["ngDocPageProcessor"], outputs: ["afterRender"] }, { kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "component", type: DialogOutletComponent, selector: "ng-doc-dialog-outlet", inputs: ["config"] }, { kind: "pipe", type: NgDocSanitizeHtmlPipe, name: "ngDocSanitizeHtml" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
178
+ provideTypeControl('boolean', NgDocBooleanControlComponent, { order: 40 }),
179
+ ], viewQueries: [{ propertyName: "pageContainer", first: true, predicate: ["pageContainer"], descendants: true, read: ElementRef, isSignal: true }], ngImport: i0, template: "@if (!fullscreenRoute()) {\n <div class=\"ng-doc-page-controls\">\n <button\n type=\"button\"\n ng-doc-button-icon\n [rounded]=\"false\"\n [attr.aria-label]=\"linkCopied() ? 'Link copied' : 'Copy link to this page'\"\n [ngDocTooltip]=\"linkCopied() ? 'Copied' : 'Copy link'\"\n [attr.data-ng-doc-copied]=\"linkCopied()\"\n (click)=\"copyLink()\">\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"1.8\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\">\n <path d=\"M10 13a5 5 0 0 0 7.5.5l3-3a5 5 0 0 0-7-7l-1.7 1.7\" />\n <path d=\"M14 11a5 5 0 0 0-7.5-.5l-3 3a5 5 0 0 0 7 7l1.7-1.7\" />\n </svg>\n </button>\n @if (rootPage.editSourceFileUrl) {\n <a\n ng-doc-button-icon\n [rounded]=\"false\"\n [href]=\"rootPage.editSourceFileUrl\"\n target=\"_blank\"\n rel=\"noopener\"\n aria-label=\"Edit this page\"\n ngDocTooltip=\"Edit this page\">\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"1.8\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\">\n <path d=\"M12 20h9M16.5 3.5a2.1 2.1 0 1 1 3 3L7 19l-4 1 1-4Z\" />\n </svg>\n </a>\n }\n @if (rootPage.viewSourceFileUrl) {\n <a\n ng-doc-button-icon\n [rounded]=\"false\"\n [href]=\"rootPage.viewSourceFileUrl\"\n target=\"_blank\"\n rel=\"noopener\"\n aria-label=\"View the page source\"\n ngDocTooltip=\"View source\">\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"1.8\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\">\n <path d=\"m8 7-5 5 5 5m8-10 5 5-5 5\" />\n </svg>\n </a>\n }\n </div>\n\n @if (rootPage.pageContentSource) {\n @if (contentController.error(); as error) {\n <div class=\"ng-doc-page-wrapper\" role=\"alert\">{{ error.message }}</div>\n } @else {\n <div\n class=\"ng-doc-page-wrapper\"\n [ngDocPageProcessor]=\"contentController.html() | ngDocSanitizeHtml\"\n [contentVersion]=\"contentController.version()\"\n (beforeRender)=\"revealLoaded($event)\"\n (contentProcessed)=\"contentController.processed($event)\"\n (processingError)=\"contentController.processingFailed($event)\"\n (afterRender)=\"createToc()\"\n #pageContainer></div>\n }\n } @else {\n <div\n class=\"ng-doc-page-wrapper\"\n [ngDocPageProcessor]=\"rootPage.pageContent | ngDocSanitizeHtml\"\n (afterRender)=\"createToc()\"\n #pageContainer></div>\n }\n}\n\n<!-- A fullscreen route replaces the page; the outlet stays, so it can open and close in place. -->\n@if (!rootPage.page?.disableFullscreenRoutes) {\n <div class=\"ng-doc-fullscreen-route\" [hidden]=\"!fullscreenRoute()\">\n @if (fullscreenRoute()) {\n <a\n class=\"ng-doc-fullscreen-route-back\"\n [routerLink]=\"pageUrl()\"\n [attr.aria-label]=\"'Back to ' + (rootPage.page?.title ?? 'the page')\"\n [ngDocTooltip]=\"'Back to ' + (rootPage.page?.title ?? 'the page')\">\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\">\n <path d=\"M19 12H5m7 7-7-7 7-7\" />\n </svg>\n <span class=\"ng-doc-fullscreen-route-back-label\">{{ rootPage.page?.title ?? 'Back' }}</span>\n </a>\n }\n <router-outlet\n (activate)=\"showFullscreenRoute(true)\"\n (deactivate)=\"showFullscreenRoute(false)\" />\n </div>\n}\n", styles: [":host{display:flex;flex-direction:column}:host .ng-doc-page-controls{position:absolute;top:0;right:0;display:flex;gap:2px;--ng-doc-button-color: var(--ng-doc-text-muted);--ng-doc-button-hover-color: var(--ng-doc-heading-color);--ng-doc-button-active-color: var(--ng-doc-heading-color);--ng-doc-button-hover-background: var(--ng-doc-hover-background)}:host .ng-doc-page-controls [data-ng-doc-copied=true]{--ng-doc-button-color: var(--ng-doc-success-strong)}.ng-doc-fullscreen-route{background-image:radial-gradient(color-mix(in srgb,var(--ng-doc-base-5) 55%,transparent) 1px,transparent 1px);background-size:16px 16px;display:grid;place-items:center;min-height:100vh;min-height:100dvh;padding:var(--ng-doc-space-16) var(--ng-doc-space-4);background-color:var(--ng-doc-demo-displayer-background, var(--ng-doc-background))}.ng-doc-fullscreen-route[hidden]{display:none}.ng-doc-fullscreen-route>router-outlet{display:none}.ng-doc-fullscreen-route-back{position:fixed;top:var(--ng-doc-space-4);left:var(--ng-doc-space-4);z-index:1;display:inline-flex;align-items:center;gap:var(--ng-doc-space-2);max-width:calc(100% - var(--ng-doc-space-8));height:32px;padding:0 var(--ng-doc-space-3) 0 var(--ng-doc-space-2);border-radius:var(--ng-doc-radius-md);background:var(--ng-doc-background);box-shadow:0 0 0 1px var(--ng-doc-border-color),var(--ng-doc-shadow-xs);color:var(--ng-doc-text-muted);font-family:var(--ng-doc-font-family);font-size:13px;font-weight:500;line-height:18px;text-decoration:none}.ng-doc-fullscreen-route-back:hover{color:var(--ng-doc-heading-color)}.ng-doc-fullscreen-route-back:focus-visible{outline:none;box-shadow:var(--ng-doc-focus-ring)}.ng-doc-fullscreen-route-back svg{flex:none;width:16px;height:16px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}.ng-doc-fullscreen-route-back-label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:host[data-ng-doc-hydration-snapshot]>:not(.ng-doc-hydration-snapshot){display:none!important}\n"], dependencies: [{ kind: "component", type: NgDocButtonIconComponent, selector: "button[ng-doc-button-icon], a[ng-doc-button-icon], button[ng-doc-button-icon-raised], a[ng-doc-button-icon-raised], button[ng-doc-button-icon-transparent], a[ng-doc-button-icon-transparent]", inputs: ["size", "rounded"] }, { kind: "directive", type: NgDocTooltipDirective, selector: "[ngDocTooltip]", inputs: ["ngDocTooltip", "delay", "displayOrigin", "pointerOrigin", "positions", "canOpen", "panelClass", "minHeight", "maxHeight", "height", "minWidth", "maxWidth", "width"], outputs: ["beforeOpen", "afterOpen", "beforeClose", "afterClose"], exportAs: ["ngDocTooltip"] }, { kind: "component", type: NgDocPageProcessorComponent, selector: "[ngDocPageProcessor]", inputs: ["ngDocPageProcessor", "contentVersion"], outputs: ["beforeRender", "afterRender", "contentProcessed", "processingError"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "browserUrl", "routerLink"] }, { kind: "directive", type: RouterOutlet, selector: "router-outlet", inputs: ["name", "routerOutletData"], outputs: ["activate", "deactivate", "attach", "detach"], exportAs: ["outlet"] }, { kind: "pipe", type: NgDocSanitizeHtmlPipe, name: "ngDocSanitizeHtml" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
36
180
  }
37
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NgDocPageComponent, decorators: [{
181
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.1", ngImport: i0, type: NgDocPageComponent, decorators: [{
38
182
  type: Component,
39
183
  args: [{ selector: 'ng-doc-page', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
40
184
  NgDocButtonIconComponent,
41
185
  NgDocTooltipDirective,
42
- NgDocIconComponent,
43
186
  NgDocPageProcessorComponent,
187
+ RouterLink,
44
188
  RouterOutlet,
45
- DialogOutletComponent,
46
189
  NgDocSanitizeHtmlPipe,
47
190
  ], providers: [
191
+ NgDocContentAnchorController,
192
+ NgDocContentController,
48
193
  provideTypeControl('NgDocTypeAlias', NgDocTypeAliasControlComponent, { order: 10 }),
49
194
  provideTypeControl('string', NgDocStringControlComponent, { order: 20 }),
50
195
  provideTypeControl('number', NgDocNumberControlComponent, { order: 30 }),
51
- provideTypeControl('boolean', NgDocBooleanControlComponent, { hideLabel: true, order: 40 }),
52
- ], host: { ngSkipHydration: 'true' }, template: "<div class=\"ng-doc-page-controls\">\n @if (rootPage.editSourceFileUrl) {\n <a\n ng-doc-button-icon\n [href]=\"rootPage.editSourceFileUrl\"\n target=\"_blank\"\n ngDocTooltip=\"Suggest Edits\">\n <ng-doc-icon icon=\"edit-2\"></ng-doc-icon>\n </a>\n }\n @if (rootPage.viewSourceFileUrl) {\n <a\n ng-doc-button-icon\n [href]=\"rootPage.viewSourceFileUrl\"\n target=\"_blank\"\n ngDocTooltip=\"View Source\">\n <ng-doc-icon icon=\"code\"></ng-doc-icon>\n </a>\n }\n</div>\n\n<div\n class=\"ng-doc-page-wrapper\"\n [ngDocPageProcessor]=\"rootPage.pageContent | ngDocSanitizeHtml\"\n (afterRender)=\"createToc()\"\n #pageContainer></div>\n\n@if (!rootPage.page?.disableFullscreenRoutes) {\n <ng-doc-dialog-outlet [config]=\"{ width: '100vw', height: '100vh' }\">\n <div class=\"ng-doc-fullscreen-wrapper\">\n <router-outlet></router-outlet>\n </div>\n </ng-doc-dialog-outlet>\n}\n", styles: [":host{display:flex;flex-direction:column}:host .ng-doc-page-controls{position:absolute;display:flex;grid-gap:var(--ng-doc-base-gutter);top:0;right:0}.ng-doc-fullscreen-wrapper{display:flex;align-items:center;justify-content:center;width:100%;height:100%}\n"] }]
53
- }], propDecorators: { pageContainer: [{
54
- type: ViewChild,
55
- args: ['pageContainer', { read: ElementRef, static: true }]
56
- }], childOutlet: [{
57
- type: ViewChild,
58
- args: ['childOutlet']
59
- }] } });
196
+ provideTypeControl('boolean', NgDocBooleanControlComponent, { order: 40 }),
197
+ ], host: {
198
+ ngSkipHydration: 'true',
199
+ // Tells the browser that the server-rendered content must be kept until the loaded content
200
+ // renders (ɵNG_DOC_ASYNC_CONTENT_ATTRIBUTE).
201
+ '[attr.data-ng-doc-async-content]': 'rootPage.pageContentSource && !fullscreenRoute() ? "" : null',
202
+ }, template: "@if (!fullscreenRoute()) {\n <div class=\"ng-doc-page-controls\">\n <button\n type=\"button\"\n ng-doc-button-icon\n [rounded]=\"false\"\n [attr.aria-label]=\"linkCopied() ? 'Link copied' : 'Copy link to this page'\"\n [ngDocTooltip]=\"linkCopied() ? 'Copied' : 'Copy link'\"\n [attr.data-ng-doc-copied]=\"linkCopied()\"\n (click)=\"copyLink()\">\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"1.8\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\">\n <path d=\"M10 13a5 5 0 0 0 7.5.5l3-3a5 5 0 0 0-7-7l-1.7 1.7\" />\n <path d=\"M14 11a5 5 0 0 0-7.5-.5l-3 3a5 5 0 0 0 7 7l1.7-1.7\" />\n </svg>\n </button>\n @if (rootPage.editSourceFileUrl) {\n <a\n ng-doc-button-icon\n [rounded]=\"false\"\n [href]=\"rootPage.editSourceFileUrl\"\n target=\"_blank\"\n rel=\"noopener\"\n aria-label=\"Edit this page\"\n ngDocTooltip=\"Edit this page\">\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"1.8\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\">\n <path d=\"M12 20h9M16.5 3.5a2.1 2.1 0 1 1 3 3L7 19l-4 1 1-4Z\" />\n </svg>\n </a>\n }\n @if (rootPage.viewSourceFileUrl) {\n <a\n ng-doc-button-icon\n [rounded]=\"false\"\n [href]=\"rootPage.viewSourceFileUrl\"\n target=\"_blank\"\n rel=\"noopener\"\n aria-label=\"View the page source\"\n ngDocTooltip=\"View source\">\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"1.8\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\">\n <path d=\"m8 7-5 5 5 5m8-10 5 5-5 5\" />\n </svg>\n </a>\n }\n </div>\n\n @if (rootPage.pageContentSource) {\n @if (contentController.error(); as error) {\n <div class=\"ng-doc-page-wrapper\" role=\"alert\">{{ error.message }}</div>\n } @else {\n <div\n class=\"ng-doc-page-wrapper\"\n [ngDocPageProcessor]=\"contentController.html() | ngDocSanitizeHtml\"\n [contentVersion]=\"contentController.version()\"\n (beforeRender)=\"revealLoaded($event)\"\n (contentProcessed)=\"contentController.processed($event)\"\n (processingError)=\"contentController.processingFailed($event)\"\n (afterRender)=\"createToc()\"\n #pageContainer></div>\n }\n } @else {\n <div\n class=\"ng-doc-page-wrapper\"\n [ngDocPageProcessor]=\"rootPage.pageContent | ngDocSanitizeHtml\"\n (afterRender)=\"createToc()\"\n #pageContainer></div>\n }\n}\n\n<!-- A fullscreen route replaces the page; the outlet stays, so it can open and close in place. -->\n@if (!rootPage.page?.disableFullscreenRoutes) {\n <div class=\"ng-doc-fullscreen-route\" [hidden]=\"!fullscreenRoute()\">\n @if (fullscreenRoute()) {\n <a\n class=\"ng-doc-fullscreen-route-back\"\n [routerLink]=\"pageUrl()\"\n [attr.aria-label]=\"'Back to ' + (rootPage.page?.title ?? 'the page')\"\n [ngDocTooltip]=\"'Back to ' + (rootPage.page?.title ?? 'the page')\">\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\">\n <path d=\"M19 12H5m7 7-7-7 7-7\" />\n </svg>\n <span class=\"ng-doc-fullscreen-route-back-label\">{{ rootPage.page?.title ?? 'Back' }}</span>\n </a>\n }\n <router-outlet\n (activate)=\"showFullscreenRoute(true)\"\n (deactivate)=\"showFullscreenRoute(false)\" />\n </div>\n}\n", styles: [":host{display:flex;flex-direction:column}:host .ng-doc-page-controls{position:absolute;top:0;right:0;display:flex;gap:2px;--ng-doc-button-color: var(--ng-doc-text-muted);--ng-doc-button-hover-color: var(--ng-doc-heading-color);--ng-doc-button-active-color: var(--ng-doc-heading-color);--ng-doc-button-hover-background: var(--ng-doc-hover-background)}:host .ng-doc-page-controls [data-ng-doc-copied=true]{--ng-doc-button-color: var(--ng-doc-success-strong)}.ng-doc-fullscreen-route{background-image:radial-gradient(color-mix(in srgb,var(--ng-doc-base-5) 55%,transparent) 1px,transparent 1px);background-size:16px 16px;display:grid;place-items:center;min-height:100vh;min-height:100dvh;padding:var(--ng-doc-space-16) var(--ng-doc-space-4);background-color:var(--ng-doc-demo-displayer-background, var(--ng-doc-background))}.ng-doc-fullscreen-route[hidden]{display:none}.ng-doc-fullscreen-route>router-outlet{display:none}.ng-doc-fullscreen-route-back{position:fixed;top:var(--ng-doc-space-4);left:var(--ng-doc-space-4);z-index:1;display:inline-flex;align-items:center;gap:var(--ng-doc-space-2);max-width:calc(100% - var(--ng-doc-space-8));height:32px;padding:0 var(--ng-doc-space-3) 0 var(--ng-doc-space-2);border-radius:var(--ng-doc-radius-md);background:var(--ng-doc-background);box-shadow:0 0 0 1px var(--ng-doc-border-color),var(--ng-doc-shadow-xs);color:var(--ng-doc-text-muted);font-family:var(--ng-doc-font-family);font-size:13px;font-weight:500;line-height:18px;text-decoration:none}.ng-doc-fullscreen-route-back:hover{color:var(--ng-doc-heading-color)}.ng-doc-fullscreen-route-back:focus-visible{outline:none;box-shadow:var(--ng-doc-focus-ring)}.ng-doc-fullscreen-route-back svg{flex:none;width:16px;height:16px;fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}.ng-doc-fullscreen-route-back-label{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:host[data-ng-doc-hydration-snapshot]>:not(.ng-doc-hydration-snapshot){display:none!important}\n"] }]
203
+ }], ctorParameters: () => [], propDecorators: { pageContainer: [{ type: i0.ViewChild, args: ['pageContainer', { ...{ read: (ElementRef) }, isSignal: true }] }] } });
60
204
 
61
205
  /**
62
206
  * Generated bundle index. Do not edit.
@@ -1 +1 @@
1
- {"version":3,"file":"ng-doc-app-components-page.mjs","sources":["../../../../libs/app/components/page/page.component.ts","../../../../libs/app/components/page/page.component.html","../../../../libs/app/components/page/ng-doc-app-components-page.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n Component,\n ElementRef,\n inject,\n TemplateRef,\n ViewChild,\n} from '@angular/core';\nimport { RouterOutlet } from '@angular/router';\nimport { NgDocRootPage } from '@ng-doc/app/classes/root-page';\nimport { NgDocPageWrapperComponent } from '@ng-doc/app/components/page-wrapper';\nimport { createComponent, generateToc } from '@ng-doc/app/helpers';\nimport { NgDocPageSkeleton } from '@ng-doc/app/interfaces';\nimport { NgDocSanitizeHtmlPipe } from '@ng-doc/app/pipes';\nimport { NgDocPageProcessorComponent } from '@ng-doc/app/processors';\nimport { provideTypeControl } from '@ng-doc/app/providers/type-control';\nimport { NG_DOC_PAGE_SKELETON } from '@ng-doc/app/tokens';\nimport {\n NgDocBooleanControlComponent,\n NgDocNumberControlComponent,\n NgDocStringControlComponent,\n NgDocTypeAliasControlComponent,\n} from '@ng-doc/app/type-controls';\nimport {\n DialogOutletComponent,\n NgDocButtonIconComponent,\n NgDocIconComponent,\n NgDocTooltipDirective,\n} from '@ng-doc/ui-kit';\n\n@Component({\n selector: 'ng-doc-page',\n templateUrl: './page.component.html',\n styleUrls: ['./page.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [\n NgDocButtonIconComponent,\n NgDocTooltipDirective,\n NgDocIconComponent,\n NgDocPageProcessorComponent,\n RouterOutlet,\n DialogOutletComponent,\n NgDocSanitizeHtmlPipe,\n ],\n providers: [\n provideTypeControl('NgDocTypeAlias', NgDocTypeAliasControlComponent, { order: 10 }),\n provideTypeControl('string', NgDocStringControlComponent, { order: 20 }),\n provideTypeControl('number', NgDocNumberControlComponent, { order: 30 }),\n provideTypeControl('boolean', NgDocBooleanControlComponent, { hideLabel: true, order: 40 }),\n ],\n host: { ngSkipHydration: 'true' },\n})\nexport class NgDocPageComponent {\n @ViewChild('pageContainer', { read: ElementRef, static: true })\n pageContainer!: ElementRef<HTMLElement>;\n\n @ViewChild('childOutlet')\n childOutlet?: TemplateRef<never>;\n\n protected rootPage: NgDocRootPage = inject(NgDocRootPage);\n protected skeleton: NgDocPageSkeleton = inject(NG_DOC_PAGE_SKELETON);\n protected changeDetectorRef = inject(ChangeDetectorRef);\n\n protected pageWrapper: NgDocPageWrapperComponent = inject(NgDocPageWrapperComponent);\n\n createToc(): void {\n if (this.pageWrapper.pageToc && this.skeleton.toc) {\n createComponent(this.pageWrapper.pageToc, this.skeleton.toc, {\n tableOfContent: generateToc(this.pageContainer.nativeElement) ?? [],\n });\n\n this.changeDetectorRef.detectChanges();\n }\n }\n}\n","<div class=\"ng-doc-page-controls\">\n @if (rootPage.editSourceFileUrl) {\n <a\n ng-doc-button-icon\n [href]=\"rootPage.editSourceFileUrl\"\n target=\"_blank\"\n ngDocTooltip=\"Suggest Edits\">\n <ng-doc-icon icon=\"edit-2\"></ng-doc-icon>\n </a>\n }\n @if (rootPage.viewSourceFileUrl) {\n <a\n ng-doc-button-icon\n [href]=\"rootPage.viewSourceFileUrl\"\n target=\"_blank\"\n ngDocTooltip=\"View Source\">\n <ng-doc-icon icon=\"code\"></ng-doc-icon>\n </a>\n }\n</div>\n\n<div\n class=\"ng-doc-page-wrapper\"\n [ngDocPageProcessor]=\"rootPage.pageContent | ngDocSanitizeHtml\"\n (afterRender)=\"createToc()\"\n #pageContainer></div>\n\n@if (!rootPage.page?.disableFullscreenRoutes) {\n <ng-doc-dialog-outlet [config]=\"{ width: '100vw', height: '100vh' }\">\n <div class=\"ng-doc-fullscreen-wrapper\">\n <router-outlet></router-outlet>\n </div>\n </ng-doc-dialog-outlet>\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-components-page.mjs","sources":["../../../../libs/app/components/page/page.component.ts","../../../../libs/app/components/page/page.component.html","../../../../libs/app/components/page/ng-doc-app-components-page.ts"],"sourcesContent":["import { Clipboard } from '@angular/cdk/clipboard';\nimport { isPlatformBrowser, LocationStrategy } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n Component,\n DestroyRef,\n effect,\n ElementRef,\n inject,\n NgZone,\n PLATFORM_ID,\n reflectComponentType,\n signal,\n untracked,\n viewChild,\n} from '@angular/core';\nimport { ActivatedRoute, RouterLink, RouterOutlet } from '@angular/router';\nimport { NgDocContentAnchorController } from '@ng-doc/app/classes/content-anchor-controller';\nimport { NgDocContentController } from '@ng-doc/app/classes/content-controller';\nimport { NgDocRootPage } from '@ng-doc/app/classes/root-page';\nimport { NgDocPageWrapperComponent } from '@ng-doc/app/components/page-wrapper';\nimport {\n createComponent,\n generateToc,\n ɵngDocPageUrl,\n ɵrestoreNgDocHydrationSnapshot,\n} from '@ng-doc/app/helpers';\nimport { NgDocPageSkeleton } from '@ng-doc/app/interfaces';\nimport { NgDocSanitizeHtmlPipe } from '@ng-doc/app/pipes';\nimport { NgDocPageProcessorComponent } from '@ng-doc/app/processors';\nimport { provideTypeControl } from '@ng-doc/app/providers/type-control';\nimport { NgDocFullscreenRouteService } from '@ng-doc/app/services/fullscreen-route';\nimport { NG_DOC_PAGE_SKELETON } from '@ng-doc/app/tokens';\nimport {\n NgDocBooleanControlComponent,\n NgDocNumberControlComponent,\n NgDocStringControlComponent,\n NgDocTypeAliasControlComponent,\n} from '@ng-doc/app/type-controls';\nimport type { NgDocContentSource } from '@ng-doc/core/interfaces';\nimport { NgDocButtonIconComponent, NgDocTooltipDirective } from '@ng-doc/ui-kit';\nimport { WA_LOCATION } from '@ng-web-apis/common';\n\n/**\n * A generated page: its rendered content, the page actions (copy link, edit and view the source),\n * the table of contents it fills in, and the outlet of its fullscreen routes.\n *\n * A fullscreen route (a child route of the page, unless the page sets `disableFullscreenRoutes`)\n * replaces the page: it is shown on its own on the canvas of demos, with a link back to the page,\n * and `NgDocFullscreenRouteService` tells the root layout and the page wrapper to hide their\n * chrome.\n */\n@Component({\n selector: 'ng-doc-page',\n templateUrl: './page.component.html',\n styleUrls: ['./page.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [\n NgDocButtonIconComponent,\n NgDocTooltipDirective,\n NgDocPageProcessorComponent,\n RouterLink,\n RouterOutlet,\n NgDocSanitizeHtmlPipe,\n ],\n providers: [\n NgDocContentAnchorController,\n NgDocContentController,\n provideTypeControl('NgDocTypeAlias', NgDocTypeAliasControlComponent, { order: 10 }),\n provideTypeControl('string', NgDocStringControlComponent, { order: 20 }),\n provideTypeControl('number', NgDocNumberControlComponent, { order: 30 }),\n provideTypeControl('boolean', NgDocBooleanControlComponent, { order: 40 }),\n ],\n host: {\n ngSkipHydration: 'true',\n // Tells the browser that the server-rendered content must be kept until the loaded content\n // renders (ɵNG_DOC_ASYNC_CONTENT_ATTRIBUTE).\n '[attr.data-ng-doc-async-content]':\n 'rootPage.pageContentSource && !fullscreenRoute() ? \"\" : null',\n },\n})\nexport class NgDocPageComponent {\n /** The element that holds the rendered page content. */\n readonly pageContainer = viewChild('pageContainer', { read: ElementRef<HTMLElement> });\n\n protected rootPage: NgDocRootPage = inject(NgDocRootPage);\n protected skeleton: NgDocPageSkeleton = inject(NG_DOC_PAGE_SKELETON);\n protected changeDetectorRef = inject(ChangeDetectorRef);\n\n protected pageWrapper: NgDocPageWrapperComponent = inject(NgDocPageWrapperComponent);\n protected readonly contentController = inject(NgDocContentController);\n /** Whether the link to the page was just copied. */\n protected readonly linkCopied = signal(false);\n /** Whether one of the page's fullscreen routes is shown instead of the page. */\n protected readonly fullscreenRoute = signal(false);\n /** URL of the page, for the link back from a fullscreen route. */\n protected readonly pageUrl = signal('/');\n private readonly route = inject(ActivatedRoute);\n private readonly fullscreenRoutes = inject(NgDocFullscreenRouteService);\n private readonly contentAnchorController = inject(NgDocContentAnchorController);\n private readonly clipboard = inject(Clipboard);\n private readonly ngZone = inject(NgZone);\n private readonly location = inject(WA_LOCATION);\n private readonly locationStrategy = inject(LocationStrategy);\n private linkCopiedTimer?: ReturnType<typeof setTimeout>;\n /** Removes the server-rendered copy shown while asynchronous content loads. */\n private snapshot?: () => void;\n\n constructor() {\n // The router state is complete when the page is created, so a fullscreen route opened\n // directly (a new tab) is known before the first render and the page content never renders.\n this.showFullscreenRoute(!!this.route.firstChild);\n\n const source: NgDocContentSource | undefined = this.rootPage.pageContentSource;\n\n if (source && !this.fullscreenRoute()) {\n // Angular empties this host (it skips hydration) and the content loads asynchronously, so\n // the server-rendered page stays visible until the loaded content renders.\n if (isPlatformBrowser(inject(PLATFORM_ID))) {\n this.snapshot = ɵrestoreNgDocHydrationSnapshot(inject(ElementRef).nativeElement);\n }\n this.connectContent(source);\n }\n // A page opened on a fullscreen route loads its content only when the reader goes back to\n // it, because pending content holds the application unstable until it renders. An effect,\n // so a page that is leaving (its route closes as it is destroyed) loads nothing.\n effect(() => {\n if (source && !this.fullscreenRoute()) untracked(() => this.connectContent(source));\n });\n // A load that needs no new pass (its content is already rendered, for example an empty body)\n // or that failed settles without `revealLoaded`.\n effect(() => {\n if (this.contentController.settled()) untracked(() => this.releaseSnapshot());\n });\n effect(() => {\n if (this.contentController.error()) {\n untracked(() => {\n this.releaseSnapshot();\n this.pageWrapper.pageToc().clear();\n this.contentAnchorController.contentFailed();\n });\n }\n });\n inject(DestroyRef).onDestroy(() => {\n clearTimeout(this.linkCopiedTimer);\n this.releaseSnapshot();\n this.fullscreenRoutes.set(this, false);\n });\n }\n\n /**\n * Shows one of the page's fullscreen routes instead of the page, or the page again. The outlet\n * of the fullscreen routes calls it when a route opens or closes.\n * @param shown - Whether a fullscreen route is shown.\n */\n protected showFullscreenRoute(shown: boolean): void {\n // Pages that disable fullscreen routes render their child routes themselves.\n const fullscreen: boolean = shown && !this.rootPage.page?.disableFullscreenRoutes;\n\n if (fullscreen) {\n this.pageUrl.set(\n '/' +\n this.route.pathFromRoot\n .flatMap((route: ActivatedRoute) => route.snapshot.url)\n .map((segment) => segment.path)\n .join('/'),\n );\n }\n this.fullscreenRoute.set(fullscreen);\n this.fullscreenRoutes.set(this, fullscreen);\n }\n\n /**\n * Creates the table of contents from the headings of the rendered page.\n */\n createToc(): void {\n const container = this.pageContainer();\n const pageToc = this.pageWrapper.pageToc();\n\n pageToc.clear();\n if (container && this.skeleton.toc) {\n const inputs: Record<string, unknown> = {\n tableOfContent: generateToc(container.nativeElement) ?? [],\n };\n // Only components that declare the input get it: a custom table of contents may not.\n const declared = reflectComponentType(this.skeleton.toc)?.inputs ?? [];\n\n if (declared.some(({ templateName }) => templateName === 'editSourceFileUrl')) {\n inputs['editSourceFileUrl'] = this.rootPage.editSourceFileUrl;\n }\n\n // API pages carry their symbol details for the rail, hidden in the content.\n const details = container.nativeElement.querySelector('[data-ng-doc-rail-details]');\n\n if (details && declared.some(({ templateName }) => templateName === 'details')) {\n details.removeAttribute('hidden');\n inputs['details'] = details;\n }\n\n createComponent(pageToc, this.skeleton.toc, inputs);\n\n this.changeDetectorRef.detectChanges();\n }\n if (this.rootPage.pageContentSource) this.contentAnchorController.contentProcessed();\n }\n\n /**\n * Shows the page's own content in place of the server-rendered copy when a pass of the loaded\n * content is about to render, in the same task, so its components render and measure visible.\n * The pass of the empty content before the source has loaded keeps the copy.\n * @param version - The content version of the pass.\n * @internal\n */\n protected revealLoaded(version: number): void {\n if (version === this.contentController.loadedVersion()) this.releaseSnapshot();\n }\n\n /**\n * Copies the link to the page, without its query and fragment.\n */\n copyLink(): void {\n this.clipboard.copy(ɵngDocPageUrl(this.locationStrategy, this.location));\n this.linkCopied.set(true);\n clearTimeout(this.linkCopiedTimer);\n // The label timer must not hold the application unstable, so it runs outside the zone.\n this.linkCopiedTimer = this.ngZone.runOutsideAngular(() =>\n setTimeout(() => this.linkCopied.set(false), 1400),\n );\n }\n\n private connectContent(source: NgDocContentSource): void {\n // Both calls do nothing once the source is connected.\n this.contentAnchorController.activate();\n this.contentController.connect(source);\n }\n\n private releaseSnapshot(): void {\n const release = this.snapshot;\n\n this.snapshot = undefined;\n release?.();\n }\n}\n","@if (!fullscreenRoute()) {\n <div class=\"ng-doc-page-controls\">\n <button\n type=\"button\"\n ng-doc-button-icon\n [rounded]=\"false\"\n [attr.aria-label]=\"linkCopied() ? 'Link copied' : 'Copy link to this page'\"\n [ngDocTooltip]=\"linkCopied() ? 'Copied' : 'Copy link'\"\n [attr.data-ng-doc-copied]=\"linkCopied()\"\n (click)=\"copyLink()\">\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"1.8\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\">\n <path d=\"M10 13a5 5 0 0 0 7.5.5l3-3a5 5 0 0 0-7-7l-1.7 1.7\" />\n <path d=\"M14 11a5 5 0 0 0-7.5-.5l-3 3a5 5 0 0 0 7 7l1.7-1.7\" />\n </svg>\n </button>\n @if (rootPage.editSourceFileUrl) {\n <a\n ng-doc-button-icon\n [rounded]=\"false\"\n [href]=\"rootPage.editSourceFileUrl\"\n target=\"_blank\"\n rel=\"noopener\"\n aria-label=\"Edit this page\"\n ngDocTooltip=\"Edit this page\">\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"1.8\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\">\n <path d=\"M12 20h9M16.5 3.5a2.1 2.1 0 1 1 3 3L7 19l-4 1 1-4Z\" />\n </svg>\n </a>\n }\n @if (rootPage.viewSourceFileUrl) {\n <a\n ng-doc-button-icon\n [rounded]=\"false\"\n [href]=\"rootPage.viewSourceFileUrl\"\n target=\"_blank\"\n rel=\"noopener\"\n aria-label=\"View the page source\"\n ngDocTooltip=\"View source\">\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"1.8\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\">\n <path d=\"m8 7-5 5 5 5m8-10 5 5-5 5\" />\n </svg>\n </a>\n }\n </div>\n\n @if (rootPage.pageContentSource) {\n @if (contentController.error(); as error) {\n <div class=\"ng-doc-page-wrapper\" role=\"alert\">{{ error.message }}</div>\n } @else {\n <div\n class=\"ng-doc-page-wrapper\"\n [ngDocPageProcessor]=\"contentController.html() | ngDocSanitizeHtml\"\n [contentVersion]=\"contentController.version()\"\n (beforeRender)=\"revealLoaded($event)\"\n (contentProcessed)=\"contentController.processed($event)\"\n (processingError)=\"contentController.processingFailed($event)\"\n (afterRender)=\"createToc()\"\n #pageContainer></div>\n }\n } @else {\n <div\n class=\"ng-doc-page-wrapper\"\n [ngDocPageProcessor]=\"rootPage.pageContent | ngDocSanitizeHtml\"\n (afterRender)=\"createToc()\"\n #pageContainer></div>\n }\n}\n\n<!-- A fullscreen route replaces the page; the outlet stays, so it can open and close in place. -->\n@if (!rootPage.page?.disableFullscreenRoutes) {\n <div class=\"ng-doc-fullscreen-route\" [hidden]=\"!fullscreenRoute()\">\n @if (fullscreenRoute()) {\n <a\n class=\"ng-doc-fullscreen-route-back\"\n [routerLink]=\"pageUrl()\"\n [attr.aria-label]=\"'Back to ' + (rootPage.page?.title ?? 'the page')\"\n [ngDocTooltip]=\"'Back to ' + (rootPage.page?.title ?? 'the page')\">\n <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\">\n <path d=\"M19 12H5m7 7-7-7 7-7\" />\n </svg>\n <span class=\"ng-doc-fullscreen-route-back-label\">{{ rootPage.page?.title ?? 'Back' }}</span>\n </a>\n }\n <router-outlet\n (activate)=\"showFullscreenRoute(true)\"\n (deactivate)=\"showFullscreenRoute(false)\" />\n </div>\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["ɵrestoreNgDocHydrationSnapshot","ɵngDocPageUrl"],"mappings":"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"}