UNPKG

ngx-md

Version:

[![Build Status][cirrus-ci-badge]][cirrus-ci-badge-url] [![npm][circleci-badge-url]][circleci-url] [![version][npm-badge-url]][npm-url] [![npm][license-badge-url]][license-url] [![npm][opencollective]][opencollective] [![FOSSA Status](https://app.fossa.io

258 lines (250 loc) 10.2 kB
import * as i0 from '@angular/core'; import { SecurityContext, Injectable, EventEmitter, PLATFORM_ID, Component, Inject, Output, Input, NgModule } from '@angular/core'; import { throwError } from 'rxjs'; import { map, catchError } from 'rxjs/operators'; import { Renderer, marked } from 'marked'; import * as i1 from '@angular/common/http'; import * as i2 from '@angular/platform-browser'; import { isPlatformBrowser, CommonModule } from '@angular/common'; import * as Prism from 'prismjs'; import { decode } from 'he'; class NgxMdService { constructor(_http, _domSanitizer) { this._http = _http; this._domSanitizer = _domSanitizer; this._renderer = new Renderer(); this.extendRenderer(); this.setMarkedOptions({}); } // get the content from remote resource getContent(path) { return this._http.get(path, { responseType: 'text' }).pipe(map(res => this.extractData(res)), catchError(this.handleError)); } get renderer() { return this._renderer; } // handle data extractData(res) { return res || ''; } setMarkedOptions(options) { options = Object.assign({ gfm: true, tables: true, breaks: false, pedantic: false, sanitize: false, smartLists: true, smartypants: false, }, options); options.renderer = this._renderer; marked.setOptions(options); } // comple markdown to html compile(data, sanitize = true) { return this._domSanitizer.sanitize(sanitize ? SecurityContext.HTML : SecurityContext.NONE, marked.parse(data).trim()); } // handle error handleError(error) { const errMsg = error.message ? error.message : error.toString(); return throwError(errMsg); } // extend marked render to support todo checkbox extendRenderer() { this._renderer.listitem = function (text) { if (/^\s*\[[x ]\]\s*/.test(text)) { text = text .replace(/^\s*\[ \]\s*/, '<input type="checkbox" class="md-checkbox" disabled> ') .replace(/^\s*\[x\]\s*/, '<input type="checkbox" class="md-checkbox" checked disabled> '); return '<li style="list-style: none">' + text + '</li>'; } else { return '<li>' + text + '</li>'; } }; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: NgxMdService, deps: [{ token: i1.HttpClient }, { token: i2.DomSanitizer }], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: NgxMdService, providedIn: 'root' }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: NgxMdService, decorators: [{ type: Injectable, args: [{ providedIn: 'root', }] }], ctorParameters: () => [{ type: i1.HttpClient }, { type: i2.DomSanitizer }] }); class NgxMdComponent { constructor(_mdService, _el, platformId) { this._mdService = _mdService; this._el = _el; this.platformId = platformId; this.changeLog = []; this.error = new EventEmitter(); this.loaded = new EventEmitter(); this.rendered = new EventEmitter(); /** * Boolean indicating if the markdown content should be sanitized to avoid script injections */ this.sanitizeHtml = true; this._path = ''; this._data = ''; this._ext = ''; } set path(value) { if (value) { this._path = value; this.onPathChange(); } } set data(value) { if (value) { this._data = value; this.onDataChange(value); } } // on input onDataChange(data) { if (data) { this._el.nativeElement.innerHTML = this._mdService.compile(data, this.sanitizeHtml); } else { this._el.nativeElement.innerHTML = ''; } this.highlightContent(false); this.rendered.emit(data); } /** * After view init */ ngAfterViewInit() { if (this._path) { this.onPathChange(); } else if (!this._data) { this.processRaw(); } } processRaw() { this._md = this.prepare(decode(this._el.nativeElement.innerHTML)); this.onDataChange(this._md); } /** * get remote conent; */ onPathChange() { this._ext = this._path && this._path .split('.') .splice(-1) .join(); this._mdService .getContent(this._path) .pipe(catchError(this.handleError)) .subscribe(data => { this._md = this._ext !== 'md' ? '```' + this._ext + '\n' + data + '\n```' : data; this.onDataChange(this.prepare(this._md)); this.loaded.emit(data); }); } /** * catch http error */ handleError(error, caught) { this.error.emit(error); console.error('An error occurred', error); // for demo purposes only return error.message || error; } /** * Prepare string */ prepare(raw) { if (!raw) { return ''; } if (this._ext === 'md' || !this.path) { let isCodeBlock = false; return raw .split('\n') .map((line) => { // If the first non-blank chars are an opening/closing code block, toggle the flag if (this.trimLeft(line).substring(0, 3) === '```') { isCodeBlock = !isCodeBlock; } return isCodeBlock ? line : line.trim(); }) .join('\n'); } return raw.replace(/\"/g, '\''); } /** * Trim left whitespace */ trimLeft(line) { return line.replace(/^\s+|\s+$/g, ''); } /** * Use Prism to highlight code snippets only on the browser */ highlightContent(async) { if (isPlatformBrowser(this.platformId)) { Prism.highlightAll(async); } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: NgxMdComponent, deps: [{ token: NgxMdService }, { token: i0.ElementRef }, { token: PLATFORM_ID }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.1.3", type: NgxMdComponent, isStandalone: false, selector: "markdown,[Markdown],ngx-md,[NgxMd]", inputs: { path: "path", data: "data", sanitizeHtml: "sanitizeHtml" }, outputs: { error: "error", loaded: "loaded", rendered: "rendered" }, ngImport: i0, template: '<ng-content></ng-content>', isInline: true, styles: [".token.operator,.token.entity,.token.url,.language-css .token.string,.style .token.string{background:none}.md-checkbox{vertical-align:middle;margin:0 .2em .25em -1.6em;font-size:16px}\n"] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: NgxMdComponent, decorators: [{ type: Component, args: [{ selector: 'markdown,[Markdown],ngx-md,[NgxMd]', template: '<ng-content></ng-content>', standalone: false, styles: [".token.operator,.token.entity,.token.url,.language-css .token.string,.style .token.string{background:none}.md-checkbox{vertical-align:middle;margin:0 .2em .25em -1.6em;font-size:16px}\n"] }] }], ctorParameters: () => [{ type: NgxMdService }, { type: i0.ElementRef }, { type: undefined, decorators: [{ type: Inject, args: [PLATFORM_ID] }] }], propDecorators: { error: [{ type: Output }], loaded: [{ type: Output }], rendered: [{ type: Output }], path: [{ type: Input }], data: [{ type: Input }], sanitizeHtml: [{ type: Input }] } }); class NgxMdConfig { static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: NgxMdConfig, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: NgxMdConfig }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: NgxMdConfig, decorators: [{ type: Injectable }] }); class NgxMdModule { static forRoot() { return { ngModule: NgxMdModule, providers: [NgxMdConfig], }; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: NgxMdModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); } static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.1.3", ngImport: i0, type: NgxMdModule, declarations: [NgxMdComponent], imports: [CommonModule], exports: [NgxMdComponent] }); } static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: NgxMdModule, providers: [NgxMdService], imports: [CommonModule] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.3", ngImport: i0, type: NgxMdModule, decorators: [{ type: NgModule, args: [{ imports: [CommonModule], declarations: [NgxMdComponent], providers: [NgxMdService], exports: [NgxMdComponent], }] }] }); /* * Public API Surface of ngx-md */ /** * Generated bundle index. Do not edit. */ export { NgxMdComponent, NgxMdModule, NgxMdService }; //# sourceMappingURL=ngx-md.mjs.map