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] [ • 10.2 kB
JavaScript
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