Skip to content

Commit 952f33c

Browse files
committed
feat: Lazy-load hljs languages
1 parent fabb820 commit 952f33c

File tree

3 files changed

+55
-19
lines changed

3 files changed

+55
-19
lines changed

projects/ngx-highlightjs/src/lib/highlight.loader.ts

Lines changed: 50 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Injectable, Inject, PLATFORM_ID, Optional } from '@angular/core';
22
import { DOCUMENT, isPlatformBrowser } from '@angular/common';
3-
import { BehaviorSubject, Observable, from, EMPTY } from 'rxjs';
3+
import { BehaviorSubject, Observable, from, EMPTY, zip } from 'rxjs';
44
import { catchError, tap, map, switchMap, filter, take } from 'rxjs/operators';
55
import { HIGHLIGHT_OPTIONS, HighlightLibrary, HighlightOptions } from './highlight.model';
66

@@ -24,13 +24,13 @@ export class HighlightLoader {
2424
this._ready.next(doc.defaultView.hljs);
2525
} else {
2626
// Load hljs library
27-
this._loadHighlightLibrary().pipe(
27+
this._loadLibrary().pipe(
2828
switchMap((hljs: HighlightLibrary) => {
2929
if (this._options.lineNumbers) {
3030
// Make hljs available on window object (required for the line numbers library)
3131
doc.defaultView.hljs = hljs;
3232
// Load line numbers library
33-
return this._loadLineNumbers().pipe(tap(() => this._ready.next(hljs)));
33+
return loadLineNumbers().pipe(tap(() => this._ready.next(hljs)));
3434
} else {
3535
this._ready.next(hljs);
3636
return EMPTY;
@@ -47,23 +47,59 @@ export class HighlightLoader {
4747
/**
4848
* Lazy-Load highlight.js library
4949
*/
50-
private _loadHighlightLibrary(): Observable<HighlightLibrary> {
51-
return this.importModule(import('highlight.js'));
50+
private _loadLibrary(): Observable<HighlightLibrary> {
51+
const core = loadCoreLibrary().pipe(
52+
switchMap((hljs: HighlightLibrary) =>
53+
this._loadLanguages(hljs).pipe(map(() => hljs))
54+
)
55+
);
56+
const all = loadAllLibrary();
57+
return (this._options && this._options.languages && Object.keys(this._options.languages).length) ? core : all;
5258
}
5359

5460
/**
55-
* Lazy-Load highlight.js library
61+
* Lazy-load highlight.js languages
5662
*/
57-
private _loadLineNumbers(): Observable<HighlightLibrary> {
58-
return this.importModule(import('highlightjs-line-numbers.js'));
59-
}
60-
61-
private importModule(loader: Promise<any>): Observable<any> {
62-
return from(loader).pipe(
63-
filter((module: any) => !!module && !!module.default),
64-
map((module: any) => module.default)
63+
private _loadLanguages(hljs: HighlightLibrary): Observable<any> {
64+
const languages = Object.entries(this._options.languages).map(([langName, langLoader]) =>
65+
importModule(langLoader()).pipe(
66+
tap((langFunc: any) => {
67+
console.log('register lang', langName, langFunc);
68+
hljs.registerLanguage(langName, langFunc);
69+
})
70+
)
6571
);
72+
return zip(...languages);
6673
}
74+
}
6775

76+
/**
77+
* Import highlight.js library with all languages
78+
*/
79+
function loadAllLibrary(): Observable<HighlightLibrary> {
80+
return importModule(import('highlight.js'));
81+
}
82+
83+
/**
84+
* Import highlight.js core library
85+
*/
86+
function loadCoreLibrary(): Observable<HighlightLibrary> {
87+
return importModule(import('highlight.js/lib/highlight'));
88+
}
6889

90+
/**
91+
* Import line numbers library
92+
*/
93+
function loadLineNumbers(): Observable<any> {
94+
return importModule(import('highlightjs-line-numbers.js'));
95+
}
96+
97+
/**
98+
* Map loader response to module object
99+
*/
100+
function importModule(moduleLoader: Promise<any>): Observable<any> {
101+
return from(moduleLoader).pipe(
102+
filter((module: any) => !!module && !!module.default),
103+
map((module: any) => module.default)
104+
);
69105
}

projects/ngx-highlightjs/src/lib/highlight.model.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ export interface HighlightResult {
9696

9797
export interface HighlightOptions {
9898
config?: HighlightConfig;
99+
languages?: { [name: string]: () => Promise<any> };
99100
lineNumbers?: boolean;
100101
}
101102

projects/ngx-highlightjs/src/lib/highlight.service.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -106,9 +106,9 @@ export class HighlightJS {
106106
* @param language A function that returns an object which represents the language definition.
107107
* The function is passed the hljs object to be able to use common regular expressions defined within it.
108108
*/
109-
registerLanguage(name: string, language: () => any): Observable<void> {
109+
registerLanguage(name: string, language: () => any): Observable<HighlightLibrary> {
110110
return this._loader.ready.pipe(
111-
map((hljs: HighlightLibrary) => hljs.registerLanguage(name, language))
111+
tap((hljs: HighlightLibrary) => hljs.registerLanguage(name, language))
112112
);
113113
}
114114

@@ -136,11 +136,10 @@ export class HighlightJS {
136136
* Display line numbers
137137
* @param el Code element
138138
*/
139-
lineNumbersBlock(el: HTMLElement): Observable<void> {
139+
lineNumbersBlock(el: HTMLElement): Observable<any> {
140140
return this._loader.ready.pipe(
141141
filter((hljs: HighlightLibrary) => !!hljs.lineNumbersBlock),
142-
tap((hljs: HighlightLibrary) => hljs.lineNumbersBlock(el)),
143-
map(() => null)
142+
tap((hljs: HighlightLibrary) => hljs.lineNumbersBlock(el))
144143
);
145144
}
146145
}

0 commit comments

Comments
 (0)