diff --git a/src/clipboardobserver.js b/src/clipboardobserver.js index ac33761..8918ce9 100644 --- a/src/clipboardobserver.js +++ b/src/clipboardobserver.js @@ -8,6 +8,7 @@ */ import DomEventObserver from '@ckeditor/ckeditor5-engine/src/view/observer/domeventobserver'; +import EventInfo from '@ckeditor/ckeditor5-utils/src/eventinfo'; import DataTransfer from './datatransfer'; /** @@ -45,10 +46,19 @@ export default class ClipboardObserver extends DomEventObserver { const targetRanges = data.dropRange ? [ data.dropRange ] : Array.from( viewDocument.selection.getRanges() ); - viewDocument.fire( 'clipboardInput', { + const eventInfo = new EventInfo( viewDocument, 'clipboardInput' ); + + viewDocument.fire( eventInfo, { dataTransfer: data.dataTransfer, targetRanges } ); + + // If CKEditor handled the input, do not bubble the original event any further. + // This helps external integrations recognize that fact and act accordingly. + // https://github.com/ckeditor/ckeditor5-upload/issues/92 + if ( eventInfo.stop.called ) { + data.stopPropagation(); + } } } diff --git a/tests/clipboard.js b/tests/clipboard.js index 7326fa2..b07bc5e 100644 --- a/tests/clipboard.js +++ b/tests/clipboard.js @@ -191,6 +191,7 @@ describe( 'Clipboard feature', () => { viewDocument.fire( 'paste', { dataTransfer: dataTransferMock, + stopPropagation() {}, preventDefault() {} } ); @@ -286,6 +287,7 @@ describe( 'Clipboard feature', () => { viewDocument.fire( 'paste', { dataTransfer: dataTransferMock, + stopPropagation() {}, preventDefault() {} } ); diff --git a/tests/clipboardobserver.js b/tests/clipboardobserver.js index d06e345..e71b764 100644 --- a/tests/clipboardobserver.js +++ b/tests/clipboardobserver.js @@ -12,7 +12,7 @@ import DataTransfer from '../src/datatransfer'; import createViewRoot from '@ckeditor/ckeditor5-engine/tests/view/_utils/createroot'; describe( 'ClipboardObserver', () => { - let view, doc, writer, observer, root, el, range, eventSpy, preventDefaultSpy; + let view, doc, writer, observer, root, el, range, eventSpy, preventDefaultSpy, stopPropagationSpy; beforeEach( () => { view = new View(); @@ -34,6 +34,7 @@ describe( 'ClipboardObserver', () => { eventSpy = sinon.spy(); preventDefaultSpy = sinon.spy(); + stopPropagationSpy = sinon.spy(); } ); it( 'should define domEventType', () => { @@ -224,6 +225,34 @@ describe( 'ClipboardObserver', () => { expect( sinon.assert.callOrder( normalPrioritySpy, eventSpy ) ); } ); + + // https://github.com/ckeditor/ckeditor5-upload/issues/92 + it( 'should stop propagation of the original event if handled by the editor', () => { + const dataTransfer = new DataTransfer( mockDomDataTransfer() ); + + doc.fire( 'drop', { + dataTransfer, + preventDefault: preventDefaultSpy, + stopPropagation: stopPropagationSpy, + dropRange: range + } ); + + sinon.assert.notCalled( stopPropagationSpy ); + + doc.on( 'clipboardInput', evt => { + // E.g. some feature handled the input. + evt.stop(); + } ); + + doc.fire( 'drop', { + dataTransfer, + preventDefault: preventDefaultSpy, + stopPropagation: stopPropagationSpy, + dropRange: range + } ); + + sinon.assert.calledOnce( stopPropagationSpy ); + } ); } ); describe( 'dragover event', () => {