@firestitch/markdown-editor 18.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.
@@ -0,0 +1,46 @@
1
+ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, inject } from '@angular/core';
2
+ import { DomSanitizer } from '@angular/platform-browser';
3
+ import * as i0 from "@angular/core";
4
+ export class FsMarkdownRendererComponent {
5
+ _sanitizer = inject(DomSanitizer);
6
+ _cdRef = inject(ChangeDetectorRef);
7
+ set setMarkdown(markdown) {
8
+ this._rawMarkdown = markdown || '';
9
+ this._renderMarkdown();
10
+ }
11
+ renderedHtml;
12
+ _rawMarkdown = '';
13
+ _renderMarkdown() {
14
+ const html = this._markdownToHtml(this._rawMarkdown);
15
+ this.renderedHtml = this._sanitizer.bypassSecurityTrustHtml(html);
16
+ this._cdRef.markForCheck();
17
+ }
18
+ _markdownToHtml(markdown) {
19
+ if (!markdown) {
20
+ return '';
21
+ }
22
+ let html = markdown;
23
+ html = html.replace(/^### (.+)$/gm, '<h3>$1</h3>');
24
+ html = html.replace(/^## (.+)$/gm, '<h2>$1</h2>');
25
+ html = html.replace(/^# (.+)$/gm, '<h1>$1</h1>');
26
+ html = html.replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>');
27
+ html = html.replace(/\*(.+?)\*/g, '<em>$1</em>');
28
+ html = html.replace(/~~(.+?)~~/g, '<del>$1</del>');
29
+ html = html.replace(/`([^`]+)`/g, '<code>$1</code>');
30
+ html = html.replace(/```(\w*)\n([\s\S]*?)```/g, '<pre><code class="language-$1">$2</code></pre>');
31
+ html = html.replace(/^\> (.+)$/gm, '<blockquote>$1</blockquote>');
32
+ html = html.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '<a href="$2">$1</a>');
33
+ html = html.replace(/\n/g, '<br>');
34
+ return html;
35
+ }
36
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: FsMarkdownRendererComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
37
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.7", type: FsMarkdownRendererComponent, isStandalone: true, selector: "fs-markdown-renderer", inputs: { setMarkdown: ["markdown", "setMarkdown"] }, ngImport: i0, template: "<div class=\"fs-markdown-renderer\" [innerHtml]=\"renderedHtml\"></div>\n", styles: [":host{display:block}:host ::ng-deep .fs-markdown-renderer{word-break:break-word}:host ::ng-deep .fs-markdown-renderer h1,:host ::ng-deep .fs-markdown-renderer h2,:host ::ng-deep .fs-markdown-renderer h3,:host ::ng-deep .fs-markdown-renderer h4,:host ::ng-deep .fs-markdown-renderer h5,:host ::ng-deep .fs-markdown-renderer h6{margin:16px 0 8px}:host ::ng-deep .fs-markdown-renderer h1:first-child,:host ::ng-deep .fs-markdown-renderer h2:first-child,:host ::ng-deep .fs-markdown-renderer h3:first-child{margin-top:0}:host ::ng-deep .fs-markdown-renderer p{margin:8px 0}:host ::ng-deep .fs-markdown-renderer code{font-family:monospace;background:#eaeaea;padding:2px 4px;border-radius:3px}:host ::ng-deep .fs-markdown-renderer pre{background:#2e3440;color:#d8dee9;padding:12px;border-radius:6px;overflow-x:auto}:host ::ng-deep .fs-markdown-renderer pre code{background:none;padding:0;color:inherit}:host ::ng-deep .fs-markdown-renderer blockquote{border-left:3px solid #ccc;margin:8px 0;padding:6px 16px;color:#6b6b6b;background:#f9f9f9}:host ::ng-deep .fs-markdown-renderer table{border-collapse:collapse;width:100%;margin:8px 0}:host ::ng-deep .fs-markdown-renderer table th,:host ::ng-deep .fs-markdown-renderer table td{padding:6px 12px;border:1px solid #ddd}:host ::ng-deep .fs-markdown-renderer table th{background:#ececec;text-align:left}:host ::ng-deep .fs-markdown-renderer ul,:host ::ng-deep .fs-markdown-renderer ol{padding-left:24px;margin:8px 0}:host ::ng-deep .fs-markdown-renderer a{color:#5e81ac;text-decoration:underline}:host ::ng-deep .fs-markdown-renderer img{max-width:100%}:host ::ng-deep .fs-markdown-renderer del{text-decoration:line-through}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
38
+ }
39
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: FsMarkdownRendererComponent, decorators: [{
40
+ type: Component,
41
+ args: [{ selector: 'fs-markdown-renderer', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, template: "<div class=\"fs-markdown-renderer\" [innerHtml]=\"renderedHtml\"></div>\n", styles: [":host{display:block}:host ::ng-deep .fs-markdown-renderer{word-break:break-word}:host ::ng-deep .fs-markdown-renderer h1,:host ::ng-deep .fs-markdown-renderer h2,:host ::ng-deep .fs-markdown-renderer h3,:host ::ng-deep .fs-markdown-renderer h4,:host ::ng-deep .fs-markdown-renderer h5,:host ::ng-deep .fs-markdown-renderer h6{margin:16px 0 8px}:host ::ng-deep .fs-markdown-renderer h1:first-child,:host ::ng-deep .fs-markdown-renderer h2:first-child,:host ::ng-deep .fs-markdown-renderer h3:first-child{margin-top:0}:host ::ng-deep .fs-markdown-renderer p{margin:8px 0}:host ::ng-deep .fs-markdown-renderer code{font-family:monospace;background:#eaeaea;padding:2px 4px;border-radius:3px}:host ::ng-deep .fs-markdown-renderer pre{background:#2e3440;color:#d8dee9;padding:12px;border-radius:6px;overflow-x:auto}:host ::ng-deep .fs-markdown-renderer pre code{background:none;padding:0;color:inherit}:host ::ng-deep .fs-markdown-renderer blockquote{border-left:3px solid #ccc;margin:8px 0;padding:6px 16px;color:#6b6b6b;background:#f9f9f9}:host ::ng-deep .fs-markdown-renderer table{border-collapse:collapse;width:100%;margin:8px 0}:host ::ng-deep .fs-markdown-renderer table th,:host ::ng-deep .fs-markdown-renderer table td{padding:6px 12px;border:1px solid #ddd}:host ::ng-deep .fs-markdown-renderer table th{background:#ececec;text-align:left}:host ::ng-deep .fs-markdown-renderer ul,:host ::ng-deep .fs-markdown-renderer ol{padding-left:24px;margin:8px 0}:host ::ng-deep .fs-markdown-renderer a{color:#5e81ac;text-decoration:underline}:host ::ng-deep .fs-markdown-renderer img{max-width:100%}:host ::ng-deep .fs-markdown-renderer del{text-decoration:line-through}\n"] }]
42
+ }], propDecorators: { setMarkdown: [{
43
+ type: Input,
44
+ args: ['markdown']
45
+ }] } });
46
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFya2Rvd24tcmVuZGVyZXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9tb2R1bGVzL21hcmtkb3duLXJlbmRlcmVyL2NvbXBvbmVudHMvbWFya2Rvd24tcmVuZGVyZXIvbWFya2Rvd24tcmVuZGVyZXIuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9tb2R1bGVzL21hcmtkb3duLXJlbmRlcmVyL2NvbXBvbmVudHMvbWFya2Rvd24tcmVuZGVyZXIvbWFya2Rvd24tcmVuZGVyZXIuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLHVCQUF1QixFQUFFLGlCQUFpQixFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3JHLE9BQU8sRUFBRSxZQUFZLEVBQVksTUFBTSwyQkFBMkIsQ0FBQzs7QUFVbkUsTUFBTSxPQUFPLDJCQUEyQjtJQUM5QixVQUFVLEdBQUcsTUFBTSxDQUFDLFlBQVksQ0FBQyxDQUFDO0lBQ2xDLE1BQU0sR0FBRyxNQUFNLENBQUMsaUJBQWlCLENBQUMsQ0FBQztJQUUzQyxJQUE4QixXQUFXLENBQUMsUUFBZ0I7UUFDeEQsSUFBSSxDQUFDLFlBQVksR0FBRyxRQUFRLElBQUksRUFBRSxDQUFDO1FBQ25DLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztJQUN6QixDQUFDO0lBRU0sWUFBWSxDQUFXO0lBRXRCLFlBQVksR0FBRyxFQUFFLENBQUM7SUFFbEIsZUFBZTtRQUNyQixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUNyRCxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsdUJBQXVCLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDbEUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUM3QixDQUFDO0lBRU8sZUFBZSxDQUFDLFFBQWdCO1FBQ3RDLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztZQUNkLE9BQU8sRUFBRSxDQUFDO1FBQ1osQ0FBQztRQUVELElBQUksSUFBSSxHQUFHLFFBQVEsQ0FBQztRQUVwQixJQUFJLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxjQUFjLEVBQUUsYUFBYSxDQUFDLENBQUM7UUFDbkQsSUFBSSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsYUFBYSxFQUFFLGFBQWEsQ0FBQyxDQUFDO1FBQ2xELElBQUksR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLFlBQVksRUFBRSxhQUFhLENBQUMsQ0FBQztRQUVqRCxJQUFJLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxnQkFBZ0IsRUFBRSxxQkFBcUIsQ0FBQyxDQUFDO1FBQzdELElBQUksR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLFlBQVksRUFBRSxhQUFhLENBQUMsQ0FBQztRQUNqRCxJQUFJLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxZQUFZLEVBQUUsZUFBZSxDQUFDLENBQUM7UUFDbkQsSUFBSSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsWUFBWSxFQUFFLGlCQUFpQixDQUFDLENBQUM7UUFFckQsSUFBSSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsMEJBQTBCLEVBQUUsZ0RBQWdELENBQUMsQ0FBQztRQUVsRyxJQUFJLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxhQUFhLEVBQUUsNkJBQTZCLENBQUMsQ0FBQztRQUVsRSxJQUFJLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQywwQkFBMEIsRUFBRSxxQkFBcUIsQ0FBQyxDQUFDO1FBRXZFLElBQUksR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxNQUFNLENBQUMsQ0FBQztRQUVuQyxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7dUdBNUNVLDJCQUEyQjsyRkFBM0IsMkJBQTJCLHNJQ1h4QywyRUFDQTs7MkZEVWEsMkJBQTJCO2tCQVB2QyxTQUFTOytCQUNFLHNCQUFzQixtQkFHZix1QkFBdUIsQ0FBQyxNQUFNLGNBQ25DLElBQUk7OEJBTWMsV0FBVztzQkFBeEMsS0FBSzt1QkFBQyxVQUFVIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENoYW5nZURldGVjdG9yUmVmLCBDb21wb25lbnQsIElucHV0LCBpbmplY3QgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IERvbVNhbml0aXplciwgU2FmZUh0bWwgfSBmcm9tICdAYW5ndWxhci9wbGF0Zm9ybS1icm93c2VyJztcblxuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdmcy1tYXJrZG93bi1yZW5kZXJlcicsXG4gIHRlbXBsYXRlVXJsOiAnbWFya2Rvd24tcmVuZGVyZXIuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnbWFya2Rvd24tcmVuZGVyZXIuY29tcG9uZW50LnNjc3MnXSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG59KVxuZXhwb3J0IGNsYXNzIEZzTWFya2Rvd25SZW5kZXJlckNvbXBvbmVudCB7XG4gIHByaXZhdGUgX3Nhbml0aXplciA9IGluamVjdChEb21TYW5pdGl6ZXIpO1xuICBwcml2YXRlIF9jZFJlZiA9IGluamVjdChDaGFuZ2VEZXRlY3RvclJlZik7XG5cbiAgQElucHV0KCdtYXJrZG93bicpIHB1YmxpYyBzZXQgc2V0TWFya2Rvd24obWFya2Rvd246IHN0cmluZykge1xuICAgIHRoaXMuX3Jhd01hcmtkb3duID0gbWFya2Rvd24gfHwgJyc7XG4gICAgdGhpcy5fcmVuZGVyTWFya2Rvd24oKTtcbiAgfVxuXG4gIHB1YmxpYyByZW5kZXJlZEh0bWw6IFNhZmVIdG1sO1xuXG4gIHByaXZhdGUgX3Jhd01hcmtkb3duID0gJyc7XG5cbiAgcHJpdmF0ZSBfcmVuZGVyTWFya2Rvd24oKTogdm9pZCB7XG4gICAgY29uc3QgaHRtbCA9IHRoaXMuX21hcmtkb3duVG9IdG1sKHRoaXMuX3Jhd01hcmtkb3duKTtcbiAgICB0aGlzLnJlbmRlcmVkSHRtbCA9IHRoaXMuX3Nhbml0aXplci5ieXBhc3NTZWN1cml0eVRydXN0SHRtbChodG1sKTtcbiAgICB0aGlzLl9jZFJlZi5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIHByaXZhdGUgX21hcmtkb3duVG9IdG1sKG1hcmtkb3duOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGlmICghbWFya2Rvd24pIHtcbiAgICAgIHJldHVybiAnJztcbiAgICB9XG5cbiAgICBsZXQgaHRtbCA9IG1hcmtkb3duO1xuXG4gICAgaHRtbCA9IGh0bWwucmVwbGFjZSgvXiMjIyAoLispJC9nbSwgJzxoMz4kMTwvaDM+Jyk7XG4gICAgaHRtbCA9IGh0bWwucmVwbGFjZSgvXiMjICguKykkL2dtLCAnPGgyPiQxPC9oMj4nKTtcbiAgICBodG1sID0gaHRtbC5yZXBsYWNlKC9eIyAoLispJC9nbSwgJzxoMT4kMTwvaDE+Jyk7XG5cbiAgICBodG1sID0gaHRtbC5yZXBsYWNlKC9cXCpcXCooLis/KVxcKlxcKi9nLCAnPHN0cm9uZz4kMTwvc3Ryb25nPicpO1xuICAgIGh0bWwgPSBodG1sLnJlcGxhY2UoL1xcKiguKz8pXFwqL2csICc8ZW0+JDE8L2VtPicpO1xuICAgIGh0bWwgPSBodG1sLnJlcGxhY2UoL35+KC4rPyl+fi9nLCAnPGRlbD4kMTwvZGVsPicpO1xuICAgIGh0bWwgPSBodG1sLnJlcGxhY2UoL2AoW15gXSspYC9nLCAnPGNvZGU+JDE8L2NvZGU+Jyk7XG5cbiAgICBodG1sID0gaHRtbC5yZXBsYWNlKC9gYGAoXFx3KilcXG4oW1xcc1xcU10qPylgYGAvZywgJzxwcmU+PGNvZGUgY2xhc3M9XCJsYW5ndWFnZS0kMVwiPiQyPC9jb2RlPjwvcHJlPicpO1xuXG4gICAgaHRtbCA9IGh0bWwucmVwbGFjZSgvXlxcPiAoLispJC9nbSwgJzxibG9ja3F1b3RlPiQxPC9ibG9ja3F1b3RlPicpO1xuXG4gICAgaHRtbCA9IGh0bWwucmVwbGFjZSgvXFxbKFteXFxdXSspXFxdXFwoKFteKV0rKVxcKS9nLCAnPGEgaHJlZj1cIiQyXCI+JDE8L2E+Jyk7XG5cbiAgICBodG1sID0gaHRtbC5yZXBsYWNlKC9cXG4vZywgJzxicj4nKTtcblxuICAgIHJldHVybiBodG1sO1xuICB9XG59XG4iLCI8ZGl2IGNsYXNzPVwiZnMtbWFya2Rvd24tcmVuZGVyZXJcIiBbaW5uZXJIdG1sXT1cInJlbmRlcmVkSHRtbFwiPjwvZGl2PlxuIl19
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Generated bundle index. Do not edit.
3
+ */
4
+ export * from './public_api';
5
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlyZXN0aXRjaC1tYXJrZG93bi1lZGl0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZmlyZXN0aXRjaC1tYXJrZG93bi1lZGl0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0dBRUc7QUFFSCxjQUFjLGNBQWMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogR2VuZXJhdGVkIGJ1bmRsZSBpbmRleC4gRG8gbm90IGVkaXQuXG4gKi9cblxuZXhwb3J0ICogZnJvbSAnLi9wdWJsaWNfYXBpJztcbiJdfQ==
@@ -0,0 +1,5 @@
1
+ export { FsMarkdownEditorModule } from './app/modules/markdown-editor/fs-markdown-editor.module';
2
+ export { FsMarkdownEditorComponent } from './app/modules/markdown-editor/components/markdown-editor/markdown-editor.component';
3
+ export { FsMarkdownRendererComponent } from './app/modules/markdown-renderer/components/markdown-renderer/markdown-renderer.component';
4
+ export { FS_MARKDOWN_EDITOR_CONFIG } from './app/modules/markdown-editor/injects/config.inject';
5
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHVibGljX2FwaS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9wdWJsaWNfYXBpLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxNQUFNLHlEQUF5RCxDQUFDO0FBRWpHLE9BQU8sRUFBRSx5QkFBeUIsRUFBRSxNQUFNLG9GQUFvRixDQUFDO0FBQy9ILE9BQU8sRUFBRSwyQkFBMkIsRUFBRSxNQUFNLDBGQUEwRixDQUFDO0FBRXZJLE9BQU8sRUFBRSx5QkFBeUIsRUFBRSxNQUFNLHFEQUFxRCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IHsgRnNNYXJrZG93bkVkaXRvck1vZHVsZSB9IGZyb20gJy4vYXBwL21vZHVsZXMvbWFya2Rvd24tZWRpdG9yL2ZzLW1hcmtkb3duLWVkaXRvci5tb2R1bGUnO1xuXG5leHBvcnQgeyBGc01hcmtkb3duRWRpdG9yQ29tcG9uZW50IH0gZnJvbSAnLi9hcHAvbW9kdWxlcy9tYXJrZG93bi1lZGl0b3IvY29tcG9uZW50cy9tYXJrZG93bi1lZGl0b3IvbWFya2Rvd24tZWRpdG9yLmNvbXBvbmVudCc7XG5leHBvcnQgeyBGc01hcmtkb3duUmVuZGVyZXJDb21wb25lbnQgfSBmcm9tICcuL2FwcC9tb2R1bGVzL21hcmtkb3duLXJlbmRlcmVyL2NvbXBvbmVudHMvbWFya2Rvd24tcmVuZGVyZXIvbWFya2Rvd24tcmVuZGVyZXIuY29tcG9uZW50JztcblxuZXhwb3J0IHsgRlNfTUFSS0RPV05fRURJVE9SX0NPTkZJRyB9IGZyb20gJy4vYXBwL21vZHVsZXMvbWFya2Rvd24tZWRpdG9yL2luamVjdHMvY29uZmlnLmluamVjdCc7XG5cbmV4cG9ydCB7IEZzTWFya2Rvd25FZGl0b3JDb25maWcgfSBmcm9tICcuL2FwcC9tb2R1bGVzL21hcmtkb3duLWVkaXRvci9pbnRlcmZhY2VzL21hcmtkb3duLWVkaXRvci1jb25maWcnO1xuIl19
@@ -0,0 +1,405 @@
1
+ import { DOCUMENT, CommonModule } from '@angular/common';
2
+ import * as i0 from '@angular/core';
3
+ import { InjectionToken, inject, Injectable, ChangeDetectorRef, NgZone, forwardRef, Optional, Component, ChangeDetectionStrategy, ViewChild, HostBinding, Input, NgModule } from '@angular/core';
4
+ import * as i1 from '@firestitch/label';
5
+ import { FsLabelModule } from '@firestitch/label';
6
+ import { NG_VALUE_ACCESSOR, NG_VALIDATORS, ControlContainer, NgForm } from '@angular/forms';
7
+ import { guid } from '@firestitch/common';
8
+ import { BehaviorSubject, Subject } from 'rxjs';
9
+ import { shareReplay, takeUntil } from 'rxjs/operators';
10
+ import { DomSanitizer } from '@angular/platform-browser';
11
+
12
+ const FS_MARKDOWN_EDITOR_DEFAULT_CONFIG = new InjectionToken('fs-markdown-editor.default-config');
13
+ const FS_MARKDOWN_EDITOR_CONFIG = new InjectionToken('fs-markdown-editor.config');
14
+
15
+ const THEME_BASE = '/assets/milkdown/theme/';
16
+ const STYLESHEETS = [
17
+ `${THEME_BASE}common/block-edit.css`,
18
+ `${THEME_BASE}common/code-mirror.css`,
19
+ `${THEME_BASE}common/cursor.css`,
20
+ `${THEME_BASE}common/image-block.css`,
21
+ `${THEME_BASE}common/latex.css`,
22
+ `${THEME_BASE}common/link-tooltip.css`,
23
+ `${THEME_BASE}common/list-item.css`,
24
+ `${THEME_BASE}common/placeholder.css`,
25
+ `${THEME_BASE}common/toolbar.css`,
26
+ `${THEME_BASE}common/table.css`,
27
+ ];
28
+ class FsMilkdownLoaderService {
29
+ _document = inject(DOCUMENT);
30
+ _loaded = new BehaviorSubject(false);
31
+ _stylesLoaded = false;
32
+ _loaded$ = this._loaded.asObservable()
33
+ .pipe(shareReplay(1));
34
+ get loaded$() {
35
+ return this._loaded$;
36
+ }
37
+ loadStyles() {
38
+ if (this._stylesLoaded) {
39
+ this._loaded.next(true);
40
+ return;
41
+ }
42
+ let remaining = STYLESHEETS.length;
43
+ if (remaining === 0) {
44
+ this._stylesLoaded = true;
45
+ this._loaded.next(true);
46
+ return;
47
+ }
48
+ STYLESHEETS.forEach((href) => {
49
+ const existing = this._document.querySelector(`link[href="${href}"]`);
50
+ if (existing) {
51
+ remaining--;
52
+ if (remaining === 0) {
53
+ this._stylesLoaded = true;
54
+ this._loaded.next(true);
55
+ }
56
+ return;
57
+ }
58
+ const link = this._document.createElement('link');
59
+ link.rel = 'stylesheet';
60
+ link.href = href;
61
+ link.onload = () => {
62
+ remaining--;
63
+ if (remaining === 0) {
64
+ this._stylesLoaded = true;
65
+ this._loaded.next(true);
66
+ }
67
+ };
68
+ link.onerror = () => {
69
+ remaining--;
70
+ if (remaining === 0) {
71
+ this._stylesLoaded = true;
72
+ this._loaded.next(true);
73
+ }
74
+ };
75
+ this._document.head.appendChild(link);
76
+ });
77
+ }
78
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: FsMilkdownLoaderService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
79
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: FsMilkdownLoaderService, providedIn: 'root' });
80
+ }
81
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: FsMilkdownLoaderService, decorators: [{
82
+ type: Injectable,
83
+ args: [{
84
+ providedIn: 'root',
85
+ }]
86
+ }] });
87
+
88
+ class FsMarkdownEditorComponent {
89
+ _defaultConfig = inject(FS_MARKDOWN_EDITOR_CONFIG, { optional: true });
90
+ _cdRef = inject(ChangeDetectorRef);
91
+ _loader = inject(FsMilkdownLoaderService);
92
+ _zone = inject(NgZone);
93
+ editorRef;
94
+ classFocused = false;
95
+ config = {};
96
+ disabled = false;
97
+ initialized = false;
98
+ containerID = `fs-markdown-editor-${guid('xxx')}`;
99
+ onTouched;
100
+ onChange;
101
+ _crepe;
102
+ _editorViewCtx;
103
+ _parserCtx;
104
+ _markdown = '';
105
+ _editorReady = false;
106
+ _destroy$ = new Subject();
107
+ get markdown() {
108
+ return this._markdown;
109
+ }
110
+ ngOnInit() {
111
+ this.config = { ...(this._defaultConfig || {}), ...(this.config || {}) };
112
+ this._loader.loadStyles();
113
+ }
114
+ ngAfterViewInit() {
115
+ this._loader.loaded$
116
+ .pipe(takeUntil(this._destroy$))
117
+ .subscribe((loaded) => {
118
+ if (loaded) {
119
+ this._initEditor();
120
+ }
121
+ });
122
+ }
123
+ writeValue(markdown) {
124
+ this._markdown = markdown || '';
125
+ if (this._editorReady) {
126
+ this._setEditorContent(this._markdown);
127
+ }
128
+ this._cdRef.markForCheck();
129
+ }
130
+ registerOnChange(fn) {
131
+ this.onChange = fn;
132
+ }
133
+ registerOnTouched(fn) {
134
+ this.onTouched = fn;
135
+ }
136
+ setDisabledState(isDisabled) {
137
+ this.disabled = isDisabled;
138
+ }
139
+ validate() {
140
+ const err = {};
141
+ if (this.config.maxLength && this._markdown) {
142
+ const length = this._markdown.length;
143
+ if (length > this.config.maxLength) {
144
+ err.maxLengthError = `Must be ${this.config.maxLength} characters or fewer. You entered ${length} characters.`;
145
+ }
146
+ }
147
+ return Object.keys(err).length ? err : null;
148
+ }
149
+ clear() {
150
+ this.writeValue('');
151
+ if (this.onChange) {
152
+ this.onChange('');
153
+ }
154
+ }
155
+ setMarkdown(markdown) {
156
+ this.writeValue(markdown);
157
+ }
158
+ getMarkdown() {
159
+ if (!this._crepe) {
160
+ return this._markdown;
161
+ }
162
+ return this._crepe.getMarkdown();
163
+ }
164
+ focus() {
165
+ if (this._crepe && this._editorViewCtx) {
166
+ this._crepe.editor.action((ctx) => {
167
+ const view = ctx.get(this._editorViewCtx);
168
+ view.focus();
169
+ });
170
+ }
171
+ }
172
+ disable() {
173
+ this.disabled = true;
174
+ this._cdRef.markForCheck();
175
+ }
176
+ destroy() {
177
+ if (this._crepe) {
178
+ this._crepe.destroy();
179
+ this._crepe = null;
180
+ }
181
+ this._editorReady = false;
182
+ this.initialized = false;
183
+ this._cdRef.markForCheck();
184
+ }
185
+ ngOnDestroy() {
186
+ this._destroy$.next();
187
+ this._destroy$.complete();
188
+ this.destroy();
189
+ }
190
+ _initEditor() {
191
+ if (this._crepe || !this.editorRef) {
192
+ return;
193
+ }
194
+ this._zone.runOutsideAngular(async () => {
195
+ const [{ Crepe }, { editorViewCtx, parserCtx }] = await Promise.all([
196
+ import('@milkdown/crepe'),
197
+ import('@milkdown/kit/core'),
198
+ ]);
199
+ this._editorViewCtx = editorViewCtx;
200
+ this._parserCtx = parserCtx;
201
+ this._crepe = new Crepe({
202
+ root: this.editorRef.nativeElement,
203
+ defaultValue: this._markdown,
204
+ features: {},
205
+ featureConfigs: {
206
+ [Crepe.Feature.Placeholder]: {
207
+ text: this.config.placeholder || 'Start typing...',
208
+ },
209
+ },
210
+ });
211
+ this._crepe.on((listener) => {
212
+ listener.markdownUpdated((_ctx, markdown, prevMarkdown) => {
213
+ if (markdown !== prevMarkdown) {
214
+ this._zone.run(() => {
215
+ this._markdown = markdown;
216
+ if (this.onChange) {
217
+ this.onChange(markdown);
218
+ }
219
+ if (this.onTouched) {
220
+ this.onTouched();
221
+ }
222
+ this._cdRef.markForCheck();
223
+ });
224
+ }
225
+ });
226
+ });
227
+ this._crepe.create().then(() => {
228
+ this._zone.run(() => {
229
+ this._editorReady = true;
230
+ this.initialized = true;
231
+ if (this._markdown) {
232
+ this._setEditorContent(this._markdown);
233
+ }
234
+ this._cdRef.markForCheck();
235
+ if (this.config.autofocus) {
236
+ this.focus();
237
+ }
238
+ if (this.config.initialized) {
239
+ this.config.initialized();
240
+ }
241
+ });
242
+ });
243
+ });
244
+ }
245
+ _setEditorContent(markdown) {
246
+ this._crepe.editor.action((ctx) => {
247
+ const view = ctx.get(this._editorViewCtx);
248
+ const parser = ctx.get(this._parserCtx);
249
+ const doc = parser(markdown);
250
+ if (doc) {
251
+ const tr = view.state.tr.replaceWith(0, view.state.doc.content.size, doc.content);
252
+ view.dispatch(tr);
253
+ }
254
+ });
255
+ }
256
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: FsMarkdownEditorComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
257
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.7", type: FsMarkdownEditorComponent, isStandalone: true, selector: "fs-markdown-editor", inputs: { config: "config", disabled: "disabled" }, host: { properties: { "class.focused": "this.classFocused", "class.disabled": "this.disabled", "class.initialized": "this.initialized" } }, providers: [
258
+ {
259
+ provide: NG_VALUE_ACCESSOR,
260
+ useExisting: forwardRef(() => FsMarkdownEditorComponent),
261
+ multi: true,
262
+ },
263
+ {
264
+ provide: NG_VALIDATORS,
265
+ useExisting: forwardRef(() => FsMarkdownEditorComponent),
266
+ multi: true,
267
+ },
268
+ ], viewQueries: [{ propertyName: "editorRef", first: true, predicate: ["editorRef"], descendants: true }], ngImport: i0, template: "<fs-label-field\n [appearance]=\"'outline'\"\n [hoverable]=\"true\"\n [showOutline]=\"initialized\"\n [disabled]=\"disabled\"\n [padless]=\"config.padless\"\n [class.initialized]=\"initialized\">\n @if (config.label) {\n <fs-label>\n {{ config.label }}\n </fs-label>\n }\n <div\n class=\"markdown-editor-container\"\n [id]=\"containerID\">\n <div #editorRef></div>\n </div>\n <fs-label-message>\n <div class=\"fs-form-message\">\n <div class=\"fs-form-hint\">\n {{ config.hint }}\n </div>\n </div>\n </fs-label-message>\n</fs-label-field>\n", styles: [":host{position:relative;display:block}:host ::ng-deep fs-label-field.initialized.appearance-outline .field-wrap{padding-top:6px;padding-bottom:4px}:host ::ng-deep .markdown-editor-container{position:relative;min-height:100px}:host ::ng-deep .milkdown{--crepe-color-background: transparent;--crepe-color-on-background: #1b1c1d;--crepe-color-surface: #f8f9ff;--crepe-color-surface-low: #f2f3fa;--crepe-color-on-surface: #191c20;--crepe-color-on-surface-variant: #43474e;--crepe-color-outline: #73777f;--crepe-color-primary: #37618e;--crepe-color-secondary: #d7e3f8;--crepe-color-on-secondary: #101c2b;--crepe-color-inverse: #2e3135;--crepe-color-on-inverse: #eff0f7;--crepe-color-inline-code: #ba1a1a;--crepe-color-error: #ba1a1a;--crepe-color-hover: #eceef4;--crepe-color-selected: #e1e2e8;--crepe-color-inline-area: #d8dae0;--crepe-font-title: Rubik, Cambria, \"Times New Roman\", Times, serif;--crepe-font-default: Inter, Arial, Helvetica, sans-serif;--crepe-font-code: \"JetBrains Mono\", Menlo, Monaco, \"Courier New\", Courier, monospace;--crepe-shadow-1: 0px 1px 3px 1px rgba(0, 0, 0, .15), 0px 1px 2px 0px rgba(0, 0, 0, .3);--crepe-shadow-2: 0px 2px 6px 2px rgba(0, 0, 0, .15), 0px 1px 2px 0px rgba(0, 0, 0, .3)}:host ::ng-deep .milkdown{position:relative;color:var(--crepe-color-on-background);background:var(--crepe-color-background)}:host ::ng-deep .milkdown *{margin:0;padding:0;box-sizing:border-box}:host ::ng-deep .milkdown button,:host ::ng-deep .milkdown input{border:none;background:none;box-shadow:none}:host ::ng-deep .milkdown button:focus,:host ::ng-deep .milkdown input:focus{outline:none}:host ::ng-deep .milkdown :focus-visible{outline:none}:host ::ng-deep .milkdown .milkdown-icon{display:inline-flex;align-items:center;justify-content:center}:host ::ng-deep .milkdown .ProseMirror-focused{outline:none}:host ::ng-deep .milkdown .ProseMirror{padding:10px 0}:host ::ng-deep .milkdown .ProseMirror *::selection{background:var(--crepe-color-selected)}:host ::ng-deep .milkdown .ProseMirror li.ProseMirror-selectednode{background:var(--crepe-color-selected);outline:none}:host ::ng-deep .milkdown .ProseMirror li.ProseMirror-selectednode::selection,:host ::ng-deep .milkdown .ProseMirror li.ProseMirror-selectednode ::selection{background:transparent}:host ::ng-deep .milkdown .ProseMirror li.ProseMirror-selectednode:after{all:unset}:host ::ng-deep .milkdown .ProseMirror .ProseMirror-selectednode{background:color-mix(in srgb,var(--crepe-color-selected),transparent 60%);outline:none}:host ::ng-deep .milkdown .ProseMirror .ProseMirror-selectednode::selection,:host ::ng-deep .milkdown .ProseMirror .ProseMirror-selectednode ::selection{background:transparent}:host ::ng-deep .milkdown .ProseMirror[data-dragging=true]::selection,:host ::ng-deep .milkdown .ProseMirror[data-dragging=true] *::selection,:host ::ng-deep .milkdown .ProseMirror[data-dragging=true] .ProseMirror-selectednode{background:transparent}:host ::ng-deep .milkdown .ProseMirror[data-dragging=true] input::selection{background:var(--crepe-color-selected)}:host ::ng-deep .milkdown .ProseMirror img{vertical-align:bottom;max-width:100%}:host ::ng-deep .milkdown .ProseMirror img.ProseMirror-selectednode{background:none;outline:2px solid var(--crepe-color-primary)}:host ::ng-deep .milkdown .ProseMirror h1,:host ::ng-deep .milkdown .ProseMirror h2,:host ::ng-deep .milkdown .ProseMirror h3,:host ::ng-deep .milkdown .ProseMirror h4,:host ::ng-deep .milkdown .ProseMirror h5,:host ::ng-deep .milkdown .ProseMirror h6{font-weight:400;padding:2px 0}:host ::ng-deep .milkdown .ProseMirror h1{font-size:42px;line-height:50px;margin-top:32px}:host ::ng-deep .milkdown .ProseMirror h2{font-size:36px;line-height:44px;margin-top:28px}:host ::ng-deep .milkdown .ProseMirror h3{font-size:32px;line-height:40px;margin-top:24px}:host ::ng-deep .milkdown .ProseMirror h4{font-size:28px;line-height:36px;margin-top:20px}:host ::ng-deep .milkdown .ProseMirror h5{font-size:24px;line-height:32px;margin-top:16px}:host ::ng-deep .milkdown .ProseMirror h6{font-size:18px;font-weight:700;line-height:28px;margin-top:16px}:host ::ng-deep .milkdown .ProseMirror p{font-size:16px;line-height:24px;padding:4px 0}:host ::ng-deep .milkdown .ProseMirror code{color:var(--crepe-color-inline-code);background:color-mix(in srgb,var(--crepe-color-inline-area),transparent 40%);padding:0 2px;border-radius:4px;font-size:87.5%;display:inline-block;line-height:1.4286}:host ::ng-deep .milkdown .ProseMirror a{color:var(--crepe-color-primary);text-decoration:underline}:host ::ng-deep .milkdown .ProseMirror pre{background:color-mix(in srgb,var(--crepe-color-inline-area),transparent 40%);padding:10px;border-radius:4px}:host ::ng-deep .milkdown .ProseMirror pre code{padding:0;background:transparent}:host ::ng-deep .milkdown .ProseMirror blockquote{position:relative;padding-left:40px;padding-top:0;padding-bottom:0;box-sizing:content-box;margin:4px 0}:host ::ng-deep .milkdown .ProseMirror blockquote:before{content:\"\";width:4px;left:0;top:4px;bottom:4px;position:absolute;background:var(--crepe-color-selected);border-radius:100px}:host ::ng-deep .milkdown .ProseMirror blockquote hr{margin-bottom:16px}:host ::ng-deep .milkdown .ProseMirror hr{border:none;background-color:color-mix(in srgb,var(--crepe-color-outline),transparent 80%);background-clip:content-box;padding:6px 0;height:13px;position:relative}:host ::ng-deep .milkdown .ProseMirror hr.ProseMirror-selectednode{outline:none;background-color:color-mix(in srgb,var(--crepe-color-outline),transparent 20%);background-clip:content-box}:host ::ng-deep .milkdown .ProseMirror hr.ProseMirror-selectednode:before{content:\"\";position:absolute;inset:0;background-color:color-mix(in srgb,var(--crepe-color-outline),transparent 80%);pointer-events:none}:host ::ng-deep .milkdown .ProseMirror ul,:host ::ng-deep .milkdown .ProseMirror ol{padding:0}:host ::ng-deep .milkdown .milkdown-code-block{--crepe-color-background: #1b1c1d;--crepe-color-on-background: #f8f9ff;--crepe-color-surface: #111418;--crepe-color-surface-low: #191c20;--crepe-color-on-surface: #e1e2e8;--crepe-color-on-surface-variant: #c3c6cf;--crepe-color-outline: #8d9199;--crepe-color-primary: #a1c9fd;--crepe-color-secondary: #3c4858;--crepe-color-on-secondary: #d7e3f8;--crepe-color-inverse: #e1e2e8;--crepe-color-on-inverse: #2e3135;--crepe-color-inline-code: #ffb4ab;--crepe-color-error: #ffb4ab;--crepe-color-hover: #1d2024;--crepe-color-selected: #32353a;--crepe-color-inline-area: #111418;--crepe-shadow-1: 0px 1px 2px 0px rgba(255, 255, 255, .3), 0px 1px 3px 1px rgba(255, 255, 255, .15);--crepe-shadow-2: 0px 1px 2px 0px rgba(255, 255, 255, .3), 0px 2px 6px 2px rgba(255, 255, 255, .15);background:var(--crepe-color-surface);border-radius:6px}:host.disabled ::ng-deep .markdown-editor-container{opacity:.5;pointer-events:none}\n"], dependencies: [{ kind: "ngmodule", type: FsLabelModule }, { kind: "component", type: i1.FsLabelComponent, selector: "fs-label" }, { kind: "component", type: i1.FsLabelFieldComponent, selector: "fs-label-field", inputs: ["appearance", "showOutline", "disabled", "focused", "hoverable", "padless"] }, { kind: "component", type: i1.FsLabelMessageComponent, selector: "fs-label-message" }], viewProviders: [
269
+ {
270
+ provide: ControlContainer,
271
+ deps: [[Optional, NgForm]],
272
+ useFactory: (ngForm) => ngForm,
273
+ },
274
+ ], changeDetection: i0.ChangeDetectionStrategy.OnPush });
275
+ }
276
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: FsMarkdownEditorComponent, decorators: [{
277
+ type: Component,
278
+ args: [{ selector: 'fs-markdown-editor', providers: [
279
+ {
280
+ provide: NG_VALUE_ACCESSOR,
281
+ useExisting: forwardRef(() => FsMarkdownEditorComponent),
282
+ multi: true,
283
+ },
284
+ {
285
+ provide: NG_VALIDATORS,
286
+ useExisting: forwardRef(() => FsMarkdownEditorComponent),
287
+ multi: true,
288
+ },
289
+ ], changeDetection: ChangeDetectionStrategy.OnPush, viewProviders: [
290
+ {
291
+ provide: ControlContainer,
292
+ deps: [[Optional, NgForm]],
293
+ useFactory: (ngForm) => ngForm,
294
+ },
295
+ ], standalone: true, imports: [
296
+ FsLabelModule,
297
+ ], template: "<fs-label-field\n [appearance]=\"'outline'\"\n [hoverable]=\"true\"\n [showOutline]=\"initialized\"\n [disabled]=\"disabled\"\n [padless]=\"config.padless\"\n [class.initialized]=\"initialized\">\n @if (config.label) {\n <fs-label>\n {{ config.label }}\n </fs-label>\n }\n <div\n class=\"markdown-editor-container\"\n [id]=\"containerID\">\n <div #editorRef></div>\n </div>\n <fs-label-message>\n <div class=\"fs-form-message\">\n <div class=\"fs-form-hint\">\n {{ config.hint }}\n </div>\n </div>\n </fs-label-message>\n</fs-label-field>\n", styles: [":host{position:relative;display:block}:host ::ng-deep fs-label-field.initialized.appearance-outline .field-wrap{padding-top:6px;padding-bottom:4px}:host ::ng-deep .markdown-editor-container{position:relative;min-height:100px}:host ::ng-deep .milkdown{--crepe-color-background: transparent;--crepe-color-on-background: #1b1c1d;--crepe-color-surface: #f8f9ff;--crepe-color-surface-low: #f2f3fa;--crepe-color-on-surface: #191c20;--crepe-color-on-surface-variant: #43474e;--crepe-color-outline: #73777f;--crepe-color-primary: #37618e;--crepe-color-secondary: #d7e3f8;--crepe-color-on-secondary: #101c2b;--crepe-color-inverse: #2e3135;--crepe-color-on-inverse: #eff0f7;--crepe-color-inline-code: #ba1a1a;--crepe-color-error: #ba1a1a;--crepe-color-hover: #eceef4;--crepe-color-selected: #e1e2e8;--crepe-color-inline-area: #d8dae0;--crepe-font-title: Rubik, Cambria, \"Times New Roman\", Times, serif;--crepe-font-default: Inter, Arial, Helvetica, sans-serif;--crepe-font-code: \"JetBrains Mono\", Menlo, Monaco, \"Courier New\", Courier, monospace;--crepe-shadow-1: 0px 1px 3px 1px rgba(0, 0, 0, .15), 0px 1px 2px 0px rgba(0, 0, 0, .3);--crepe-shadow-2: 0px 2px 6px 2px rgba(0, 0, 0, .15), 0px 1px 2px 0px rgba(0, 0, 0, .3)}:host ::ng-deep .milkdown{position:relative;color:var(--crepe-color-on-background);background:var(--crepe-color-background)}:host ::ng-deep .milkdown *{margin:0;padding:0;box-sizing:border-box}:host ::ng-deep .milkdown button,:host ::ng-deep .milkdown input{border:none;background:none;box-shadow:none}:host ::ng-deep .milkdown button:focus,:host ::ng-deep .milkdown input:focus{outline:none}:host ::ng-deep .milkdown :focus-visible{outline:none}:host ::ng-deep .milkdown .milkdown-icon{display:inline-flex;align-items:center;justify-content:center}:host ::ng-deep .milkdown .ProseMirror-focused{outline:none}:host ::ng-deep .milkdown .ProseMirror{padding:10px 0}:host ::ng-deep .milkdown .ProseMirror *::selection{background:var(--crepe-color-selected)}:host ::ng-deep .milkdown .ProseMirror li.ProseMirror-selectednode{background:var(--crepe-color-selected);outline:none}:host ::ng-deep .milkdown .ProseMirror li.ProseMirror-selectednode::selection,:host ::ng-deep .milkdown .ProseMirror li.ProseMirror-selectednode ::selection{background:transparent}:host ::ng-deep .milkdown .ProseMirror li.ProseMirror-selectednode:after{all:unset}:host ::ng-deep .milkdown .ProseMirror .ProseMirror-selectednode{background:color-mix(in srgb,var(--crepe-color-selected),transparent 60%);outline:none}:host ::ng-deep .milkdown .ProseMirror .ProseMirror-selectednode::selection,:host ::ng-deep .milkdown .ProseMirror .ProseMirror-selectednode ::selection{background:transparent}:host ::ng-deep .milkdown .ProseMirror[data-dragging=true]::selection,:host ::ng-deep .milkdown .ProseMirror[data-dragging=true] *::selection,:host ::ng-deep .milkdown .ProseMirror[data-dragging=true] .ProseMirror-selectednode{background:transparent}:host ::ng-deep .milkdown .ProseMirror[data-dragging=true] input::selection{background:var(--crepe-color-selected)}:host ::ng-deep .milkdown .ProseMirror img{vertical-align:bottom;max-width:100%}:host ::ng-deep .milkdown .ProseMirror img.ProseMirror-selectednode{background:none;outline:2px solid var(--crepe-color-primary)}:host ::ng-deep .milkdown .ProseMirror h1,:host ::ng-deep .milkdown .ProseMirror h2,:host ::ng-deep .milkdown .ProseMirror h3,:host ::ng-deep .milkdown .ProseMirror h4,:host ::ng-deep .milkdown .ProseMirror h5,:host ::ng-deep .milkdown .ProseMirror h6{font-weight:400;padding:2px 0}:host ::ng-deep .milkdown .ProseMirror h1{font-size:42px;line-height:50px;margin-top:32px}:host ::ng-deep .milkdown .ProseMirror h2{font-size:36px;line-height:44px;margin-top:28px}:host ::ng-deep .milkdown .ProseMirror h3{font-size:32px;line-height:40px;margin-top:24px}:host ::ng-deep .milkdown .ProseMirror h4{font-size:28px;line-height:36px;margin-top:20px}:host ::ng-deep .milkdown .ProseMirror h5{font-size:24px;line-height:32px;margin-top:16px}:host ::ng-deep .milkdown .ProseMirror h6{font-size:18px;font-weight:700;line-height:28px;margin-top:16px}:host ::ng-deep .milkdown .ProseMirror p{font-size:16px;line-height:24px;padding:4px 0}:host ::ng-deep .milkdown .ProseMirror code{color:var(--crepe-color-inline-code);background:color-mix(in srgb,var(--crepe-color-inline-area),transparent 40%);padding:0 2px;border-radius:4px;font-size:87.5%;display:inline-block;line-height:1.4286}:host ::ng-deep .milkdown .ProseMirror a{color:var(--crepe-color-primary);text-decoration:underline}:host ::ng-deep .milkdown .ProseMirror pre{background:color-mix(in srgb,var(--crepe-color-inline-area),transparent 40%);padding:10px;border-radius:4px}:host ::ng-deep .milkdown .ProseMirror pre code{padding:0;background:transparent}:host ::ng-deep .milkdown .ProseMirror blockquote{position:relative;padding-left:40px;padding-top:0;padding-bottom:0;box-sizing:content-box;margin:4px 0}:host ::ng-deep .milkdown .ProseMirror blockquote:before{content:\"\";width:4px;left:0;top:4px;bottom:4px;position:absolute;background:var(--crepe-color-selected);border-radius:100px}:host ::ng-deep .milkdown .ProseMirror blockquote hr{margin-bottom:16px}:host ::ng-deep .milkdown .ProseMirror hr{border:none;background-color:color-mix(in srgb,var(--crepe-color-outline),transparent 80%);background-clip:content-box;padding:6px 0;height:13px;position:relative}:host ::ng-deep .milkdown .ProseMirror hr.ProseMirror-selectednode{outline:none;background-color:color-mix(in srgb,var(--crepe-color-outline),transparent 20%);background-clip:content-box}:host ::ng-deep .milkdown .ProseMirror hr.ProseMirror-selectednode:before{content:\"\";position:absolute;inset:0;background-color:color-mix(in srgb,var(--crepe-color-outline),transparent 80%);pointer-events:none}:host ::ng-deep .milkdown .ProseMirror ul,:host ::ng-deep .milkdown .ProseMirror ol{padding:0}:host ::ng-deep .milkdown .milkdown-code-block{--crepe-color-background: #1b1c1d;--crepe-color-on-background: #f8f9ff;--crepe-color-surface: #111418;--crepe-color-surface-low: #191c20;--crepe-color-on-surface: #e1e2e8;--crepe-color-on-surface-variant: #c3c6cf;--crepe-color-outline: #8d9199;--crepe-color-primary: #a1c9fd;--crepe-color-secondary: #3c4858;--crepe-color-on-secondary: #d7e3f8;--crepe-color-inverse: #e1e2e8;--crepe-color-on-inverse: #2e3135;--crepe-color-inline-code: #ffb4ab;--crepe-color-error: #ffb4ab;--crepe-color-hover: #1d2024;--crepe-color-selected: #32353a;--crepe-color-inline-area: #111418;--crepe-shadow-1: 0px 1px 2px 0px rgba(255, 255, 255, .3), 0px 1px 3px 1px rgba(255, 255, 255, .15);--crepe-shadow-2: 0px 1px 2px 0px rgba(255, 255, 255, .3), 0px 2px 6px 2px rgba(255, 255, 255, .15);background:var(--crepe-color-surface);border-radius:6px}:host.disabled ::ng-deep .markdown-editor-container{opacity:.5;pointer-events:none}\n"] }]
298
+ }], propDecorators: { editorRef: [{
299
+ type: ViewChild,
300
+ args: ['editorRef']
301
+ }], classFocused: [{
302
+ type: HostBinding,
303
+ args: ['class.focused']
304
+ }], config: [{
305
+ type: Input
306
+ }], disabled: [{
307
+ type: Input
308
+ }, {
309
+ type: HostBinding,
310
+ args: ['class.disabled']
311
+ }], initialized: [{
312
+ type: HostBinding,
313
+ args: ['class.initialized']
314
+ }] } });
315
+
316
+ class FsMarkdownEditorModule {
317
+ static forRoot(config = {}) {
318
+ return {
319
+ ngModule: FsMarkdownEditorModule,
320
+ providers: [
321
+ { provide: FS_MARKDOWN_EDITOR_DEFAULT_CONFIG, useValue: config },
322
+ {
323
+ provide: FS_MARKDOWN_EDITOR_CONFIG,
324
+ useFactory: markdownEditorConfigFactory,
325
+ deps: [FS_MARKDOWN_EDITOR_DEFAULT_CONFIG],
326
+ },
327
+ ],
328
+ };
329
+ }
330
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: FsMarkdownEditorModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
331
+ static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.7", ngImport: i0, type: FsMarkdownEditorModule, imports: [CommonModule,
332
+ FsLabelModule,
333
+ FsMarkdownEditorComponent], exports: [FsMarkdownEditorComponent] });
334
+ static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: FsMarkdownEditorModule, imports: [CommonModule,
335
+ FsLabelModule,
336
+ FsMarkdownEditorComponent] });
337
+ }
338
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: FsMarkdownEditorModule, decorators: [{
339
+ type: NgModule,
340
+ args: [{
341
+ imports: [
342
+ CommonModule,
343
+ FsLabelModule,
344
+ FsMarkdownEditorComponent,
345
+ ],
346
+ exports: [
347
+ FsMarkdownEditorComponent,
348
+ ],
349
+ }]
350
+ }] });
351
+ function markdownEditorConfigFactory(config) {
352
+ return {
353
+ ...config,
354
+ };
355
+ }
356
+
357
+ class FsMarkdownRendererComponent {
358
+ _sanitizer = inject(DomSanitizer);
359
+ _cdRef = inject(ChangeDetectorRef);
360
+ set setMarkdown(markdown) {
361
+ this._rawMarkdown = markdown || '';
362
+ this._renderMarkdown();
363
+ }
364
+ renderedHtml;
365
+ _rawMarkdown = '';
366
+ _renderMarkdown() {
367
+ const html = this._markdownToHtml(this._rawMarkdown);
368
+ this.renderedHtml = this._sanitizer.bypassSecurityTrustHtml(html);
369
+ this._cdRef.markForCheck();
370
+ }
371
+ _markdownToHtml(markdown) {
372
+ if (!markdown) {
373
+ return '';
374
+ }
375
+ let html = markdown;
376
+ html = html.replace(/^### (.+)$/gm, '<h3>$1</h3>');
377
+ html = html.replace(/^## (.+)$/gm, '<h2>$1</h2>');
378
+ html = html.replace(/^# (.+)$/gm, '<h1>$1</h1>');
379
+ html = html.replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>');
380
+ html = html.replace(/\*(.+?)\*/g, '<em>$1</em>');
381
+ html = html.replace(/~~(.+?)~~/g, '<del>$1</del>');
382
+ html = html.replace(/`([^`]+)`/g, '<code>$1</code>');
383
+ html = html.replace(/```(\w*)\n([\s\S]*?)```/g, '<pre><code class="language-$1">$2</code></pre>');
384
+ html = html.replace(/^\> (.+)$/gm, '<blockquote>$1</blockquote>');
385
+ html = html.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '<a href="$2">$1</a>');
386
+ html = html.replace(/\n/g, '<br>');
387
+ return html;
388
+ }
389
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: FsMarkdownRendererComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
390
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.7", type: FsMarkdownRendererComponent, isStandalone: true, selector: "fs-markdown-renderer", inputs: { setMarkdown: ["markdown", "setMarkdown"] }, ngImport: i0, template: "<div class=\"fs-markdown-renderer\" [innerHtml]=\"renderedHtml\"></div>\n", styles: [":host{display:block}:host ::ng-deep .fs-markdown-renderer{word-break:break-word}:host ::ng-deep .fs-markdown-renderer h1,:host ::ng-deep .fs-markdown-renderer h2,:host ::ng-deep .fs-markdown-renderer h3,:host ::ng-deep .fs-markdown-renderer h4,:host ::ng-deep .fs-markdown-renderer h5,:host ::ng-deep .fs-markdown-renderer h6{margin:16px 0 8px}:host ::ng-deep .fs-markdown-renderer h1:first-child,:host ::ng-deep .fs-markdown-renderer h2:first-child,:host ::ng-deep .fs-markdown-renderer h3:first-child{margin-top:0}:host ::ng-deep .fs-markdown-renderer p{margin:8px 0}:host ::ng-deep .fs-markdown-renderer code{font-family:monospace;background:#eaeaea;padding:2px 4px;border-radius:3px}:host ::ng-deep .fs-markdown-renderer pre{background:#2e3440;color:#d8dee9;padding:12px;border-radius:6px;overflow-x:auto}:host ::ng-deep .fs-markdown-renderer pre code{background:none;padding:0;color:inherit}:host ::ng-deep .fs-markdown-renderer blockquote{border-left:3px solid #ccc;margin:8px 0;padding:6px 16px;color:#6b6b6b;background:#f9f9f9}:host ::ng-deep .fs-markdown-renderer table{border-collapse:collapse;width:100%;margin:8px 0}:host ::ng-deep .fs-markdown-renderer table th,:host ::ng-deep .fs-markdown-renderer table td{padding:6px 12px;border:1px solid #ddd}:host ::ng-deep .fs-markdown-renderer table th{background:#ececec;text-align:left}:host ::ng-deep .fs-markdown-renderer ul,:host ::ng-deep .fs-markdown-renderer ol{padding-left:24px;margin:8px 0}:host ::ng-deep .fs-markdown-renderer a{color:#5e81ac;text-decoration:underline}:host ::ng-deep .fs-markdown-renderer img{max-width:100%}:host ::ng-deep .fs-markdown-renderer del{text-decoration:line-through}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush });
391
+ }
392
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: FsMarkdownRendererComponent, decorators: [{
393
+ type: Component,
394
+ args: [{ selector: 'fs-markdown-renderer', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, template: "<div class=\"fs-markdown-renderer\" [innerHtml]=\"renderedHtml\"></div>\n", styles: [":host{display:block}:host ::ng-deep .fs-markdown-renderer{word-break:break-word}:host ::ng-deep .fs-markdown-renderer h1,:host ::ng-deep .fs-markdown-renderer h2,:host ::ng-deep .fs-markdown-renderer h3,:host ::ng-deep .fs-markdown-renderer h4,:host ::ng-deep .fs-markdown-renderer h5,:host ::ng-deep .fs-markdown-renderer h6{margin:16px 0 8px}:host ::ng-deep .fs-markdown-renderer h1:first-child,:host ::ng-deep .fs-markdown-renderer h2:first-child,:host ::ng-deep .fs-markdown-renderer h3:first-child{margin-top:0}:host ::ng-deep .fs-markdown-renderer p{margin:8px 0}:host ::ng-deep .fs-markdown-renderer code{font-family:monospace;background:#eaeaea;padding:2px 4px;border-radius:3px}:host ::ng-deep .fs-markdown-renderer pre{background:#2e3440;color:#d8dee9;padding:12px;border-radius:6px;overflow-x:auto}:host ::ng-deep .fs-markdown-renderer pre code{background:none;padding:0;color:inherit}:host ::ng-deep .fs-markdown-renderer blockquote{border-left:3px solid #ccc;margin:8px 0;padding:6px 16px;color:#6b6b6b;background:#f9f9f9}:host ::ng-deep .fs-markdown-renderer table{border-collapse:collapse;width:100%;margin:8px 0}:host ::ng-deep .fs-markdown-renderer table th,:host ::ng-deep .fs-markdown-renderer table td{padding:6px 12px;border:1px solid #ddd}:host ::ng-deep .fs-markdown-renderer table th{background:#ececec;text-align:left}:host ::ng-deep .fs-markdown-renderer ul,:host ::ng-deep .fs-markdown-renderer ol{padding-left:24px;margin:8px 0}:host ::ng-deep .fs-markdown-renderer a{color:#5e81ac;text-decoration:underline}:host ::ng-deep .fs-markdown-renderer img{max-width:100%}:host ::ng-deep .fs-markdown-renderer del{text-decoration:line-through}\n"] }]
395
+ }], propDecorators: { setMarkdown: [{
396
+ type: Input,
397
+ args: ['markdown']
398
+ }] } });
399
+
400
+ /**
401
+ * Generated bundle index. Do not edit.
402
+ */
403
+
404
+ export { FS_MARKDOWN_EDITOR_CONFIG, FsMarkdownEditorComponent, FsMarkdownEditorModule, FsMarkdownRendererComponent };
405
+ //# sourceMappingURL=firestitch-markdown-editor.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"firestitch-markdown-editor.mjs","sources":["../../src/app/modules/markdown-editor/injects/config.inject.ts","../../src/app/modules/markdown-editor/services/milkdown-loader.service.ts","../../src/app/modules/markdown-editor/components/markdown-editor/markdown-editor.component.ts","../../src/app/modules/markdown-editor/components/markdown-editor/markdown-editor.component.html","../../src/app/modules/markdown-editor/fs-markdown-editor.module.ts","../../src/app/modules/markdown-renderer/components/markdown-renderer/markdown-renderer.component.ts","../../src/app/modules/markdown-renderer/components/markdown-renderer/markdown-renderer.component.html","../../src/firestitch-markdown-editor.ts"],"sourcesContent":["import { InjectionToken } from '@angular/core';\n\nexport const FS_MARKDOWN_EDITOR_DEFAULT_CONFIG = new InjectionToken<any[]>('fs-markdown-editor.default-config');\nexport const FS_MARKDOWN_EDITOR_CONFIG = new InjectionToken<any[]>('fs-markdown-editor.config');\n","import { DOCUMENT } from '@angular/common';\nimport { Injectable, inject } from '@angular/core';\n\nimport { BehaviorSubject, Observable } from 'rxjs';\nimport { shareReplay } from 'rxjs/operators';\n\nconst THEME_BASE = '/assets/milkdown/theme/';\n\nconst STYLESHEETS = [\n `${THEME_BASE}common/block-edit.css`,\n `${THEME_BASE}common/code-mirror.css`,\n `${THEME_BASE}common/cursor.css`,\n `${THEME_BASE}common/image-block.css`,\n `${THEME_BASE}common/latex.css`,\n `${THEME_BASE}common/link-tooltip.css`,\n `${THEME_BASE}common/list-item.css`,\n `${THEME_BASE}common/placeholder.css`,\n `${THEME_BASE}common/toolbar.css`,\n `${THEME_BASE}common/table.css`,\n];\n\n@Injectable({\n providedIn: 'root',\n})\nexport class FsMilkdownLoaderService {\n private _document = inject<Document>(DOCUMENT);\n private _loaded = new BehaviorSubject(false);\n private _stylesLoaded = false;\n\n private _loaded$ = this._loaded.asObservable()\n .pipe(\n shareReplay(1),\n );\n\n public get loaded$(): Observable<boolean> {\n return this._loaded$;\n }\n\n public loadStyles(): void {\n if (this._stylesLoaded) {\n this._loaded.next(true);\n\n return;\n }\n\n let remaining = STYLESHEETS.length;\n\n if (remaining === 0) {\n this._stylesLoaded = true;\n this._loaded.next(true);\n\n return;\n }\n\n STYLESHEETS.forEach((href) => {\n const existing = this._document.querySelector(`link[href=\"${href}\"]`);\n if (existing) {\n remaining--;\n if (remaining === 0) {\n this._stylesLoaded = true;\n this._loaded.next(true);\n }\n\n return;\n }\n\n const link = this._document.createElement('link');\n link.rel = 'stylesheet';\n link.href = href;\n link.onload = () => {\n remaining--;\n if (remaining === 0) {\n this._stylesLoaded = true;\n this._loaded.next(true);\n }\n };\n link.onerror = () => {\n remaining--;\n if (remaining === 0) {\n this._stylesLoaded = true;\n this._loaded.next(true);\n }\n };\n\n this._document.head.appendChild(link);\n });\n }\n}\n","import {\n AfterViewInit,\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n Component,\n ElementRef,\n forwardRef,\n HostBinding,\n inject,\n Input,\n NgZone,\n OnDestroy,\n OnInit,\n Optional,\n ViewChild,\n} from '@angular/core';\nimport {\n ControlContainer,\n ControlValueAccessor,\n NG_VALIDATORS,\n NG_VALUE_ACCESSOR,\n NgForm,\n ValidationErrors,\n Validator,\n} from '@angular/forms';\n\nimport { guid } from '@firestitch/common';\nimport { FsLabelModule } from '@firestitch/label';\n\nimport { Subject } from 'rxjs';\nimport { takeUntil } from 'rxjs/operators';\n\nimport type { Crepe } from '@milkdown/crepe';\n\nimport { FS_MARKDOWN_EDITOR_CONFIG } from '../../injects/config.inject';\nimport { FsMarkdownEditorConfig } from '../../interfaces/markdown-editor-config';\nimport { FsMilkdownLoaderService } from '../../services/milkdown-loader.service';\n\n\n@Component({\n selector: 'fs-markdown-editor',\n templateUrl: './markdown-editor.component.html',\n styleUrls: ['./markdown-editor.component.scss'],\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => FsMarkdownEditorComponent),\n multi: true,\n },\n {\n provide: NG_VALIDATORS,\n useExisting: forwardRef(() => FsMarkdownEditorComponent),\n multi: true,\n },\n ],\n changeDetection: ChangeDetectionStrategy.OnPush,\n viewProviders: [\n {\n provide: ControlContainer,\n deps: [[Optional, NgForm]],\n useFactory: (ngForm: NgForm) => ngForm,\n },\n ],\n standalone: true,\n imports: [\n FsLabelModule,\n ],\n})\nexport class FsMarkdownEditorComponent\n implements OnInit, AfterViewInit, ControlValueAccessor, Validator, OnDestroy {\n\n private _defaultConfig = inject<FsMarkdownEditorConfig>(FS_MARKDOWN_EDITOR_CONFIG, { optional: true });\n private _cdRef = inject(ChangeDetectorRef);\n private _loader = inject(FsMilkdownLoaderService);\n private _zone = inject(NgZone);\n\n @ViewChild('editorRef') public editorRef: ElementRef;\n\n @HostBinding('class.focused') public classFocused = false;\n\n @Input() public config: FsMarkdownEditorConfig = {};\n\n @Input()\n @HostBinding('class.disabled')\n public disabled = false;\n\n @HostBinding('class.initialized')\n public initialized = false;\n\n public readonly containerID = `fs-markdown-editor-${guid('xxx')}`;\n public onTouched: () => void;\n public onChange: (data: any) => void;\n\n private _crepe: Crepe;\n private _editorViewCtx: any;\n private _parserCtx: any;\n private _markdown = '';\n private _editorReady = false;\n private _destroy$ = new Subject<void>();\n\n public get markdown(): string {\n return this._markdown;\n }\n\n public ngOnInit(): void {\n this.config = { ...(this._defaultConfig || {}), ...(this.config || {}) };\n this._loader.loadStyles();\n }\n\n public ngAfterViewInit(): void {\n this._loader.loaded$\n .pipe(takeUntil(this._destroy$))\n .subscribe((loaded) => {\n if (loaded) {\n this._initEditor();\n }\n });\n }\n\n public writeValue(markdown: string): void {\n this._markdown = markdown || '';\n\n if (this._editorReady) {\n this._setEditorContent(this._markdown);\n }\n\n this._cdRef.markForCheck();\n }\n\n public registerOnChange(fn: (data: any) => void): void {\n this.onChange = fn;\n }\n\n public registerOnTouched(fn: () => void): void {\n this.onTouched = fn;\n }\n\n public setDisabledState(isDisabled: boolean): void {\n this.disabled = isDisabled;\n }\n\n public validate(): ValidationErrors | null {\n const err: any = {};\n if (this.config.maxLength && this._markdown) {\n const length = this._markdown.length;\n if (length > this.config.maxLength) {\n err.maxLengthError = `Must be ${this.config.maxLength} characters or fewer. You entered ${length} characters.`;\n }\n }\n\n return Object.keys(err).length ? err : null;\n }\n\n public clear(): void {\n this.writeValue('');\n if (this.onChange) {\n this.onChange('');\n }\n }\n\n public setMarkdown(markdown: string): void {\n this.writeValue(markdown);\n }\n\n public getMarkdown(): string {\n if (!this._crepe) {\n return this._markdown;\n }\n\n return this._crepe.getMarkdown();\n }\n\n public focus(): void {\n if (this._crepe && this._editorViewCtx) {\n this._crepe.editor.action((ctx) => {\n const view = ctx.get(this._editorViewCtx) as any;\n view.focus();\n });\n }\n }\n\n public disable(): void {\n this.disabled = true;\n this._cdRef.markForCheck();\n }\n\n public destroy(): void {\n if (this._crepe) {\n this._crepe.destroy();\n this._crepe = null;\n }\n this._editorReady = false;\n this.initialized = false;\n this._cdRef.markForCheck();\n }\n\n public ngOnDestroy(): void {\n this._destroy$.next();\n this._destroy$.complete();\n this.destroy();\n }\n\n private _initEditor(): void {\n if (this._crepe || !this.editorRef) {\n return;\n }\n\n this._zone.runOutsideAngular(async () => {\n const [{ Crepe }, { editorViewCtx, parserCtx }] = await Promise.all([\n import('@milkdown/crepe'),\n import('@milkdown/kit/core'),\n ]);\n\n this._editorViewCtx = editorViewCtx;\n this._parserCtx = parserCtx;\n\n this._crepe = new Crepe({\n root: this.editorRef.nativeElement,\n defaultValue: this._markdown,\n features: {},\n featureConfigs: {\n [Crepe.Feature.Placeholder]: {\n text: this.config.placeholder || 'Start typing...',\n },\n },\n });\n\n this._crepe.on((listener) => {\n listener.markdownUpdated((_ctx, markdown, prevMarkdown) => {\n if (markdown !== prevMarkdown) {\n this._zone.run(() => {\n this._markdown = markdown;\n if (this.onChange) {\n this.onChange(markdown);\n }\n if (this.onTouched) {\n this.onTouched();\n }\n this._cdRef.markForCheck();\n });\n }\n });\n });\n\n this._crepe.create().then(() => {\n this._zone.run(() => {\n this._editorReady = true;\n this.initialized = true;\n\n if (this._markdown) {\n this._setEditorContent(this._markdown);\n }\n\n this._cdRef.markForCheck();\n\n if (this.config.autofocus) {\n this.focus();\n }\n\n if (this.config.initialized) {\n this.config.initialized();\n }\n });\n });\n });\n }\n\n private _setEditorContent(markdown: string): void {\n this._crepe.editor.action((ctx) => {\n const view = ctx.get(this._editorViewCtx) as any;\n const parser = ctx.get(this._parserCtx) as any;\n const doc = parser(markdown);\n if (doc) {\n const tr = view.state.tr.replaceWith(\n 0, view.state.doc.content.size, doc.content,\n );\n view.dispatch(tr);\n }\n });\n }\n}\n","<fs-label-field\n [appearance]=\"'outline'\"\n [hoverable]=\"true\"\n [showOutline]=\"initialized\"\n [disabled]=\"disabled\"\n [padless]=\"config.padless\"\n [class.initialized]=\"initialized\">\n @if (config.label) {\n <fs-label>\n {{ config.label }}\n </fs-label>\n }\n <div\n class=\"markdown-editor-container\"\n [id]=\"containerID\">\n <div #editorRef></div>\n </div>\n <fs-label-message>\n <div class=\"fs-form-message\">\n <div class=\"fs-form-hint\">\n {{ config.hint }}\n </div>\n </div>\n </fs-label-message>\n</fs-label-field>\n","import { CommonModule } from '@angular/common';\nimport { ModuleWithProviders, NgModule } from '@angular/core';\n\nimport { FsLabelModule } from '@firestitch/label';\n\nimport { FsMarkdownEditorComponent } from './components/markdown-editor/markdown-editor.component';\nimport { FS_MARKDOWN_EDITOR_CONFIG, FS_MARKDOWN_EDITOR_DEFAULT_CONFIG } from './injects/config.inject';\nimport { FsMarkdownEditorConfig } from './interfaces/markdown-editor-config';\n\n\n@NgModule({\n imports: [\n CommonModule,\n FsLabelModule,\n FsMarkdownEditorComponent,\n ],\n exports: [\n FsMarkdownEditorComponent,\n ],\n})\nexport class FsMarkdownEditorModule {\n public static forRoot(config: FsMarkdownEditorConfig = {}): ModuleWithProviders<FsMarkdownEditorModule> {\n return {\n ngModule: FsMarkdownEditorModule,\n providers: [\n { provide: FS_MARKDOWN_EDITOR_DEFAULT_CONFIG, useValue: config },\n {\n provide: FS_MARKDOWN_EDITOR_CONFIG,\n useFactory: markdownEditorConfigFactory,\n deps: [FS_MARKDOWN_EDITOR_DEFAULT_CONFIG],\n },\n ],\n };\n }\n}\n\nexport function markdownEditorConfigFactory(config: FsMarkdownEditorConfig) {\n return {\n ...config,\n };\n}\n","import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, inject } from '@angular/core';\nimport { DomSanitizer, SafeHtml } from '@angular/platform-browser';\n\n\n@Component({\n selector: 'fs-markdown-renderer',\n templateUrl: 'markdown-renderer.component.html',\n styleUrls: ['markdown-renderer.component.scss'],\n changeDetection: ChangeDetectionStrategy.OnPush,\n standalone: true,\n})\nexport class FsMarkdownRendererComponent {\n private _sanitizer = inject(DomSanitizer);\n private _cdRef = inject(ChangeDetectorRef);\n\n @Input('markdown') public set setMarkdown(markdown: string) {\n this._rawMarkdown = markdown || '';\n this._renderMarkdown();\n }\n\n public renderedHtml: SafeHtml;\n\n private _rawMarkdown = '';\n\n private _renderMarkdown(): void {\n const html = this._markdownToHtml(this._rawMarkdown);\n this.renderedHtml = this._sanitizer.bypassSecurityTrustHtml(html);\n this._cdRef.markForCheck();\n }\n\n private _markdownToHtml(markdown: string): string {\n if (!markdown) {\n return '';\n }\n\n let html = markdown;\n\n html = html.replace(/^### (.+)$/gm, '<h3>$1</h3>');\n html = html.replace(/^## (.+)$/gm, '<h2>$1</h2>');\n html = html.replace(/^# (.+)$/gm, '<h1>$1</h1>');\n\n html = html.replace(/\\*\\*(.+?)\\*\\*/g, '<strong>$1</strong>');\n html = html.replace(/\\*(.+?)\\*/g, '<em>$1</em>');\n html = html.replace(/~~(.+?)~~/g, '<del>$1</del>');\n html = html.replace(/`([^`]+)`/g, '<code>$1</code>');\n\n html = html.replace(/```(\\w*)\\n([\\s\\S]*?)```/g, '<pre><code class=\"language-$1\">$2</code></pre>');\n\n html = html.replace(/^\\> (.+)$/gm, '<blockquote>$1</blockquote>');\n\n html = html.replace(/\\[([^\\]]+)\\]\\(([^)]+)\\)/g, '<a href=\"$2\">$1</a>');\n\n html = html.replace(/\\n/g, '<br>');\n\n return html;\n }\n}\n","<div class=\"fs-markdown-renderer\" [innerHtml]=\"renderedHtml\"></div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":"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"}
package/index.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Generated bundle index. Do not edit.
3
+ */
4
+ /// <amd-module name="@firestitch/markdown-editor" />
5
+ export * from './public_api';
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "@firestitch/markdown-editor",
3
+ "version": "18.0.0",
4
+ "repository": {
5
+ "type": "git",
6
+ "url": "https://github.com/Firestitch/ngx-markdown-editor"
7
+ },
8
+ "author": {
9
+ "name": "Firestitch",
10
+ "email": "admin@firestitch.com"
11
+ },
12
+ "keywords": [
13
+ "angular"
14
+ ],
15
+ "license": "MIT",
16
+ "dependencies": {
17
+ "@milkdown/crepe": "^7.18.0",
18
+ "@milkdown/kit": "^7.18.0",
19
+ "tslib": "^2.3.0"
20
+ },
21
+ "sideEffects": false,
22
+ "module": "fesm2022/firestitch-markdown-editor.mjs",
23
+ "typings": "index.d.ts",
24
+ "exports": {
25
+ "./package.json": {
26
+ "default": "./package.json"
27
+ },
28
+ ".": {
29
+ "types": "./index.d.ts",
30
+ "esm2022": "./esm2022/firestitch-markdown-editor.mjs",
31
+ "esm": "./esm2022/firestitch-markdown-editor.mjs",
32
+ "default": "./fesm2022/firestitch-markdown-editor.mjs"
33
+ }
34
+ }
35
+ }
@@ -0,0 +1,5 @@
1
+ export { FsMarkdownEditorModule } from './app/modules/markdown-editor/fs-markdown-editor.module';
2
+ export { FsMarkdownEditorComponent } from './app/modules/markdown-editor/components/markdown-editor/markdown-editor.component';
3
+ export { FsMarkdownRendererComponent } from './app/modules/markdown-renderer/components/markdown-renderer/markdown-renderer.component';
4
+ export { FS_MARKDOWN_EDITOR_CONFIG } from './app/modules/markdown-editor/injects/config.inject';
5
+ export { FsMarkdownEditorConfig } from './app/modules/markdown-editor/interfaces/markdown-editor-config';