UNPKG

ngx-markdown

Version:

Angular library that uses marked to parse markdown to html combined with Prism.js for synthax highlights

158 lines (157 loc) 14.1 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ import { isPlatformBrowser } from '@angular/common'; import { HttpClient } from '@angular/common/http'; import { Inject, Injectable, Optional, PLATFORM_ID, SecurityContext } from '@angular/core'; import { DomSanitizer } from '@angular/platform-browser'; import { parse, Renderer } from 'marked'; import { map } from 'rxjs/operators'; import { MarkedOptions } from './marked-options'; /** @type {?} */ export const errorSrcWithoutHttpClient = '[ngx-markdown] When using the [src] attribute you *have to* pass the `HttpClient` as a parameter of the `forRoot` method. See README for more information'; export class MarkdownService { /** * @param {?} platform * @param {?} http * @param {?} domSanitizer * @param {?} options */ constructor(platform, http, domSanitizer, options) { this.platform = platform; this.http = http; this.domSanitizer = domSanitizer; this.options = options; if (!this.renderer) { this.renderer = new Renderer(); } } /** * @return {?} */ get renderer() { return this.options.renderer; } /** * @param {?} value * @return {?} */ set renderer(value) { this.options.renderer = value; } /** * @param {?} markdown * @param {?=} decodeHtml * @param {?=} markedOptions * @return {?} */ compile(markdown, decodeHtml = false, markedOptions = this.options) { /** @type {?} */ const precompiled = this.precompile(markdown); /** @type {?} */ const compiled = parse(decodeHtml ? this.decodeHtml(precompiled) : precompiled, markedOptions); return markedOptions.sanitize && !markedOptions.sanitizer ? this.domSanitizer.sanitize(SecurityContext.HTML, compiled) : compiled; } /** * @param {?} src * @return {?} */ getSource(src) { if (!this.http) { throw new Error(errorSrcWithoutHttpClient); } return this.http .get(src, { responseType: 'text' }) .pipe(map(markdown => this.handleExtension(src, markdown))); } /** * @return {?} */ highlight() { if (isPlatformBrowser(this.platform) && typeof Prism !== 'undefined') { Prism.highlightAll(false); } } /** * @param {?} html * @return {?} */ decodeHtml(html) { if (isPlatformBrowser(this.platform)) { /** @type {?} */ const textarea = document.createElement('textarea'); textarea.innerHTML = html; return textarea.value; } return html; } /** * @param {?} src * @param {?} markdown * @return {?} */ handleExtension(src, markdown) { /** @type {?} */ const extension = src ? src.split('.').splice(-1).join() : null; return extension !== 'md' ? '```' + extension + '\n' + markdown + '\n```' : markdown; } /** * @param {?} markdown * @return {?} */ precompile(markdown) { if (!markdown) { return ''; } /** @type {?} */ let indentStart; return markdown .split('\n') .map(line => { /** @type {?} */ let lineIdentStart = indentStart; // find position of 1st non-whitespace character // to determine the current line indentation start if (line.length > 0) { lineIdentStart = isNaN(lineIdentStart) ? line.search(/\S|$/) : Math.min(line.search(/\S|$/), lineIdentStart); } // keep 1st non-whitespace line indentation // as base reference for other lines if (isNaN(indentStart)) { indentStart = lineIdentStart; } // remove whitespaces before current line indentation return !!lineIdentStart ? line.substring(lineIdentStart) : line; }).join('\n'); } } MarkdownService.decorators = [ { type: Injectable }, ]; /** @nocollapse */ MarkdownService.ctorParameters = () => [ { type: Object, decorators: [{ type: Inject, args: [PLATFORM_ID,] }] }, { type: HttpClient, decorators: [{ type: Optional }] }, { type: DomSanitizer }, { type: MarkedOptions } ]; if (false) { /** @type {?} */ MarkdownService.prototype.platform; /** @type {?} */ MarkdownService.prototype.http; /** @type {?} */ MarkdownService.prototype.domSanitizer; /** @type {?} */ MarkdownService.prototype.options; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFya2Rvd24uc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiJuZzovL25neC1tYXJrZG93bi8iLCJzb3VyY2VzIjpbInNyYy9tYXJrZG93bi5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7QUFBQSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNwRCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDbEQsT0FBTyxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFLFdBQVcsRUFBRSxlQUFlLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDM0YsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQ3pELE9BQU8sRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLE1BQU0sUUFBUSxDQUFDO0FBRXpDLE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUVyQyxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7O0FBT2pELGFBQWEseUJBQXlCLEdBQUcsMkpBQTJKLENBQUM7QUFHck0sTUFBTSxPQUFPLGVBQWU7Ozs7Ozs7SUFNMUIsWUFDK0IsUUFBZ0IsRUFDekIsSUFBZ0IsRUFDNUIsY0FDRDtRQUhzQixhQUFRLEdBQVIsUUFBUSxDQUFRO1FBQ3pCLFNBQUksR0FBSixJQUFJLENBQVk7UUFDNUIsaUJBQVksR0FBWixZQUFZO1FBQ2IsWUFBTyxHQUFQLE9BQU87UUFFZCxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRTtZQUNsQixJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksUUFBUSxFQUFFLENBQUM7U0FDaEM7S0FDRjs7OztJQWRELElBQUksUUFBUSxLQUFlLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsRUFBRTs7Ozs7SUFDMUQsSUFBSSxRQUFRLENBQUMsS0FBc0I7UUFDakMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxR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QzthQUNuRDs7O1lBR0QsSUFBSSxLQUFLLENBQUMsV0FBVyxDQUFDLEVBQUU7Z0JBQ3RCLFdBQVcsR0FBRyxjQUFjLENBQUM7YUFDOUI7O1lBRUQsT0FBTyxDQUFDLENBQUMsY0FBYztnQkFDckIsQ0FBQyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsY0FBYyxDQUFDO2dCQUNoQyxDQUFDLENBQUMsSUFBSSxDQUFDO1NBQ1YsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQzs7OztZQXZGbkIsVUFBVTs7OztZQVFnQyxNQUFNLHVCQUE1QyxNQUFNLFNBQUMsV0FBVztZQXhCZCxVQUFVLHVCQXlCZCxRQUFRO1lBdkJKLFlBQVk7WUFLWixhQUFhIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgaXNQbGF0Zm9ybUJyb3dzZXIgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xyXG5pbXBvcnQgeyBIdHRwQ2xpZW50IH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uL2h0dHAnO1xyXG5pbXBvcnQgeyBJbmplY3QsIEluamVjdGFibGUsIE9wdGlvbmFsLCBQTEFURk9STV9JRCwgU2VjdXJpdHlDb250ZXh0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IERvbVNhbml0aXplciB9IGZyb20gJ0Bhbmd1bGFyL3BsYXRmb3JtLWJyb3dzZXInO1xyXG5pbXBvcnQgeyBwYXJzZSwgUmVuZGVyZXIgfSBmcm9tICdtYXJrZWQnO1xyXG5pbXBvcnQgeyBPYnNlcnZhYmxlIH0gZnJvbSAncnhqcyc7XHJcbmltcG9ydCB7IG1hcCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcclxuXHJcbmltcG9ydCB7IE1hcmtlZE9wdGlvbnMgfSBmcm9tICcuL21hcmtlZC1vcHRpb25zJztcclxuXHJcbmRlY2xhcmUgdmFyIFByaXNtOiB7XHJcbiAgaGlnaGxpZ2h0QWxsOiAoYXN5bmM6IGJvb2xlYW4pID0+IHZvaWQ7XHJcbn07XHJcblxyXG4vLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bWF4LWxpbmUtbGVuZ3RoXHJcbmV4cG9ydCBjb25zdCBlcnJvclNyY1dpdGhvdXRIdHRwQ2xpZW50ID0gJ1tuZ3gtbWFya2Rvd25dIFdoZW4gdXNpbmcgdGhlIFtzcmNdIGF0dHJpYnV0ZSB5b3UgKmhhdmUgdG8qIHBhc3MgdGhlIGBIdHRwQ2xpZW50YCBhcyBhIHBhcmFtZXRlciBvZiB0aGUgYGZvclJvb3RgIG1ldGhvZC4gU2VlIFJFQURNRSBmb3IgbW9yZSBpbmZvcm1hdGlvbic7XHJcblxyXG5ASW5qZWN0YWJsZSgpXHJcbmV4cG9ydCBjbGFzcyBNYXJrZG93blNlcnZpY2Uge1xyXG4gIGdldCByZW5kZXJlcigpOiBSZW5kZXJlciB7IHJldHVybiB0aGlzLm9wdGlvbnMucmVuZGVyZXI7IH1cclxuICBzZXQgcmVuZGVyZXIodmFsdWU6IG1hcmtlZC5SZW5kZXJlcikge1xyXG4gICAgdGhpcy5vcHRpb25zLnJlbmRlcmVyID0gdmFsdWU7XHJcbiAgfVxyXG5cclxuICBjb25zdHJ1Y3RvcihcclxuICAgIEBJbmplY3QoUExBVEZPUk1fSUQpIHByaXZhdGUgcGxhdGZvcm06IE9iamVjdCxcclxuICAgIEBPcHRpb25hbCgpIHByaXZhdGUgaHR0cDogSHR0cENsaWVudCxcclxuICAgIHByaXZhdGUgZG9tU2FuaXRpemVyOiBEb21TYW5pdGl6ZXIsXHJcbiAgICBwdWJsaWMgb3B0aW9uczogTWFya2VkT3B0aW9ucyxcclxuICApIHtcclxuICAgIGlmICghdGhpcy5yZW5kZXJlcikge1xyXG4gICAgICB0aGlzLnJlbmRlcmVyID0gbmV3IFJlbmRlcmVyKCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBjb21waWxlKG1hcmtkb3duOiBzdHJpbmcsIGRlY29kZUh0bWwgPSBmYWxzZSwgbWFya2VkT3B0aW9ucyA9IHRoaXMub3B0aW9ucyk6IHN0cmluZyB7XHJcbiAgICBjb25zdCBwcmVjb21waWxlZCA9IHRoaXMucHJlY29tcGlsZShtYXJrZG93bik7XHJcbiAgICBjb25zdCBjb21waWxlZCA9IHBhcnNlKFxyXG4gICAgICBkZWNvZGVIdG1sID8gdGhpcy5kZWNvZGVIdG1sKHByZWNvbXBpbGVkKSA6IHByZWNvbXBpbGVkLFxyXG4gICAgICBtYXJrZWRPcHRpb25zKTtcclxuICAgIHJldHVybiBtYXJrZWRPcHRpb25zLnNhbml0aXplICYmICFtYXJrZWRPcHRpb25zLnNhbml0aXplclxyXG4gICAgICA/IHRoaXMuZG9tU2FuaXRpemVyLnNhbml0aXplKFNlY3VyaXR5Q29udGV4dC5IVE1MLCBjb21waWxlZClcclxuICAgICAgOiBjb21waWxlZDtcclxuICB9XHJcblxyXG4gIGdldFNvdXJjZShzcmM6IHN0cmluZyk6IE9ic2VydmFibGU8c3RyaW5nPiB7XHJcbiAgICBpZiAoIXRoaXMuaHR0cCkge1xyXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoZXJyb3JTcmNXaXRob3V0SHR0cENsaWVudCk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdGhpcy5odHRwXHJcbiAgICAgIC5nZXQoc3JjLCB7IHJlc3BvbnNlVHlwZTogJ3RleHQnIH0pXHJcbiAgICAgIC5waXBlKG1hcChtYXJrZG93biA9PiB0aGlzLmhhbmRsZUV4dGVuc2lvbihzcmMsIG1hcmtkb3duKSkpO1xyXG4gIH1cclxuXHJcbiAgaGlnaGxpZ2h0KCkge1xyXG4gICAgaWYgKGlzUGxhdGZvcm1Ccm93c2VyKHRoaXMucGxhdGZvcm0pICYmIHR5cGVvZiBQcmlzbSAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgICAgUHJpc20uaGlnaGxpZ2h0QWxsKGZhbHNlKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgZGVjb2RlSHRtbChodG1sOiBzdHJpbmcpIHtcclxuICAgIGlmIChpc1BsYXRmb3JtQnJvd3Nlcih0aGlzLnBsYXRmb3JtKSkge1xyXG4gICAgICBjb25zdCB0ZXh0YXJlYSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3RleHRhcmVhJyk7XHJcbiAgICAgIHRleHRhcmVhLmlubmVySFRNTCA9IGh0bWw7XHJcbiAgICAgIHJldHVybiB0ZXh0YXJlYS52YWx1ZTtcclxuICAgIH1cclxuICAgIHJldHVybiBodG1sO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBoYW5kbGVFeHRlbnNpb24oc3JjOiBzdHJpbmcsIG1hcmtkb3duOiBzdHJpbmcpOiBzdHJpbmcge1xyXG4gICAgY29uc3QgZXh0ZW5zaW9uID0gc3JjXHJcbiAgICAgID8gc3JjLnNwbGl0KCcuJykuc3BsaWNlKC0xKS5qb2luKClcclxuICAgICAgOiBudWxsO1xyXG4gICAgcmV0dXJuIGV4dGVuc2lvbiAhPT0gJ21kJ1xyXG4gICAgICA/ICdgYGAnICsgZXh0ZW5zaW9uICsgJ1xcbicgKyBtYXJrZG93biArICdcXG5gYGAnXHJcbiAgICAgIDogbWFya2Rvd247XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIHByZWNvbXBpbGUobWFya2Rvd246IHN0cmluZyk6IHN0cmluZyB7XHJcbiAgICBpZiAoIW1hcmtkb3duKSB7XHJcbiAgICAgIHJldHVybiAnJztcclxuICAgIH1cclxuICAgIGxldCBpbmRlbnRTdGFydDogbnVtYmVyO1xyXG4gICAgcmV0dXJuIG1hcmtkb3duXHJcbiAgICAgIC5zcGxpdCgnXFxuJylcclxuICAgICAgLm1hcChsaW5lID0+IHtcclxuICAgICAgICAvLyBzZXQgY3VycmVudCBsaW5lIGlkZW50IHN0YXJ0IHRvIGJhc2UgcmVmZXJlbmNlIGluZGVudGF0aW9uXHJcbiAgICAgICAgbGV0IGxpbmVJZGVudFN0YXJ0ID0gaW5kZW50U3RhcnQ7XHJcbiAgICAgICAgLy8gZmluZCBwb3NpdGlvbiBvZiAxc3Qgbm9uLXdoaXRlc3BhY2UgY2hhcmFjdGVyXHJcbiAgICAgICAgLy8gdG8gZGV0ZXJtaW5lIHRoZSBjdXJyZW50IGxpbmUgaW5kZW50YXRpb24gc3RhcnRcclxuICAgICAgICBpZiAobGluZS5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICBsaW5lSWRlbnRTdGFydCA9IGlzTmFOKGxpbmVJZGVudFN0YXJ0KVxyXG4gICAgICAgICAgICA/IGxpbmUuc2VhcmNoKC9cXFN8JC8pXHJcbiAgICAgICAgICAgIDogTWF0aC5taW4obGluZS5zZWFyY2goL1xcU3wkLyksIGxpbmVJZGVudFN0YXJ0KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8ga2VlcCAxc3Qgbm9uLXdoaXRlc3BhY2UgbGluZSBpbmRlbnRhdGlvblxyXG4gICAgICAgIC8vIGFzIGJhc2UgcmVmZXJlbmNlIGZvciBvdGhlciBsaW5lc1xyXG4gICAgICAgIGlmIChpc05hTihpbmRlbnRTdGFydCkpIHtcclxuICAgICAgICAgIGluZGVudFN0YXJ0ID0gbGluZUlkZW50U3RhcnQ7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIHJlbW92ZSB3aGl0ZXNwYWNlcyBiZWZvcmUgY3VycmVudCBsaW5lIGluZGVudGF0aW9uXHJcbiAgICAgICAgcmV0dXJuICEhbGluZUlkZW50U3RhcnRcclxuICAgICAgICAgID8gbGluZS5zdWJzdHJpbmcobGluZUlkZW50U3RhcnQpXHJcbiAgICAgICAgICA6IGxpbmU7XHJcbiAgICAgIH0pLmpvaW4oJ1xcbicpO1xyXG4gIH1cclxufVxyXG4iXX0=