@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.
- 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 +178 -68
- 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-pane.mjs +39 -36
- package/fesm2022/ng-doc-app-components-demo-pane.mjs.map +1 -1
- package/fesm2022/ng-doc-app-components-demo.mjs +129 -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 +187 -91
- 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 +69 -24
- 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 +392 -263
- 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 +90 -63
- package/fesm2022/ng-doc-app-components-sidebar.mjs.map +1 -1
- package/fesm2022/ng-doc-app-components-tabs.mjs +18 -12
- 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 +268 -90
- package/fesm2022/ng-doc-app-components-toc.mjs.map +1 -1
- package/fesm2022/ng-doc-app-components.mjs +3 -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-directives-code-highlighter.mjs +14 -7
- 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 +285 -1
- 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 +12 -1
- 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-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 +83 -14
- package/fesm2022/ng-doc-app-services-highlighter.mjs.map +1 -1
- package/fesm2022/ng-doc-app-services-route-preloader.mjs +360 -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 +22 -16
- package/fesm2022/ng-doc-app-type-controls-type-alias-control.mjs.map +1 -1
- package/package.json +74 -32
- package/styles/global.css +1129 -205
- package/styles/main.css +1129 -205
- package/styles/themes/dark.css +78 -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 +6 -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-pane.d.ts +19 -15
- package/types/ng-doc-app-components-demo.d.ts +62 -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 +146 -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 +13 -4
- 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 +3 -1
- 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 +124 -3
- package/types/ng-doc-app-interfaces.d.ts +48 -28
- 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 +5 -1
- package/types/ng-doc-app-providers-ng-doc-app.d.ts +17 -0
- package/types/ng-doc-app-providers-playground-demo.d.ts +1 -1
- package/types/ng-doc-app-providers-type-control.d.ts +2 -2
- 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 +40 -5
- package/types/ng-doc-app-services-route-preloader.d.ts +109 -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 +13 -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
|
@@ -1,49 +1,176 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { inject, ElementRef,
|
|
2
|
+
import { inject, ElementRef, input, computed, signal, untracked, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
3
3
|
import { NgDocCopyButtonComponent } from '@ng-doc/app/components/copy-button';
|
|
4
4
|
import { NgDocSanitizeHtmlPipe } from '@ng-doc/app/pipes';
|
|
5
5
|
import { NgDocPageProcessorComponent } from '@ng-doc/app/processors/page-processor';
|
|
6
6
|
import { linkProcessor } from '@ng-doc/app/processors/processors/link';
|
|
7
7
|
import { tooltipProcessor } from '@ng-doc/app/processors/processors/tooltip';
|
|
8
8
|
import { provideMainPageProcessor } from '@ng-doc/app/tokens';
|
|
9
|
-
import {
|
|
9
|
+
import { NgDocIconComponent } from '@ng-doc/ui-kit';
|
|
10
10
|
|
|
11
|
+
/** Display names of common language ids; other ids are shown capitalized. */
|
|
12
|
+
const LANGUAGE_LABELS = {
|
|
13
|
+
'angular-html': 'HTML',
|
|
14
|
+
'angular-ts': 'TypeScript',
|
|
15
|
+
bash: 'Shell',
|
|
16
|
+
css: 'CSS',
|
|
17
|
+
diff: 'Diff',
|
|
18
|
+
html: 'HTML',
|
|
19
|
+
javascript: 'JavaScript',
|
|
20
|
+
js: 'JavaScript',
|
|
21
|
+
json: 'JSON',
|
|
22
|
+
jsonc: 'JSON',
|
|
23
|
+
jsx: 'JSX',
|
|
24
|
+
less: 'Less',
|
|
25
|
+
markdown: 'Markdown',
|
|
26
|
+
md: 'Markdown',
|
|
27
|
+
mermaid: 'Mermaid',
|
|
28
|
+
nunjucks: 'Nunjucks',
|
|
29
|
+
sass: 'Sass',
|
|
30
|
+
scss: 'SCSS',
|
|
31
|
+
sh: 'Shell',
|
|
32
|
+
shell: 'Shell',
|
|
33
|
+
ts: 'TypeScript',
|
|
34
|
+
tsx: 'TSX',
|
|
35
|
+
typescript: 'TypeScript',
|
|
36
|
+
xml: 'XML',
|
|
37
|
+
yaml: 'YAML',
|
|
38
|
+
yml: 'YAML',
|
|
39
|
+
};
|
|
40
|
+
/** Language ids of plain text, which get no language chip. */
|
|
41
|
+
const PLAIN_LANGUAGES = new Set(['', 'text', 'txt', 'plain', 'plaintext']);
|
|
42
|
+
/**
|
|
43
|
+
* Renders a code block: a header with the file name, the language and the highlighted lines
|
|
44
|
+
* (shown when the block has a name or an icon), line numbers and a copy button.
|
|
45
|
+
*
|
|
46
|
+
* Line numbers are CSS counters, so they are neither copied nor announced. Setting the
|
|
47
|
+
* `code-line-numbers` theme variable to `none` hides them.
|
|
48
|
+
*/
|
|
11
49
|
class NgDocCodeComponent {
|
|
12
50
|
constructor() {
|
|
13
51
|
this.elementRef = inject(ElementRef);
|
|
14
|
-
|
|
15
|
-
this.
|
|
52
|
+
/** Highlighted HTML of the code. When empty, the projected content is shown instead. */
|
|
53
|
+
this.html = input('', /* @ts-ignore */
|
|
54
|
+
...(ngDevMode ? [{ debugName: "html" }] : /* istanbul ignore next */ []));
|
|
55
|
+
/** Whether the copy button is shown. */
|
|
56
|
+
this.copyButton = input(true, /* @ts-ignore */
|
|
57
|
+
...(ngDevMode ? [{ debugName: "copyButton" }] : /* istanbul ignore next */ []));
|
|
58
|
+
/** File name shown in the header. */
|
|
59
|
+
this.name = input(undefined, /* @ts-ignore */
|
|
60
|
+
...(ngDevMode ? [{ debugName: "name" }] : /* istanbul ignore next */ []));
|
|
61
|
+
/** Name of a custom icon shown before the file name. */
|
|
62
|
+
this.icon = input(undefined, /* @ts-ignore */
|
|
63
|
+
...(ngDevMode ? [{ debugName: "icon" }] : /* istanbul ignore next */ []));
|
|
64
|
+
/** Whether the header bar is shown: a block with a file name or an icon has one. */
|
|
65
|
+
this.hasHeader = computed(() => !!this.name() || !!this.icon(), /* @ts-ignore */
|
|
66
|
+
...(ngDevMode ? [{ debugName: "hasHeader" }] : /* istanbul ignore next */ []));
|
|
67
|
+
/** Language and highlighted lines of projected code, read from the DOM. */
|
|
68
|
+
this.projected = signal({ language: '', highlightedLines: [] }, /* @ts-ignore */
|
|
69
|
+
...(ngDevMode ? [{ debugName: "projected" }] : /* istanbul ignore next */ []));
|
|
70
|
+
/**
|
|
71
|
+
* Language and highlighted lines of the code. Highlighted HTML is parsed as a string, so the
|
|
72
|
+
* header is complete in server-rendered and prerendered pages; projected code is read from its
|
|
73
|
+
* DOM, which the server renderer provides too.
|
|
74
|
+
*/
|
|
75
|
+
this.rendered = computed(() => {
|
|
76
|
+
const html = this.html();
|
|
77
|
+
return html ? parseHighlightedCode(html) : this.projected();
|
|
78
|
+
}, /* @ts-ignore */
|
|
79
|
+
...(ngDevMode ? [{ debugName: "rendered" }] : /* istanbul ignore next */ []));
|
|
80
|
+
/** Display name of the language; empty for plain text. */
|
|
81
|
+
this.language = computed(() => {
|
|
82
|
+
const id = this.rendered().language.toLowerCase();
|
|
83
|
+
return PLAIN_LANGUAGES.has(id)
|
|
84
|
+
? ''
|
|
85
|
+
: LANGUAGE_LABELS[id] ?? id.charAt(0).toUpperCase() + id.slice(1);
|
|
86
|
+
}, /* @ts-ignore */
|
|
87
|
+
...(ngDevMode ? [{ debugName: "language" }] : /* istanbul ignore next */ []));
|
|
88
|
+
/** The highlighted lines as text, for example "Lines 6–7" or "Lines 2, 5–6". */
|
|
89
|
+
this.range = computed(() => describeLines(this.rendered().highlightedLines), /* @ts-ignore */
|
|
90
|
+
...(ngDevMode ? [{ debugName: "range" }] : /* istanbul ignore next */ []));
|
|
91
|
+
/** Reads the text of the rendered code when the copy button is pressed. */
|
|
92
|
+
this.text = () => this.codeElement()?.textContent ?? '';
|
|
16
93
|
}
|
|
17
|
-
|
|
18
|
-
|
|
94
|
+
/**
|
|
95
|
+
* Reads projected code once the view has rendered it. The page's code is projected inside a
|
|
96
|
+
* control-flow block, so it is in place only after the first render; this hook also runs on the
|
|
97
|
+
* server, so prerendered pages get the language and the highlighted lines. The page processor
|
|
98
|
+
* relies on that late projection: it replaces the page's `pre` with this component after
|
|
99
|
+
* creating it.
|
|
100
|
+
*/
|
|
101
|
+
ngAfterViewInit() {
|
|
102
|
+
if (!untracked(this.html)) {
|
|
103
|
+
this.projected.set(readProjectedCode(this.codeElement()));
|
|
104
|
+
}
|
|
19
105
|
}
|
|
20
|
-
|
|
21
|
-
return this.elementRef
|
|
106
|
+
codeElement() {
|
|
107
|
+
return this.elementRef.nativeElement.querySelector('pre code');
|
|
22
108
|
}
|
|
23
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "
|
|
24
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "
|
|
109
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.2.1", ngImport: i0, type: NgDocCodeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
110
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.2.1", type: NgDocCodeComponent, isStandalone: true, selector: "ng-doc-code", inputs: { html: { classPropertyName: "html", publicName: "html", isSignal: true, isRequired: false, transformFunction: null }, copyButton: { classPropertyName: "copyButton", publicName: "copyButton", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.data-ng-doc-has-header": "hasHeader()" } }, ngImport: i0, template: "@if (hasHeader()) {\n <div class=\"ng-doc-code-header\">\n <span class=\"ng-doc-code-file-name\">\n @if (icon(); as icon) {\n <ng-doc-icon [customIcon]=\"icon\"></ng-doc-icon>\n }\n <span class=\"ng-doc-code-file-name-text\">{{ name() }}</span>\n </span>\n @if (language(); as language) {\n <span class=\"ng-doc-code-language\">{{ language }}</span>\n }\n <span class=\"ng-doc-code-header-spacer\"></span>\n @if (range(); as range) {\n <span class=\"ng-doc-code-range\">{{ range }}</span>\n }\n @if (copyButton()) {\n <ng-doc-copy-button class=\"ng-doc-code-header-copy\" [text]=\"text\">\n <ng-doc-icon icon=\"copy\"></ng-doc-icon>\n </ng-doc-copy-button>\n }\n </div>\n}\n<div class=\"ng-doc-code-body\">\n @if (html()) {\n <div class=\"ng-doc-code-wrapper\" [ngDocPageProcessor]=\"html() | ngDocSanitizeHtml\"></div>\n } @else {\n <div class=\"ng-doc-code-wrapper\">\n <ng-content></ng-content>\n </div>\n }\n\n @if (copyButton() && !hasHeader()) {\n <ng-doc-copy-button class=\"ng-doc-copy-button\" [text]=\"text\">\n <ng-doc-icon icon=\"copy\"></ng-doc-icon>\n </ng-doc-copy-button>\n }\n</div>\n", styles: [":host{position:relative;display:block;margin:var(--ng-doc-code-margin);border:var(--ng-doc-code-border, 1px solid var(--ng-doc-border-color));border-radius:var(--ng-doc-code-border-radius, var(--ng-doc-radius-lg));background:var(--ng-doc-code-background);overflow:hidden;min-width:0;--ng-doc-code-shadow: none}:host:hover .ng-doc-copy-button,:host:focus-within .ng-doc-copy-button{opacity:1}:host .ng-doc-code-header{display:flex;align-items:center;gap:var(--ng-doc-space-2);height:var(--ng-doc-code-header-height);padding:0 var(--ng-doc-space-1) 0 var(--ng-doc-space-4);border-bottom:1px solid var(--ng-doc-border-color);background:var(--ng-doc-code-header-background, transparent);font-family:var(--ng-doc-font-family);font-size:13px;line-height:18px;color:var(--ng-doc-text-muted)}:host .ng-doc-code-file-name{display:inline-flex;align-items:center;gap:6px;min-width:0;font-weight:500;color:var(--ng-doc-code-header-color, var(--ng-doc-heading-color))}:host .ng-doc-code-file-name-text{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}:host .ng-doc-code-language{display:inline-flex;align-items:center;flex:none;height:18px;padding:0 5px;border-radius:var(--ng-doc-radius-sm);font-size:10.5px;font-weight:600;line-height:1;white-space:nowrap;color:color-mix(in oklab,var(--ng-doc-hue-neutral) var(--ng-doc-mix-strong),var(--ng-doc-heading-color));background:color-mix(in oklab,var(--ng-doc-hue-neutral) var(--ng-doc-mix-chip),var(--ng-doc-background));box-shadow:inset 0 0 0 1px color-mix(in oklab,var(--ng-doc-hue-neutral) 24%,transparent)}:host .ng-doc-code-header-spacer{flex:1}:host .ng-doc-code-range{font-size:12px;white-space:nowrap;font-variant-numeric:tabular-nums}:host .ng-doc-code-header-copy,:host .ng-doc-copy-button{--ng-doc-icon-color: var(--ng-doc-text-muted)}:host .ng-doc-copy-button{position:absolute;top:var(--ng-doc-space-2);right:var(--ng-doc-space-2);transition:var(--ng-doc-transition);opacity:0}:host .ng-doc-code-wrapper{--ng-doc-code-margin: 0;--ng-doc-code-border: none;height:100%}:host .ng-doc-code-body{position:relative;height:100%}:host .ng-doc-code-body ::ng-deep pre{display:flex;margin:var(--ng-doc-code-margin);height:100%}:host .ng-doc-code-body ::ng-deep pre code{display:block;padding:var(--ng-doc-space-4) 0;width:100%;font-family:var(--ng-doc-code-font);font-size:var(--ng-doc-code-font-size);line-height:var(--ng-doc-code-line-height);max-height:var(--ng-doc-code-max-height);overflow:auto;height:100%;counter-reset:ng-doc-code-line}:host .ng-doc-code-body ::ng-deep pre code.code-lines{display:grid}:host .ng-doc-code-body ::ng-deep pre code .line{display:inline-block;width:100%;min-width:max-content;padding:0 var(--ng-doc-space-5) 0 0}:host .ng-doc-code-body ::ng-deep pre code .line:before{counter-increment:ng-doc-code-line;content:counter(ng-doc-code-line);content:counter(ng-doc-code-line)/\"\";display:var(--ng-doc-code-line-numbers);width:3ch;margin:0 var(--ng-doc-space-4) 0 var(--ng-doc-space-3);text-align:right;color:var(--ng-doc-code-line-number-color);user-select:none;-webkit-user-select:none}:host .ng-doc-code-body ::ng-deep pre code .line.highlighted{background:color-mix(in srgb,var(--ng-doc-code-highlight-color) 10%,transparent)!important;box-shadow:inset 2px 0 0 var(--ng-doc-code-highlight-color)}:host .ng-doc-code-body ::ng-deep pre code .line.highlighted span{background:transparent!important}:host .ng-doc-code-body ::ng-deep pre code .line.highlighted:before{color:var(--ng-doc-primary-strong);font-weight:600}@container style(--ng-doc-code-line-numbers: none){:host .ng-doc-code-body ::ng-deep pre code .line{padding-left:var(--ng-doc-space-5)}}@media(max-width:640px){:host .ng-doc-code-range{display:none}:host .ng-doc-code-body ::ng-deep pre code{font-size:13px}:host .ng-doc-code-body ::ng-deep pre code .line:before{width:2ch;margin:0 var(--ng-doc-space-3) 0 var(--ng-doc-space-2)}}\n"], dependencies: [{ kind: "component", type: NgDocIconComponent, selector: "ng-doc-icon", inputs: ["icon", "customIcon", "size"] }, { kind: "component", type: NgDocPageProcessorComponent, selector: "[ngDocPageProcessor]", inputs: ["ngDocPageProcessor", "contentVersion"], outputs: ["beforeRender", "afterRender", "contentProcessed", "processingError"] }, { kind: "component", type: NgDocCopyButtonComponent, selector: "ng-doc-copy-button", inputs: ["text", "label"] }, { kind: "pipe", type: NgDocSanitizeHtmlPipe, name: "ngDocSanitizeHtml" }], viewProviders: [provideMainPageProcessor([linkProcessor, tooltipProcessor])], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
25
111
|
}
|
|
26
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "
|
|
112
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.1", ngImport: i0, type: NgDocCodeComponent, decorators: [{
|
|
27
113
|
type: Component,
|
|
28
114
|
args: [{ selector: 'ng-doc-code', changeDetection: ChangeDetectionStrategy.OnPush, imports: [
|
|
29
|
-
NgDocTextComponent,
|
|
30
115
|
NgDocIconComponent,
|
|
31
116
|
NgDocPageProcessorComponent,
|
|
32
117
|
NgDocCopyButtonComponent,
|
|
33
118
|
NgDocSanitizeHtmlPipe,
|
|
34
|
-
], viewProviders: [provideMainPageProcessor([linkProcessor, tooltipProcessor])],
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
119
|
+
], viewProviders: [provideMainPageProcessor([linkProcessor, tooltipProcessor])], host: {
|
|
120
|
+
'[attr.data-ng-doc-has-header]': 'hasHeader()',
|
|
121
|
+
}, template: "@if (hasHeader()) {\n <div class=\"ng-doc-code-header\">\n <span class=\"ng-doc-code-file-name\">\n @if (icon(); as icon) {\n <ng-doc-icon [customIcon]=\"icon\"></ng-doc-icon>\n }\n <span class=\"ng-doc-code-file-name-text\">{{ name() }}</span>\n </span>\n @if (language(); as language) {\n <span class=\"ng-doc-code-language\">{{ language }}</span>\n }\n <span class=\"ng-doc-code-header-spacer\"></span>\n @if (range(); as range) {\n <span class=\"ng-doc-code-range\">{{ range }}</span>\n }\n @if (copyButton()) {\n <ng-doc-copy-button class=\"ng-doc-code-header-copy\" [text]=\"text\">\n <ng-doc-icon icon=\"copy\"></ng-doc-icon>\n </ng-doc-copy-button>\n }\n </div>\n}\n<div class=\"ng-doc-code-body\">\n @if (html()) {\n <div class=\"ng-doc-code-wrapper\" [ngDocPageProcessor]=\"html() | ngDocSanitizeHtml\"></div>\n } @else {\n <div class=\"ng-doc-code-wrapper\">\n <ng-content></ng-content>\n </div>\n }\n\n @if (copyButton() && !hasHeader()) {\n <ng-doc-copy-button class=\"ng-doc-copy-button\" [text]=\"text\">\n <ng-doc-icon icon=\"copy\"></ng-doc-icon>\n </ng-doc-copy-button>\n }\n</div>\n", styles: [":host{position:relative;display:block;margin:var(--ng-doc-code-margin);border:var(--ng-doc-code-border, 1px solid var(--ng-doc-border-color));border-radius:var(--ng-doc-code-border-radius, var(--ng-doc-radius-lg));background:var(--ng-doc-code-background);overflow:hidden;min-width:0;--ng-doc-code-shadow: none}:host:hover .ng-doc-copy-button,:host:focus-within .ng-doc-copy-button{opacity:1}:host .ng-doc-code-header{display:flex;align-items:center;gap:var(--ng-doc-space-2);height:var(--ng-doc-code-header-height);padding:0 var(--ng-doc-space-1) 0 var(--ng-doc-space-4);border-bottom:1px solid var(--ng-doc-border-color);background:var(--ng-doc-code-header-background, transparent);font-family:var(--ng-doc-font-family);font-size:13px;line-height:18px;color:var(--ng-doc-text-muted)}:host .ng-doc-code-file-name{display:inline-flex;align-items:center;gap:6px;min-width:0;font-weight:500;color:var(--ng-doc-code-header-color, var(--ng-doc-heading-color))}:host .ng-doc-code-file-name-text{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}:host .ng-doc-code-language{display:inline-flex;align-items:center;flex:none;height:18px;padding:0 5px;border-radius:var(--ng-doc-radius-sm);font-size:10.5px;font-weight:600;line-height:1;white-space:nowrap;color:color-mix(in oklab,var(--ng-doc-hue-neutral) var(--ng-doc-mix-strong),var(--ng-doc-heading-color));background:color-mix(in oklab,var(--ng-doc-hue-neutral) var(--ng-doc-mix-chip),var(--ng-doc-background));box-shadow:inset 0 0 0 1px color-mix(in oklab,var(--ng-doc-hue-neutral) 24%,transparent)}:host .ng-doc-code-header-spacer{flex:1}:host .ng-doc-code-range{font-size:12px;white-space:nowrap;font-variant-numeric:tabular-nums}:host .ng-doc-code-header-copy,:host .ng-doc-copy-button{--ng-doc-icon-color: var(--ng-doc-text-muted)}:host .ng-doc-copy-button{position:absolute;top:var(--ng-doc-space-2);right:var(--ng-doc-space-2);transition:var(--ng-doc-transition);opacity:0}:host .ng-doc-code-wrapper{--ng-doc-code-margin: 0;--ng-doc-code-border: none;height:100%}:host .ng-doc-code-body{position:relative;height:100%}:host .ng-doc-code-body ::ng-deep pre{display:flex;margin:var(--ng-doc-code-margin);height:100%}:host .ng-doc-code-body ::ng-deep pre code{display:block;padding:var(--ng-doc-space-4) 0;width:100%;font-family:var(--ng-doc-code-font);font-size:var(--ng-doc-code-font-size);line-height:var(--ng-doc-code-line-height);max-height:var(--ng-doc-code-max-height);overflow:auto;height:100%;counter-reset:ng-doc-code-line}:host .ng-doc-code-body ::ng-deep pre code.code-lines{display:grid}:host .ng-doc-code-body ::ng-deep pre code .line{display:inline-block;width:100%;min-width:max-content;padding:0 var(--ng-doc-space-5) 0 0}:host .ng-doc-code-body ::ng-deep pre code .line:before{counter-increment:ng-doc-code-line;content:counter(ng-doc-code-line);content:counter(ng-doc-code-line)/\"\";display:var(--ng-doc-code-line-numbers);width:3ch;margin:0 var(--ng-doc-space-4) 0 var(--ng-doc-space-3);text-align:right;color:var(--ng-doc-code-line-number-color);user-select:none;-webkit-user-select:none}:host .ng-doc-code-body ::ng-deep pre code .line.highlighted{background:color-mix(in srgb,var(--ng-doc-code-highlight-color) 10%,transparent)!important;box-shadow:inset 2px 0 0 var(--ng-doc-code-highlight-color)}:host .ng-doc-code-body ::ng-deep pre code .line.highlighted span{background:transparent!important}:host .ng-doc-code-body ::ng-deep pre code .line.highlighted:before{color:var(--ng-doc-primary-strong);font-weight:600}@container style(--ng-doc-code-line-numbers: none){:host .ng-doc-code-body ::ng-deep pre code .line{padding-left:var(--ng-doc-space-5)}}@media(max-width:640px){:host .ng-doc-code-range{display:none}:host .ng-doc-code-body ::ng-deep pre code{font-size:13px}:host .ng-doc-code-body ::ng-deep pre code .line:before{width:2ch;margin:0 var(--ng-doc-space-3) 0 var(--ng-doc-space-2)}}\n"] }]
|
|
122
|
+
}], propDecorators: { html: [{ type: i0.Input, args: [{ isSignal: true, alias: "html", required: false }] }], copyButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "copyButton", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], icon: [{ type: i0.Input, args: [{ isSignal: true, alias: "icon", required: false }] }] } });
|
|
123
|
+
/**
|
|
124
|
+
* Reads the language and the highlighted lines of highlighted code HTML.
|
|
125
|
+
* @param html - Highlighted HTML: a `pre > code.language-*` with one `span.line` per line.
|
|
126
|
+
*/
|
|
127
|
+
function parseHighlightedCode(html) {
|
|
128
|
+
const language = /<code\b[^>]*\bclass="[^"]*\blanguage-([\w+#-]+)/.exec(html)?.[1] ?? '';
|
|
129
|
+
const highlightedLines = [];
|
|
130
|
+
let line = 0;
|
|
131
|
+
for (const match of html.matchAll(/<span\b[^>]*\bclass="(line(?:\s[^"]*)?)"/g)) {
|
|
132
|
+
line++;
|
|
133
|
+
if (/\bhighlighted\b/.test(match[1])) {
|
|
134
|
+
highlightedLines.push(line);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return { language, highlightedLines };
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Reads the language and the highlighted lines of a rendered `code` element.
|
|
141
|
+
* @param code - The `code` element, if any.
|
|
142
|
+
*/
|
|
143
|
+
function readProjectedCode(code) {
|
|
144
|
+
return {
|
|
145
|
+
language: Array.from(code?.classList ?? [])
|
|
146
|
+
.find((name) => name.startsWith('language-'))
|
|
147
|
+
?.slice('language-'.length) ?? '',
|
|
148
|
+
highlightedLines: Array.from(code?.querySelectorAll('.line') ?? [])
|
|
149
|
+
.map((line, index) => line.classList.contains('highlighted') ? index + 1 : 0)
|
|
150
|
+
.filter(Boolean),
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Describes line numbers as ranges.
|
|
155
|
+
* @param lines - Ascending one-based line numbers.
|
|
156
|
+
* @returns "Line 3", "Lines 6–7" or "Lines 2, 5–6"; an empty string for no lines.
|
|
157
|
+
*/
|
|
158
|
+
function describeLines(lines) {
|
|
159
|
+
const ranges = [];
|
|
160
|
+
for (const line of lines) {
|
|
161
|
+
const last = ranges[ranges.length - 1];
|
|
162
|
+
if (last && line === last[1] + 1) {
|
|
163
|
+
last[1] = line;
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
ranges.push([line, line]);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
const text = ranges
|
|
170
|
+
.map(([start, end]) => (start === end ? `${start}` : `${start}–${end}`))
|
|
171
|
+
.join(', ');
|
|
172
|
+
return text ? `${lines.length === 1 ? 'Line' : 'Lines'} ${text}` : '';
|
|
173
|
+
}
|
|
47
174
|
|
|
48
175
|
/**
|
|
49
176
|
* Generated bundle index. Do not edit.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ng-doc-app-components-code.mjs","sources":["../../../../libs/app/components/code/code.component.ts","../../../../libs/app/components/code/code.component.html","../../../../libs/app/components/code/ng-doc-app-components-code.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n HostBinding,\n inject,\n Input,\n} from '@angular/core';\nimport { NgDocCopyButtonComponent } from '@ng-doc/app/components/copy-button';\nimport { NgDocSanitizeHtmlPipe } from '@ng-doc/app/pipes';\nimport { NgDocPageProcessorComponent } from '@ng-doc/app/processors/page-processor';\nimport { linkProcessor } from '@ng-doc/app/processors/processors/link';\nimport { tooltipProcessor } from '@ng-doc/app/processors/processors/tooltip';\nimport { provideMainPageProcessor } from '@ng-doc/app/tokens';\nimport { NgDocIconComponent, NgDocTextComponent } from '@ng-doc/ui-kit';\n\n@Component({\n selector: 'ng-doc-code',\n templateUrl: './code.component.html',\n styleUrls: ['./code.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [\n NgDocTextComponent,\n NgDocIconComponent,\n NgDocPageProcessorComponent,\n NgDocCopyButtonComponent,\n NgDocSanitizeHtmlPipe,\n ],\n viewProviders: [provideMainPageProcessor([linkProcessor, tooltipProcessor])],\n})\nexport class NgDocCodeComponent {\n private elementRef = inject<ElementRef<HTMLElement>>(ElementRef);\n\n @Input()\n html: string = '';\n\n @Input()\n copyButton: boolean = true;\n\n @Input()\n name?: string;\n\n @Input()\n icon?: string;\n\n constructor() {}\n\n @HostBinding('attr.data-ng-doc-has-header')\n get hasHeader(): boolean {\n return !!this.name || !!this.icon;\n }\n\n get codeElement(): HTMLElement | null {\n return this.elementRef?.nativeElement.querySelector('code') ?? null;\n }\n}\n","@if (hasHeader) {\n <div class=\"ng-doc-code-header\">\n <span class=\"ng-doc-code-file-name\" ng-doc-text>\n @if (icon) {\n <ng-doc-icon [customIcon]=\"icon\"></ng-doc-icon>\n }\n {{ name }}\n </span>\n </div>\n}\n<div class=\"ng-doc-code-body\">\n @if (html) {\n <div class=\"ng-doc-code-wrapper\" [ngDocPageProcessor]=\"html | ngDocSanitizeHtml\"></div>\n } @else {\n <div class=\"ng-doc-code-wrapper\">\n <ng-content></ng-content>\n </div>\n }\n\n @if (copyButton) {\n <ng-doc-copy-button class=\"ng-doc-copy-button\" [text]=\"this.codeElement?.textContent ?? ''\">\n <ng-doc-icon icon=\"copy\"></ng-doc-icon>\n </ng-doc-copy-button>\n }\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;;;;;;MA8Ba,kBAAkB,CAAA;AAe7B,IAAA,WAAA,GAAA;AAdQ,QAAA,IAAA,CAAA,UAAU,GAAG,MAAM,CAA0B,UAAU,CAAC;QAGhE,IAAA,CAAA,IAAI,GAAW,EAAE;QAGjB,IAAA,CAAA,UAAU,GAAY,IAAI;IAQX;AAEf,IAAA,IACI,SAAS,GAAA;QACX,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI;IACnC;AAEA,IAAA,IAAI,WAAW,GAAA;AACb,QAAA,OAAO,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,IAAI;IACrE;8GAxBW,kBAAkB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;kGAAlB,kBAAkB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,aAAA,EAAA,MAAA,EAAA,EAAA,IAAA,EAAA,MAAA,EAAA,UAAA,EAAA,YAAA,EAAA,IAAA,EAAA,MAAA,EAAA,IAAA,EAAA,MAAA,EAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,6BAAA,EAAA,gBAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EC9B/B,ysBAyBA,EAAA,MAAA,EAAA,CAAA,ilFAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EDHI,kBAAkB,iHAClB,kBAAkB,EAAA,QAAA,EAAA,aAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,YAAA,EAAA,MAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAClB,2BAA2B,EAAA,QAAA,EAAA,sBAAA,EAAA,MAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,OAAA,EAAA,CAAA,aAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAC3B,wBAAwB,EAAA,QAAA,EAAA,oBAAA,EAAA,MAAA,EAAA,CAAA,MAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,MAAA,EAAA,IAAA,EACxB,qBAAqB,EAAA,IAAA,EAAA,mBAAA,EAAA,CAAA,EAAA,aAAA,EAER,CAAC,wBAAwB,CAAC,CAAC,aAAa,EAAE,gBAAgB,CAAC,CAAC,CAAC,EAAA,eAAA,EAAA,EAAA,CAAA,uBAAA,CAAA,MAAA,EAAA,CAAA,CAAA;;2FAEjE,kBAAkB,EAAA,UAAA,EAAA,CAAA;kBAd9B,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,aAAa,EAAA,eAAA,EAGN,uBAAuB,CAAC,MAAM,EAAA,OAAA,EACtC;wBACP,kBAAkB;wBAClB,kBAAkB;wBAClB,2BAA2B;wBAC3B,wBAAwB;wBACxB,qBAAqB;qBACtB,EAAA,aAAA,EACc,CAAC,wBAAwB,CAAC,CAAC,aAAa,EAAE,gBAAgB,CAAC,CAAC,CAAC,EAAA,QAAA,EAAA,ysBAAA,EAAA,MAAA,EAAA,CAAA,ilFAAA,CAAA,EAAA;;sBAK3E;;sBAGA;;sBAGA;;sBAGA;;sBAKA,WAAW;uBAAC,6BAA6B;;;AE/C5C;;AAEG;;;;"}
|
|
1
|
+
{"version":3,"file":"ng-doc-app-components-code.mjs","sources":["../../../../libs/app/components/code/code.component.ts","../../../../libs/app/components/code/code.component.html","../../../../libs/app/components/code/ng-doc-app-components-code.ts"],"sourcesContent":["import {\n AfterViewInit,\n ChangeDetectionStrategy,\n Component,\n computed,\n ElementRef,\n inject,\n input,\n Signal,\n signal,\n untracked,\n} from '@angular/core';\nimport { NgDocCopyButtonComponent } from '@ng-doc/app/components/copy-button';\nimport { NgDocSanitizeHtmlPipe } from '@ng-doc/app/pipes';\nimport { NgDocPageProcessorComponent } from '@ng-doc/app/processors/page-processor';\nimport { linkProcessor } from '@ng-doc/app/processors/processors/link';\nimport { tooltipProcessor } from '@ng-doc/app/processors/processors/tooltip';\nimport { provideMainPageProcessor } from '@ng-doc/app/tokens';\nimport { NgDocIconComponent } from '@ng-doc/ui-kit';\n\n/** Display names of common language ids; other ids are shown capitalized. */\nconst LANGUAGE_LABELS: Record<string, string> = {\n 'angular-html': 'HTML',\n 'angular-ts': 'TypeScript',\n bash: 'Shell',\n css: 'CSS',\n diff: 'Diff',\n html: 'HTML',\n javascript: 'JavaScript',\n js: 'JavaScript',\n json: 'JSON',\n jsonc: 'JSON',\n jsx: 'JSX',\n less: 'Less',\n markdown: 'Markdown',\n md: 'Markdown',\n mermaid: 'Mermaid',\n nunjucks: 'Nunjucks',\n sass: 'Sass',\n scss: 'SCSS',\n sh: 'Shell',\n shell: 'Shell',\n ts: 'TypeScript',\n tsx: 'TSX',\n typescript: 'TypeScript',\n xml: 'XML',\n yaml: 'YAML',\n yml: 'YAML',\n};\n\n/** Language ids of plain text, which get no language chip. */\nconst PLAIN_LANGUAGES: ReadonlySet<string> = new Set(['', 'text', 'txt', 'plain', 'plaintext']);\n\n/** What the component reads back from the rendered code. */\ninterface NgDocRenderedCode {\n /** Language id from the `language-*` class of the `code` element. */\n language: string;\n /** One-based numbers of the highlighted lines. */\n highlightedLines: number[];\n}\n\n/**\n * Renders a code block: a header with the file name, the language and the highlighted lines\n * (shown when the block has a name or an icon), line numbers and a copy button.\n *\n * Line numbers are CSS counters, so they are neither copied nor announced. Setting the\n * `code-line-numbers` theme variable to `none` hides them.\n */\n@Component({\n selector: 'ng-doc-code',\n templateUrl: './code.component.html',\n styleUrls: ['./code.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n imports: [\n NgDocIconComponent,\n NgDocPageProcessorComponent,\n NgDocCopyButtonComponent,\n NgDocSanitizeHtmlPipe,\n ],\n viewProviders: [provideMainPageProcessor([linkProcessor, tooltipProcessor])],\n host: {\n '[attr.data-ng-doc-has-header]': 'hasHeader()',\n },\n})\nexport class NgDocCodeComponent implements AfterViewInit {\n private readonly elementRef: ElementRef<HTMLElement> = inject(ElementRef);\n\n /** Highlighted HTML of the code. When empty, the projected content is shown instead. */\n readonly html = input<string>('');\n\n /** Whether the copy button is shown. */\n readonly copyButton = input<boolean>(true);\n\n /** File name shown in the header. */\n readonly name = input<string | undefined>(undefined);\n\n /** Name of a custom icon shown before the file name. */\n readonly icon = input<string | undefined>(undefined);\n\n /** Whether the header bar is shown: a block with a file name or an icon has one. */\n readonly hasHeader: Signal<boolean> = computed(() => !!this.name() || !!this.icon());\n\n /** Language and highlighted lines of projected code, read from the DOM. */\n private readonly projected = signal<NgDocRenderedCode>({ language: '', highlightedLines: [] });\n\n /**\n * Language and highlighted lines of the code. Highlighted HTML is parsed as a string, so the\n * header is complete in server-rendered and prerendered pages; projected code is read from its\n * DOM, which the server renderer provides too.\n */\n private readonly rendered: Signal<NgDocRenderedCode> = computed(() => {\n const html: string = this.html();\n\n return html ? parseHighlightedCode(html) : this.projected();\n });\n\n /** Display name of the language; empty for plain text. */\n protected readonly language: Signal<string> = computed(() => {\n const id: string = this.rendered().language.toLowerCase();\n\n return PLAIN_LANGUAGES.has(id)\n ? ''\n : LANGUAGE_LABELS[id] ?? id.charAt(0).toUpperCase() + id.slice(1);\n });\n\n /** The highlighted lines as text, for example \"Lines 6–7\" or \"Lines 2, 5–6\". */\n protected readonly range: Signal<string> = computed(() =>\n describeLines(this.rendered().highlightedLines),\n );\n\n /** Reads the text of the rendered code when the copy button is pressed. */\n protected readonly text = (): string => this.codeElement()?.textContent ?? '';\n\n /**\n * Reads projected code once the view has rendered it. The page's code is projected inside a\n * control-flow block, so it is in place only after the first render; this hook also runs on the\n * server, so prerendered pages get the language and the highlighted lines. The page processor\n * relies on that late projection: it replaces the page's `pre` with this component after\n * creating it.\n */\n ngAfterViewInit(): void {\n if (!untracked(this.html)) {\n this.projected.set(readProjectedCode(this.codeElement()));\n }\n }\n\n private codeElement(): HTMLElement | null {\n return this.elementRef.nativeElement.querySelector('pre code');\n }\n}\n\n/**\n * Reads the language and the highlighted lines of highlighted code HTML.\n * @param html - Highlighted HTML: a `pre > code.language-*` with one `span.line` per line.\n */\nfunction parseHighlightedCode(html: string): NgDocRenderedCode {\n const language: string = /<code\\b[^>]*\\bclass=\"[^\"]*\\blanguage-([\\w+#-]+)/.exec(html)?.[1] ?? '';\n const highlightedLines: number[] = [];\n let line: number = 0;\n\n for (const match of html.matchAll(/<span\\b[^>]*\\bclass=\"(line(?:\\s[^\"]*)?)\"/g)) {\n line++;\n\n if (/\\bhighlighted\\b/.test(match[1])) {\n highlightedLines.push(line);\n }\n }\n\n return { language, highlightedLines };\n}\n\n/**\n * Reads the language and the highlighted lines of a rendered `code` element.\n * @param code - The `code` element, if any.\n */\nfunction readProjectedCode(code: HTMLElement | null): NgDocRenderedCode {\n return {\n language:\n Array.from(code?.classList ?? [])\n .find((name: string) => name.startsWith('language-'))\n ?.slice('language-'.length) ?? '',\n highlightedLines: Array.from(code?.querySelectorAll('.line') ?? [])\n .map((line: Element, index: number) =>\n line.classList.contains('highlighted') ? index + 1 : 0,\n )\n .filter(Boolean),\n };\n}\n\n/**\n * Describes line numbers as ranges.\n * @param lines - Ascending one-based line numbers.\n * @returns \"Line 3\", \"Lines 6–7\" or \"Lines 2, 5–6\"; an empty string for no lines.\n */\nfunction describeLines(lines: number[]): string {\n const ranges: Array<[number, number]> = [];\n\n for (const line of lines) {\n const last: [number, number] | undefined = ranges[ranges.length - 1];\n\n if (last && line === last[1] + 1) {\n last[1] = line;\n } else {\n ranges.push([line, line]);\n }\n }\n\n const text: string = ranges\n .map(([start, end]: [number, number]) => (start === end ? `${start}` : `${start}–${end}`))\n .join(', ');\n\n return text ? `${lines.length === 1 ? 'Line' : 'Lines'} ${text}` : '';\n}\n","@if (hasHeader()) {\n <div class=\"ng-doc-code-header\">\n <span class=\"ng-doc-code-file-name\">\n @if (icon(); as icon) {\n <ng-doc-icon [customIcon]=\"icon\"></ng-doc-icon>\n }\n <span class=\"ng-doc-code-file-name-text\">{{ name() }}</span>\n </span>\n @if (language(); as language) {\n <span class=\"ng-doc-code-language\">{{ language }}</span>\n }\n <span class=\"ng-doc-code-header-spacer\"></span>\n @if (range(); as range) {\n <span class=\"ng-doc-code-range\">{{ range }}</span>\n }\n @if (copyButton()) {\n <ng-doc-copy-button class=\"ng-doc-code-header-copy\" [text]=\"text\">\n <ng-doc-icon icon=\"copy\"></ng-doc-icon>\n </ng-doc-copy-button>\n }\n </div>\n}\n<div class=\"ng-doc-code-body\">\n @if (html()) {\n <div class=\"ng-doc-code-wrapper\" [ngDocPageProcessor]=\"html() | ngDocSanitizeHtml\"></div>\n } @else {\n <div class=\"ng-doc-code-wrapper\">\n <ng-content></ng-content>\n </div>\n }\n\n @if (copyButton() && !hasHeader()) {\n <ng-doc-copy-button class=\"ng-doc-copy-button\" [text]=\"text\">\n <ng-doc-icon icon=\"copy\"></ng-doc-icon>\n </ng-doc-copy-button>\n }\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|