MurhafSousli / ngx-highlightjs

Angular syntax highlighting module

Home Page:https://ngx-highlight.netlify.app/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Binding data from innerHtml

peripurnama opened this issue · comments

Feature Description

Binding data from innerHtml

Use Case

How to enter this html code

const fullContent = `<p>Test Syntax</p>
<pre><code [highlight]="`public class HelloWorld {
    public static void main(String[] args) {
        System.out.println(&quot;Hello World&quot;);
    }
}`" [languages]="['java']" 
(highlighted)="onHighlight($event)" [lineNumbers]="false"></code></pre>`;

from the code above this line that you want to highlight:

`public class HelloWorld {
    public static void main(String[] args) {
        System.out.println(&quot;Hello World&quot;);
    }
}`

<div [innerHtml]="fullContent | safeMode"></div>

Tampilan yg di harapkan

Screenshot 2023-01-01 214822

You can already do that, however, you need to use the highlight service and manually highlight using highlightAll or highlightElement functions

i tried the manual way with this code it works, but in the browser there is a warning

var blocks = this.elementRef.nativeElement.querySelectorAll('pre code');
    blocks.forEach((block:any) => {
      this.highlightJS.hljs?.highlightElement(block);
});

One of your code blocks includes unescaped HTML. This is a potentially serious security risk.

I found a solution, you can use this method,
maybe in the library you can add this directive

@Pipe({ name: "safeHtml" })
export class SafeHtmlPipe implements PipeTransform {
  constructor(private sanitizer: DomSanitizer) {}

  transform(value:any) {
    return this.sanitizer.bypassSecurityTrustHtml(value);
  }
}

@Pipe({
  name: 'highlightCode',
})
export class HighlightCodePipe implements PipeTransform {

  constructor(private highlightJS: HighlightJS,
    private sanitizer: DomSanitizer){
  }

  transform(htmlMarkup: string): string {
    const preCodeRegex = /<pre><code(?: class="language-(.*)")?>([\s\S]*?)<\/code><\/pre>/g;

    let result = htmlMarkup.replace(preCodeRegex,  (_match, languageName, codeBlock) => {
      let codeBlockHighlighted: string = '';
      if (!languageName) {
        codeBlockHighlighted = hljs.highlightAuto(codeBlock, ['java']).value || ''
      } else {

        codeBlockHighlighted = hljs.highlight(codeBlock, {
          language: languageName,
          ignoreIllegals: true
        }).value || '';
        
      }

      const code = '<pre><code class="hljs">' + codeBlockHighlighted + '</pre></code>';
      
      return code;
    });
    return result;
  }
}

the html component will look like this

<div [innerHTML]="content | highlightCode | safeHtml"></div>

Be caution when using a pipe, it isn't ideal for heavy JS, because it will be executed with every change detection.

I built a directive for this. Hopefully, it helps people. Usage:

<pre ngsHighlightContent>
const myVar = 1;
console.log(myVar);
</pre>