{"version":3,"file":null,"sources":["/Users/stefansteinhart/Development/Web/ios-html5-drag-drop-shim/src/index.ts"],"sourcesContent":["// debug mode, which will highlight drop target, immediate user selection and events fired as you interact.\nconst DEBUG = false;\n\n//\n\ninterface DetectedFeatures {\n draggable:boolean;\n dragEvents:boolean;\n touchEvents:boolean;\n userAgentSupportingNativeDnD:boolean;\n}\n\nfunction detectFeatures():DetectedFeatures {\n\n let features:DetectedFeatures = {\n dragEvents: (\"ondragstart\" in document.documentElement),\n draggable: (\"draggable\" in document.documentElement),\n touchEvents: (\"ontouchstart\" in document.documentElement),\n userAgentSupportingNativeDnD: undefined\n };\n\n const isBlinkEngine = !!((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 && features.touchEvents)\n );\n\n if (DEBUG) {\n Object.keys(features).forEach(function (key) {\n console.log(\"dnd-poly: detected feature '\" + key + \" = \" + features[key] + \"'\");\n });\n }\n\n return features;\n}\n\nlet supportsPassive:boolean;\n\nfunction 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\n//\n\n//\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 // flag to force the polyfill being applied and not rely on internal feature detection\n forceApply?:boolean;\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 // if the dragImage shall be centered on the touch coordinates\n // defaults to false\n dragImageCenterOnTouch?:boolean;\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 // hook for custom logic that decides if a drag operation should start\n dragStartConditionOverride?:(event:TouchEvent) => boolean;\n // hook for custom logic that can manipulate the drag image translate offset\n dragImageTranslateOverride?:DragImageTranslateOverrideFn;\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 // Drag action delay on touch devices (\"hold to drag\" functionality, useful for scrolling draggable items). Defaults to no delay.\n holdToDrag?: number;\n}\n\n// default config\nconst config:Config = {\n iterationInterval: 150,\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 // 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 supportsPassive = supportsPassiveEventListener();\n\n // add listeners suitable for detecting a potential drag operation\n if (config.holdToDrag) {\n addDocumentListener(\"touchstart\", onDelayTouchstart, false);\n } else {\n addDocumentListener(\"touchstart\", onTouchstart, false);\n }\n\n return true;\n}\n\n//\n\n//\n\n// reference the currently active drag operation\nlet activeDragOperation:DragOperationController;\n\n/**\n * event handler listening for initial 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 = 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 return;\n }\n\n try {\n activeDragOperation = new DragOperationController(e, config, dragTarget, dragOperationEnded);\n }\n catch (err) {\n dragOperationEnded(config, e, DragOperationState.CANCELLED);\n // rethrow exception after cleanup\n throw err;\n }\n}\n\n/**\n * Search for a possible draggable item upon an event that can initialize a drag operation.\n */\nfunction tryFindDraggableTarget(event:TouchEvent):Element {\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( (event.target).nodeType === 3 ) {\n //\n // config.log( \"drag on text\" );\n // return 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 = event.target;\n\n do {\n if (el.draggable === false) {\n continue;\n }\n if (el.getAttribute && el.getAttribute(\"draggable\") === \"true\") {\n return el;\n }\n } while ((el = el.parentNode) && el !== document.body);\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//\n\n//\n\n/**\n * For tracking the different states of a drag operation.\n */\nconst 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// contains all possible values of the effectAllowed property\nconst 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\nconst ALLOWED_EFFECTS = [\"none\", \"copy\", \"copyLink\", \"copyMove\", \"link\", \"linkMove\", \"move\", \"all\"];\n\n// contains all possible values of the dropEffect property\nconst enum DROP_EFFECT {\n NONE = 0,\n COPY = 1,\n MOVE = 2,\n LINK = 3,\n}\n\nconst DROP_EFFECTS = [\"none\", \"copy\", \"move\", \"link\"];\n\n// cross-browser css transform property prefixes\nconst TRANSFORM_CSS_VENDOR_PREFIXES = [\"\", \"-webkit-\"];\n// css classes\nconst CLASS_PREFIX = \"dnd-poly-\";\nconst CLASS_DRAG_IMAGE = CLASS_PREFIX + \"drag-image\";\nconst CLASS_DRAG_IMAGE_SNAPBACK = CLASS_PREFIX + \"snapback\";\nconst CLASS_DRAG_OPERATION_ICON = CLASS_PREFIX + \"icon\";\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 */\nclass 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 //\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 //\n }\n\n //\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 this._dragImage = createDragImage(dragImageSrc);\n this._dragImageTransforms = extractTransformStyles(this._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 translateDragImage(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 = 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 //\n\n //\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 translateDragImage(\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 translateDragImage(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 //\n\n //\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 = document.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 if (this._dragImage.classList.contains(currentDragOperationClass) === false) {\n this._dragImage.classList.add(currentDragOperationClass);\n }\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 //\n}\n\n//\n\n//\n\n/**\n * Polyfills https://html.spec.whatwg.org/multipage/interaction.html#drag-data-store-mode\n */\nconst 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 */\ninterface DragDataStore {\n _mode:DragDataStoreMode;\n _data:{ [type:string]:any };\n _types:Array;\n _effectAllowed:string;\n}\n\n/**\n * Polyfills https://html.spec.whatwg.org/multipage/interaction.html#datatransfer\n * TODO fail with errors when somebody uses it wrong so they know they are doing it wrong?\n */\nclass DataTransfer {\n\n private _dropEffect:string = DROP_EFFECTS[DROP_EFFECT.NONE];\n\n constructor(private _dataStore:DragDataStore,\n private _setDragImageHandler:(image:Element, x:number, y:number) => void) {\n }\n\n //public get files():FileList {\n // return undefined;\n //}\n //\n //public get items():DataTransferItemList {\n // return undefined;\n //}\n\n public get types():ReadonlyArray {\n if (this._dataStore._mode !== DragDataStoreMode._DISCONNECTED) {\n return Object.freeze(this._dataStore._types);\n }\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 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 public get dropEffect() {\n return this._dropEffect;\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\n//\n\n//\n\nexport interface Point {\n x:number;\n y:number;\n}\n\nfunction addDocumentListener(ev:string, handler:EventListener, passive:boolean = true) {\n\n (document as EventTarget).addEventListener(ev, handler, supportsPassive ? {passive: passive} : false);\n}\n\nfunction removeDocumentListener(ev:string, handler:EventListener) {\n document.removeEventListener(ev, handler);\n}\n\nfunction average(array:Array) {\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\nfunction isDOMElement(object:any) {\n return object && object.tagName;\n}\n\nfunction isTouchIdentifierContainedInTouchEvent(newTouch:TouchEvent, touchIdentifier:number) {\n for (let i = 0; i < newTouch.changedTouches.length; i++) {\n const touch = newTouch.changedTouches[i];\n if (touch.identifier === touchIdentifier) {\n return true;\n }\n }\n return false;\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 });\n\n // cast our polyfill\n (dndEvent as any).dataTransfer = dataTransfer;\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 * 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 */\nfunction updateCentroidCoordinatesOfTouchesIn(coordinateProp:string, event:TouchEvent, outPoint:Point):void {\n const pageXs:Array = [], pageYs:Array = [];\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\nfunction prepareNodeCopyAsDragImage(srcNode:HTMLElement, dstNode:HTMLElement) {\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\n // Do the same for the children\n if (srcNode.hasChildNodes()) {\n for (let i = 0; i < srcNode.childNodes.length; i++) {\n prepareNodeCopyAsDragImage(srcNode.childNodes[i], dstNode.childNodes[i]);\n }\n }\n}\n\nfunction createDragImage(sourceNode:HTMLElement):HTMLElement {\n\n const dragImage = 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 // 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\n return dragImage;\n}\n\nfunction extractTransformStyles(sourceNode:HTMLElement):string[] {\n\n return TRANSFORM_CSS_VENDOR_PREFIXES.map(function (prefix) {\n\n let transform = sourceNode.style[prefix + \"transform\"];\n\n if (!transform || transform === \"none\") {\n return \"\";\n }\n\n // TODO what about translateX(x), translateY(x), translateZ(z), translate3d(x,y,z), matrix(*,*,*,*,x,y) ?\n\n // removes translate(x,y)\n return transform.replace(/translate\\(\\D*\\d+[^,]*,\\D*\\d+[^,]*\\)\\s*/g, \"\");\n });\n}\n\nfunction translateDragImage(dragImage: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(dragImage.offsetWidth, 10) / 2);\n y -= (parseInt(dragImage.offsetHeight, 10) / 2);\n }\n\n // using translate3d for best 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 dragImage.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 */\nfunction 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.. 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 translateDragImage(dragImage, pnt, dragImageTransforms, undefined, false);\n\n setTimeout(transitionEndCb, durationInMs);\n}\n\n//\n\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 */\nfunction 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 && (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\n/**\n * Reference https://html.spec.whatwg.org/multipage/interaction.html#dndevents\n */\nfunction dispatchDragEvent(dragEvent:string,\n targetElement:Element,\n touchEvent:TouchEvent,\n dataStore:DragDataStore,\n dataTransfer:DataTransfer,\n cancelable = true,\n relatedTarget:Element = null):boolean {\n\n console.log(\"dnd-poly: dispatching \" + dragEvent);\n\n if (DEBUG) {\n var 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 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 */\nfunction 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\nfunction onDelayTouchstart(evt: TouchEvent) {\n const el = evt.target;\n\n const heldItem = () => {\n end.off();\n cancel.off();\n scroll.off();\n onTouchstart(evt);\n };\n\n const onReleasedItem = () => {\n end.off();\n cancel.off();\n scroll.off();\n clearTimeout(timer);\n };\n\n const timer = setTimeout(heldItem, config.holdToDrag);\n\n const end = onEvt(el, 'touchend', onReleasedItem, this);\n const cancel = onEvt(el, 'touchcancel', onReleasedItem, this);\n const scroll = onEvt(window, 'scroll', onReleasedItem, this);\n}\n\nfunction onEvt(el: EventTarget, event: string, handler: () => any, context: any) {\n if (context) {\n handler = handler.bind(context);\n }\n\n el.addEventListener(event, handler);\n\n return {\n off() {\n return el.removeEventListener(event, handler);\n }\n };\n}\n\n//\n\n//\n\n/**\n * // THIS IS SKIPPED SINCE SUPPORT IS ONLY AVAILABLE FOR DOM ELEMENTS\n */\n//public static ElementIsTextDropzone( element:HTMLElement, dragDataStore?:DragDataStore ) {\n//\n// if( dragDataStore && !dragDataStore.data[ \"text/plain\" ] ) {\n// return false;\n// }\n//\n// if( element.isContentEditable ) {\n// return true;\n// }\n//\n// if( element.tagName === \"TEXTAREA\" ) {\n// return true;\n// }\n//\n// if( element.tagName === \"INPUT\" ) {\n// if( element.getAttribute( \"type\" ) === \"text\" ) {\n// return true;\n// }\n// }\n//\n// return false;\n//}\n\n/**\n * NO DROPZONE SUPPORT SINCE NATIVE IMPLEMENTATIONS IN BROWSERS ALSO DO NOT\n *\n * Helper method for recursively go from a nested element up the ancestor chain\n * to see if any element has a dropzone.\n */\n//private static FindDropzoneElement( element:HTMLElement ):HTMLElement {\n//\n// if( !element || !element.hasAttribute || typeof element.hasAttribute !== \"function\" ) {\n// return null;\n// }\n//\n// if( element.hasAttribute( \"dropzone\" ) ) {\n// return element;\n// }\n//\n// if( element === window.document.body ) {\n// return null;\n// }\n//\n// return DragOperationController.FindDropzoneElement( element.parentElement );\n//}\n\n/**\n * NO DROPZONE SUPPORT SINCE NATIVE IMPLEMENTATIONS IN BROWSERS ALSO DO NOT\n *\n * Polyfills https://html.spec.whatwg.org/multipage/interaction.html#the-dropzone-attribute\n * by implementing the dropzone processing steps.\n */\n//private static GetOperationForMatchingDropzone( element:HTMLElement, dragDataStore:DragDataStore ):string {\n\n// If the current target element is an element with a dropzone attribute that matches the drag data store and specifies an operation\n// Set the current drag operation to the operation specified by the dropzone attribute of the current target element.\n// If the current target element is an element with a dropzone attribute that matches the drag data store and does not specify an operation\n// Set the current drag operation to \"copy\".\n// Otherwise\n// Reset the current drag operation to \"none\".\n//var value = element.getAttribute( \"dropzone\" );\n//if( !value ) {\n//\n// return \"none\";\n//}\n//\n//var matched = false;\n//var operation;\n//var keywords = value.split( \" \" );\n//\n//for( var i:number = 0; i < keywords.length; i++ ) {\n// var keyword = keywords[ i ];\n//\n// if( keyword === \"copy\" || keyword === \"move\" || keyword === \"link\" ) {\n// if( !operation ) {\n// operation = keyword;\n// }\n// continue;\n// }\n//\n// if( keyword.length < 3 || keyword[ 1 ] !== \":\" ) {\n// continue;\n// }\n//\n// var splitKeyword = keyword.split( \":\" );\n// var kind = splitKeyword[ 0 ].toLowerCase();\n// var type = splitKeyword[ 1 ].toLowerCase();\n//\n// if( dragDataStore.types.indexOf( type ) > -1 ) {\n// matched = true;\n// }\n//}\n//\n//if( !matched ) {\n// return \"none\";\n//}\n//\n//if( !operation ) {\n// return \"copy\";\n//}\n//\n//return operation;\n//}\n\n//\n"],"names":[],"mappings":"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"}