{"version":3,"sources":["webpack:///./node_modules/@ckeditor/ckeditor5-clipboard/src/index.js","webpack:///./node_modules/@ckeditor/ckeditor5-clipboard/src/dragdrop.js"],"names":["_clipboard__WEBPACK_IMPORTED_MODULE_0__","__webpack_require__","d","__webpack_exports__","_clipboardpipeline__WEBPACK_IMPORTED_MODULE_1__","DragDrop","_this","this","editor","view","editing","_draggedRange","_draggingUid","_draggableElement","_updateDropMarkerThrottled","throttle","targetRange","_updateDropMarker","_removeDropMarkerDelayed","delay","_removeDropMarker","_clearDraggableAttributesDelayed","_clearDraggableAttributes","addObserver","ClipboardObserver","MouseObserver","_setupDragging","_setupContentInsertionIntegration","_setupClipboardInputIntegration","_setupDropMarker","_setupDraggableAttributeHandling","listenTo","evt","name","isReadOnly","forceDisabled","clearForceDisabled","on","isEnabled","_finalizeDragging","env","isAndroid","detach","cancel","Object","D_Projects_UA_repo_Source_Client_UA_User_Web_node_modules_babel_runtime_helpers_esm_get_js__WEBPACK_IMPORTED_MODULE_6__","D_Projects_UA_repo_Source_Client_UA_User_Web_node_modules_babel_runtime_helpers_esm_getPrototypeOf_js__WEBPACK_IMPORTED_MODULE_9__","prototype","call","_this2","model","modelDocument","document","viewDocument","data","selection","target","is","preventDefault","draggableWidget","findDraggableWidget","modelElement","mapper","toModelElement","LiveRange","fromRange","createRangeOn","plugins","has","get","isCollapsed","selectedElement","getSelectedElement","isWidget","getFirstRange","uid","dataTransfer","effectAllowed","setData","draggedSelection","createSelection","toRange","content","toView","getSelectedContent","fire","method","priority","isCanceled","dropEffect","focus","findDropTargetRange","targetRanges","isGecko","includes","_this3","stop","getData","isMove","getFinalDropEffect","containsRange","toViewRange","_this4","clipboardPipeline","ClipboardPipeline","ranges","map","viewRange","toModelRange","change","writer","setSelection","isSuccess","resultRange","_this5","draggableElement","isBlink","editableElement","setAttribute","_this6","root","rootName","removeAttribute","toViewElement","conversion","for","markerToHighlight","classes","markerToElement","_ref","inText","schema","checkChild","markerRange","start","createUIElement","class","domDocument","domElement","toDomElement","innerHTML","markers","getRange","isEqual","updateMarker","range","addMarker","usingOperation","affectsData","removeMarker","moved","deleteContent","doNotAutoparagraph","Widget","Plugin","targetViewRanges","targetViewElement","targetViewPosition","parent","findDropTargetRangeOnWidget","targetModelElement","getClosestMappedModelElement","targetModelPosition","toModelPosition","findDropTargetRangeBetweenBlocks","getNearestSelectionRange","findDropTargetRangeOnAncestorObject","findDropTargetRangeInElement","ancestor","findAncestor","node","positionAtElementStart","createPositionAt","commonPath","path","slice","length","betweenBlocksPosition","createPositionFromPath","nodeAfter","isObject","element","viewPosition","createPositionBefore","viewElement","findMappedViewAncestor","func","wait","timer","delayed","_len","arguments","args","Array","_key","setTimeout","apply","clearTimeout","hasClass"],"mappings":"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","file":"js/chunk-51c5b69c.29d88b9b.js","sourcesContent":["/**\n * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module clipboard\n */\n\nexport { default as Clipboard } from './clipboard';\nexport { default as ClipboardPipeline } from './clipboardpipeline';\nexport { default as DragDrop } from './dragdrop';\nexport { default as PastePlainText } from './pasteplaintext';\n","/**\n * @license Copyright (c) 2003-2021, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license\n */\n\n/**\n * @module clipboard/dragdrop\n */\n\n/* globals setTimeout, clearTimeout */\n\nimport Plugin from '@ckeditor/ckeditor5-core/src/plugin';\nimport LiveRange from '@ckeditor/ckeditor5-engine/src/model/liverange';\nimport MouseObserver from '@ckeditor/ckeditor5-engine/src/view/observer/mouseobserver';\nimport Widget from '@ckeditor/ckeditor5-widget/src/widget';\nimport uid from '@ckeditor/ckeditor5-utils/src/uid';\nimport env from '@ckeditor/ckeditor5-utils/src/env';\nimport { isWidget } from '@ckeditor/ckeditor5-widget/src/utils';\n\nimport ClipboardPipeline from './clipboardpipeline';\nimport ClipboardObserver from './clipboardobserver';\n\nimport { throttle } from 'lodash-es';\n\nimport '../theme/clipboard.css';\n\n// Drag and drop events overview:\n//\n// ┌──────────────────┐\n// │ mousedown │ Sets the draggable attribute.\n// └─────────┬────────┘\n// │\n// └─────────────────────┐\n// │ │\n// │ ┌─────────V────────┐\n// │ │ mouseup │ Dragging did not start, removes the draggable attribute.\n// │ └──────────────────┘\n// │\n// ┌─────────V────────┐ Retrieves the selected model.DocumentFragment\n// │ dragstart │ and converts it to view.DocumentFragment.\n// └─────────┬────────┘\n// │\n// ┌─────────V────────┐ Processes view.DocumentFragment to text/html and text/plain\n// │ clipboardOutput │ and stores the results in data.dataTransfer.\n// └─────────┬────────┘\n// │\n// │ DOM dragover\n// ┌────────────┐\n// │ │\n// ┌─────────V────────┐ │\n// │ dragging │ │ Updates the drop target marker.\n// └─────────┬────────┘ │\n// │ │\n// ┌─────────────└────────────┘\n// │ │ │\n// │ ┌─────────V────────┐ │\n// │ │ dragleave │ │ Removes the drop target marker.\n// │ └─────────┬────────┘ │\n// │ │ │\n// ┌───│─────────────┘ │\n// │ │ │ │\n// │ │ ┌─────────V────────┐ │\n// │ │ │ dragenter │ │ Focuses the editor view.\n// │ │ └─────────┬────────┘ │\n// │ │ │ │\n// │ │ └────────────┘\n// │ │\n// │ └─────────────┐\n// │ │ │\n// │ │ ┌─────────V────────┐\n// └───┐ │ drop │ (The default handler of the clipboard pipeline).\n// │ └─────────┬────────┘\n// │ │\n// │ ┌─────────V────────┐ Resolves the final data.targetRanges.\n// │ │ clipboardInput │ Aborts if dropping on dragged content.\n// │ └─────────┬────────┘\n// │ │\n// │ ┌─────────V────────┐\n// │ │ clipboardInput │ (The default handler of the clipboard pipeline).\n// │ └─────────┬────────┘\n// │ │\n// │ ┌───────────V───────────┐\n// │ │ inputTransformation │ (The default handler of the clipboard pipeline).\n// │ └───────────┬───────────┘\n// │ │\n// │ ┌──────────V──────────┐\n// │ │ contentInsertion │ Updates the document selection to drop range.\n// │ └──────────┬──────────┘\n// │ │\n// │ ┌──────────V──────────┐\n// │ │ contentInsertion │ (The default handler of the clipboard pipeline).\n// │ └──────────┬──────────┘\n// │ │\n// │ ┌──────────V──────────┐\n// │ │ contentInsertion │ Removes the content from the original range if the insertion was successful.\n// │ └──────────┬──────────┘\n// │ │\n// └─────────────┐\n// │\n// ┌─────────V────────┐\n// │ dragend │ Removes the drop marker and cleans the state.\n// └──────────────────┘\n//\n\n/**\n * The drag and drop feature. It works on top of the {@link module:clipboard/clipboardpipeline~ClipboardPipeline}.\n *\n * Read more about the clipboard integration in the {@glink framework/guides/deep-dive/clipboard clipboard deep dive guide}.\n *\n * @extends module:core/plugin~Plugin\n */\nexport default class DragDrop extends Plugin {\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get pluginName() {\n\t\treturn 'DragDrop';\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tstatic get requires() {\n\t\treturn [ ClipboardPipeline, Widget ];\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tinit() {\n\t\tconst editor = this.editor;\n\t\tconst view = editor.editing.view;\n\n\t\t/**\n\t\t * The live range over the original content that is being dragged.\n\t\t *\n\t\t * @private\n\t\t * @type {module:engine/model/liverange~LiveRange}\n\t\t */\n\t\tthis._draggedRange = null;\n\n\t\t/**\n\t\t * The UID of current dragging that is used to verify if the drop started in the same editor as the drag start.\n\t\t *\n\t\t * **Note**: This is a workaround for broken 'dragend' events (they are not fired if the source text node got removed).\n\t\t *\n\t\t * @private\n\t\t * @type {String}\n\t\t */\n\t\tthis._draggingUid = '';\n\n\t\t/**\n\t\t * The reference to the model element that currently has a `draggable` attribute set (it is set while dragging).\n\t\t *\n\t\t * @private\n\t\t * @type {module:engine/model/element~Element}\n\t\t */\n\t\tthis._draggableElement = null;\n\n\t\t/**\n\t\t * A throttled callback updating the drop marker.\n\t\t *\n\t\t * @private\n\t\t * @type {Function}\n\t\t */\n\t\tthis._updateDropMarkerThrottled = throttle( targetRange => this._updateDropMarker( targetRange ), 40 );\n\n\t\t/**\n\t\t * A delayed callback removing the drop marker.\n\t\t *\n\t\t * @private\n\t\t * @type {Function}\n\t\t */\n\t\tthis._removeDropMarkerDelayed = delay( () => this._removeDropMarker(), 40 );\n\n\t\t/**\n\t\t * A delayed callback removing draggable attributes.\n\t\t *\n\t\t * @private\n\t\t * @type {Function}\n\t\t */\n\t\tthis._clearDraggableAttributesDelayed = delay( () => this._clearDraggableAttributes(), 40 );\n\n\t\tview.addObserver( ClipboardObserver );\n\t\tview.addObserver( MouseObserver );\n\n\t\tthis._setupDragging();\n\t\tthis._setupContentInsertionIntegration();\n\t\tthis._setupClipboardInputIntegration();\n\t\tthis._setupDropMarker();\n\t\tthis._setupDraggableAttributeHandling();\n\n\t\tthis.listenTo( editor, 'change:isReadOnly', ( evt, name, isReadOnly ) => {\n\t\t\tif ( isReadOnly ) {\n\t\t\t\tthis.forceDisabled( 'readOnlyMode' );\n\t\t\t} else {\n\t\t\t\tthis.clearForceDisabled( 'readOnlyMode' );\n\t\t\t}\n\t\t} );\n\n\t\tthis.on( 'change:isEnabled', ( evt, name, isEnabled ) => {\n\t\t\tif ( !isEnabled ) {\n\t\t\t\tthis._finalizeDragging( false );\n\t\t\t}\n\t\t} );\n\n\t\tif ( env.isAndroid ) {\n\t\t\tthis.forceDisabled( 'noAndroidSupport' );\n\t\t}\n\t}\n\n\t/**\n\t * @inheritDoc\n\t */\n\tdestroy() {\n\t\tif ( this._draggedRange ) {\n\t\t\tthis._draggedRange.detach();\n\t\t\tthis._draggedRange = null;\n\t\t}\n\n\t\tthis._updateDropMarkerThrottled.cancel();\n\t\tthis._removeDropMarkerDelayed.cancel();\n\t\tthis._clearDraggableAttributesDelayed.cancel();\n\n\t\treturn super.destroy();\n\t}\n\n\t/**\n\t * Drag and drop events handling.\n\t *\n\t * @private\n\t */\n\t_setupDragging() {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\t\tconst modelDocument = model.document;\n\t\tconst view = editor.editing.view;\n\t\tconst viewDocument = view.document;\n\n\t\t// The handler for the drag start; it is responsible for setting data transfer object.\n\t\tthis.listenTo( viewDocument, 'dragstart', ( evt, data ) => {\n\t\t\tconst selection = modelDocument.selection;\n\n\t\t\t// Don't drag the editable element itself.\n\t\t\tif ( data.target && data.target.is( 'editableElement' ) ) {\n\t\t\t\tdata.preventDefault();\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// TODO we could clone this node somewhere and style it to match editing view but without handles,\n\t\t\t// selection outline, WTA buttons, etc.\n\t\t\t// data.dataTransfer._native.setDragImage( data.domTarget, 0, 0 );\n\n\t\t\t// Check if this is dragstart over the widget (but not a nested editable).\n\t\t\tconst draggableWidget = data.target ? findDraggableWidget( data.target ) : null;\n\n\t\t\tif ( draggableWidget ) {\n\t\t\t\tconst modelElement = editor.editing.mapper.toModelElement( draggableWidget );\n\n\t\t\t\tthis._draggedRange = LiveRange.fromRange( model.createRangeOn( modelElement ) );\n\n\t\t\t\t// Disable toolbars so they won't obscure the drop area.\n\t\t\t\tif ( editor.plugins.has( 'WidgetToolbarRepository' ) ) {\n\t\t\t\t\teditor.plugins.get( 'WidgetToolbarRepository' ).forceDisabled( 'dragDrop' );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If this was not a widget we should check if we need to drag some text content.\n\t\t\telse if ( !viewDocument.selection.isCollapsed ) {\n\t\t\t\tconst selectedElement = viewDocument.selection.getSelectedElement();\n\n\t\t\t\tif ( !selectedElement || !isWidget( selectedElement ) ) {\n\t\t\t\t\tthis._draggedRange = LiveRange.fromRange( selection.getFirstRange() );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( !this._draggedRange ) {\n\t\t\t\tdata.preventDefault();\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis._draggingUid = uid();\n\n\t\t\tdata.dataTransfer.effectAllowed = this.isEnabled ? 'copyMove' : 'copy';\n\t\t\tdata.dataTransfer.setData( 'application/ckeditor5-dragging-uid', this._draggingUid );\n\n\t\t\tconst draggedSelection = model.createSelection( this._draggedRange.toRange() );\n\t\t\tconst content = editor.data.toView( model.getSelectedContent( draggedSelection ) );\n\n\t\t\tviewDocument.fire( 'clipboardOutput', { dataTransfer: data.dataTransfer, content, method: evt.name } );\n\n\t\t\tif ( !this.isEnabled ) {\n\t\t\t\tthis._draggedRange.detach();\n\t\t\t\tthis._draggedRange = null;\n\t\t\t\tthis._draggingUid = '';\n\t\t\t}\n\t\t}, { priority: 'low' } );\n\n\t\t// The handler for finalizing drag and drop. It should always be triggered after dragging completes\n\t\t// even if it was completed in a different application.\n\t\t// Note: This is not fired if source text node got removed while downcasting a marker.\n\t\tthis.listenTo( viewDocument, 'dragend', ( evt, data ) => {\n\t\t\tthis._finalizeDragging( !data.dataTransfer.isCanceled && data.dataTransfer.dropEffect == 'move' );\n\t\t}, { priority: 'low' } );\n\n\t\t// Dragging over the editable.\n\t\tthis.listenTo( viewDocument, 'dragenter', () => {\n\t\t\tif ( !this.isEnabled ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tview.focus();\n\t\t} );\n\n\t\t// Dragging out of the editable.\n\t\tthis.listenTo( viewDocument, 'dragleave', () => {\n\t\t\t// We do not know if the mouse left the editor or just some element in it, so let us wait a few milliseconds\n\t\t\t// to check if 'dragover' is not fired.\n\t\t\tthis._removeDropMarkerDelayed();\n\t\t} );\n\n\t\t// Handler for moving dragged content over the target area.\n\t\tthis.listenTo( viewDocument, 'dragging', ( evt, data ) => {\n\t\t\tif ( !this.isEnabled ) {\n\t\t\t\tdata.dataTransfer.dropEffect = 'none';\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis._removeDropMarkerDelayed.cancel();\n\n\t\t\tconst targetRange = findDropTargetRange( editor, data.targetRanges, data.target );\n\n\t\t\t// If this is content being dragged from another editor, moving out of current editor instance\n\t\t\t// is not possible until 'dragend' event case will be fixed.\n\t\t\tif ( !this._draggedRange ) {\n\t\t\t\tdata.dataTransfer.dropEffect = 'copy';\n\t\t\t}\n\n\t\t\t// In Firefox it is already set and effect allowed remains the same as originally set.\n\t\t\tif ( !env.isGecko ) {\n\t\t\t\tif ( data.dataTransfer.effectAllowed == 'copy' ) {\n\t\t\t\t\tdata.dataTransfer.dropEffect = 'copy';\n\t\t\t\t} else if ( [ 'all', 'copyMove' ].includes( data.dataTransfer.effectAllowed ) ) {\n\t\t\t\t\tdata.dataTransfer.dropEffect = 'move';\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t/* istanbul ignore else */\n\t\t\tif ( targetRange ) {\n\t\t\t\tthis._updateDropMarkerThrottled( targetRange );\n\t\t\t}\n\t\t}, { priority: 'low' } );\n\t}\n\n\t/**\n\t * Integration with the `clipboardInput` event.\n\t *\n\t * @private\n\t */\n\t_setupClipboardInputIntegration() {\n\t\tconst editor = this.editor;\n\t\tconst view = editor.editing.view;\n\t\tconst viewDocument = view.document;\n\n\t\t// Update the event target ranges and abort dropping if dropping over itself.\n\t\tthis.listenTo( viewDocument, 'clipboardInput', ( evt, data ) => {\n\t\t\tif ( data.method != 'drop' ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst targetRange = findDropTargetRange( editor, data.targetRanges, data.target );\n\n\t\t\t// The dragging markers must be removed after searching for the target range because sometimes\n\t\t\t// the target lands on the marker itself.\n\t\t\tthis._removeDropMarker();\n\n\t\t\t/* istanbul ignore if */\n\t\t\tif ( !targetRange ) {\n\t\t\t\tthis._finalizeDragging( false );\n\t\t\t\tevt.stop();\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Since we cannot rely on the drag end event, we must check if the local drag range is from the current drag and drop\n\t\t\t// or it is from some previous not cleared one.\n\t\t\tif ( this._draggedRange && this._draggingUid != data.dataTransfer.getData( 'application/ckeditor5-dragging-uid' ) ) {\n\t\t\t\tthis._draggedRange.detach();\n\t\t\t\tthis._draggedRange = null;\n\t\t\t\tthis._draggingUid = '';\n\t\t\t}\n\n\t\t\t// Do not do anything if some content was dragged within the same document to the same position.\n\t\t\tconst isMove = getFinalDropEffect( data.dataTransfer ) == 'move';\n\n\t\t\tif ( isMove && this._draggedRange && this._draggedRange.containsRange( targetRange, true ) ) {\n\t\t\t\tthis._finalizeDragging( false );\n\t\t\t\tevt.stop();\n\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Override the target ranges with the one adjusted to the best one for a drop.\n\t\t\tdata.targetRanges = [ editor.editing.mapper.toViewRange( targetRange ) ];\n\t\t}, { priority: 'high' } );\n\t}\n\n\t/**\n\t * Integration with the `contentInsertion` event of the clipboard pipeline.\n\t *\n\t * @private\n\t */\n\t_setupContentInsertionIntegration() {\n\t\tconst clipboardPipeline = this.editor.plugins.get( ClipboardPipeline );\n\n\t\tclipboardPipeline.on( 'contentInsertion', ( evt, data ) => {\n\t\t\tif ( !this.isEnabled || data.method !== 'drop' ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Update the selection to the target range in the same change block to avoid selection post-fixing\n\t\t\t// and to be able to clone text attributes for plain text dropping.\n\t\t\tconst ranges = data.targetRanges.map( viewRange => this.editor.editing.mapper.toModelRange( viewRange ) );\n\n\t\t\tthis.editor.model.change( writer => writer.setSelection( ranges ) );\n\t\t}, { priority: 'high' } );\n\n\t\tclipboardPipeline.on( 'contentInsertion', ( evt, data ) => {\n\t\t\tif ( !this.isEnabled || data.method !== 'drop' ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Remove dragged range content, remove markers, clean after dragging.\n\t\t\tconst isMove = getFinalDropEffect( data.dataTransfer ) == 'move';\n\n\t\t\t// Whether any content was inserted (insertion might fail if the schema is disallowing some elements\n\t\t\t// (for example an image caption allows only the content of a block but not blocks themselves.\n\t\t\t// Some integrations might not return valid range (i.e., table pasting).\n\t\t\tconst isSuccess = !data.resultRange || !data.resultRange.isCollapsed;\n\n\t\t\tthis._finalizeDragging( isSuccess && isMove );\n\t\t}, { priority: 'lowest' } );\n\t}\n\n\t/**\n\t * Adds listeners that add the `draggable` attribute to the elements while the mouse button is down so the dragging could start.\n\t *\n\t * @private\n\t */\n\t_setupDraggableAttributeHandling() {\n\t\tconst editor = this.editor;\n\t\tconst view = editor.editing.view;\n\t\tconst viewDocument = view.document;\n\n\t\t// Add the 'draggable' attribute to the widget while pressing the selection handle.\n\t\t// This is required for widgets to be draggable. In Chrome it will enable dragging text nodes.\n\t\tthis.listenTo( viewDocument, 'mousedown', ( evt, data ) => {\n\t\t\t// The lack of data can be caused by editor tests firing fake mouse events. This should not occur\n\t\t\t// in real-life scenarios but this greatly simplifies editor tests that would otherwise fail a lot.\n\t\t\tif ( env.isAndroid || !data ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis._clearDraggableAttributesDelayed.cancel();\n\n\t\t\t// Check if this is a mousedown over the widget (but not a nested editable).\n\t\t\tlet draggableElement = findDraggableWidget( data.target );\n\n\t\t\t// Note: There is a limitation that if more than a widget is selected (a widget and some text)\n\t\t\t// and dragging starts on the widget, then only the widget is dragged.\n\n\t\t\t// If this was not a widget then we should check if we need to drag some text content.\n\t\t\t// In Chrome set a 'draggable' attribute on closest editable to allow immediate dragging of the selected text range.\n\t\t\t// In Firefox this is not needed. In Safari it makes the whole editable draggable (not just textual content).\n\t\t\t// Disabled in read-only mode because draggable=\"true\" + contenteditable=\"false\" results\n\t\t\t// in not firing selectionchange event ever, which makes the selection stuck in read-only mode.\n\t\t\tif ( env.isBlink && !editor.isReadOnly && !draggableElement && !viewDocument.selection.isCollapsed ) {\n\t\t\t\tconst selectedElement = viewDocument.selection.getSelectedElement();\n\n\t\t\t\tif ( !selectedElement || !isWidget( selectedElement ) ) {\n\t\t\t\t\tdraggableElement = viewDocument.selection.editableElement;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( draggableElement ) {\n\t\t\t\tview.change( writer => {\n\t\t\t\t\twriter.setAttribute( 'draggable', 'true', draggableElement );\n\t\t\t\t} );\n\n\t\t\t\t// Keep the reference to the model element in case the view element gets removed while dragging.\n\t\t\t\tthis._draggableElement = editor.editing.mapper.toModelElement( draggableElement );\n\t\t\t}\n\t\t} );\n\n\t\t// Remove the draggable attribute in case no dragging started (only mousedown + mouseup).\n\t\tthis.listenTo( viewDocument, 'mouseup', () => {\n\t\t\tif ( !env.isAndroid ) {\n\t\t\t\tthis._clearDraggableAttributesDelayed();\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Removes the `draggable` attribute from the element that was used for dragging.\n\t *\n\t * @private\n\t */\n\t_clearDraggableAttributes() {\n\t\tconst editing = this.editor.editing;\n\n\t\tediting.view.change( writer => {\n\t\t\t// Remove 'draggable' attribute.\n\t\t\tif ( this._draggableElement && this._draggableElement.root.rootName != '$graveyard' ) {\n\t\t\t\twriter.removeAttribute( 'draggable', editing.mapper.toViewElement( this._draggableElement ) );\n\t\t\t}\n\n\t\t\tthis._draggableElement = null;\n\t\t} );\n\t}\n\n\t/**\n\t * Creates downcast conversion for the drop target marker.\n\t *\n\t * @private\n\t */\n\t_setupDropMarker() {\n\t\tconst editor = this.editor;\n\n\t\t// Drop marker conversion for hovering over widgets.\n\t\teditor.conversion.for( 'editingDowncast' ).markerToHighlight( {\n\t\t\tmodel: 'drop-target',\n\t\t\tview: {\n\t\t\t\tclasses: [ 'ck-clipboard-drop-target-range' ]\n\t\t\t}\n\t\t} );\n\n\t\t// Drop marker conversion for in text drop target.\n\t\teditor.conversion.for( 'editingDowncast' ).markerToElement( {\n\t\t\tmodel: 'drop-target',\n\t\t\tview: ( data, { writer } ) => {\n\t\t\t\tconst inText = editor.model.schema.checkChild( data.markerRange.start, '$text' );\n\n\t\t\t\tif ( !inText ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\treturn writer.createUIElement( 'span', { class: 'ck ck-clipboard-drop-target-position' }, function( domDocument ) {\n\t\t\t\t\tconst domElement = this.toDomElement( domDocument );\n\n\t\t\t\t\t// Using word joiner to make this marker as high as text and also making text not break on marker.\n\t\t\t\t\tdomElement.innerHTML = '⁠⁠';\n\n\t\t\t\t\treturn domElement;\n\t\t\t\t} );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Updates the drop target marker to the provided range.\n\t *\n\t * @private\n\t * @param {module:engine/model/range~Range} targetRange The range to set the marker to.\n\t */\n\t_updateDropMarker( targetRange ) {\n\t\tconst editor = this.editor;\n\t\tconst markers = editor.model.markers;\n\n\t\teditor.model.change( writer => {\n\t\t\tif ( markers.has( 'drop-target' ) ) {\n\t\t\t\tif ( !markers.get( 'drop-target' ).getRange().isEqual( targetRange ) ) {\n\t\t\t\t\twriter.updateMarker( 'drop-target', { range: targetRange } );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\twriter.addMarker( 'drop-target', {\n\t\t\t\t\trange: targetRange,\n\t\t\t\t\tusingOperation: false,\n\t\t\t\t\taffectsData: false\n\t\t\t\t} );\n\t\t\t}\n\t\t} );\n\t}\n\n\t/**\n\t * Removes the drop target marker.\n\t *\n\t * @private\n\t */\n\t_removeDropMarker() {\n\t\tconst model = this.editor.model;\n\n\t\tthis._removeDropMarkerDelayed.cancel();\n\t\tthis._updateDropMarkerThrottled.cancel();\n\n\t\tif ( model.markers.has( 'drop-target' ) ) {\n\t\t\tmodel.change( writer => {\n\t\t\t\twriter.removeMarker( 'drop-target' );\n\t\t\t} );\n\t\t}\n\t}\n\n\t/**\n\t * Deletes the dragged content from its original range and clears the dragging state.\n\t *\n\t * @private\n\t * @param {Boolean} moved Whether the move succeeded.\n\t */\n\t_finalizeDragging( moved ) {\n\t\tconst editor = this.editor;\n\t\tconst model = editor.model;\n\n\t\tthis._removeDropMarker();\n\t\tthis._clearDraggableAttributes();\n\n\t\tif ( editor.plugins.has( 'WidgetToolbarRepository' ) ) {\n\t\t\teditor.plugins.get( 'WidgetToolbarRepository' ).clearForceDisabled( 'dragDrop' );\n\t\t}\n\n\t\tthis._draggingUid = '';\n\n\t\tif ( !this._draggedRange ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Delete moved content.\n\t\tif ( moved && this.isEnabled ) {\n\t\t\tmodel.deleteContent( model.createSelection( this._draggedRange ), { doNotAutoparagraph: true } );\n\t\t}\n\n\t\tthis._draggedRange.detach();\n\t\tthis._draggedRange = null;\n\t}\n}\n\n// Returns fixed selection range for given position and target element.\n//\n// @param {module:core/editor/editor~Editor} editor\n// @param {Array.} targetViewRanges\n// @param {module:engine/view/element~Element} targetViewElement\n// @returns {module:engine/model/range~Range|null}\nfunction findDropTargetRange( editor, targetViewRanges, targetViewElement ) {\n\tconst model = editor.model;\n\tconst mapper = editor.editing.mapper;\n\n\tlet range = null;\n\n\tconst targetViewPosition = targetViewRanges ? targetViewRanges[ 0 ].start : null;\n\n\t// A UIElement is not a valid drop element, use parent (this could be a drop marker or any other UIElement).\n\tif ( targetViewElement.is( 'uiElement' ) ) {\n\t\ttargetViewElement = targetViewElement.parent;\n\t}\n\n\t// Quick win if the target is a widget (but not a nested editable).\n\trange = findDropTargetRangeOnWidget( editor, targetViewElement );\n\n\tif ( range ) {\n\t\treturn range;\n\t}\n\n\t// The easiest part is over, now we need to move to the model space.\n\n\t// Find target model element and position.\n\tconst targetModelElement = getClosestMappedModelElement( editor, targetViewElement );\n\tconst targetModelPosition = targetViewPosition ? mapper.toModelPosition( targetViewPosition ) : null;\n\n\t// There is no target position while hovering over an empty table cell.\n\t// In Safari, target position can be empty while hovering over a widget (e.g., a page-break).\n\t// Find the drop position inside the element.\n\tif ( !targetModelPosition ) {\n\t\treturn findDropTargetRangeInElement( editor, targetModelElement );\n\t}\n\n\t// Check if target position is between blocks and adjust drop position to the next object.\n\t// This is because while hovering over a root element next to a widget the target position can jump in crazy places.\n\trange = findDropTargetRangeBetweenBlocks( editor, targetModelPosition, targetModelElement );\n\n\tif ( range ) {\n\t\treturn range;\n\t}\n\n\t// Try fixing selection position.\n\t// In Firefox, the target position lands before widgets but in other browsers it tends to land after a widget.\n\trange = model.schema.getNearestSelectionRange( targetModelPosition, env.isGecko ? 'forward' : 'backward' );\n\n\tif ( range ) {\n\t\treturn range;\n\t}\n\n\t// There is no valid selection position inside the current limit element so find a closest object ancestor.\n\t// This happens if the model position lands directly in the element itself (view target element was a `
`\n\t// so a nested editable, but view target position was directly in the `
` element).\n\treturn findDropTargetRangeOnAncestorObject( editor, targetModelPosition.parent );\n}\n\n// Returns fixed selection range for a given position and a target element if it is over the widget but not over its nested editable.\n//\n// @param {module:core/editor/editor~Editor} editor\n// @param {module:engine/view/element~Element} targetViewElement\n// @returns {module:engine/model/range~Range|null}\nfunction findDropTargetRangeOnWidget( editor, targetViewElement ) {\n\tconst model = editor.model;\n\tconst mapper = editor.editing.mapper;\n\n\t// Quick win if the target is a widget.\n\tif ( isWidget( targetViewElement ) ) {\n\t\treturn model.createRangeOn( mapper.toModelElement( targetViewElement ) );\n\t}\n\n\t// Check if we are deeper over a widget (but not over a nested editable).\n\tif ( !targetViewElement.is( 'editableElement' ) ) {\n\t\t// Find a closest ancestor that is either a widget or an editable element...\n\t\tconst ancestor = targetViewElement.findAncestor( node => isWidget( node ) || node.is( 'editableElement' ) );\n\n\t\t// ...and if the widget was closer then it is a drop target.\n\t\tif ( isWidget( ancestor ) ) {\n\t\t\treturn model.createRangeOn( mapper.toModelElement( ancestor ) );\n\t\t}\n\t}\n\n\treturn null;\n}\n\n// Returns fixed selection range inside a model element.\n//\n// @param {module:core/editor/editor~Editor} editor\n// @param {module:engine/model/element~Element} targetModelElement\n// @returns {module:engine/model/range~Range}\nfunction findDropTargetRangeInElement( editor, targetModelElement ) {\n\tconst model = editor.model;\n\tconst schema = model.schema;\n\n\tconst positionAtElementStart = model.createPositionAt( targetModelElement, 0 );\n\n\treturn schema.getNearestSelectionRange( positionAtElementStart, 'forward' );\n}\n\n// Returns fixed selection range for a given position and a target element if the drop is between blocks.\n//\n// @param {module:core/editor/editor~Editor} editor\n// @param {module:engine/model/position~Position} targetModelPosition\n// @param {module:engine/model/element~Element} targetModelElement\n// @returns {module:engine/model/range~Range|null}\nfunction findDropTargetRangeBetweenBlocks( editor, targetModelPosition, targetModelElement ) {\n\tconst model = editor.model;\n\n\t// Check if target is between blocks.\n\tif ( !model.schema.checkChild( targetModelElement, '$block' ) ) {\n\t\treturn null;\n\t}\n\n\t// Find position between blocks.\n\tconst positionAtElementStart = model.createPositionAt( targetModelElement, 0 );\n\n\t// Get the common part of the path (inside the target element and the target position).\n\tconst commonPath = targetModelPosition.path.slice( 0, positionAtElementStart.path.length );\n\n\t// Position between the blocks.\n\tconst betweenBlocksPosition = model.createPositionFromPath( targetModelPosition.root, commonPath );\n\tconst nodeAfter = betweenBlocksPosition.nodeAfter;\n\n\t// Adjust drop position to the next object.\n\t// This is because while hovering over a root element next to a widget the target position can jump in crazy places.\n\tif ( nodeAfter && model.schema.isObject( nodeAfter ) ) {\n\t\treturn model.createRangeOn( nodeAfter );\n\t}\n\n\treturn null;\n}\n\n// Returns a selection range on the ancestor object.\n//\n// @param {module:core/editor/editor~Editor} editor\n// @param {module:engine/model/element~Element} element\n// @returns {module:engine/model/range~Range}\nfunction findDropTargetRangeOnAncestorObject( editor, element ) {\n\tconst model = editor.model;\n\n\twhile ( element ) {\n\t\tif ( model.schema.isObject( element ) ) {\n\t\t\treturn model.createRangeOn( element );\n\t\t}\n\n\t\telement = element.parent;\n\t}\n}\n\n// Returns the closest model element for the specified view element.\n//\n// @param {module:core/editor/editor~Editor} editor\n// @param {module:engine/view/element~Element} element\n// @returns {module:engine/model/element~Element}\nfunction getClosestMappedModelElement( editor, element ) {\n\tconst mapper = editor.editing.mapper;\n\tconst view = editor.editing.view;\n\n\tconst targetModelElement = mapper.toModelElement( element );\n\n\tif ( targetModelElement ) {\n\t\treturn targetModelElement;\n\t}\n\n\t// Find mapped ancestor if the target is inside not mapped element (for example inline code element).\n\tconst viewPosition = view.createPositionBefore( element );\n\tconst viewElement = mapper.findMappedViewAncestor( viewPosition );\n\n\treturn mapper.toModelElement( viewElement );\n}\n\n// Returns the drop effect that should be a result of dragging the content.\n// This function is handling a quirk when checking the effect in the 'drop' DOM event.\nfunction getFinalDropEffect( dataTransfer ) {\n\tif ( env.isGecko ) {\n\t\treturn dataTransfer.dropEffect;\n\t}\n\n\treturn [ 'all', 'copyMove' ].includes( dataTransfer.effectAllowed ) ? 'move' : 'copy';\n}\n\n// Returns a function wrapper that will trigger a function after a specified wait time.\n// The timeout can be canceled by calling the cancel function on the returned wrapped function.\n//\n// @param {Function} func The function to wrap.\n// @param {Number} wait The timeout in ms.\n// @returns {Function}\nfunction delay( func, wait ) {\n\tlet timer;\n\n\tfunction delayed( ...args ) {\n\t\tdelayed.cancel();\n\t\ttimer = setTimeout( () => func( ...args ), wait );\n\t}\n\n\tdelayed.cancel = () => {\n\t\tclearTimeout( timer );\n\t};\n\n\treturn delayed;\n}\n\n// Returns a widget element that should be dragged.\n//\n// @param {module:engine/view/element~Element} target\n// @returns {module:engine/view/element~Element}\nfunction findDraggableWidget( target ) {\n\t// This is directly an editable so not a widget for sure.\n\tif ( target.is( 'editableElement' ) ) {\n\t\treturn null;\n\t}\n\n\t// TODO: Let's have a isWidgetSelectionHandleDomElement() helper in ckeditor5-widget utils.\n\tif ( target.hasClass( 'ck-widget__selection-handle' ) ) {\n\t\treturn target.findAncestor( isWidget );\n\t}\n\n\t// Direct hit on a widget.\n\tif ( isWidget( target ) ) {\n\t\treturn target;\n\t}\n\n\t// Find closest ancestor that is either a widget or an editable element...\n\tconst ancestor = target.findAncestor( node => isWidget( node ) || node.is( 'editableElement' ) );\n\n\t// ...and if closer was the widget then enable dragging it.\n\tif ( isWidget( ancestor ) ) {\n\t\treturn ancestor;\n\t}\n\n\treturn null;\n}\n"],"sourceRoot":""}