Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit",
"source.fixAll.stylelint": "explicit"
}
}
893 changes: 0 additions & 893 deletions .yarn/releases/yarn-4.0.1.cjs

This file was deleted.

934 changes: 934 additions & 0 deletions .yarn/releases/yarn-4.5.2.cjs

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion .yarnrc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ enableImmutableInstalls: false

nodeLinker: node-modules

yarnPath: .yarn/releases/yarn-4.0.1.cjs
yarnPath: .yarn/releases/yarn-4.5.2.cjs
41 changes: 9 additions & 32 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# ngx-highlight-js

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)
Expand Down Expand Up @@ -29,29 +30,13 @@ Load the [highlight.js](https://highlightjs.org/download/) and theme css in page

## Usage

**NgModule**

Import the `HighlightJsModule` in to your root `AppModule`.

```typescript
import { HighlightJsModule } from 'ngx-highlight-js';
@NgModule({
imports: [ HighlightJsModule ],
bootstrap: [AppComponent]
})
export class AppModule {
}
```

**Standalone**

```typescript
import { Component } from '@angular/core';
import { HighlightJsDirective } from 'ngx-highlight-js';

@Component({
selector: 'test',
template: `<textarea highlight-js [lang]="'bash'">npm install --save ngx-highlight-js</textarea>`,
standalone: true,
imports: [HighlightJsDirective],
})
export class SimpleComponent {}
Expand Down Expand Up @@ -101,26 +86,18 @@ Will render each `<pre><code>`:

### Parameter

| Property | Description | Type | Default | Global Config |
|----------|-------------|------|---------|---------------|
| `[mode]` | - `default` Will render each `<pre><code>`<br>- `simple` Render all content according to `lang` language | `default, simple` | `simple` | ✅ |
| `[options]` | Equar [configure(options)](https://highlightjs.readthedocs.io/en/latest/api.html#configure) | `any` | - | ✅ |
| `[lang]` | Uses language detection by default but you can specify the language | `string` | `html` | ✅ |
| `[code]` | Specify content | `string` | `html` | - |
| Property | Description | Type | Default | Global Config |
| ----------- | -------------------------------------------------------------------------------------------------------- | ----------------- | -------- | ------------- |
| `[mode]` | - `default` Will render each `<pre><code>`<br>- `simple` Render all content according to `lang` language | `default, simple` | `simple` | ✅ |
| `[options]` | Equar [configure(options)](https://highlightjs.readthedocs.io/en/latest/api.html#configure) | `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 ],
providers: [provideSFConfig({ lang: 'html' })],
})
export class AppDemoModule {}
```
Expand Down
2 changes: 1 addition & 1 deletion lib/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ngx-highlight-js",
"version": "18.0.0",
"version": "19.0.0",
"description": "Angular for syntax highlighting with highlight.js",
"keywords": [
"highlight",
Expand Down
6 changes: 3 additions & 3 deletions lib/spec/directive.spec.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
import { Component } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { HighlightJsModule } from '../src/highlight-js.module';
import { DOCUMENT } from '@angular/common';
import { HighlightJsDirective } from 'lib/public-api';

describe('Component: ngx-highlight-js', () => {
let fixture: ComponentFixture<any>;
let context: TestComponent;

beforeEach(() => {
TestBed.configureTestingModule({
declarations: [TestComponent],
imports: [HighlightJsModule],
imports: [TestComponent],
});
});

Expand Down Expand Up @@ -47,5 +46,6 @@ describe('Component: ngx-highlight-js', () => {
import { Component } from '@angular/core';
</textarea>
`,
imports: [HighlightJsDirective],
})
class TestComponent {}
15 changes: 14 additions & 1 deletion lib/src/highlight-js.config.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { InjectionToken } from '@angular/core';
import { EnvironmentProviders, InjectionToken, makeEnvironmentProviders, Provider } from '@angular/core';
import type { HLJSOptions } from 'highlight.js';

export interface HighlightJsConfig {
Expand All @@ -19,3 +19,16 @@
}

export const HIGHLIGHTJS_CONFIG = new InjectionToken<HighlightJsConfig>('HighlightJs-Config');

export function provideSFConfig(options: Partial<HighlightJsConfig>): EnvironmentProviders {
const provides: Array<Provider | EnvironmentProviders> = [

Check warning on line 24 in lib/src/highlight-js.config.ts

View check run for this annotation

Codecov / codecov/patch

lib/src/highlight-js.config.ts#L23-L24

Added lines #L23 - L24 were not covered by tests
{
provide: HIGHLIGHTJS_CONFIG,
useValue: {
lang: 'html',
...options,
} as HighlightJsConfig,
},
];
return makeEnvironmentProviders(provides);

Check warning on line 33 in lib/src/highlight-js.config.ts

View check run for this annotation

Codecov / codecov/patch

lib/src/highlight-js.config.ts#L33

Added line #L33 was not covered by tests
}
45 changes: 22 additions & 23 deletions lib/src/highlight-js.directive.ts
Original file line number Diff line number Diff line change
@@ -1,39 +1,37 @@
import { Directive, ElementRef, Input, OnDestroy, AfterViewInit, Inject, Optional, NgZone } from '@angular/core';
import { Directive, ElementRef, OnDestroy, AfterViewInit, NgZone, input, model, inject } 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';
import { HIGHLIGHTJS_CONFIG } from './highlight-js.config';
import type { HLJSApi, HLJSOptions } from 'highlight.js';

declare const ngDevMode: boolean;

@Directive({
selector: '[highlight-js]',
host: {
'[style.display]': `mode === 'simple' ? 'none' : null`,
'[style.display]': `mode() === 'simple' ? 'none' : null`,
},
exportAs: 'highlightJs',
standalone: true,
})
export class HighlightJsDirective implements AfterViewInit, OnDestroy {
@Input() options?: Partial<HLJSOptions>;
@Input() lang = 'html';
@Input() code?: string;
@Input() mode: 'default' | 'simple' = 'simple';
readonly options = input<Partial<HLJSOptions>>();
readonly l = input<string>('html', { alias: 'lang'});
readonly code = model<string>();
readonly mode = input<'default' | 'simple'>('simple');

protected codeEl?: HTMLElement;
protected parentEl?: HTMLElement;
private modelValue$?: Subscription;
private observer?: MutationObserver;
private el = inject<ElementRef<HTMLElement>>(ElementRef);
private ngModel = inject<NgModel>(NgModel, {optional: true});
private doc = inject(DOCUMENT);
private cog = inject(HIGHLIGHTJS_CONFIG, {optional: true});
private ngZone = inject(NgZone);

constructor(
private el: ElementRef<HTMLElement>,
@Optional() private ngModel: NgModel,
@Inject(DOCUMENT) private doc: any,
@Optional() @Inject(HIGHLIGHTJS_CONFIG) cog: HighlightJsConfig,
private ngZone: NgZone,
) {
Object.assign(this, cog);
constructor() {
Object.assign(this, this.cog);
}

private escapeHTML(str: string): string {
Expand All @@ -44,15 +42,16 @@
this.ngZone.runOutsideAngular(() => {
this.destroy();
const el = this.el.nativeElement;
const code = this.code || '' + el.innerHTML.trim();
const code = this.code() ?? '' + el.innerHTML.trim();
const doc = this.doc as Document;
this.codeEl = doc.createElement(this.mode === 'default' ? 'div' : 'pre') as HTMLElement;
this.codeEl = doc.createElement(this.mode() === 'default' ? 'div' : 'pre') as HTMLElement;
if (this.codeEl == null) return;

const isSimple = this.mode === 'simple';
const isSimple = this.mode() === 'simple';
if (isSimple) {
if (this.lang) {
this.codeEl.className = this.lang;
const lang = this.l();
if (lang) {
this.codeEl.className = lang;
}
this.parentEl = el.parentNode as HTMLElement;
this.parentEl.insertBefore(this.codeEl, el.nextSibling);
Expand All @@ -70,7 +69,7 @@
return;
}

hljs.configure({ ...this.options });
hljs.configure({ ...this.options() });

if (isSimple) {
hljs.highlightElement(this.codeEl);
Expand All @@ -93,7 +92,7 @@
this.init();
if (this.ngModel) {
this.modelValue$ = this.ngModel.valueChanges?.subscribe((res) => {
this.code = this.escapeHTML(res);
this.code.set(this.escapeHTML(res));

Check warning on line 95 in lib/src/highlight-js.directive.ts

View check run for this annotation

Codecov / codecov/patch

lib/src/highlight-js.directive.ts#L95

Added line #L95 was not covered by tests
this.init();
});
} else {
Expand Down
55 changes: 29 additions & 26 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "ngx-highlight-js",
"version": "18.0.0",
"version": "19.0.0",
"description": "Angular for syntax highlighting with highlight.js",
"keywords": [
"highlight",
Expand Down Expand Up @@ -28,39 +28,42 @@
"release:next": "npm run build && cd publish && npm publish --access public --tag next"
},
"dependencies": {
"@angular/animations": "^18.0.0",
"@angular/common": "^18.0.0",
"@angular/compiler": "^18.0.0",
"@angular/core": "^18.0.0",
"@angular/forms": "^18.0.0",
"@angular/platform-browser": "^18.0.0",
"@angular/platform-browser-dynamic": "^18.0.0",
"@angular/router": "^18.0.0",
"@angular/animations": "^19.0.0",
"@angular/common": "^19.0.0",
"@angular/compiler": "^19.0.0",
"@angular/core": "^19.0.0",
"@angular/forms": "^19.0.0",
"@angular/platform-browser": "^19.0.0",
"@angular/platform-browser-dynamic": "^19.0.0",
"@angular/router": "^19.0.0",
"highlight.js": "^11.10.0",
"rxjs": "~7.8.0",
"tslib": "^2.3.0",
"zone.js": "~0.14.3",
"highlight.js": "^11.0.0"
"zone.js": "~0.15.0"
},
"devDependencies": {
"@angular-devkit/build-angular": "^18.0.4",
"@angular/cli": "^18.0.4",
"@angular/compiler-cli": "^18.0.0",
"@angular-devkit/build-angular": "^19.0.1",
"@angular-eslint/builder": "^18.4.1",
"@angular-eslint/eslint-plugin": "^18.4.1",
"@angular-eslint/eslint-plugin-template": "^18.4.1",
"@angular-eslint/schematics": "^18.4.1",
"@angular-eslint/template-parser": "^18.4.1",
"@angular/cli": "^19.0.1",
"@angular/compiler-cli": "^19.0.0",
"@types/file-saver": "^2.0.7",
"@types/jasmine": "~5.1.0",
"jasmine-core": "~5.1.0",
"@typescript-eslint/eslint-plugin": "^8.15.0",
"@typescript-eslint/parser": "^8.15.0",
"eslint": "^8.53.0",
"file-saver": "^2.0.5",
"jasmine-core": "~5.4.0",
"karma": "~6.4.0",
"karma-chrome-launcher": "~3.2.0",
"karma-coverage": "~2.2.0",
"karma-jasmine": "~5.1.0",
"karma-jasmine-html-reporter": "~2.1.0",
"typescript": "~5.4.2",
"@angular-eslint/builder": "^18.0.0",
"@angular-eslint/eslint-plugin": "^18.0.0",
"@angular-eslint/eslint-plugin-template": "^18.0.0",
"@angular-eslint/schematics": "^18.0.0",
"@angular-eslint/template-parser": "^18.0.0",
"@typescript-eslint/eslint-plugin": "^7.13.0",
"@typescript-eslint/parser": "^7.13.0",
"eslint": "^8.53.0",
"ng-packagr": "^18.0.0"
}
"ng-packagr": "^19.0.1",
"typescript": "~5.6.2"
},
"packageManager": "[email protected]"
}
1 change: 0 additions & 1 deletion src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import { DemoComponent } from './components/demo.component';
<demo></demo>
`,
encapsulation: ViewEncapsulation.None,
standalone: true,
imports: [DemoComponent],
})
export class AppComponent {}
1 change: 0 additions & 1 deletion src/app/components/demo.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ const r = (min: number, max: number) => Math.floor(Math.random() * (max - min +
@Component({
selector: 'demo',
templateUrl: './demo.component.html',
standalone: true,
imports: [CommonModule, FormsModule, HighlightJsDirective],
})
export class DemoComponent implements OnInit {
Expand Down
4 changes: 2 additions & 2 deletions src/main.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app/app.component';
import { HighlightJsConfig, HIGHLIGHTJS_CONFIG } from 'ngx-highlight-js';
import { provideSFConfig } from 'ngx-highlight-js';

bootstrapApplication(AppComponent, {
providers: [{ provide: HIGHLIGHTJS_CONFIG, useValue: { lang: 'html' } as HighlightJsConfig }],
providers: [provideSFConfig({ lang: 'html' })],
}).catch((err) => console.error(err));
Loading