index.js.map 94 KB

1
  1. {"version":3,"file":"index.js","sources":["internal/constants.ts","internal/feature-detection.ts","internal/dom-utils.ts","internal/drag-data-store.ts","internal/drag-utils.ts","internal/drag-operation-controller.ts","index.ts"],"sourcesContent":["// debug mode, which will highlight drop target, immediate user selection and events fired as you interact\n// only available in non-minified js / development environment\n// export const DEBUG = false;\n\n// css classes\nexport const CLASS_PREFIX = \"dnd-poly-\";\nexport const CLASS_DRAG_IMAGE = CLASS_PREFIX + \"drag-image\";\nexport const CLASS_DRAG_IMAGE_SNAPBACK = CLASS_PREFIX + \"snapback\";\nexport const CLASS_DRAG_OPERATION_ICON = CLASS_PREFIX + \"icon\";\n\n// custom event\nexport const EVENT_PREFIX = \"dnd-poly-\";\nexport const EVENT_DRAG_DRAGSTART_PENDING = EVENT_PREFIX + \"dragstart-pending\";\nexport const EVENT_DRAG_DRAGSTART_CANCEL = EVENT_PREFIX + \"dragstart-cancel\";\n\n// defines the array indexes to access string in ALLOWED_EFFECTS\nexport const enum EFFECT_ALLOWED {\n NONE = 0,\n COPY = 1,\n COPY_LINK = 2,\n COPY_MOVE = 3,\n LINK = 4,\n LINK_MOVE = 5,\n MOVE = 6,\n ALL = 7\n}\n\n// contains all possible values of the effectAllowed property\nexport const ALLOWED_EFFECTS = [ \"none\", \"copy\", \"copyLink\", \"copyMove\", \"link\", \"linkMove\", \"move\", \"all\" ];\n\n// defines the array indexes to access string in DROP_EFFECTS\nexport const enum DROP_EFFECT {\n NONE = 0,\n COPY = 1,\n MOVE = 2,\n LINK = 3,\n}\n\n// contains all possible values of the dropEffect property\nexport const DROP_EFFECTS = [ \"none\", \"copy\", \"move\", \"link\" ];\n","export interface DetectedFeatures {\n draggable:boolean;\n dragEvents:boolean;\n userAgentSupportingNativeDnD:boolean;\n}\n\nexport function detectFeatures():DetectedFeatures {\n\n let features:DetectedFeatures = {\n dragEvents: (\"ondragstart\" in document.documentElement),\n draggable: (\"draggable\" in document.documentElement),\n userAgentSupportingNativeDnD: undefined\n };\n\n const isBlinkEngine = !!((<any>window).chrome) || /chrome/i.test( navigator.userAgent );\n\n features.userAgentSupportingNativeDnD = !(\n // if is mobile safari or android browser -> no native dnd\n (/iPad|iPhone|iPod|Android/.test( navigator.userAgent ))\n || // OR\n //if is blink(chrome/opera) with touch events enabled -> no native dnd\n (isBlinkEngine && (\"ontouchstart\" in document.documentElement))\n );\n\n return features;\n}\n\nexport function supportsPassiveEventListener():boolean {\n\n let supportsPassiveEventListeners = false;\n\n // reference https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md\n try {\n let opts = Object.defineProperty( {}, \"passive\", {\n get: function() {\n supportsPassiveEventListeners = true;\n }\n } );\n window.addEventListener( \"test\", null, opts );\n }\n // tslint:disable-next-line:no-empty\n catch( e ) {\n }\n\n return supportsPassiveEventListeners;\n}\n","import { CLASS_DRAG_IMAGE_SNAPBACK } from \"./constants\";\nimport { supportsPassiveEventListener } from \"./feature-detection\";\n\n// evaluate once on startup\nconst supportsPassive = supportsPassiveEventListener();\n\nexport interface Point {\n x:number;\n y:number;\n}\n\nexport function isDOMElement( object:Element ) {\n return object && object.tagName;\n}\n\nexport function addDocumentListener( ev:string, handler:EventListener, passive:boolean = true ) {\n document.addEventListener( ev, handler, supportsPassive ? { passive: passive } : false );\n}\n\nexport function removeDocumentListener( ev:string, handler:EventListener ) {\n document.removeEventListener( ev, handler );\n}\n\nexport function onEvt(el:EventTarget, event:string, handler:EventListener, capture:boolean = false) {\n\n const options = supportsPassive ? {passive: true, capture: capture} : capture;\n\n el.addEventListener(event, handler, options);\n\n return {\n off() {\n el.removeEventListener(event, handler, options as any);\n }\n };\n}\n\nfunction prepareNodeCopyAsDragImage( srcNode:HTMLElement, dstNode:HTMLElement ) {\n\n // Is this node an element?\n if( srcNode.nodeType === 1 ) {\n\n // Clone the style\n const cs = getComputedStyle( srcNode );\n for( let i = 0; i < cs.length; i++ ) {\n const csName = cs[ i ];\n dstNode.style.setProperty( csName, cs.getPropertyValue( csName ), cs.getPropertyPriority( csName ) );\n }\n\n // no interaction with the drag image, pls! this is also important to make the drag image transparent for hit-testing\n // hit testing is done in the drag and drop iteration to find the element the user currently is hovering over while dragging.\n // if pointer-events is not none or a browser does behave in an unexpected way than the hit test transparency on the drag image\n // will break\n dstNode.style.pointerEvents = \"none\";\n\n // Remove any potential conflict attributes\n dstNode.removeAttribute( \"id\" );\n dstNode.removeAttribute( \"class\" );\n dstNode.removeAttribute( \"draggable\" );\n\n // canvas elements need special handling by copying canvas image data\n if( dstNode.nodeName === \"CANVAS\" ) {\n\n const canvasSrc = srcNode as HTMLCanvasElement;\n const canvasDst = dstNode as HTMLCanvasElement;\n\n const canvasSrcImgData = canvasSrc.getContext( \"2d\" ).getImageData( 0, 0, canvasSrc.width, canvasSrc.height );\n\n canvasDst.getContext( \"2d\" ).putImageData( canvasSrcImgData, 0, 0 );\n }\n }\n\n // Do the same for the children\n if( srcNode.hasChildNodes() ) {\n\n for( let i = 0; i < srcNode.childNodes.length; i++ ) {\n\n prepareNodeCopyAsDragImage( <HTMLElement>srcNode.childNodes[ i ], <HTMLElement>dstNode.childNodes[ i ] );\n }\n }\n}\n\nexport function createDragImage( sourceNode:HTMLElement ):HTMLElement {\n\n const dragImage = <HTMLElement>sourceNode.cloneNode( true );\n\n // this removes any id's and stuff that could interfere with drag and drop\n prepareNodeCopyAsDragImage( sourceNode, dragImage );\n\n return dragImage;\n}\n\nfunction average( array:Array<number> ) {\n if( array.length === 0 ) {\n return 0;\n }\n return array.reduce( (function( s, v ) {\n return v + s;\n }), 0 ) / array.length;\n}\n\nexport function isTouchIdentifierContainedInTouchEvent( touchEvent:TouchEvent, touchIdentifier:number ) {\n for( let i = 0; i < touchEvent.changedTouches.length; i++ ) {\n const touch = touchEvent.changedTouches[ i ];\n if( touch.identifier === touchIdentifier ) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Calc center of polygon spanned by multiple touches in page (full page size, with hidden scrollable area) coordinates\n * or in viewport (screen coordinates) coordinates.\n */\nexport function updateCentroidCoordinatesOfTouchesIn( coordinateProp:\"page\" | \"client\", event:TouchEvent, outPoint:Point ):void {\n const pageXs:Array<number> = [], pageYs:Array<number> = [];\n for( let i = 0; i < event.touches.length; i++ ) {\n const touch = event.touches[ i ];\n pageXs.push( touch[ coordinateProp + \"X\" ] );\n pageYs.push( touch[ coordinateProp + \"Y\" ] );\n }\n outPoint.x = average( pageXs );\n outPoint.y = average( pageYs );\n}\n\n// cross-browser css transform property prefixes\nconst TRANSFORM_CSS_VENDOR_PREFIXES = [ \"\", \"-webkit-\" ];\n\nexport function extractTransformStyles( sourceNode:HTMLElement ):string[] {\n\n return TRANSFORM_CSS_VENDOR_PREFIXES.map( function( prefix:string ) {\n\n let transform = sourceNode.style[ prefix + \"transform\" ];\n\n if( !transform || transform === \"none\" ) {\n return \"\";\n }\n\n // removes translate(x,y)\n return transform.replace( /translate\\(\\D*\\d+[^,]*,\\D*\\d+[^,]*\\)\\s*/g, \"\" );\n } );\n}\n\nexport function translateElementToPoint( element:HTMLElement, pnt:Point, originalTransforms:string[], offset?:Point, centerOnCoordinates = true ):void {\n\n let x = pnt.x, y = pnt.y;\n\n if( offset ) {\n x += offset.x;\n y += offset.y;\n }\n\n if( centerOnCoordinates ) {\n x -= (parseInt( <any>element.offsetWidth, 10 ) / 2);\n y -= (parseInt( <any>element.offsetHeight, 10 ) / 2);\n }\n\n // using translate3d for max performance\n const translate = \"translate3d(\" + x + \"px,\" + y + \"px, 0)\";\n\n for( let i = 0; i < TRANSFORM_CSS_VENDOR_PREFIXES.length; i++ ) {\n const transformProp = TRANSFORM_CSS_VENDOR_PREFIXES[ i ] + \"transform\";\n element.style[ transformProp ] = translate + \" \" + originalTransforms[ i ];\n }\n}\n\n/**\n * calculates the coordinates of the drag source and transitions the drag image to those coordinates.\n * the drag operation is finished after the transition has ended.\n */\nexport function applyDragImageSnapback( sourceEl:HTMLElement, dragImage:HTMLElement, dragImageTransforms:string[], transitionEndCb:Function ):void {\n\n const cs = getComputedStyle( sourceEl );\n\n if( cs.visibility === \"hidden\" || cs.display === \"none\" ) {\n console.log( \"dnd-poly: source node is not visible. skipping snapback transition.\" );\n // shortcut to end the drag operation\n transitionEndCb();\n return;\n }\n // add class containing transition rules\n dragImage.classList.add( CLASS_DRAG_IMAGE_SNAPBACK );\n\n const csDragImage = getComputedStyle( dragImage );\n const durationInS = parseFloat( csDragImage.transitionDuration );\n if( isNaN( durationInS ) || durationInS === 0 ) {\n console.log( \"dnd-poly: no transition used - skipping snapback\" );\n transitionEndCb();\n return;\n }\n\n console.log( \"dnd-poly: starting dragimage snap back\" );\n\n // calc source node position\n const rect = sourceEl.getBoundingClientRect();\n\n const pnt:Point = {\n x: rect.left,\n y: rect.top\n };\n\n // add scroll offset of document\n pnt.x += (document.body.scrollLeft || document.documentElement.scrollLeft);\n pnt.y += (document.body.scrollTop || document.documentElement.scrollTop);\n\n //TODO this sometimes fails to calculate the correct origin position.. find out when exactly and how to detect\n pnt.x -= parseInt( cs.marginLeft, 10 );\n pnt.y -= parseInt( cs.marginTop, 10 );\n\n const delayInS = parseFloat( csDragImage.transitionDelay );\n const durationInMs = Math.round( (durationInS + delayInS) * 1000 );\n\n // apply the translate\n translateElementToPoint( dragImage, pnt, dragImageTransforms, undefined, false );\n\n setTimeout( transitionEndCb, durationInMs );\n}\n","import { ALLOWED_EFFECTS, DROP_EFFECT, DROP_EFFECTS } from \"./constants\";\n\n/**\n * Polyfills https://html.spec.whatwg.org/multipage/interaction.html#drag-data-store-mode\n */\nexport const enum DragDataStoreMode {\n _DISCONNECTED, // adding an extra mode here because we need a special state to disconnect the data store from dataTransfer instance\n READONLY,\n READWRITE,\n PROTECTED\n}\n\n/**\n * Polyfills https://html.spec.whatwg.org/multipage/interaction.html#the-drag-data-store\n */\nexport interface DragDataStore {\n mode:DragDataStoreMode;\n data:{ [type:string]:any };\n types:Array<string>;\n effectAllowed:string;\n}\n\n/**\n * Polyfills https://html.spec.whatwg.org/multipage/interaction.html#datatransfer\n */\nexport class DataTransfer {\n\n private _dropEffect:string = DROP_EFFECTS[ DROP_EFFECT.NONE ];\n\n public get dropEffect() {\n return this._dropEffect;\n }\n\n //public get files():FileList {\n // return undefined;\n //}\n //\n //public get items():DataTransferItemList {\n // return undefined;\n //}\n\n public set dropEffect( value ) {\n if( this._dataStore.mode !== DragDataStoreMode._DISCONNECTED\n && ALLOWED_EFFECTS.indexOf( value ) > -1 ) {\n this._dropEffect = value;\n }\n }\n\n public get types():ReadonlyArray<string> {\n if( this._dataStore.mode !== DragDataStoreMode._DISCONNECTED ) {\n return Object.freeze( this._dataStore.types );\n }\n }\n\n public get effectAllowed() {\n return this._dataStore.effectAllowed;\n }\n\n public set effectAllowed( value ) {\n if( this._dataStore.mode === DragDataStoreMode.READWRITE\n && ALLOWED_EFFECTS.indexOf( value ) > -1 ) {\n this._dataStore.effectAllowed = value;\n }\n }\n\n constructor( private _dataStore:DragDataStore,\n private _setDragImageHandler:( image:Element, x:number, y:number ) => void ) {\n }\n\n public setData( type:string, data:string ):void {\n if( this._dataStore.mode === DragDataStoreMode.READWRITE ) {\n\n if( type.indexOf( \" \" ) > -1 ) {\n throw new Error( \"illegal arg: type contains space\" );\n }\n\n this._dataStore.data[ type ] = data;\n\n if( this._dataStore.types.indexOf( type ) === -1 ) {\n this._dataStore.types.push( type );\n }\n }\n }\n\n public getData( type:string ):string {\n if( this._dataStore.mode === DragDataStoreMode.READONLY\n || this._dataStore.mode === DragDataStoreMode.READWRITE ) {\n return this._dataStore.data[ type ] || \"\";\n }\n }\n\n public clearData( format?:string ):void {\n if( this._dataStore.mode === DragDataStoreMode.READWRITE ) {\n // delete data for format\n if( format && this._dataStore.data[ format ] ) {\n delete this._dataStore.data[ format ];\n var index = this._dataStore.types.indexOf( format );\n if( index > -1 ) {\n this._dataStore.types.splice( index, 1 );\n }\n return;\n }\n // delete all data\n this._dataStore.data = {};\n this._dataStore.types = [];\n }\n }\n\n public setDragImage( image:Element, x:number, y:number ):void {\n if( this._dataStore.mode === DragDataStoreMode.READWRITE ) {\n this._setDragImageHandler( image, x, y );\n }\n }\n}\n","import { ALLOWED_EFFECTS, DROP_EFFECT, DROP_EFFECTS, EFFECT_ALLOWED } from \"./constants\";\nimport { DataTransfer, DragDataStore, DragDataStoreMode } from \"./drag-data-store\";\n\n/**\n * Search for a possible draggable item upon an event that can initialize a drag operation.\n * Can be overridden in polyfill config.\n */\nexport function tryFindDraggableTarget( event:TouchEvent ):HTMLElement | undefined {\n\n //1. Determine what is being dragged, as follows:\n\n // THIS IS SKIPPED SINCE SUPPORT IS ONLY AVAILABLE FOR DOM ELEMENTS\n // If the drag operation was invoked on a selection, then it is the selection that is being dragged.\n //if( (<Element>event.target).nodeType === 3 ) {\n //\n // config.log( \"drag on text\" );\n // return <Element>event.target;\n //}\n //Otherwise, if the drag operation was invoked on a Document, it is the first element, going up the ancestor chain, starting at the node that the\n // user tried to drag, that has the IDL attribute draggable set to true.\n //else {\n\n let el = <HTMLElement>event.target;\n\n do {\n if( el.draggable === false ) {\n continue;\n }\n if( el.draggable === true ) {\n return el;\n }\n if( el.getAttribute\n && el.getAttribute( \"draggable\" ) === \"true\" ) {\n return el;\n }\n } while( (el = <HTMLElement>el.parentNode) && el !== document.body );\n}\n\n/**\n * Implements \"6.\" in the processing steps defined for a dnd event\n * https://html.spec.whatwg.org/multipage/interaction.html#dragevent\n */\nexport function determineDropEffect( effectAllowed:string, sourceNode:Element ) {\n\n // uninitialized\n if( !effectAllowed ) {\n\n // THIS IS SKIPPED SINCE SUPPORT IS ONLY AVAILABLE FOR DOM ELEMENTS\n //if( sourceNode.nodeType === 1 ) {\n //\n //return \"move\";\n //}\n\n // link\n if( sourceNode.nodeType === 3 && (<HTMLElement>sourceNode).tagName === \"A\" ) {\n return DROP_EFFECTS[ DROP_EFFECT.LINK ];\n }\n\n // copy\n return DROP_EFFECTS[ DROP_EFFECT.COPY ];\n }\n\n // none\n if( effectAllowed === ALLOWED_EFFECTS[ EFFECT_ALLOWED.NONE ] ) {\n return DROP_EFFECTS[ DROP_EFFECT.NONE ];\n }\n // copy or all\n if( effectAllowed.indexOf( ALLOWED_EFFECTS[ EFFECT_ALLOWED.COPY ] ) === 0 || effectAllowed === ALLOWED_EFFECTS[ EFFECT_ALLOWED.ALL ] ) {\n return DROP_EFFECTS[ DROP_EFFECT.COPY ];\n }\n // link\n if( effectAllowed.indexOf( ALLOWED_EFFECTS[ EFFECT_ALLOWED.LINK ] ) === 0 ) {\n return DROP_EFFECTS[ DROP_EFFECT.LINK ];\n }\n // move\n if( effectAllowed === ALLOWED_EFFECTS[ EFFECT_ALLOWED.MOVE ] ) {\n return DROP_EFFECTS[ DROP_EFFECT.MOVE ];\n }\n\n // copy\n return DROP_EFFECTS[ DROP_EFFECT.COPY ];\n}\n\nfunction createDragEventFromTouch( targetElement:Element,\n e:TouchEvent,\n type:string,\n cancelable:boolean,\n window:Window,\n dataTransfer:DataTransfer,\n relatedTarget:Element = null ) {\n\n const touch:Touch = e.changedTouches[ 0 ];\n\n const dndEvent:DragEvent = new Event( type, {\n bubbles: true,\n cancelable: cancelable\n } ) as DragEvent;\n\n // cast our polyfill\n (dndEvent as any).dataTransfer = dataTransfer as any;\n (dndEvent as any).relatedTarget = relatedTarget;\n\n // set the coordinates\n (dndEvent as any).screenX = touch.screenX;\n (dndEvent as any).screenY = touch.screenY;\n (dndEvent as any).clientX = touch.clientX;\n (dndEvent as any).clientY = touch.clientY;\n (dndEvent as any).pageX = touch.pageX;\n (dndEvent as any).pageY = touch.pageY;\n\n const targetRect = targetElement.getBoundingClientRect();\n (dndEvent as any).offsetX = dndEvent.clientX - targetRect.left;\n (dndEvent as any).offsetY = dndEvent.clientY - targetRect.top;\n\n return dndEvent;\n}\n\n/**\n * Reference https://html.spec.whatwg.org/multipage/interaction.html#dndevents\n */\nexport function dispatchDragEvent( dragEvent:string,\n targetElement:Element,\n touchEvent:TouchEvent,\n dataStore:DragDataStore,\n dataTransfer:DataTransfer,\n cancelable:boolean = true,\n relatedTarget:Element | null = null ):boolean {\n\n console.log( \"dnd-poly: dispatching \" + dragEvent );\n\n // if( DEBUG ) {\n // const debug_class = CLASS_PREFIX + \"debug\",\n // debug_class_event_target = CLASS_PREFIX + \"event-target\",\n // debug_class_event_related_target = CLASS_PREFIX + \"event-related-target\";\n // targetElement.classList.add( debug_class );\n // targetElement.classList.add( debug_class_event_target );\n // if( relatedTarget ) {\n // relatedTarget.classList.add( debug_class );\n // relatedTarget.classList.add( debug_class_event_related_target );\n // }\n // }\n\n const leaveEvt = createDragEventFromTouch( targetElement, touchEvent, dragEvent, cancelable, document.defaultView, dataTransfer, relatedTarget );\n const cancelled = !targetElement.dispatchEvent( leaveEvt );\n\n dataStore.mode = DragDataStoreMode._DISCONNECTED;\n\n // if( DEBUG ) {\n // const debug_class_event_target = CLASS_PREFIX + \"event-target\",\n // debug_class_event_related_target = CLASS_PREFIX + \"event-related-target\";\n // targetElement.classList.remove( debug_class_event_target );\n // if( relatedTarget ) {\n // relatedTarget.classList.remove( debug_class_event_related_target );\n // }\n // }\n\n return cancelled;\n}\n\n/**\n * according to https://html.spec.whatwg.org/multipage/interaction.html#drag-and-drop-processing-model\n */\nexport function determineDragOperation( effectAllowed:string, dropEffect:string ):string {\n\n // unitialized or all\n if( !effectAllowed || effectAllowed === ALLOWED_EFFECTS[ 7 ] ) {\n return dropEffect;\n }\n\n if( dropEffect === DROP_EFFECTS[ DROP_EFFECT.COPY ] ) {\n if( effectAllowed.indexOf( DROP_EFFECTS[ DROP_EFFECT.COPY ] ) === 0 ) {\n return DROP_EFFECTS[ DROP_EFFECT.COPY ];\n }\n }\n else if( dropEffect === DROP_EFFECTS[ DROP_EFFECT.LINK ] ) {\n if( effectAllowed.indexOf( DROP_EFFECTS[ DROP_EFFECT.LINK ] ) === 0 || effectAllowed.indexOf( \"Link\" ) > -1 ) {\n return DROP_EFFECTS[ DROP_EFFECT.LINK ];\n }\n }\n else if( dropEffect === DROP_EFFECTS[ DROP_EFFECT.MOVE ] ) {\n if( effectAllowed.indexOf( DROP_EFFECTS[ DROP_EFFECT.MOVE ] ) === 0 || effectAllowed.indexOf( \"Move\" ) > -1 ) {\n return DROP_EFFECTS[ DROP_EFFECT.MOVE ];\n }\n }\n\n return DROP_EFFECTS[ DROP_EFFECT.NONE ];\n}\n","import { Config } from \"../index\";\nimport {\n CLASS_DRAG_IMAGE, CLASS_DRAG_OPERATION_ICON, CLASS_PREFIX, DROP_EFFECT, DROP_EFFECTS\n} from \"./constants\";\nimport {\n addDocumentListener, applyDragImageSnapback, extractTransformStyles, isDOMElement,\n isTouchIdentifierContainedInTouchEvent, Point, removeDocumentListener, translateElementToPoint,\n updateCentroidCoordinatesOfTouchesIn\n} from \"./dom-utils\";\nimport { DataTransfer, DragDataStore, DragDataStoreMode } from \"./drag-data-store\";\nimport { determineDragOperation, determineDropEffect, dispatchDragEvent } from \"./drag-utils\";\n\n/**\n * For tracking the different states of a drag operation.\n */\nexport const enum DragOperationState {\n // initial state of a controller, if no movement is detected the operation ends with this state\n POTENTIAL,\n // after movement is detected the drag operation starts and keeps this state until it ends\n STARTED,\n // when the drag operation ended normally\n ENDED,\n // when the drag operation ended with a cancelled input event\n CANCELLED\n}\n\n/**\n * Aims to implement the HTML5 d'n'd spec (https://html.spec.whatwg.org/multipage/interaction.html#dnd) as close as it can get.\n * Note that all props that are private should start with an underscore to enable better minification.\n *\n * TODO remove lengthy spec comments in favor of short references to the spec\n */\nexport class DragOperationController {\n\n private _dragOperationState:DragOperationState = DragOperationState.POTENTIAL;\n\n private _dragImage:HTMLElement;\n private _dragImageTransforms:string[];\n private _dragImagePageCoordinates:Point; // the current page coordinates of the dragImage\n private _dragImageOffset:Point; // offset of the drag image relative to the coordinates\n\n private _currentHotspotCoordinates:Point; // the point relative to viewport for determining the immediate user selection\n\n private _immediateUserSelection:HTMLElement = null; // the element the user currently hovers while dragging\n private _currentDropTarget:HTMLElement = null; // the element that was selected as a valid drop target by the d'n'd operation\n\n private _dragDataStore:DragDataStore;\n private _dataTransfer:DataTransfer;\n\n private _currentDragOperation:string; // the current drag operation set according to the d'n'd processing model\n\n private _initialTouch:Touch; // the identifier for the touch that initiated the drag operation\n private _touchMoveHandler:EventListener;\n private _touchEndOrCancelHandler:EventListener;\n private _lastTouchEvent:TouchEvent;\n\n private _iterationLock:boolean;\n private _iterationIntervalId:number;\n\n constructor( private _initialEvent:TouchEvent,\n private _config:Config,\n private _sourceNode:HTMLElement,\n private _dragOperationEndedCb:( config:Config, event:TouchEvent, state:DragOperationState ) => void ) {\n\n console.log( \"dnd-poly: setting up potential drag operation..\" );\n\n this._lastTouchEvent = _initialEvent;\n this._initialTouch = _initialEvent.changedTouches[ 0 ];\n\n // create bound event listeners\n this._touchMoveHandler = this._onTouchMove.bind( this );\n this._touchEndOrCancelHandler = this._onTouchEndOrCancel.bind( this );\n addDocumentListener( \"touchmove\", this._touchMoveHandler, false );\n addDocumentListener( \"touchend\", this._touchEndOrCancelHandler, false );\n addDocumentListener( \"touchcancel\", this._touchEndOrCancelHandler, false );\n\n // the only thing we do is setup the touch listeners. if drag will really start is decided in touch move handler.\n\n //<spec>\n\n // THIS IS SKIPPED SINCE SUPPORT IS ONLY AVAILABLE FOR DOM ELEMENTS\n // 3. Establish which DOM node is the source node, as follows:\n // If it is a selection that is being dragged, then the source node is the text node that the user started the drag on (typically the text node\n // that the user originally clicked). If the user did not specify a particular node, for example if the user just told the user agent to begin\n // a drag of \"the selection\", then the source node is the first text node containing a part of the selection. Otherwise, if it is an element\n // that is being dragged, then the source node is the element that is being dragged. Otherwise, the source node is part of another document or\n // application. When this specification requires that an event be dispatched at the source node in this case, the user agent must instead\n // follow the platform-specific conventions relevant to that situation.\n\n // THIS IS SKIPPED SINCE SUPPORT IS ONLY AVAILABLE FOR DOM ELEMENTS\n // 4. Determine the list of dragged nodes, as follows:\n\n // If it is a selection that is being dragged, then the list of dragged nodes contains, in tree order, every node that is partially or\n // completely included in the selection (including all their ancestors).\n\n // Otherwise, the list of dragged nodes contains only the source node, if any.\n\n // THIS IS SKIPPED SINCE SUPPORT IS ONLY AVAILABLE FOR DOM ELEMENTS\n // 5. If it is a selection that is being dragged, then add an item to the drag data store item list, with its properties set as follows:\n\n //The drag data item type string\n //\"text/plain\"\n //The drag data item kind\n //Plain Unicode string\n //The actual data\n //The text of the selection\n //Otherwise, if any files are being dragged, then add one item per file to the drag data store item list, with their properties set as follows:\n //\n //The drag data item type string\n //The MIME type of the file, if known, or \"application/octet-stream\" otherwise.\n // The drag data item kind\n //File\n //The actual data\n //The file's contents and name.\n //Dragging files can currently only happen from outside a browsing context, for example from a file system manager application.\n //\n // If the drag initiated outside of the application, the user agent must add items to the drag data store item list as appropriate for the data\n // being dragged, honoring platform conventions where appropriate; however, if the platform conventions do not use MIME types to label dragged\n // data, the user agent must make a best-effort attempt to map the types to MIME types, and, in any case, all the drag data item type strings must\n // be converted to ASCII lowercase. Perform drag-and-drop initialization steps defined in any other applicable specifications.\n\n //</spec>\n }\n\n //<editor-fold desc=\"setup/teardown\">\n\n /**\n * Setup dragImage, input listeners and the drag\n * and drop process model iteration interval.\n */\n private _setup():boolean {\n console.log( \"dnd-poly: starting drag and drop operation\" );\n\n this._dragOperationState = DragOperationState.STARTED;\n\n this._currentDragOperation = DROP_EFFECTS[ DROP_EFFECT.NONE ];\n\n this._dragDataStore = {\n data: {},\n effectAllowed: undefined,\n mode: DragDataStoreMode.PROTECTED,\n types: [],\n };\n\n this._currentHotspotCoordinates = {\n x: null,\n y: null\n };\n\n this._dragImagePageCoordinates = {\n x: null,\n y: null\n };\n\n let dragImageSrc:HTMLElement = this._sourceNode;\n\n this._dataTransfer = new DataTransfer( this._dragDataStore, ( element:HTMLElement, x:number, y:number ) => {\n\n dragImageSrc = element;\n\n if( typeof x === \"number\" || typeof y === \"number\" ) {\n this._dragImageOffset = {\n x: x || 0,\n y: y || 0\n };\n }\n } );\n\n // 9. Fire a DND event named dragstart at the source node.\n this._dragDataStore.mode = DragDataStoreMode.READWRITE;\n this._dataTransfer.dropEffect = DROP_EFFECTS[ DROP_EFFECT.NONE ];\n if( dispatchDragEvent( \"dragstart\", this._sourceNode, this._lastTouchEvent, this._dragDataStore, this._dataTransfer ) ) {\n console.log( \"dnd-poly: dragstart cancelled\" );\n // dragstart has been prevented -> cancel d'n'd\n this._dragOperationState = DragOperationState.CANCELLED;\n this._cleanup();\n return false;\n }\n\n updateCentroidCoordinatesOfTouchesIn( \"page\", this._lastTouchEvent, this._dragImagePageCoordinates );\n const dragImage = this._config.dragImageSetup( dragImageSrc );\n this._dragImageTransforms = extractTransformStyles( dragImage );\n // set layout styles for freely moving it around\n dragImage.style.position = \"absolute\";\n dragImage.style.left = \"0px\";\n dragImage.style.top = \"0px\";\n // on top of all\n dragImage.style.zIndex = \"999999\";\n\n // add polyfill class for default styling\n dragImage.classList.add( CLASS_DRAG_IMAGE );\n dragImage.classList.add( CLASS_DRAG_OPERATION_ICON );\n this._dragImage = dragImage;\n\n if( !this._dragImageOffset ) {\n\n // apply specific offset\n if( this._config.dragImageOffset ) {\n\n this._dragImageOffset = {\n x: this._config.dragImageOffset.x,\n y: this._config.dragImageOffset.y\n };\n }\n // center drag image on touch coordinates\n else if( this._config.dragImageCenterOnTouch ) {\n\n const cs = getComputedStyle( dragImageSrc );\n this._dragImageOffset = {\n x: 0 - parseInt( cs.marginLeft, 10 ),\n y: 0 - parseInt( cs.marginTop, 10 )\n };\n }\n // by default initialize drag image offset the same as desktop\n else {\n\n const targetRect = dragImageSrc.getBoundingClientRect();\n const cs = getComputedStyle( dragImageSrc );\n this._dragImageOffset = {\n x: targetRect.left - this._initialTouch.clientX - parseInt( cs.marginLeft, 10 ) + targetRect.width / 2,\n y: targetRect.top - this._initialTouch.clientY - parseInt( cs.marginTop, 10 ) + targetRect.height / 2\n };\n }\n }\n\n translateElementToPoint( this._dragImage, this._dragImagePageCoordinates, this._dragImageTransforms, this._dragImageOffset, this._config.dragImageCenterOnTouch );\n document.body.appendChild( this._dragImage );\n\n // 10. Initiate the drag-and-drop operation in a manner consistent with platform conventions, and as described below.\n this._iterationIntervalId = window.setInterval( () => {\n\n // If the user agent is still performing the previous iteration of the sequence (if any) when the next iteration becomes due,\n // abort these steps for this iteration (effectively \"skipping missed frames\" of the drag-and-drop operation).\n if( this._iterationLock ) {\n console.log( \"dnd-poly: iteration skipped because previous iteration hast not yet finished.\" );\n return;\n }\n this._iterationLock = true;\n\n this._dragAndDropProcessModelIteration();\n\n this._iterationLock = false;\n }, this._config.iterationInterval );\n\n return true;\n }\n\n private _cleanup() {\n\n console.log( \"dnd-poly: cleanup\" );\n\n if( this._iterationIntervalId ) {\n clearInterval( this._iterationIntervalId );\n this._iterationIntervalId = null;\n }\n\n removeDocumentListener( \"touchmove\", this._touchMoveHandler );\n removeDocumentListener( \"touchend\", this._touchEndOrCancelHandler );\n removeDocumentListener( \"touchcancel\", this._touchEndOrCancelHandler );\n\n if( this._dragImage ) {\n this._dragImage.parentNode.removeChild( this._dragImage );\n this._dragImage = null;\n }\n\n this._dragOperationEndedCb( this._config, this._lastTouchEvent, this._dragOperationState );\n }\n\n //</editor-fold>\n\n //<editor-fold desc=\"touch handlers\">\n\n private _onTouchMove( event:TouchEvent ) {\n\n // filter unrelated touches\n if( isTouchIdentifierContainedInTouchEvent( event, this._initialTouch.identifier ) === false ) {\n return;\n }\n\n // update the reference to the last received touch event\n this._lastTouchEvent = event;\n\n // drag operation did not start yet but on movement it should start\n if( this._dragOperationState === DragOperationState.POTENTIAL ) {\n\n let startDrag:boolean;\n\n // is a lifecycle hook present?\n if( this._config.dragStartConditionOverride ) {\n\n try {\n startDrag = this._config.dragStartConditionOverride( event );\n }\n catch( e ) {\n console.error( \"dnd-poly: error in dragStartConditionOverride hook: \" + e );\n startDrag = false;\n }\n }\n else {\n\n // by default only allow a single moving finger to initiate a drag operation\n startDrag = (event.touches.length === 1);\n }\n\n if( !startDrag ) {\n\n this._cleanup();\n return;\n }\n\n // setup will return true when drag operation starts\n if( this._setup() === true ) {\n\n // prevent scrolling when drag operation starts\n this._initialEvent.preventDefault();\n event.preventDefault();\n }\n\n return;\n }\n\n console.log( \"dnd-poly: moving draggable..\" );\n\n // we emulate d'n'd so we dont want any defaults to apply\n event.preventDefault();\n\n // populate shared coordinates from touch event\n updateCentroidCoordinatesOfTouchesIn( \"client\", event, this._currentHotspotCoordinates );\n updateCentroidCoordinatesOfTouchesIn( \"page\", event, this._dragImagePageCoordinates );\n\n if( this._config.dragImageTranslateOverride ) {\n\n try {\n\n let handledDragImageTranslate = false;\n\n this._config.dragImageTranslateOverride(\n event,\n {\n x: this._currentHotspotCoordinates.x,\n y: this._currentHotspotCoordinates.y\n },\n this._immediateUserSelection,\n ( offsetX:number, offsetY:number ) => {\n\n // preventing translation of drag image when there was a drag operation cleanup meanwhile\n if( !this._dragImage ) {\n return;\n }\n\n handledDragImageTranslate = true;\n\n this._currentHotspotCoordinates.x += offsetX;\n this._currentHotspotCoordinates.y += offsetY;\n this._dragImagePageCoordinates.x += offsetX;\n this._dragImagePageCoordinates.y += offsetY;\n\n translateElementToPoint(\n this._dragImage,\n this._dragImagePageCoordinates,\n this._dragImageTransforms,\n this._dragImageOffset,\n this._config.dragImageCenterOnTouch\n );\n }\n );\n\n if( handledDragImageTranslate ) {\n return;\n }\n }\n catch( e ) {\n console.log( \"dnd-poly: error in dragImageTranslateOverride hook: \" + e );\n }\n }\n\n translateElementToPoint( this._dragImage, this._dragImagePageCoordinates, this._dragImageTransforms, this._dragImageOffset, this._config.dragImageCenterOnTouch );\n }\n\n private _onTouchEndOrCancel( event:TouchEvent ) {\n\n // filter unrelated touches\n if( isTouchIdentifierContainedInTouchEvent( event, this._initialTouch.identifier ) === false ) {\n return;\n }\n\n // let the dragImageTranslateOverride know that its over\n if( this._config.dragImageTranslateOverride ) {\n try {\n /* tslint:disable */\n this._config.dragImageTranslateOverride( undefined, undefined, undefined, function() {\n } );\n }\n catch( e ) {\n console.log( \"dnd-poly: error in dragImageTranslateOverride hook: \" + e );\n }\n }\n\n // drag operation did not even start\n if( this._dragOperationState === DragOperationState.POTENTIAL ) {\n this._cleanup();\n return;\n }\n\n // we emulate d'n'd so we dont want any defaults to apply\n event.preventDefault();\n\n this._dragOperationState = (event.type === \"touchcancel\") ? DragOperationState.CANCELLED : DragOperationState.ENDED;\n }\n\n //</editor-fold>\n\n //<editor-fold desc=\"dnd spec logic\">\n\n /**\n * according to https://html.spec.whatwg.org/multipage/interaction.html#drag-and-drop-processing-model\n */\n private _dragAndDropProcessModelIteration():void {\n\n // if( DEBUG ) {\n // var debug_class = CLASS_PREFIX + \"debug\",\n // debug_class_user_selection = CLASS_PREFIX + \"immediate-user-selection\",\n // debug_class_drop_target = CLASS_PREFIX + \"current-drop-target\";\n // }\n\n const previousDragOperation = this._currentDragOperation;\n\n // Fire a DND event named drag event at the source node.\n this._dragDataStore.mode = DragDataStoreMode.PROTECTED;\n this._dataTransfer.dropEffect = DROP_EFFECTS[ DROP_EFFECT.NONE ];\n const dragCancelled = dispatchDragEvent( \"drag\", this._sourceNode, this._lastTouchEvent, this._dragDataStore, this._dataTransfer );\n if( dragCancelled ) {\n console.log( \"dnd-poly: drag event cancelled.\" );\n // If this event is canceled, the user agent must set the current drag operation to \"none\" (no drag operation).\n this._currentDragOperation = DROP_EFFECTS[ DROP_EFFECT.NONE ];\n }\n\n // Otherwise, if the user ended the drag-and-drop operation (e.g. by releasing the mouse button in a mouse-driven drag-and-drop interface),\n // or if the drag event was canceled, then this will be the last iteration.\n if( dragCancelled || this._dragOperationState === DragOperationState.ENDED || this._dragOperationState === DragOperationState.CANCELLED ) {\n\n const dragFailed = this._dragOperationEnded( this._dragOperationState );\n\n // if drag failed transition snap back\n if( dragFailed ) {\n\n applyDragImageSnapback( this._sourceNode, this._dragImage, this._dragImageTransforms, () => {\n this._finishDragOperation();\n } );\n return;\n }\n\n // Otherwise immediately\n // Fire a DND event named dragend at the source node.\n this._finishDragOperation();\n return;\n }\n\n // If the drag event was not canceled and the user has not ended the drag-and-drop operation,\n // check the state of the drag-and-drop operation, as follows:\n const newUserSelection:HTMLElement = <HTMLElement>this._config.elementFromPoint( this._currentHotspotCoordinates.x, this._currentHotspotCoordinates.y );\n\n console.log( \"dnd-poly: new immediate user selection is: \" + newUserSelection );\n\n const previousTargetElement = this._currentDropTarget;\n\n // If the user is indicating a different immediate user selection than during the last iteration (or if this is the first iteration),\n // and if this immediate user selection is not the same as the current target element,\n // then fire a DND event named dragexit at the current target element,\n // and then update the current target element as follows:\n if( newUserSelection !== this._immediateUserSelection && newUserSelection !== this._currentDropTarget ) {\n\n // if( DEBUG ) {\n //\n // if( this._immediateUserSelection ) {\n // this._immediateUserSelection.classList.remove( debug_class_user_selection );\n // }\n //\n // if( newUserSelection ) {\n // newUserSelection.classList.add( debug_class );\n // newUserSelection.classList.add( debug_class_user_selection );\n // }\n // }\n\n this._immediateUserSelection = newUserSelection;\n\n if( this._currentDropTarget !== null ) {\n this._dragDataStore.mode = DragDataStoreMode.PROTECTED;\n this._dataTransfer.dropEffect = DROP_EFFECTS[ DROP_EFFECT.NONE ];\n dispatchDragEvent( \"dragexit\", this._currentDropTarget, this._lastTouchEvent, this._dragDataStore, this._dataTransfer, false );\n }\n\n // If the new immediate user selection is null\n if( this._immediateUserSelection === null ) {\n //Set the current target element to null also.\n this._currentDropTarget = this._immediateUserSelection;\n\n console.log( \"dnd-poly: current drop target changed to null\" );\n }\n // THIS IS SKIPPED SINCE SUPPORT IS ONLY AVAILABLE FOR DOM ELEMENTS\n // If the new immediate user selection is in a non-DOM document or application\n // else if() {\n // Set the current target element to the immediate user selection.\n // this.currentDropTarget = this.immediateUserSelection;\n // return;\n // }\n // Otherwise\n else {\n // Fire a DND event named dragenter at the immediate user selection.\n //the polyfill cannot determine if a handler even exists as browsers do to silently\n // allow drop when no listener existed, so this event MUST be handled by the client\n this._dragDataStore.mode = DragDataStoreMode.PROTECTED;\n this._dataTransfer.dropEffect = determineDropEffect( this._dragDataStore.effectAllowed, this._sourceNode );\n if( dispatchDragEvent( \"dragenter\", this._immediateUserSelection, this._lastTouchEvent, this._dragDataStore, this._dataTransfer ) ) {\n console.log( \"dnd-poly: dragenter default prevented\" );\n // If the event is canceled, then set the current target element to the immediate user selection.\n this._currentDropTarget = this._immediateUserSelection;\n this._currentDragOperation = determineDragOperation( this._dataTransfer.effectAllowed, this._dataTransfer.dropEffect );\n }\n // Otherwise, run the appropriate step from the following list:\n else {\n\n // NO DROPZONE SUPPORT SINCE NATIVE IMPLEMENTATIONS IN BROWSERS ALSO DO NOT\n //console.log( \"dnd-poly: dragenter not prevented, searching for dropzone..\" );\n //var newTarget = DragOperationController.FindDropzoneElement( this.immediateUserSelection );\n\n // THIS IS SKIPPED SINCE SUPPORT IS ONLY AVAILABLE FOR DOM ELEMENTS\n // If the current target element is a text field (e.g. textarea, or an input element whose type attribute is in the Text state) or an\n // editable element, and the drag data store item list has an item with the drag data item type string \"text/plain\" and the drag data\n // item kind Plain Unicode string\n //if( ElementIsTextDropzone( this.immediateUserSelection, this.dragDataStore ) ) {\n //Set the current target element to the immediate user selection anyway.\n //this.currentDropTarget = this.immediateUserSelection;\n //}\n //else\n // If the current target element is an element with a dropzone attribute that matches the drag data store\n //if( newTarget === this.immediateUserSelection &&\n // DragOperationController.GetOperationForMatchingDropzone( this.immediateUserSelection, this.dragDataStore ) !== \"none\" ) {\n // Set the current target element to the immediate user selection anyway.\n // this.currentDropTarget = this.immediateUserSelection;\n //}\n // If the immediate user selection is an element that itself has an ancestor element\n // with a dropzone attribute that matches the drag data store\n // NO DROPZONE SUPPORT SINCE NATIVE IMPLEMENTATIONS IN BROWSERS ALSO DO NOT\n //else if( newTarget !== null && DragOperationController.GetOperationForMatchingDropzone( newTarget, this.dragDataStore ) ) {\n\n // If the immediate user selection is new target, then leave the current target element unchanged.\n\n // Otherwise, fire a DND event named dragenter at new target, with the current target element\n // as the specific related target. Then, set the current target element to new target,\n // regardless of whether that event was canceled or not.\n //this.dragenter( newTarget, this.currentDropTarget );\n //this.currentDropTarget = newTarget;\n //}\n // If the current target element is not the body element\n //else\n if( this._immediateUserSelection !== document.body ) {\n // Fire a DND event named dragenter at the body element, and set the current target element to the body element, regardless of\n // whether that event was canceled or not.\n // Note: If the body element is null, then the event will be fired at the Document object (as\n // required by the definition of the body element), but the current target element would be set to null, not the Document object.\n\n // We do not listen to what the spec says here because this results in doubled events on the body/document because if the first one\n // was not cancelled it will have bubbled up to the body already ;)\n // this.dragenter( window.document.body );\n this._currentDropTarget = document.body;\n }\n // Otherwise\n //else {\n // leave the current drop target unchanged\n //}\n }\n }\n }\n\n // If the previous step caused the current target element to change,\n // and if the previous target element was not null or a part of a non-DOM document,\n // then fire a DND event named dragleave at the previous target element.\n if( previousTargetElement !== this._currentDropTarget && (isDOMElement( previousTargetElement )) ) {\n\n // if( DEBUG ) {\n // previousTargetElement.classList.remove( debug_class_drop_target );\n // }\n\n console.log( \"dnd-poly: current drop target changed.\" );\n\n this._dragDataStore.mode = DragDataStoreMode.PROTECTED;\n this._dataTransfer.dropEffect = DROP_EFFECTS[ DROP_EFFECT.NONE ];\n dispatchDragEvent( \"dragleave\", previousTargetElement, this._lastTouchEvent, this._dragDataStore, this._dataTransfer, false, this._currentDropTarget );\n }\n\n // If the current target element is a DOM element, then fire a DND event named dragover at this current target element.\n if( isDOMElement( this._currentDropTarget ) ) {\n\n // if( DEBUG ) {\n // this._currentDropTarget.classList.add( debug_class );\n // this._currentDropTarget.classList.add( debug_class_drop_target );\n // }\n\n // If the dragover event is not canceled, run the appropriate step from the following list:\n this._dragDataStore.mode = DragDataStoreMode.PROTECTED;\n this._dataTransfer.dropEffect = determineDropEffect( this._dragDataStore.effectAllowed, this._sourceNode );\n if( dispatchDragEvent( \"dragover\", this._currentDropTarget, this._lastTouchEvent, this._dragDataStore, this._dataTransfer ) === false ) {\n\n console.log( \"dnd-poly: dragover not prevented on possible drop-target.\" );\n // NO DROPZONE SUPPORT SINCE NATIVE IMPLEMENTATIONS IN BROWSERS ALSO DO NOT\n\n // THIS IS SKIPPED SINCE SUPPORT IS ONLY AVAILABLE FOR DOM ELEMENTS\n // If the current target element is a text field (e.g. textarea, or an input element whose type attribute is in the Text state) or\n // an editable element, and the drag data store item list has an item with the drag data item type string \"text/plain\" and the drag\n // data item kind Plain Unicode string\n //if( ElementIsTextDropzone( this.currentDropTarget, this.dragDataStore ) ) {\n // Set the current drag operation to either \"copy\" or \"move\", as appropriate given the platform conventions.\n //this.currentDragOperation = \"copy\"; //or move. spec says its platform specific behaviour.\n //}\n //else {\n // If the current target element is an element with a dropzone attribute that matches the drag data store\n //this.currentDragOperation = DragOperationController.GetOperationForMatchingDropzone( this.currentDropTarget, this.dragDataStore );\n //}\n // when dragover is not prevented and no dropzones are there, no drag operation\n this._currentDragOperation = DROP_EFFECTS[ DROP_EFFECT.NONE ];\n }\n // Otherwise (if the dragover event is canceled), set the current drag operation based on the values of the effectAllowed and\n // dropEffect attributes of the DragEvent object's dataTransfer object as they stood after the event dispatch finished\n else {\n\n console.log( \"dnd-poly: dragover prevented.\" );\n\n this._currentDragOperation = determineDragOperation( this._dataTransfer.effectAllowed, this._dataTransfer.dropEffect );\n }\n }\n\n console.log( \"dnd-poly: d'n'd iteration ended. current drag operation: \" + this._currentDragOperation );\n\n // THIS IS SKIPPED SINCE SUPPORT IS ONLY AVAILABLE FOR DOM ELEMENTS\n // Otherwise, if the current target element is not a DOM element, use platform-specific mechanisms to determine what drag operation is\n // being performed (none, copy, link, or move), and set the current drag operation accordingly.\n\n //Update the drag feedback (e.g. the mouse cursor) to match the current drag operation, as follows:\n // ---------------------------------------------------------------------------------------------------------\n // Drag operation |\tFeedback\n // \"copy\"\t | Data will be copied if dropped here.\n // \"link\"\t | Data will be linked if dropped here.\n // \"move\"\t | Data will be moved if dropped here.\n // \"none\"\t | No operation allowed, dropping here will cancel the drag-and-drop operation.\n // ---------------------------------------------------------------------------------------------------------\n\n if( previousDragOperation !== this._currentDragOperation ) {\n this._dragImage.classList.remove( CLASS_PREFIX + previousDragOperation );\n }\n\n const currentDragOperationClass = CLASS_PREFIX + this._currentDragOperation;\n\n this._dragImage.classList.add( currentDragOperationClass );\n }\n\n /**\n * according to https://html.spec.whatwg.org/multipage/interaction.html#drag-and-drop-processing-model\n */\n private _dragOperationEnded( state:DragOperationState ):boolean {\n\n console.log( \"dnd-poly: drag operation end detected with \" + this._currentDragOperation );\n\n // if( DEBUG ) {\n //\n // var debug_class_user_selection = CLASS_PREFIX + \"immediate-user-selection\",\n // debug_class_drop_target = CLASS_PREFIX + \"current-drop-target\";\n //\n // if( this._currentDropTarget ) {\n // this._currentDropTarget.classList.remove( debug_class_drop_target );\n //\n // }\n // if( this._immediateUserSelection ) {\n // this._immediateUserSelection.classList.remove( debug_class_user_selection );\n // }\n // }\n\n //var dropped:boolean = undefined;\n\n // Run the following steps, then stop the drag-and-drop operation:\n\n // If the current drag operation is \"none\" (no drag operation), or,\n // if the user ended the drag-and-drop operation by canceling it (e.g. by hitting the Escape key), or\n // if the current target element is null, then the drag operation failed.\n const dragFailed = (this._currentDragOperation === DROP_EFFECTS[ DROP_EFFECT.NONE ]\n || this._currentDropTarget === null\n || state === DragOperationState.CANCELLED);\n if( dragFailed ) {\n\n // Run these substeps:\n\n // Let dropped be false.\n //dropped = false;\n\n // If the current target element is a DOM element, fire a DND event named dragleave at it;\n if( isDOMElement( this._currentDropTarget ) ) {\n this._dragDataStore.mode = DragDataStoreMode.PROTECTED;\n this._dataTransfer.dropEffect = DROP_EFFECTS[ DROP_EFFECT.NONE ];\n dispatchDragEvent( \"dragleave\", this._currentDropTarget, this._lastTouchEvent, this._dragDataStore, this._dataTransfer, false );\n }\n\n // THIS IS SKIPPED SINCE SUPPORT IS ONLY AVAILABLE FOR DOM ELEMENTS\n // otherwise, if it is not null, use platform-specific conventions for drag cancellation.\n //else if( this.currentDropTarget !== null ) {\n //}\n }\n // Otherwise, the drag operation was as success; run these substeps:\n else {\n\n // Let dropped be true.\n //dropped = true;\n\n // If the current target element is a DOM element, fire a DND event named drop at it;\n if( isDOMElement( this._currentDropTarget ) ) {\n\n // If the event is canceled, set the current drag operation to the value of the dropEffect attribute of the\n // DragEvent object's dataTransfer object as it stood after the event dispatch finished.\n\n this._dragDataStore.mode = DragDataStoreMode.READONLY;\n this._dataTransfer.dropEffect = this._currentDragOperation;\n if( dispatchDragEvent( \"drop\", this._currentDropTarget, this._lastTouchEvent, this._dragDataStore, this._dataTransfer ) ===\n true ) {\n\n this._currentDragOperation = this._dataTransfer.dropEffect;\n }\n // Otherwise, the event is not canceled; perform the event's default action, which depends on the exact target as follows:\n else {\n\n // THIS IS SKIPPED SINCE SUPPORT IS ONLY AVAILABLE FOR DOM ELEMENTS\n // If the current target element is a text field (e.g. textarea, or an input element whose type attribute is in the Text state)\n // or an editable element,\n // and the drag data store item list has an item with the drag data item type string \"text/plain\"\n // and the drag data item kind Plain Unicode string\n //if( ElementIsTextDropzone( this.currentDropTarget, this.dragDataStore ) ) {\n // Insert the actual data of the first item in the drag data store item list to have a drag data item type string of\n // \"text/plain\" and a drag data item kind that is Plain Unicode string into the text field or editable element in a manner\n // consistent with platform-specific conventions (e.g. inserting it at the current mouse cursor position, or inserting it at\n // the end of the field).\n //}\n // Otherwise\n //else {\n // Reset the current drag operation to \"none\".\n this._currentDragOperation = DROP_EFFECTS[ DROP_EFFECT.NONE ];\n //}\n }\n }\n // THIS IS SKIPPED SINCE SUPPORT IS ONLY AVAILABLE FOR DOM ELEMENTS\n // otherwise, use platform-specific conventions for indicating a drop.\n //else {\n //}\n }\n\n return dragFailed;\n\n // THIS IS SKIPPED SINCE SUPPORT IS ONLY AVAILABLE FOR DOM ELEMENTS\n //if( this.dragend( this.sourceNode ) ) {\n // return;\n //}\n\n // Run the appropriate steps from the following list as the default action of the dragend event:\n\n //if( !dropped ) {\n // return;\n //}\n // dropped is true\n\n //if( this.currentDragOperation !== \"move\" ) {\n // return;\n //}\n //// drag operation is move\n //\n //if( ElementIsTextDropzone( this.currentDropTarget ) === false ) {\n // return;\n //}\n //// element is textfield\n //\n //// and the source of the drag-and-drop operation is a selection in the DOM\n //if( this.sourceNode.nodeType === 1 ) {\n // // The user agent should delete the range representing the dragged selection from the DOM.\n //}\n //// and the source of the drag-and-drop operation is a selection in a text field\n //else if( this.sourceNode.nodeType === 3 ) {\n // // The user agent should delete the dragged selection from the relevant text field.\n //}\n //// Otherwise, The event has no default action.\n }\n\n // dispatch dragend event and cleanup drag operation\n private _finishDragOperation():void {\n console.log( \"dnd-poly: dragimage snap back transition ended\" );\n\n // Fire a DND event named dragend at the source node.\n this._dragDataStore.mode = DragDataStoreMode.PROTECTED;\n this._dataTransfer.dropEffect = this._currentDragOperation;\n dispatchDragEvent( \"dragend\", this._sourceNode, this._lastTouchEvent, this._dragDataStore, this._dataTransfer, false );\n\n // drag operation over and out\n this._dragOperationState = DragOperationState.ENDED;\n this._cleanup();\n }\n\n //</editor-fold>\n}\n","import { addDocumentListener, createDragImage, onEvt, Point } from \"./internal/dom-utils\";\nimport { DragOperationController, DragOperationState } from \"./internal/drag-operation-controller\";\nimport { tryFindDraggableTarget } from \"./internal/drag-utils\";\nimport { detectFeatures } from \"./internal/feature-detection\";\nimport { EVENT_DRAG_DRAGSTART_PENDING, EVENT_DRAG_DRAGSTART_CANCEL } from \"./internal/constants\";\n\n// default config\nconst config:Config = {\n iterationInterval: 150,\n tryFindDraggableTarget: tryFindDraggableTarget,\n dragImageSetup: createDragImage,\n elementFromPoint: function( x, y ) { return document.elementFromPoint( x, y ); }\n};\n\n// reference to the currently active drag operation\nlet activeDragOperation:DragOperationController;\n\n/**\n * event handler for initial touch events that possibly start a drag and drop operation.\n */\nfunction onTouchstart( e:TouchEvent ) {\n\n console.log( \"dnd-poly: global touchstart\" );\n\n // From the moment that the user agent is to initiate the drag-and-drop operation,\n // until the end of the drag-and-drop operation, device input events (e.g. mouse and keyboard events) must be suppressed.\n\n // only allow one drag operation at a time\n if( activeDragOperation ) {\n console.log( \"dnd-poly: drag operation already active\" );\n return;\n }\n\n let dragTarget = config.tryFindDraggableTarget( e );\n\n // If there is no such element, then nothing is being dragged; abort these\n // steps, the drag-and-drop operation is never started.\n if( !dragTarget ) {\n console.log(\"dnd-poly: no draggable at touchstart coordinates\");\n return;\n }\n\n try {\n activeDragOperation = new DragOperationController( e, config, dragTarget as HTMLElement, dragOperationEnded );\n }\n catch( err ) {\n dragOperationEnded( config, e, DragOperationState.CANCELLED );\n // rethrow exception after cleanup\n throw err;\n }\n}\n\nfunction onDelayTouchstart( evt:TouchEvent ) {\n\n console.log(\"dnd-poly: setup delayed dragstart..\");\n\n const el = evt.target;\n\n const heldItem = () => {\n\n console.log(\"dnd-poly: starting delayed drag..\");\n\n end.off();\n cancel.off();\n move.off();\n scroll.off();\n onTouchstart( evt );\n };\n\n const onReleasedItem = (event:Event) => {\n\n console.log(\"dnd-poly: aborting delayed drag because of \" + event.type);\n\n end.off();\n cancel.off();\n move.off();\n scroll.off();\n\n if (el) {\n el.dispatchEvent(new CustomEvent(EVENT_DRAG_DRAGSTART_CANCEL, { bubbles: true, cancelable: true }));\n }\n\n clearTimeout( timer );\n };\n\n if (el) {\n el.dispatchEvent(new CustomEvent(EVENT_DRAG_DRAGSTART_PENDING, { bubbles: true, cancelable: true }));\n }\n\n const timer = window.setTimeout( heldItem, config.holdToDrag );\n\n const end = onEvt( el, \"touchend\", onReleasedItem );\n const cancel = onEvt( el, \"touchcancel\", onReleasedItem );\n const move = onEvt( el, \"touchmove\", onReleasedItem );\n // scroll events don't bubble, only way to listen to scroll events\n // that are about to happen in nested scrollables is by listening in capture phase\n const scroll = onEvt( window, \"scroll\", onReleasedItem, true );\n}\n\n/**\n * Implements callback invoked when a drag operation has ended or crashed.\n */\nfunction dragOperationEnded( _config:Config, event:TouchEvent, state:DragOperationState ) {\n\n // we need to make the default action happen only when no drag operation took place\n if( state === DragOperationState.POTENTIAL ) {\n\n console.log( \"dnd-poly: Drag never started. Last event was \" + event.type );\n\n // when lifecycle hook is present\n if( _config.defaultActionOverride ) {\n\n try {\n\n _config.defaultActionOverride( event );\n\n if( event.defaultPrevented ) {\n\n console.log( \"dnd-poly: defaultActionOverride has taken care of triggering the default action. preventing default on original event\" );\n }\n\n }\n catch( e ) {\n\n console.log( \"dnd-poly: error in defaultActionOverride: \" + e );\n }\n }\n }\n\n // reset drag operation container\n activeDragOperation = null;\n}\n\n//<editor-fold desc=\"public api\">\n\nexport { Point } from \"./internal/dom-utils\";\n\n// function signature for the dragImageTranslateOverride hook\nexport type DragImageTranslateOverrideFn = ( // corresponding touchmove event\n event:TouchEvent,\n // the processed touch event viewport coordinates\n hoverCoordinates:Point,\n // the element under the calculated touch coordinates\n hoveredElement:HTMLElement,\n // callback for updating the drag image offset\n translateDragImageFn:( offsetX:number, offsetY:number ) => void ) => void;\n\nexport interface Config {\n\n // flag to force the polyfill being applied and not rely on internal feature detection\n forceApply?:boolean;\n\n // useful for when you want the default drag image but still want to apply\n // some static offset from touch coordinates to drag image coordinates\n // defaults to (0,0)\n dragImageOffset?:Point;\n\n // if the dragImage shall be centered on the touch coordinates\n // defaults to false\n dragImageCenterOnTouch?:boolean;\n\n // the drag and drop operation involves some processing. here you can specify in what interval this processing takes place.\n // defaults to 150ms\n iterationInterval?:number;\n\n // hook for custom logic that decides if a drag operation should start\n dragStartConditionOverride?:( event:TouchEvent ) => boolean;\n\n // hook for custom logic that can manipulate the drag image translate offset\n dragImageTranslateOverride?:DragImageTranslateOverrideFn;\n\n // hook for custom logic that can override the default action based on the original touch event when the drag never started\n // be sure to call event.preventDefault() if handling the default action in the override to prevent the browser default.\n defaultActionOverride?:( event:TouchEvent ) => void;\n\n // Drag action delay on touch devices (\"hold to drag\" functionality, useful for scrolling draggable items). Defaults to no delay.\n holdToDrag?:number;\n\n // function invoked for each touchstart event to determine if and which touched element is detected as \"draggable\"\n tryFindDraggableTarget?:( event:TouchEvent ) => HTMLElement | undefined;\n\n // function for creating a copy of the dragged element\n dragImageSetup?:( element:HTMLElement ) => HTMLElement;\n\n // function for determining element that is currently hovered while dragging\n // defaults to `document.elementFromPoint()`\n elementFromPoint?:( x:number, y:number ) => Element;\n}\n\nexport function polyfill( override?:Config ):boolean {\n\n if( override ) {\n // overwrite default config with user config\n Object.keys( override ).forEach( function( key ) {\n config[ key ] = override[ key ];\n } );\n }\n\n // only do feature detection when config does not force apply the polyfill\n if( !config.forceApply ) {\n\n // feature/browser detection\n const detectedFeatures = detectFeatures();\n\n // if( DEBUG ) {\n // Object.keys( detectedFeatures ).forEach( function( key ) {\n // console.log( \"dnd-poly: detected feature '\" + key + \" = \" + detectedFeatures[ key ] + \"'\" );\n // } );\n // }\n\n // check if native drag and drop support is there\n if( detectedFeatures.userAgentSupportingNativeDnD\n && detectedFeatures.draggable\n && detectedFeatures.dragEvents ) {\n // no polyfilling required\n return false;\n }\n }\n\n console.log( \"dnd-poly: Applying mobile drag and drop polyfill.\" );\n\n // add listeners suitable for detecting a potential drag operation\n if( config.holdToDrag ) {\n console.log(\"dnd-poly: holdToDrag set to \" + config.holdToDrag);\n addDocumentListener( \"touchstart\", onDelayTouchstart, false );\n } else {\n addDocumentListener( \"touchstart\", onTouchstart, false );\n }\n\n return true;\n}\n\n//</editor-fold>\n"],"names":[],"mappings":"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"}