diff --git a/.prettierrc b/.prettierrc index 669ac5d..42ddb74 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1,5 +1,5 @@ { - "printWidth": 80, + "printWidth": 140, "singleQuote": true, "trailingComma": "all" } diff --git a/README.md b/README.md index fd37383..5221907 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,7 @@ Angular for syntax highlighting with highlight.js [![NPM version](https://img.shields.io/npm/v/ngx-highlight-js.svg)](https://www.npmjs.com/package/ngx-highlight-js) -[![Build Status](https://travis-ci.org/cipchk/ngx-highlight-js.svg?branch=master)](https://travis-ci.org/cipchk/ngx-highlight-js) - +[![Ci](https://github.com/cipchk/ngx-highlight-js/workflows/Ci/badge.svg)](https://github.com/cipchk/ngx-highlight-js/actions) ## Demo @@ -35,14 +34,15 @@ export class AppModule { Load the highlight.js and theme css in page. ```html - + ``` ```html - + ``` -## Only ` ``` -**[options]** equar [configure(options)](http://highlightjs.readthedocs.io/en/latest/api.html#configure-options). (optional) +### Default mode + +Will render each `
`:
+
+```html
+
+```
+
+### Parameter
 
-**[lang]** uses language detection by default but you can specify the language. (optional)
+| Property | Description | Type | Default | Global Config |
+|----------|-------------|------|---------|---------------|
+| `[mode]` | - `default` Will render each `
`
- `simple` Render all content according to `lang` language | `default, simple` | `simple` | ✅ | +| `[options]` | Equar [configure(options)](http://highlightjs.readthedocs.io/en/latest/api.html#configure-options) | `any` | - | ✅ | +| `[lang]` | Uses language detection by default but you can specify the language | `string` | `html` | ✅ | +| `[code]` | Specify content | `string` | `html` | - | + +**Global Config** + +```ts +@NgModule({ + providers: [ + { + provide: HIGHLIGHTJS_CONFIG, + useValue: { + lang: 'html' + } as HighlightJsConfig + } + ], + imports: [ HighlightJsModule ], +}) +export class AppDemoModule {} +``` ## Troubleshooting diff --git a/lib/package.json b/lib/package.json index ed8efe9..455d5af 100644 --- a/lib/package.json +++ b/lib/package.json @@ -1,6 +1,6 @@ { "name": "ngx-highlight-js", - "version": "11.0.0", + "version": "11.1.0", "description": "Angular for syntax highlighting with highlight.js", "keywords": [ "highlight", diff --git a/lib/public_api.ts b/lib/public_api.ts index 3d33662..ba6b69a 100644 --- a/lib/public_api.ts +++ b/lib/public_api.ts @@ -1,2 +1,3 @@ export { HighlightJsDirective } from './src/highlight-js.directive'; export * from './src/highlight-js.module'; +export * from './src/highlight-js.config'; diff --git a/lib/src/highlight-js.config.ts b/lib/src/highlight-js.config.ts new file mode 100644 index 0000000..25b1a59 --- /dev/null +++ b/lib/src/highlight-js.config.ts @@ -0,0 +1,20 @@ +import { InjectionToken } from '@angular/core'; + +export interface HighlightJsConfig { + /** + * Specify rendering mode + * - `default` Will render each `
`
+   * - `simple` Render all content according to `lang` language
+   */
+  mode?: 'default' | 'simple';
+  /**
+   * Uses language detection by default but you can specify the language
+   */
+  lang?: string;
+  /**
+   * Equar [configure(options)](http://highlightjs.readthedocs.io/en/latest/api.html#configure-options)
+   */
+  options?: any;
+}
+
+export const HIGHLIGHTJS_CONFIG = new InjectionToken('HighlightJs-Config');
diff --git a/lib/src/highlight-js.directive.ts b/lib/src/highlight-js.directive.ts
index 9d16833..85362df 100644
--- a/lib/src/highlight-js.directive.ts
+++ b/lib/src/highlight-js.directive.ts
@@ -1,80 +1,80 @@
-import {
-  Directive,
-  ElementRef,
-  Input,
-  OnInit,
-  OnDestroy,
-  AfterViewInit,
-  Inject,
-  Optional,
-} from '@angular/core';
+import { Directive, ElementRef, Input, OnDestroy, AfterViewInit, Inject, Optional } from '@angular/core';
 import { DOCUMENT } from '@angular/common';
 import { NgModel } from '@angular/forms';
 import { Subscription } from 'rxjs';
+import { HighlightJsConfig, HIGHLIGHTJS_CONFIG } from './highlight-js.config';
 
 declare const hljs: any;
 
 @Directive({
   selector: '[highlight-js]',
   host: {
-    '[style.display]': `'none'`,
+    '[style.display]': `mode === 'simple' ? 'none' : null`,
   },
   exportAs: 'highlightJs',
 })
-export class HighlightJsDirective implements OnInit, AfterViewInit, OnDestroy {
-  constructor(
-    private el: ElementRef,
-    @Optional() private ngModel: NgModel,
-    @Inject(DOCUMENT) private doc: any,
-  ) {}
+export class HighlightJsDirective implements AfterViewInit, OnDestroy {
   @Input() options: any;
   @Input() lang = 'html';
   @Input() code!: string;
+  @Input() mode: 'default' | 'simple' = 'simple';
 
   protected codeEl?: HTMLElement;
   protected parentEl!: HTMLElement;
   private modelValue$?: Subscription;
-
-  // #region Mutation
-
   private observer!: MutationObserver;
 
+  constructor(
+    private el: ElementRef,
+    @Optional() private ngModel: NgModel,
+    @Inject(DOCUMENT) private doc: any,
+    @Optional() @Inject(HIGHLIGHTJS_CONFIG) cog: HighlightJsConfig,
+  ) {
+    Object.assign(this, cog);
+  }
+
   private escapeHTML(str: string): string {
-    return (str || '')
-      .replace(/&/g, '&')
-      .replace(//g, '>')
-      .replace(/"/g, '"')
-      .replace(/'/g, ''');
+    return (str || '').replace(/&/g, '&').replace(//g, '>').replace(/"/g, '"').replace(/'/g, ''');
   }
 
   private init(): void {
     this.destroy();
-    this.codeEl = this.doc.createElement('pre') as HTMLElement;
-    if (this.lang) {
-      this.codeEl.className = this.lang;
+    const el = this.el.nativeElement;
+    const code = this.code || '' + el.innerHTML.trim();
+    this.codeEl = this.doc.createElement(this.mode === 'default' ? 'div' : 'pre') as HTMLElement;
+    const isSimple = this.mode === 'simple';
+    if (isSimple) {
+      if (this.lang) {
+        this.codeEl.className = this.lang;
+      }
+      this.parentEl = el.parentNode as HTMLElement;
+      this.parentEl.insertBefore(this.codeEl, el.nextSibling);
+    } else {
+      this.parentEl = el;
+      this.parentEl.innerHTML = ``;
+      this.parentEl.appendChild(this.codeEl);
     }
-    this.codeEl.innerHTML =
-      this.code || '' + this.el.nativeElement.innerHTML.trim();
-    this.parentEl = this.el.nativeElement.parentNode as HTMLElement;
-    this.parentEl.insertBefore(this.codeEl, this.el.nativeElement.nextSibling);
-
+    this.codeEl.innerHTML = code;
     hljs.configure({ ...this.options });
-    hljs.highlightBlock(this.codeEl);
+
+    if (isSimple) {
+      hljs.highlightBlock(this.codeEl);
+    } else {
+      this.codeEl.querySelectorAll('pre code').forEach((block) => {
+        hljs.highlightBlock(block);
+      });
+    }
   }
 
   private destroy(): void {
-    if (this.codeEl) {
+    if (this.codeEl && this.parentEl) {
       this.parentEl.removeChild(this.codeEl);
       this.codeEl = undefined;
     }
   }
 
-  ngOnInit(): void {
-    this.init();
-  }
-
   ngAfterViewInit(): void {
+    this.init();
     if (this.ngModel) {
       this.modelValue$ = this.ngModel.valueChanges?.subscribe((res) => {
         this.code = this.escapeHTML(res);
@@ -111,6 +111,4 @@ export class HighlightJsDirective implements OnInit, AfterViewInit, OnDestroy {
     }
     this.observer.disconnect();
   }
-
-  // #endregionn
 }
diff --git a/package.json b/package.json
index 9bbc763..520a237 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "ngx-highlight-js",
-  "version": "11.0.0",
+  "version": "11.1.0",
   "description": "Angular for syntax highlighting with highlight.js",
   "keywords": [
     "highlight",
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index c496867..8c2a680 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -1,12 +1,13 @@
 import { BrowserModule } from '@angular/platform-browser';
 import { NgModule } from '@angular/core';
 import { FormsModule } from '@angular/forms';
-import { HighlightJsModule } from 'ngx-highlight-js';
+import { HighlightJsConfig, HighlightJsModule, HIGHLIGHTJS_CONFIG } from 'ngx-highlight-js';
 
 import { AppComponent } from './app.component';
 import { DemoComponent } from './components/demo.component';
 
 @NgModule({
+  providers: [{ provide: HIGHLIGHTJS_CONFIG, useValue: { lang: 'html' } as HighlightJsConfig }],
   imports: [BrowserModule, FormsModule, HighlightJsModule],
   declarations: [AppComponent, DemoComponent],
   bootstrap: [AppComponent],
diff --git a/src/app/components/demo.component.html b/src/app/components/demo.component.html
index 35942d2..daeab05 100644
--- a/src/app/components/demo.component.html
+++ b/src/app/components/demo.component.html
@@ -2,14 +2,10 @@
   
Installation instructions
1、Install
- +
-
- 2、Import the `HighlightJsModule` in to your root `AppModule`. -
+
2、Import the `HighlightJsModule` in to your root `AppModule`.
-

[options] equar - configure(options). (optional) -

-

- [lang] uses language detection by default but you can - specify the language. (optional) + configure(options). + (optional)

+

[lang] uses language detection by default but you can specify the language. (optional)

Support `ngModel`
- +
Observe Content
@@ -90,9 +75,17 @@
Observe Content
- + + + +
Default mode
+
+
+

Should be will render each <pre><code>

+ +
+
Result
+

diff --git a/src/app/components/demo.component.ts b/src/app/components/demo.component.ts index 0661b64..78ea1ca 100644 --- a/src/app/components/demo.component.ts +++ b/src/app/components/demo.component.ts @@ -1,32 +1,32 @@ -import { Component } from '@angular/core'; +import { Component, OnInit } from '@angular/core'; +import codeHtml from './files/code'; const r = (min: number, max: number) => Math.floor(Math.random() * (max - min + 1) + min); @Component({ selector: 'demo', - templateUrl: './demo.component.html' + templateUrl: './demo.component.html', }) -export class DemoComponent { +export class DemoComponent implements OnInit { switchStatus = true; html = ``; random = ``; + code = codeHtml; private getHtml(): string { - const DATA = [ - `1`, - `

2
`, - `3`, - `4`, - `

5

`, - ]; + const DATA = [`1`, `
2
`, `3`, `4`, `

5

`]; return DATA[r(0, DATA.length - 1)]; } - updateHTML() { + updateHTML(): void { this.html = this.getHtml(); } - randomHtml() { + randomHtml(): void { this.random = this.getHtml(); } + + ngOnInit(): void { + this.randomHtml(); + } } diff --git a/src/app/components/files/code.ts b/src/app/components/files/code.ts new file mode 100644 index 0000000..cf00711 --- /dev/null +++ b/src/app/components/files/code.ts @@ -0,0 +1,17 @@ +export default ` +

+ The bare minimum for using highlight.js on a web page is linking to the library along with one of the styles and calling + initHighlightingOnLoad: +

+
<link rel="stylesheet" href="/path/to/styles/default.css">
+<script src="/path/to/highlight.min.js"></script>
+<script>hljs.initHighlightingOnLoad();</script>
+
+

+ This will find and highlight code inside of <pre><code> tags; it tries to detect the language automatically. If + automatic detection doesn’t work for you, you can specify the language in the class attribute: +

+
<pre><code class="html">...</code></pre>
+
+`; diff --git a/src/index.html b/src/index.html index 2391d5f..fd6edf8 100644 --- a/src/index.html +++ b/src/index.html @@ -1,27 +1,28 @@ - + + + + ngx-highlight-js | Angular for syntax highlighting with highlight.js + + + + + + + - - - ngx-highlight-js | Angular for syntax highlighting with highlight.js - - - - - - - - - -
- Loading... -
- - - Fork me on GitHub - - - + +
+ Loading... +
+ + Fork me on GitHub + +