Skip to content

Commit 84f7fc9

Browse files
authored
Merge pull request #521 from ckeditor/ck/520
Adjust watchdog demos, add `disableWatchdog` flag and fix memory leaks when unmount editor with attached context watchdog.
2 parents 8bdaa0e + a34fde3 commit 84f7fc9

21 files changed

Lines changed: 514 additions & 190 deletions
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
type: Feature
3+
closes:
4+
- https://github.com/ckeditor/ckeditor5-angular/issues/469
5+
---
6+
7+
Added the `disableWatchdog` input to the `CKEditorComponent` that allows disabling the watchdog functionality even when a watchdog instance is provided via the `watchdog` input.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
type: Fix
3+
---
4+
5+
Remove `itemError` event listener from the watchdog when the `CKEditorComponent` is destroyed. This prevents potential memory leaks when the component is removed from the DOM.

src/app/app.component.css

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,13 @@ nav a.active {
1717
:host ::ng-deep h4 {
1818
border-bottom: 1px solid #ddd;
1919
}
20+
21+
:host ::ng-deep .alert-box {
22+
padding: 15px;
23+
margin-top: 20px;
24+
border: 1px solid transparent;
25+
border-radius: 4px;
26+
color: #684E00;
27+
background-color: #fff3cd;
28+
border-color: #ffeeba;
29+
}

src/app/app.component.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ <h1>CKEditor 5 integration with Angular</h1>
66
<li><a href="/simple-cdn-usage" routerLinkActive="active">Simple CDN usage</a></li>
77
<li><a href="/forms" routerLinkActive="active">Integration with forms (<code>ngModel</code>)</a></li>
88
<li><a href="/reactive-forms" routerLinkActive="active">Integration with reactive forms (<code>formControlName</code>)</a></li>
9-
<li><a href="/watchdog" routerLinkActive="active">Integration with CKEditor Watchdog</a></li>
9+
<li><a href="/reuse-watchdog" routerLinkActive="active">Integration with CKEditor Watchdog (via watchdog prop)</a></li>
10+
<li><a href="/editor-watchdog" routerLinkActive="active">Integration with CKEditor Watchdog (via editorWatchdogConfig prop)</a></li>
1011
<li><a href="/context" routerLinkActive="active">Integration with CKEditor Context</a></li>
1112
<li><a href="/init-crash" routerLinkActive="active">Catching error when editor crashes during initialization</a></li>
1213
</ul>

src/app/app.module.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,12 @@ const appRoutes: Routes = [
2020
loadChildren: () => import( './demo-reactive-form/demo-reactive-form.module' ).then( m => m.DemoReactiveFormModule )
2121
},
2222
{
23-
path: 'watchdog',
24-
loadChildren: () => import( './watchdog-demo/watchdog-demo.module' ).then( m => m.WatchdogDemoModule )
23+
path: 'reuse-watchdog',
24+
loadChildren: () => import( './reuse-watchdog-demo/reuse-watchdog-demo.module' ).then( m => m.ReuseWatchdogDemoModule )
25+
},
26+
{
27+
path: 'editor-watchdog',
28+
loadChildren: () => import( './editor-watchdog-demo/editor-watchdog-demo.module' ).then( m => m.EditorWatchdogDemoModule )
2529
},
2630
{
2731
path: 'simple-usage',

src/app/watchdog-demo/watchdog-demo.css renamed to src/app/editor-watchdog-demo/editor-watchdog-demo.css

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,10 @@
22
background: #fafafa;
33
color: #888;
44
}
5+
6+
.test-toolbar {
7+
display: flex;
8+
flex-direction: row;
9+
gap: 10px;
10+
margin-bottom: 15px;
11+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<h2>Watchdog demo (via editorWatchdogConfig prop)</h2>
2+
3+
<div class="test-toolbar">
4+
<button (click)="toggle()">Toggle disabled mode</button>
5+
<label><input type="checkbox" [checked]="isWatchdogDisabled" (change)="toggleWatchdog()"> Disable watchdog</label>
6+
<button (click)="simulateError()">Simulate Error</button>
7+
</div>
8+
9+
<ckeditor
10+
data="Watchdog demo"
11+
[editor]="Editor"
12+
[editorWatchdogConfig]="editorWatchdogConfig"
13+
(ready)="onReady($event)"
14+
[disabled]="isDisabled"
15+
[disableWatchdog]="isWatchdogDisabled"
16+
(error)="onError($event)"
17+
>
18+
</ckeditor>
19+
20+
<div *ngIf="errors.length > 0" style="margin-top: 20px;">
21+
<h3>Errors:</h3>
22+
<ul>
23+
<li *ngFor="let error of errors">
24+
<strong>{{ error.timestamp | date:'medium' }}:</strong> {{ error.message }}
25+
</li>
26+
</ul>
27+
</div>
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { NgModule } from '@angular/core';
2+
import { RouterModule } from '@angular/router';
3+
import { BrowserModule } from '@angular/platform-browser';
4+
import { CKEditorModule } from 'src/ckeditor';
5+
import { EditorWatchdogDemoComponent } from './editor-watchdog-demo';
6+
7+
@NgModule( {
8+
declarations: [
9+
EditorWatchdogDemoComponent
10+
],
11+
imports: [
12+
BrowserModule,
13+
CKEditorModule,
14+
RouterModule.forChild( [
15+
{
16+
path: '',
17+
component: EditorWatchdogDemoComponent
18+
}
19+
] )
20+
]
21+
} )
22+
export class EditorWatchdogDemoModule {}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import { Component, Inject, NgZone } from '@angular/core';
2+
import type { WatchdogConfig } from 'ckeditor5';
3+
import { AngularEditor } from 'src/editor/editor';
4+
5+
@Component( {
6+
selector: 'watchdog-demo',
7+
templateUrl: './editor-watchdog-demo.html',
8+
styleUrls: [ './editor-watchdog-demo.css' ]
9+
} )
10+
export class EditorWatchdogDemoComponent {
11+
public Editor = AngularEditor;
12+
13+
public ready = false;
14+
public isDisabled = false;
15+
public isWatchdogDisabled = false;
16+
public errors: Array<{ timestamp: Date; message: string }> = [];
17+
public editorWatchdogConfig: WatchdogConfig = {
18+
crashNumberLimit: 500,
19+
minimumNonErrorTimePeriod: 1000,
20+
saveInterval: 1200
21+
};
22+
23+
private editor?: AngularEditor;
24+
private ngZone: NgZone;
25+
26+
constructor( @Inject( NgZone ) ngZone: NgZone ) {
27+
this.ngZone = ngZone;
28+
}
29+
30+
public onReady( editor: AngularEditor ): void {
31+
console.log( 'Editor initialized', editor );
32+
this.editor = editor;
33+
}
34+
35+
public toggle(): void {
36+
this.isDisabled = !this.isDisabled;
37+
}
38+
39+
public toggleWatchdog(): void {
40+
this.isWatchdogDisabled = !this.isWatchdogDisabled;
41+
}
42+
43+
public simulateError(): void {
44+
this.ngZone.runOutsideAngular( () => {
45+
setTimeout( () => {
46+
const err: any = new Error( 'foo' );
47+
48+
err.context = this.editor;
49+
err.is = () => !!this.editor;
50+
51+
throw err;
52+
} );
53+
} );
54+
}
55+
56+
public onError( error: any ): void {
57+
// Watchdog should return undefined error when it restarts the editor.
58+
this.errors.unshift( {
59+
timestamp: new Date(),
60+
message: error?.toString() ?? 'Watchdog restarted editor.'
61+
} );
62+
}
63+
}

src/app/initialization-crash/initialization-crash.component.css

Whitespace-only changes.

0 commit comments

Comments
 (0)