8
0

clipboardobserver.js 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. /**
  2. * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved.
  3. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
  4. */
  5. /**
  6. * @module clipboard/clipboardobserver
  7. */
  8. import DomEventObserver from '@ckeditor/ckeditor5-engine/src/view/observer/domeventobserver';
  9. import EventInfo from '@ckeditor/ckeditor5-utils/src/eventinfo';
  10. import DataTransfer from './datatransfer';
  11. /**
  12. * Clipboard events observer.
  13. *
  14. * Fires the following events:
  15. *
  16. * * {@link module:engine/view/document~Document#event:clipboardInput}
  17. * * {@link module:engine/view/document~Document#event:dragover}
  18. * * {@link module:engine/view/document~Document#event:drop}
  19. * * {@link module:engine/view/document~Document#event:paste}
  20. * * {@link module:engine/view/document~Document#event:copy}
  21. * * {@link module:engine/view/document~Document#event:cut}
  22. *
  23. * Note that this observer is not available by default (it is not added by the engine).
  24. * To make it available it needs to be added to {@link module:engine/view/document~Document} by
  25. * the {@link module:engine/view/view~View#addObserver `View#addObserver()`} method. You can also load the
  26. * {@link module:clipboard/clipboard~Clipboard} plugin which adds this observer automatically (because it uses it).
  27. *
  28. * @extends module:engine/view/observer/domeventobserver~DomEventObserver
  29. */
  30. export default class ClipboardObserver extends DomEventObserver {
  31. constructor( view ) {
  32. super( view );
  33. const viewDocument = this.document;
  34. this.domEventType = [ 'paste', 'copy', 'cut', 'drop', 'dragover' ];
  35. this.listenTo( viewDocument, 'paste', handleInput, { priority: 'low' } );
  36. this.listenTo( viewDocument, 'drop', handleInput, { priority: 'low' } );
  37. function handleInput( evt, data ) {
  38. data.preventDefault();
  39. const targetRanges = data.dropRange ? [ data.dropRange ] : Array.from( viewDocument.selection.getRanges() );
  40. const eventInfo = new EventInfo( viewDocument, 'clipboardInput' );
  41. viewDocument.fire( eventInfo, {
  42. dataTransfer: data.dataTransfer,
  43. targetRanges
  44. } );
  45. // If CKEditor handled the input, do not bubble the original event any further.
  46. // This helps external integrations recognize that fact and act accordingly.
  47. // https://github.com/ckeditor/ckeditor5-upload/issues/92
  48. if ( eventInfo.stop.called ) {
  49. data.stopPropagation();
  50. }
  51. }
  52. }
  53. onDomEvent( domEvent ) {
  54. const evtData = {
  55. dataTransfer: new DataTransfer( domEvent.clipboardData ? domEvent.clipboardData : domEvent.dataTransfer )
  56. };
  57. if ( domEvent.type == 'drop' ) {
  58. evtData.dropRange = getDropViewRange( this.view, domEvent );
  59. }
  60. this.fire( domEvent.type, domEvent, evtData );
  61. }
  62. }
  63. function getDropViewRange( view, domEvent ) {
  64. const domDoc = domEvent.target.ownerDocument;
  65. const x = domEvent.clientX;
  66. const y = domEvent.clientY;
  67. let domRange;
  68. // Webkit & Blink.
  69. if ( domDoc.caretRangeFromPoint && domDoc.caretRangeFromPoint( x, y ) ) {
  70. domRange = domDoc.caretRangeFromPoint( x, y );
  71. }
  72. // FF.
  73. else if ( domEvent.rangeParent ) {
  74. domRange = domDoc.createRange();
  75. domRange.setStart( domEvent.rangeParent, domEvent.rangeOffset );
  76. domRange.collapse( true );
  77. }
  78. if ( domRange ) {
  79. return view.domConverter.domRangeToView( domRange );
  80. } else {
  81. return view.document.selection.getFirstRange();
  82. }
  83. }
  84. /**
  85. * Fired as a continuation of {@link #event:paste} and {@link #event:drop} events.
  86. *
  87. * It is a part of the {@glink framework/guides/deep-dive/clipboard#input-pipeline "clipboard input pipeline"}.
  88. *
  89. * Fired with a `dataTransfer` which comes from the clipboard and which content should be processed
  90. * and inserted into the editor.
  91. *
  92. * Note that this event is not available by default. To make it available {@link module:clipboard/clipboardobserver~ClipboardObserver}
  93. * needs to be added to {@link module:engine/view/document~Document} by the {@link module:engine/view/view~View#addObserver} method.
  94. * It's done by the {@link module:clipboard/clipboard~Clipboard} feature. If it's not loaded, it must be done manually.
  95. *
  96. * @see module:clipboard/clipboardobserver~ClipboardObserver
  97. * @see module:clipboard/clipboard~Clipboard
  98. * @event module:engine/view/document~Document#event:clipboardInput
  99. * @param {Object} data Event data.
  100. * @param {module:clipboard/datatransfer~DataTransfer} data.dataTransfer Data transfer instance.
  101. * @param {Array.<module:engine/view/range~Range>} data.targetRanges Ranges which are the target of the operation
  102. * (usually – into which the content should be inserted).
  103. * If clipboard input was triggered by a paste operation, then these are the selection ranges. If by a drop operation,
  104. * then it's the drop position (which can be different than the selection at the moment of drop).
  105. */
  106. /**
  107. * Fired when user drags content over one of the editables.
  108. *
  109. * Introduced by {@link module:clipboard/clipboardobserver~ClipboardObserver}.
  110. *
  111. * Note that this event is not available by default. To make it available {@link module:clipboard/clipboardobserver~ClipboardObserver}
  112. * needs to be added to {@link module:engine/view/document~Document} by the {@link module:engine/view/view~View#addObserver} method.
  113. * It's done by the {@link module:clipboard/clipboard~Clipboard} feature. If it's not loaded, it must be done manually.
  114. *
  115. * @see module:engine/view/document~Document#event:clipboardInput
  116. * @event module:engine/view/document~Document#event:dragover
  117. * @param {module:clipboard/clipboardobserver~ClipboardEventData} data Event data.
  118. */
  119. /**
  120. * Fired when user dropped content into one of the editables.
  121. *
  122. * Introduced by {@link module:clipboard/clipboardobserver~ClipboardObserver}.
  123. *
  124. * Note that this event is not available by default. To make it available {@link module:clipboard/clipboardobserver~ClipboardObserver}
  125. * needs to be added to {@link module:engine/view/document~Document} by the {@link module:engine/view/view~View#addObserver} method.
  126. * It's done by the {@link module:clipboard/clipboard~Clipboard} feature. If it's not loaded, it must be done manually.
  127. *
  128. * @see module:engine/view/document~Document#event:clipboardInput
  129. * @event module:engine/view/document~Document#event:drop
  130. * @param {module:clipboard/clipboardobserver~ClipboardEventData} data Event data.
  131. * @param {module:engine/view/range~Range} dropRange The position into which the content is dropped.
  132. */
  133. /**
  134. * Fired when user pasted content into one of the editables.
  135. *
  136. * Introduced by {@link module:clipboard/clipboardobserver~ClipboardObserver}.
  137. *
  138. * Note that this event is not available by default. To make it available {@link module:clipboard/clipboardobserver~ClipboardObserver}
  139. * needs to be added to {@link module:engine/view/document~Document} by the {@link module:engine/view/view~View#addObserver} method.
  140. * It's done by the {@link module:clipboard/clipboard~Clipboard} feature. If it's not loaded, it must be done manually.
  141. *
  142. * @see module:engine/view/document~Document#event:clipboardInput
  143. * @event module:engine/view/document~Document#event:paste
  144. * @param {module:clipboard/clipboardobserver~ClipboardEventData} data Event data.
  145. */
  146. /**
  147. * Fired when user copied content from one of the editables.
  148. *
  149. * Introduced by {@link module:clipboard/clipboardobserver~ClipboardObserver}.
  150. *
  151. * Note that this event is not available by default. To make it available {@link module:clipboard/clipboardobserver~ClipboardObserver}
  152. * needs to be added to {@link module:engine/view/document~Document} by the {@link module:engine/view/view~View#addObserver} method.
  153. * It's done by the {@link module:clipboard/clipboard~Clipboard} feature. If it's not loaded, it must be done manually.
  154. *
  155. * @see module:clipboard/clipboardobserver~ClipboardObserver
  156. * @event module:engine/view/document~Document#event:copy
  157. * @param {module:clipboard/clipboardobserver~ClipboardEventData} data Event data.
  158. */
  159. /**
  160. * Fired when user cut content from one of the editables.
  161. *
  162. * Introduced by {@link module:clipboard/clipboardobserver~ClipboardObserver}.
  163. *
  164. * Note that this event is not available by default. To make it available {@link module:clipboard/clipboardobserver~ClipboardObserver}
  165. * needs to be added to {@link module:engine/view/document~Document} by the {@link module:engine/view/view~View#addObserver} method.
  166. * It's done by the {@link module:clipboard/clipboard~Clipboard} feature. If it's not loaded, it must be done manually.
  167. *
  168. * @see module:clipboard/clipboardobserver~ClipboardObserver
  169. * @event module:engine/view/document~Document#event:cut
  170. * @param {module:clipboard/clipboardobserver~ClipboardEventData} data Event data.
  171. */
  172. /**
  173. * The value of the {@link module:engine/view/document~Document#event:paste},
  174. * {@link module:engine/view/document~Document#event:copy} and {@link module:engine/view/document~Document#event:cut} events.
  175. *
  176. * In order to access clipboard data use `dataTransfer` property.
  177. *
  178. * @class module:clipboard/clipboardobserver~ClipboardEventData
  179. * @extends module:engine/view/observer/domeventdata~DomEventData
  180. */
  181. /**
  182. * Data transfer instance.
  183. *
  184. * @readonly
  185. * @member {module:clipboard/datatransfer~DataTransfer} module:clipboard/clipboardobserver~ClipboardEventData#dataTransfer
  186. */