@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.
- package/app/modules/markdown-editor/components/markdown-editor/markdown-editor.component.d.ts +43 -0
- package/app/modules/markdown-editor/fs-markdown-editor.module.d.ts +22 -0
- package/app/modules/markdown-editor/injects/config.inject.d.ts +3 -0
- package/app/modules/markdown-editor/interfaces/markdown-editor-config.d.ts +10 -0
- package/app/modules/markdown-editor/services/milkdown-loader.service.d.ts +12 -0
- package/app/modules/markdown-renderer/components/markdown-renderer/markdown-renderer.component.d.ts +13 -0
- package/assets/frame.svg +42 -0
- package/esm2022/app/modules/markdown-editor/components/markdown-editor/markdown-editor.component.mjs +238 -0
- package/esm2022/app/modules/markdown-editor/fs-markdown-editor.module.mjs +47 -0
- package/esm2022/app/modules/markdown-editor/injects/config.inject.mjs +4 -0
- package/esm2022/app/modules/markdown-editor/interfaces/markdown-editor-config.mjs +2 -0
- package/esm2022/app/modules/markdown-editor/services/milkdown-loader.service.mjs +78 -0
- package/esm2022/app/modules/markdown-renderer/components/markdown-renderer/markdown-renderer.component.mjs +46 -0
- package/esm2022/firestitch-markdown-editor.mjs +5 -0
- package/esm2022/public_api.mjs +5 -0
- package/fesm2022/firestitch-markdown-editor.mjs +405 -0
- package/fesm2022/firestitch-markdown-editor.mjs.map +1 -0
- package/index.d.ts +5 -0
- package/package.json +35 -0
- package/public_api.d.ts +5 -0
- package/styles.scss +17 -0
|
@@ -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
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
|
+
}
|
package/public_api.d.ts
ADDED
|
@@ -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';
|