Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extend component to output additional CKEditor events #21

Merged
merged 11 commits into from
May 5, 2020
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
# CKEditor 4 Angular Integration Changelog

## ckeditor4-angular 1.2.0

New Features:

* [#7](/~https://github.com/ckeditor/ckeditor4-angular/issues/7): CKEditor 4 component now exposes more CKEditor 4 native events. Thanks to [Eduard Zintz](/~https://github.com/ezintz)! New exposed events are:
* [paste](https://ckeditor.com/docs/ckeditor4/latest/api/CKEDITOR_editor.html#event-paste)
* [afterPaste](https://ckeditor.com/docs/ckeditor4/latest/api/CKEDITOR_editor.html#event-afterPaste)
* [dragStat](https://ckeditor.com/docs/ckeditor4/latest/api/CKEDITOR_editor.html#event-dragstart)
* [dragEnd](https://ckeditor.com/docs/ckeditor4/latest/api/CKEDITOR_editor.html#event-dragend)
* [drop](https://ckeditor.com/docs/ckeditor4/latest/api/CKEDITOR_editor.html#event-drop)
* [fileUploadRequest](https://ckeditor.com/docs/ckeditor4/latest/api/CKEDITOR_editor.html#event-fileUploadRequest)
* [fileUploadResponse](https://ckeditor.com/docs/ckeditor4/latest/api/CKEDITOR_editor.html#event-fileUploadResponse)

## ckeditor4-angular 1.1.0

Other Changes:
Expand Down
11 changes: 9 additions & 2 deletions src/app/simple-usage/simple-usage.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,15 @@ <h3>{{ editor }} Editor:</h3>
(ready)="onReady( $event, editor )"
(change)="onChange( $event, editor )"
(focus)="onFocus( $event, editor )"
(blur)="onBlur( $event, editor )">
</ckeditor>
(blur)="onBlur( $event, editor )"
(paste)="onPaste( $event, editor )"
(afterPaste)="onAfterPaste( $event, editor )"
(dragStart)="onDragStart( $event, editor )"
(dragEnd)="onDragEnd( $event, editor )"
(drop)="onDrop( $event, editor )"
(fileUploadRequest)="onFileUploadRequest( $event, editor )"
(fileUploadResponse)="onFileUploadResponse( $event, editor )"
></ckeditor>
</div>

<p>Note: editors have it's data synchronized, so every change in one of editors propagates to another.</p>
Expand Down
28 changes: 28 additions & 0 deletions src/app/simple-usage/simple-usage.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,32 @@ You learn to appreciate each and every single one of the differences while you b
onBlur( event: CKEditor4.EventInfo, editorName: string ): void {
console.log( `Blurred ${editorName.toLowerCase()} editing view.` );
}

onPaste( event: CKEditor4.EventInfo, editorName: string ): void {
console.log( `Pasted into ${editorName.toLowerCase()} editing view.` );
}

onAfterPaste( event: CKEditor4.EventInfo, editorName: string ): void {
console.log( `After pasted fired in ${editorName.toLowerCase()} editing view.` );
}

onDragStart( event: CKEditor4.EventInfo, editorName: string ): void {
console.log( `Drag started in ${editorName.toLowerCase()} editing view.` );
}

onDragEnd( event: CKEditor4.EventInfo, editorName: string ): void {
console.log( `Drag ended in ${editorName.toLowerCase()} editing view.` );
}

onDrop( event: CKEditor4.EventInfo, editorName: string ): void {
console.log( `Dropped in ${editorName.toLowerCase()} editing view.` );
}

onFileUploadRequest( event: CKEditor4.EventInfo, editorName: string ): void {
console.log( `File upload requested in ${editorName.toLowerCase()} editor.` );
}

onFileUploadResponse( event: CKEditor4.EventInfo, editorName: string ): void {
console.log( `File upload responded in ${editorName.toLowerCase()} editor.` );
}
}
126 changes: 125 additions & 1 deletion src/ckeditor/ckeditor.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,14 @@

import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { CKEditorComponent } from './ckeditor.component';
import { whenEvent, whenDataReady, setDataMultipleTimes } from '../test.tools';
import {
fireDragEvent,
mockDropEvent,
mockPasteEvent,
setDataMultipleTimes,
whenDataReady,
whenEvent
} from '../test.tools';
import { CKEditor4 } from './ckeditor';
import EditorType = CKEditor4.EditorType;

Expand Down Expand Up @@ -345,6 +352,123 @@ describe( 'CKEditorComponent', () => {

expect( spy ).toHaveBeenCalledTimes( 1 );
} );

it( 'paste should emit component paste', () => {
const pasteEventMock = mockPasteEvent();
pasteEventMock.$.clipboardData.setData( 'text/html', '<p>bam</p>' );

fixture.detectChanges();

const spy = jasmine.createSpy();
component.paste.subscribe( spy );

const editable = component.instance.editable();
editable.fire( 'paste', pasteEventMock );

return whenEvent( 'paste', component ).then( () => {
expect( spy ).toHaveBeenCalledTimes( 1 );
expect( component.instance.getData() ).toEqual( '<p>bam</p>\n' );
} );
} );

it( 'afterPaste should emit component afterPaste', () => {
const pasteEventMock = mockPasteEvent();
pasteEventMock.$.clipboardData.setData( 'text/html', '<p>bam</p>' );

fixture.detectChanges();

const spy = jasmine.createSpy();
component.afterPaste.subscribe( spy );

const editable = component.instance.editable();
editable.fire( 'paste', pasteEventMock );

return whenEvent( 'afterPaste', component ).then( () => {
expect( spy ).toHaveBeenCalledTimes( 1 );
expect( component.instance.getData() ).toEqual( '<p>bam</p>\n' );
} );
} );

it( 'drag/drop events should emit component dragStart, dragEnd and drop', async done => {
fixture.detectChanges();

const spyDragStart = jasmine.createSpy( 'dragstart' );
component.dragStart.subscribe( spyDragStart );

const spyDragEnd = jasmine.createSpy( 'dragend' );
component.dragEnd.subscribe( spyDragEnd );

const spyDrop = jasmine.createSpy( 'drop' );
component.drop.subscribe( spyDrop );

whenDataReady( component.instance, () => {
const dropEvent = mockDropEvent();
const paragraph = component.instance.editable().findOne( 'p' );

component.instance.getSelection().selectElement( paragraph );

fireDragEvent( 'dragstart', component.instance, dropEvent );

expect( spyDragStart ).toHaveBeenCalledTimes( 1 );

fireDragEvent( 'dragend', component.instance, dropEvent );

expect( spyDragEnd ).toHaveBeenCalledTimes( 1 );

// There is some issue in Firefox with simulating drag-drop flow. The drop event
// is not fired making this assertion fail. Let's skip it for now.
if ( !CKEDITOR.env.gecko ) {
fireDragEvent( 'drop', component.instance, dropEvent );

expect( spyDrop ).toHaveBeenCalledTimes( 1 );
}

done();
} );
} );

it( 'fileUploadRequest should emit component fileUploadRequest', () => {
fixture.detectChanges();

const spy = jasmine.createSpy();
component.fileUploadRequest.subscribe( spy );

const fileLoaderMock = {
fileLoader: {
file: Blob ? new Blob() : '',
fileName: 'fileName',
xhr: {
open: function() {},
send: function() {}
}
},
requestData: {}
};

component.instance.fire( 'fileUploadRequest', fileLoaderMock );

expect( spy ).toHaveBeenCalledTimes( 1 );
} );

it( 'fileUploadResponse should emit component fileUploadResponse', () => {
fixture.detectChanges();

const spy = jasmine.createSpy();
component.fileUploadResponse.subscribe( spy );

const data = {
fileLoader: {
xhr: { responseText: 'Not a JSON.' },
lang: {
filetools: { responseError: 'Error' }
}
}
};

component.instance.fire( 'fileUploadResponse', data );

expect( spy ).toHaveBeenCalledTimes( 1 );
} );
} );

describe( 'when control value accessor callbacks are set', () => {
Expand Down
92 changes: 92 additions & 0 deletions src/ckeditor/ckeditor.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,13 +146,63 @@ export class CKEditorComponent implements AfterViewInit, OnDestroy, ControlValue
*/
@Output() dataChange = new EventEmitter<CKEditor4.EventInfo>();

/**
* Fires when the native drop event occurs. It corresponds with the `editor#dragstart`
* https://ckeditor.com/docs/ckeditor4/latest/api/CKEDITOR_editor.html#event-dragstart
* event.
*/
@Output() dragStart = new EventEmitter<CKEditor4.EventInfo>();

/**
* Fires when the native drop event occurs. It corresponds with the `editor#dragend`
* https://ckeditor.com/docs/ckeditor4/latest/api/CKEDITOR_editor.html#event-dragend
* event.
*/
@Output() dragEnd = new EventEmitter<CKEditor4.EventInfo>();

/**
* Fires when the native drop event occurs. It corresponds with the `editor#drop`
* https://ckeditor.com/docs/ckeditor4/latest/api/CKEDITOR_editor.html#event-drop
* event.
*/
@Output() drop = new EventEmitter<CKEditor4.EventInfo>();

/**
* Fires when the file loader response is received. It corresponds with the `editor#fileUploadResponse`
* https://ckeditor.com/docs/ckeditor4/latest/api/CKEDITOR_editor.html#event-fileUploadResponse
* event.
*/
@Output() fileUploadResponse = new EventEmitter<CKEditor4.EventInfo>();

/**
* Fires when the file loader should send XHR. It corresponds with the `editor#fileUploadRequest`
* https://ckeditor.com/docs/ckeditor4/latest/api/CKEDITOR_editor.html#event-fileUploadRequest
* event.
*/
@Output() fileUploadRequest = new EventEmitter<CKEditor4.EventInfo>();

/**
* Fires when the editing view of the editor is focused. It corresponds with the `editor#focus`
* https://ckeditor.com/docs/ckeditor4/latest/api/CKEDITOR_editor.html#event-focus
* event.
*/
@Output() focus = new EventEmitter<CKEditor4.EventInfo>();

/**
* Fires after the user initiated a paste action, but before the data is inserted.
* It corresponds with the `editor#paste`
* https://ckeditor.com/docs/ckeditor4/latest/api/CKEDITOR_editor.html#event-paste
* event.
*/
@Output() paste = new EventEmitter<CKEditor4.EventInfo>();

/**
* Fires after the `paste` event if content was modified. It corresponds with the `editor#afterPaste`
* https://ckeditor.com/docs/ckeditor4/latest/api/CKEDITOR_editor.html#event-afterPaste
* event.
*/
@Output() afterPaste = new EventEmitter<CKEditor4.EventInfo>();

/**
* Fires when the editing view of the editor is blurred. It corresponds with the `editor#blur`
* https://ckeditor.com/docs/ckeditor4/latest/api/CKEDITOR_editor.html#event-blur
Expand Down Expand Up @@ -278,6 +328,48 @@ export class CKEditorComponent implements AfterViewInit, OnDestroy, ControlValue
} );
} );

editor.on( 'paste', evt => {
this.ngZone.run( () => {
this.paste.emit( evt );
} );
} );

editor.on( 'afterPaste', evt => {
this.ngZone.run( () => {
this.afterPaste.emit( evt );
} );
} );

editor.on( 'dragend', evt => {
this.ngZone.run( () => {
this.dragEnd.emit( evt );
} );
});

editor.on( 'dragstart', evt => {
this.ngZone.run( () => {
this.dragStart.emit( evt );
} );
} );

editor.on( 'drop', evt => {
this.ngZone.run( () => {
this.drop.emit( evt );
} );
} );

editor.on( 'fileUploadRequest', evt => {
this.ngZone.run( () => {
this.fileUploadRequest.emit(evt);
} );
} );

editor.on( 'fileUploadResponse', evt => {
this.ngZone.run(() => {
this.fileUploadResponse.emit(evt);
} );
} );

editor.on( 'blur', evt => {
this.ngZone.run( () => {
if ( this.onTouched ) {
Expand Down
Loading