浏览代码

Fix: View event should not bubble up if the `clipboardInput` was handled. Closes ckeditor/ckeditor5-upload#92.

Aleksander Nowodzinski 6 年之前
父节点
当前提交
bfcd94f9e9

+ 11 - 1
packages/ckeditor5-clipboard/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();
+			}
 		}
 	}
 

+ 2 - 0
packages/ckeditor5-clipboard/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() {}
 			} );
 

+ 30 - 1
packages/ckeditor5-clipboard/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', () => {