index.js 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760
  1. (function (global, factory) {
  2. typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
  3. typeof define === 'function' && define.amd ? define(['exports'], factory) :
  4. (factory((global.MobileDragDrop = global.MobileDragDrop || {})));
  5. }(this, (function (exports) { 'use strict';
  6. var CLASS_PREFIX = "dnd-poly-";
  7. var CLASS_DRAG_IMAGE = CLASS_PREFIX + "drag-image";
  8. var CLASS_DRAG_IMAGE_SNAPBACK = CLASS_PREFIX + "snapback";
  9. var CLASS_DRAG_OPERATION_ICON = CLASS_PREFIX + "icon";
  10. var EVENT_PREFIX = "dnd-poly-";
  11. var EVENT_DRAG_DRAGSTART_PENDING = EVENT_PREFIX + "dragstart-pending";
  12. var EVENT_DRAG_DRAGSTART_CANCEL = EVENT_PREFIX + "dragstart-cancel";
  13. var ALLOWED_EFFECTS = ["none", "copy", "copyLink", "copyMove", "link", "linkMove", "move", "all"];
  14. var DROP_EFFECTS = ["none", "copy", "move", "link"];
  15. function detectFeatures() {
  16. var features = {
  17. dragEvents: ("ondragstart" in document.documentElement),
  18. draggable: ("draggable" in document.documentElement),
  19. userAgentSupportingNativeDnD: undefined
  20. };
  21. var isBlinkEngine = !!(window.chrome) || /chrome/i.test(navigator.userAgent);
  22. features.userAgentSupportingNativeDnD = !((/iPad|iPhone|iPod|Android/.test(navigator.userAgent))
  23. ||
  24. (isBlinkEngine && ("ontouchstart" in document.documentElement)));
  25. return features;
  26. }
  27. function supportsPassiveEventListener() {
  28. var supportsPassiveEventListeners = false;
  29. try {
  30. var opts = Object.defineProperty({}, "passive", {
  31. get: function () {
  32. supportsPassiveEventListeners = true;
  33. }
  34. });
  35. window.addEventListener("test", null, opts);
  36. }
  37. catch (e) {
  38. }
  39. return supportsPassiveEventListeners;
  40. }
  41. var supportsPassive = supportsPassiveEventListener();
  42. function isDOMElement(object) {
  43. return object && object.tagName;
  44. }
  45. function addDocumentListener(ev, handler, passive) {
  46. if (passive === void 0) { passive = true; }
  47. document.addEventListener(ev, handler, supportsPassive ? { passive: passive } : false);
  48. }
  49. function removeDocumentListener(ev, handler) {
  50. document.removeEventListener(ev, handler);
  51. }
  52. function onEvt(el, event, handler, capture) {
  53. if (capture === void 0) { capture = false; }
  54. var options = supportsPassive ? { passive: true, capture: capture } : capture;
  55. el.addEventListener(event, handler, options);
  56. return {
  57. off: function () {
  58. el.removeEventListener(event, handler, options);
  59. }
  60. };
  61. }
  62. function prepareNodeCopyAsDragImage(srcNode, dstNode) {
  63. if (srcNode.nodeType === 1) {
  64. var cs = getComputedStyle(srcNode);
  65. for (var i = 0; i < cs.length; i++) {
  66. var csName = cs[i];
  67. dstNode.style.setProperty(csName, cs.getPropertyValue(csName), cs.getPropertyPriority(csName));
  68. }
  69. dstNode.style.pointerEvents = "none";
  70. dstNode.removeAttribute("id");
  71. dstNode.removeAttribute("class");
  72. dstNode.removeAttribute("draggable");
  73. if (dstNode.nodeName === "CANVAS") {
  74. var canvasSrc = srcNode;
  75. var canvasDst = dstNode;
  76. var canvasSrcImgData = canvasSrc.getContext("2d").getImageData(0, 0, canvasSrc.width, canvasSrc.height);
  77. canvasDst.getContext("2d").putImageData(canvasSrcImgData, 0, 0);
  78. }
  79. }
  80. if (srcNode.hasChildNodes()) {
  81. for (var i = 0; i < srcNode.childNodes.length; i++) {
  82. prepareNodeCopyAsDragImage(srcNode.childNodes[i], dstNode.childNodes[i]);
  83. }
  84. }
  85. }
  86. function createDragImage(sourceNode) {
  87. var dragImage = sourceNode.cloneNode(true);
  88. prepareNodeCopyAsDragImage(sourceNode, dragImage);
  89. return dragImage;
  90. }
  91. function average(array) {
  92. if (array.length === 0) {
  93. return 0;
  94. }
  95. return array.reduce((function (s, v) {
  96. return v + s;
  97. }), 0) / array.length;
  98. }
  99. function isTouchIdentifierContainedInTouchEvent(touchEvent, touchIdentifier) {
  100. for (var i = 0; i < touchEvent.changedTouches.length; i++) {
  101. var touch = touchEvent.changedTouches[i];
  102. if (touch.identifier === touchIdentifier) {
  103. return true;
  104. }
  105. }
  106. return false;
  107. }
  108. function updateCentroidCoordinatesOfTouchesIn(coordinateProp, event, outPoint) {
  109. var pageXs = [], pageYs = [];
  110. for (var i = 0; i < event.touches.length; i++) {
  111. var touch = event.touches[i];
  112. pageXs.push(touch[coordinateProp + "X"]);
  113. pageYs.push(touch[coordinateProp + "Y"]);
  114. }
  115. outPoint.x = average(pageXs);
  116. outPoint.y = average(pageYs);
  117. }
  118. var TRANSFORM_CSS_VENDOR_PREFIXES = ["", "-webkit-"];
  119. function extractTransformStyles(sourceNode) {
  120. return TRANSFORM_CSS_VENDOR_PREFIXES.map(function (prefix) {
  121. var transform = sourceNode.style[prefix + "transform"];
  122. if (!transform || transform === "none") {
  123. return "";
  124. }
  125. return transform.replace(/translate\(\D*\d+[^,]*,\D*\d+[^,]*\)\s*/g, "");
  126. });
  127. }
  128. function translateElementToPoint(element, pnt, originalTransforms, offset, centerOnCoordinates) {
  129. if (centerOnCoordinates === void 0) { centerOnCoordinates = true; }
  130. var x = pnt.x, y = pnt.y;
  131. if (offset) {
  132. x += offset.x;
  133. y += offset.y;
  134. }
  135. if (centerOnCoordinates) {
  136. x -= (parseInt(element.offsetWidth, 10) / 2);
  137. y -= (parseInt(element.offsetHeight, 10) / 2);
  138. }
  139. var translate = "translate3d(" + x + "px," + y + "px, 0)";
  140. for (var i = 0; i < TRANSFORM_CSS_VENDOR_PREFIXES.length; i++) {
  141. var transformProp = TRANSFORM_CSS_VENDOR_PREFIXES[i] + "transform";
  142. element.style[transformProp] = translate + " " + originalTransforms[i];
  143. }
  144. }
  145. function applyDragImageSnapback(sourceEl, dragImage, dragImageTransforms, transitionEndCb) {
  146. var cs = getComputedStyle(sourceEl);
  147. if (cs.visibility === "hidden" || cs.display === "none") {
  148. console.log("dnd-poly: source node is not visible. skipping snapback transition.");
  149. transitionEndCb();
  150. return;
  151. }
  152. dragImage.classList.add(CLASS_DRAG_IMAGE_SNAPBACK);
  153. var csDragImage = getComputedStyle(dragImage);
  154. var durationInS = parseFloat(csDragImage.transitionDuration);
  155. if (isNaN(durationInS) || durationInS === 0) {
  156. console.log("dnd-poly: no transition used - skipping snapback");
  157. transitionEndCb();
  158. return;
  159. }
  160. console.log("dnd-poly: starting dragimage snap back");
  161. var rect = sourceEl.getBoundingClientRect();
  162. var pnt = {
  163. x: rect.left,
  164. y: rect.top
  165. };
  166. pnt.x += (document.body.scrollLeft || document.documentElement.scrollLeft);
  167. pnt.y += (document.body.scrollTop || document.documentElement.scrollTop);
  168. pnt.x -= parseInt(cs.marginLeft, 10);
  169. pnt.y -= parseInt(cs.marginTop, 10);
  170. var delayInS = parseFloat(csDragImage.transitionDelay);
  171. var durationInMs = Math.round((durationInS + delayInS) * 1000);
  172. translateElementToPoint(dragImage, pnt, dragImageTransforms, undefined, false);
  173. setTimeout(transitionEndCb, durationInMs);
  174. }
  175. var DataTransfer = (function () {
  176. function DataTransfer(_dataStore, _setDragImageHandler) {
  177. this._dataStore = _dataStore;
  178. this._setDragImageHandler = _setDragImageHandler;
  179. this._dropEffect = DROP_EFFECTS[0];
  180. }
  181. Object.defineProperty(DataTransfer.prototype, "dropEffect", {
  182. get: function () {
  183. return this._dropEffect;
  184. },
  185. set: function (value) {
  186. if (this._dataStore.mode !== 0
  187. && ALLOWED_EFFECTS.indexOf(value) > -1) {
  188. this._dropEffect = value;
  189. }
  190. },
  191. enumerable: true,
  192. configurable: true
  193. });
  194. Object.defineProperty(DataTransfer.prototype, "types", {
  195. get: function () {
  196. if (this._dataStore.mode !== 0) {
  197. return Object.freeze(this._dataStore.types);
  198. }
  199. },
  200. enumerable: true,
  201. configurable: true
  202. });
  203. Object.defineProperty(DataTransfer.prototype, "effectAllowed", {
  204. get: function () {
  205. return this._dataStore.effectAllowed;
  206. },
  207. set: function (value) {
  208. if (this._dataStore.mode === 2
  209. && ALLOWED_EFFECTS.indexOf(value) > -1) {
  210. this._dataStore.effectAllowed = value;
  211. }
  212. },
  213. enumerable: true,
  214. configurable: true
  215. });
  216. DataTransfer.prototype.setData = function (type, data) {
  217. if (this._dataStore.mode === 2) {
  218. if (type.indexOf(" ") > -1) {
  219. throw new Error("illegal arg: type contains space");
  220. }
  221. this._dataStore.data[type] = data;
  222. if (this._dataStore.types.indexOf(type) === -1) {
  223. this._dataStore.types.push(type);
  224. }
  225. }
  226. };
  227. DataTransfer.prototype.getData = function (type) {
  228. if (this._dataStore.mode === 1
  229. || this._dataStore.mode === 2) {
  230. return this._dataStore.data[type] || "";
  231. }
  232. };
  233. DataTransfer.prototype.clearData = function (format) {
  234. if (this._dataStore.mode === 2) {
  235. if (format && this._dataStore.data[format]) {
  236. delete this._dataStore.data[format];
  237. var index = this._dataStore.types.indexOf(format);
  238. if (index > -1) {
  239. this._dataStore.types.splice(index, 1);
  240. }
  241. return;
  242. }
  243. this._dataStore.data = {};
  244. this._dataStore.types = [];
  245. }
  246. };
  247. DataTransfer.prototype.setDragImage = function (image, x, y) {
  248. if (this._dataStore.mode === 2) {
  249. this._setDragImageHandler(image, x, y);
  250. }
  251. };
  252. return DataTransfer;
  253. }());
  254. function tryFindDraggableTarget(event) {
  255. var el = event.target;
  256. do {
  257. if (el.draggable === false) {
  258. continue;
  259. }
  260. if (el.draggable === true) {
  261. return el;
  262. }
  263. if (el.getAttribute
  264. && el.getAttribute("draggable") === "true") {
  265. return el;
  266. }
  267. } while ((el = el.parentNode) && el !== document.body);
  268. }
  269. function determineDropEffect(effectAllowed, sourceNode) {
  270. if (!effectAllowed) {
  271. if (sourceNode.nodeType === 3 && sourceNode.tagName === "A") {
  272. return DROP_EFFECTS[3];
  273. }
  274. return DROP_EFFECTS[1];
  275. }
  276. if (effectAllowed === ALLOWED_EFFECTS[0]) {
  277. return DROP_EFFECTS[0];
  278. }
  279. if (effectAllowed.indexOf(ALLOWED_EFFECTS[1]) === 0 || effectAllowed === ALLOWED_EFFECTS[7]) {
  280. return DROP_EFFECTS[1];
  281. }
  282. if (effectAllowed.indexOf(ALLOWED_EFFECTS[4]) === 0) {
  283. return DROP_EFFECTS[3];
  284. }
  285. if (effectAllowed === ALLOWED_EFFECTS[6]) {
  286. return DROP_EFFECTS[2];
  287. }
  288. return DROP_EFFECTS[1];
  289. }
  290. function createDragEventFromTouch(targetElement, e, type, cancelable, window, dataTransfer, relatedTarget) {
  291. if (relatedTarget === void 0) { relatedTarget = null; }
  292. var touch = e.changedTouches[0];
  293. var dndEvent = new Event(type, {
  294. bubbles: true,
  295. cancelable: cancelable
  296. });
  297. dndEvent.dataTransfer = dataTransfer;
  298. dndEvent.relatedTarget = relatedTarget;
  299. dndEvent.screenX = touch.screenX;
  300. dndEvent.screenY = touch.screenY;
  301. dndEvent.clientX = touch.clientX;
  302. dndEvent.clientY = touch.clientY;
  303. dndEvent.pageX = touch.pageX;
  304. dndEvent.pageY = touch.pageY;
  305. var targetRect = targetElement.getBoundingClientRect();
  306. dndEvent.offsetX = dndEvent.clientX - targetRect.left;
  307. dndEvent.offsetY = dndEvent.clientY - targetRect.top;
  308. return dndEvent;
  309. }
  310. function dispatchDragEvent(dragEvent, targetElement, touchEvent, dataStore, dataTransfer, cancelable, relatedTarget) {
  311. if (cancelable === void 0) { cancelable = true; }
  312. if (relatedTarget === void 0) { relatedTarget = null; }
  313. console.log("dnd-poly: dispatching " + dragEvent);
  314. var leaveEvt = createDragEventFromTouch(targetElement, touchEvent, dragEvent, cancelable, document.defaultView, dataTransfer, relatedTarget);
  315. var cancelled = !targetElement.dispatchEvent(leaveEvt);
  316. dataStore.mode = 0;
  317. return cancelled;
  318. }
  319. function determineDragOperation(effectAllowed, dropEffect) {
  320. if (!effectAllowed || effectAllowed === ALLOWED_EFFECTS[7]) {
  321. return dropEffect;
  322. }
  323. if (dropEffect === DROP_EFFECTS[1]) {
  324. if (effectAllowed.indexOf(DROP_EFFECTS[1]) === 0) {
  325. return DROP_EFFECTS[1];
  326. }
  327. }
  328. else if (dropEffect === DROP_EFFECTS[3]) {
  329. if (effectAllowed.indexOf(DROP_EFFECTS[3]) === 0 || effectAllowed.indexOf("Link") > -1) {
  330. return DROP_EFFECTS[3];
  331. }
  332. }
  333. else if (dropEffect === DROP_EFFECTS[2]) {
  334. if (effectAllowed.indexOf(DROP_EFFECTS[2]) === 0 || effectAllowed.indexOf("Move") > -1) {
  335. return DROP_EFFECTS[2];
  336. }
  337. }
  338. return DROP_EFFECTS[0];
  339. }
  340. var DragOperationController = (function () {
  341. function DragOperationController(_initialEvent, _config, _sourceNode, _dragOperationEndedCb) {
  342. this._initialEvent = _initialEvent;
  343. this._config = _config;
  344. this._sourceNode = _sourceNode;
  345. this._dragOperationEndedCb = _dragOperationEndedCb;
  346. this._dragOperationState = 0;
  347. this._immediateUserSelection = null;
  348. this._currentDropTarget = null;
  349. console.log("dnd-poly: setting up potential drag operation..");
  350. this._lastTouchEvent = _initialEvent;
  351. this._initialTouch = _initialEvent.changedTouches[0];
  352. this._touchMoveHandler = this._onTouchMove.bind(this);
  353. this._touchEndOrCancelHandler = this._onTouchEndOrCancel.bind(this);
  354. addDocumentListener("touchmove", this._touchMoveHandler, false);
  355. addDocumentListener("touchend", this._touchEndOrCancelHandler, false);
  356. addDocumentListener("touchcancel", this._touchEndOrCancelHandler, false);
  357. }
  358. DragOperationController.prototype._setup = function () {
  359. var _this = this;
  360. console.log("dnd-poly: starting drag and drop operation");
  361. this._dragOperationState = 1;
  362. this._currentDragOperation = DROP_EFFECTS[0];
  363. this._dragDataStore = {
  364. data: {},
  365. effectAllowed: undefined,
  366. mode: 3,
  367. types: [],
  368. };
  369. this._currentHotspotCoordinates = {
  370. x: null,
  371. y: null
  372. };
  373. this._dragImagePageCoordinates = {
  374. x: null,
  375. y: null
  376. };
  377. var dragImageSrc = this._sourceNode;
  378. this._dataTransfer = new DataTransfer(this._dragDataStore, function (element, x, y) {
  379. dragImageSrc = element;
  380. if (typeof x === "number" || typeof y === "number") {
  381. _this._dragImageOffset = {
  382. x: x || 0,
  383. y: y || 0
  384. };
  385. }
  386. });
  387. this._dragDataStore.mode = 2;
  388. this._dataTransfer.dropEffect = DROP_EFFECTS[0];
  389. if (dispatchDragEvent("dragstart", this._sourceNode, this._lastTouchEvent, this._dragDataStore, this._dataTransfer)) {
  390. console.log("dnd-poly: dragstart cancelled");
  391. this._dragOperationState = 3;
  392. this._cleanup();
  393. return false;
  394. }
  395. updateCentroidCoordinatesOfTouchesIn("page", this._lastTouchEvent, this._dragImagePageCoordinates);
  396. var dragImage = this._config.dragImageSetup(dragImageSrc);
  397. this._dragImageTransforms = extractTransformStyles(dragImage);
  398. dragImage.style.position = "absolute";
  399. dragImage.style.left = "0px";
  400. dragImage.style.top = "0px";
  401. dragImage.style.zIndex = "999999";
  402. dragImage.classList.add(CLASS_DRAG_IMAGE);
  403. dragImage.classList.add(CLASS_DRAG_OPERATION_ICON);
  404. this._dragImage = dragImage;
  405. if (!this._dragImageOffset) {
  406. if (this._config.dragImageOffset) {
  407. this._dragImageOffset = {
  408. x: this._config.dragImageOffset.x,
  409. y: this._config.dragImageOffset.y
  410. };
  411. }
  412. else if (this._config.dragImageCenterOnTouch) {
  413. var cs = getComputedStyle(dragImageSrc);
  414. this._dragImageOffset = {
  415. x: 0 - parseInt(cs.marginLeft, 10),
  416. y: 0 - parseInt(cs.marginTop, 10)
  417. };
  418. }
  419. else {
  420. var targetRect = dragImageSrc.getBoundingClientRect();
  421. var cs = getComputedStyle(dragImageSrc);
  422. this._dragImageOffset = {
  423. x: targetRect.left - this._initialTouch.clientX - parseInt(cs.marginLeft, 10) + targetRect.width / 2,
  424. y: targetRect.top - this._initialTouch.clientY - parseInt(cs.marginTop, 10) + targetRect.height / 2
  425. };
  426. }
  427. }
  428. translateElementToPoint(this._dragImage, this._dragImagePageCoordinates, this._dragImageTransforms, this._dragImageOffset, this._config.dragImageCenterOnTouch);
  429. document.body.appendChild(this._dragImage);
  430. this._iterationIntervalId = window.setInterval(function () {
  431. if (_this._iterationLock) {
  432. console.log("dnd-poly: iteration skipped because previous iteration hast not yet finished.");
  433. return;
  434. }
  435. _this._iterationLock = true;
  436. _this._dragAndDropProcessModelIteration();
  437. _this._iterationLock = false;
  438. }, this._config.iterationInterval);
  439. return true;
  440. };
  441. DragOperationController.prototype._cleanup = function () {
  442. console.log("dnd-poly: cleanup");
  443. if (this._iterationIntervalId) {
  444. clearInterval(this._iterationIntervalId);
  445. this._iterationIntervalId = null;
  446. }
  447. removeDocumentListener("touchmove", this._touchMoveHandler);
  448. removeDocumentListener("touchend", this._touchEndOrCancelHandler);
  449. removeDocumentListener("touchcancel", this._touchEndOrCancelHandler);
  450. if (this._dragImage) {
  451. this._dragImage.parentNode.removeChild(this._dragImage);
  452. this._dragImage = null;
  453. }
  454. this._dragOperationEndedCb(this._config, this._lastTouchEvent, this._dragOperationState);
  455. };
  456. DragOperationController.prototype._onTouchMove = function (event) {
  457. var _this = this;
  458. if (isTouchIdentifierContainedInTouchEvent(event, this._initialTouch.identifier) === false) {
  459. return;
  460. }
  461. this._lastTouchEvent = event;
  462. if (this._dragOperationState === 0) {
  463. var startDrag = void 0;
  464. if (this._config.dragStartConditionOverride) {
  465. try {
  466. startDrag = this._config.dragStartConditionOverride(event);
  467. }
  468. catch (e) {
  469. console.error("dnd-poly: error in dragStartConditionOverride hook: " + e);
  470. startDrag = false;
  471. }
  472. }
  473. else {
  474. startDrag = (event.touches.length === 1);
  475. }
  476. if (!startDrag) {
  477. this._cleanup();
  478. return;
  479. }
  480. if (this._setup() === true) {
  481. this._initialEvent.preventDefault();
  482. event.preventDefault();
  483. }
  484. return;
  485. }
  486. console.log("dnd-poly: moving draggable..");
  487. event.preventDefault();
  488. updateCentroidCoordinatesOfTouchesIn("client", event, this._currentHotspotCoordinates);
  489. updateCentroidCoordinatesOfTouchesIn("page", event, this._dragImagePageCoordinates);
  490. if (this._config.dragImageTranslateOverride) {
  491. try {
  492. var handledDragImageTranslate_1 = false;
  493. this._config.dragImageTranslateOverride(event, {
  494. x: this._currentHotspotCoordinates.x,
  495. y: this._currentHotspotCoordinates.y
  496. }, this._immediateUserSelection, function (offsetX, offsetY) {
  497. if (!_this._dragImage) {
  498. return;
  499. }
  500. handledDragImageTranslate_1 = true;
  501. _this._currentHotspotCoordinates.x += offsetX;
  502. _this._currentHotspotCoordinates.y += offsetY;
  503. _this._dragImagePageCoordinates.x += offsetX;
  504. _this._dragImagePageCoordinates.y += offsetY;
  505. translateElementToPoint(_this._dragImage, _this._dragImagePageCoordinates, _this._dragImageTransforms, _this._dragImageOffset, _this._config.dragImageCenterOnTouch);
  506. });
  507. if (handledDragImageTranslate_1) {
  508. return;
  509. }
  510. }
  511. catch (e) {
  512. console.log("dnd-poly: error in dragImageTranslateOverride hook: " + e);
  513. }
  514. }
  515. translateElementToPoint(this._dragImage, this._dragImagePageCoordinates, this._dragImageTransforms, this._dragImageOffset, this._config.dragImageCenterOnTouch);
  516. };
  517. DragOperationController.prototype._onTouchEndOrCancel = function (event) {
  518. if (isTouchIdentifierContainedInTouchEvent(event, this._initialTouch.identifier) === false) {
  519. return;
  520. }
  521. if (this._config.dragImageTranslateOverride) {
  522. try {
  523. this._config.dragImageTranslateOverride(undefined, undefined, undefined, function () {
  524. });
  525. }
  526. catch (e) {
  527. console.log("dnd-poly: error in dragImageTranslateOverride hook: " + e);
  528. }
  529. }
  530. if (this._dragOperationState === 0) {
  531. this._cleanup();
  532. return;
  533. }
  534. event.preventDefault();
  535. this._dragOperationState = (event.type === "touchcancel") ? 3 : 2;
  536. };
  537. DragOperationController.prototype._dragAndDropProcessModelIteration = function () {
  538. var _this = this;
  539. var previousDragOperation = this._currentDragOperation;
  540. this._dragDataStore.mode = 3;
  541. this._dataTransfer.dropEffect = DROP_EFFECTS[0];
  542. var dragCancelled = dispatchDragEvent("drag", this._sourceNode, this._lastTouchEvent, this._dragDataStore, this._dataTransfer);
  543. if (dragCancelled) {
  544. console.log("dnd-poly: drag event cancelled.");
  545. this._currentDragOperation = DROP_EFFECTS[0];
  546. }
  547. if (dragCancelled || this._dragOperationState === 2 || this._dragOperationState === 3) {
  548. var dragFailed = this._dragOperationEnded(this._dragOperationState);
  549. if (dragFailed) {
  550. applyDragImageSnapback(this._sourceNode, this._dragImage, this._dragImageTransforms, function () {
  551. _this._finishDragOperation();
  552. });
  553. return;
  554. }
  555. this._finishDragOperation();
  556. return;
  557. }
  558. var newUserSelection = this._config.elementFromPoint(this._currentHotspotCoordinates.x, this._currentHotspotCoordinates.y);
  559. console.log("dnd-poly: new immediate user selection is: " + newUserSelection);
  560. var previousTargetElement = this._currentDropTarget;
  561. if (newUserSelection !== this._immediateUserSelection && newUserSelection !== this._currentDropTarget) {
  562. this._immediateUserSelection = newUserSelection;
  563. if (this._currentDropTarget !== null) {
  564. this._dragDataStore.mode = 3;
  565. this._dataTransfer.dropEffect = DROP_EFFECTS[0];
  566. dispatchDragEvent("dragexit", this._currentDropTarget, this._lastTouchEvent, this._dragDataStore, this._dataTransfer, false);
  567. }
  568. if (this._immediateUserSelection === null) {
  569. this._currentDropTarget = this._immediateUserSelection;
  570. console.log("dnd-poly: current drop target changed to null");
  571. }
  572. else {
  573. this._dragDataStore.mode = 3;
  574. this._dataTransfer.dropEffect = determineDropEffect(this._dragDataStore.effectAllowed, this._sourceNode);
  575. if (dispatchDragEvent("dragenter", this._immediateUserSelection, this._lastTouchEvent, this._dragDataStore, this._dataTransfer)) {
  576. console.log("dnd-poly: dragenter default prevented");
  577. this._currentDropTarget = this._immediateUserSelection;
  578. this._currentDragOperation = determineDragOperation(this._dataTransfer.effectAllowed, this._dataTransfer.dropEffect);
  579. }
  580. else {
  581. if (this._immediateUserSelection !== document.body) {
  582. this._currentDropTarget = document.body;
  583. }
  584. }
  585. }
  586. }
  587. if (previousTargetElement !== this._currentDropTarget && (isDOMElement(previousTargetElement))) {
  588. console.log("dnd-poly: current drop target changed.");
  589. this._dragDataStore.mode = 3;
  590. this._dataTransfer.dropEffect = DROP_EFFECTS[0];
  591. dispatchDragEvent("dragleave", previousTargetElement, this._lastTouchEvent, this._dragDataStore, this._dataTransfer, false, this._currentDropTarget);
  592. }
  593. if (isDOMElement(this._currentDropTarget)) {
  594. this._dragDataStore.mode = 3;
  595. this._dataTransfer.dropEffect = determineDropEffect(this._dragDataStore.effectAllowed, this._sourceNode);
  596. if (dispatchDragEvent("dragover", this._currentDropTarget, this._lastTouchEvent, this._dragDataStore, this._dataTransfer) === false) {
  597. console.log("dnd-poly: dragover not prevented on possible drop-target.");
  598. this._currentDragOperation = DROP_EFFECTS[0];
  599. }
  600. else {
  601. console.log("dnd-poly: dragover prevented.");
  602. this._currentDragOperation = determineDragOperation(this._dataTransfer.effectAllowed, this._dataTransfer.dropEffect);
  603. }
  604. }
  605. console.log("dnd-poly: d'n'd iteration ended. current drag operation: " + this._currentDragOperation);
  606. if (previousDragOperation !== this._currentDragOperation) {
  607. this._dragImage.classList.remove(CLASS_PREFIX + previousDragOperation);
  608. }
  609. var currentDragOperationClass = CLASS_PREFIX + this._currentDragOperation;
  610. this._dragImage.classList.add(currentDragOperationClass);
  611. };
  612. DragOperationController.prototype._dragOperationEnded = function (state) {
  613. console.log("dnd-poly: drag operation end detected with " + this._currentDragOperation);
  614. var dragFailed = (this._currentDragOperation === DROP_EFFECTS[0]
  615. || this._currentDropTarget === null
  616. || state === 3);
  617. if (dragFailed) {
  618. if (isDOMElement(this._currentDropTarget)) {
  619. this._dragDataStore.mode = 3;
  620. this._dataTransfer.dropEffect = DROP_EFFECTS[0];
  621. dispatchDragEvent("dragleave", this._currentDropTarget, this._lastTouchEvent, this._dragDataStore, this._dataTransfer, false);
  622. }
  623. }
  624. else {
  625. if (isDOMElement(this._currentDropTarget)) {
  626. this._dragDataStore.mode = 1;
  627. this._dataTransfer.dropEffect = this._currentDragOperation;
  628. if (dispatchDragEvent("drop", this._currentDropTarget, this._lastTouchEvent, this._dragDataStore, this._dataTransfer) ===
  629. true) {
  630. this._currentDragOperation = this._dataTransfer.dropEffect;
  631. }
  632. else {
  633. this._currentDragOperation = DROP_EFFECTS[0];
  634. }
  635. }
  636. }
  637. return dragFailed;
  638. };
  639. DragOperationController.prototype._finishDragOperation = function () {
  640. console.log("dnd-poly: dragimage snap back transition ended");
  641. this._dragDataStore.mode = 3;
  642. this._dataTransfer.dropEffect = this._currentDragOperation;
  643. dispatchDragEvent("dragend", this._sourceNode, this._lastTouchEvent, this._dragDataStore, this._dataTransfer, false);
  644. this._dragOperationState = 2;
  645. this._cleanup();
  646. };
  647. return DragOperationController;
  648. }());
  649. var config = {
  650. iterationInterval: 150,
  651. tryFindDraggableTarget: tryFindDraggableTarget,
  652. dragImageSetup: createDragImage,
  653. elementFromPoint: function (x, y) { return document.elementFromPoint(x, y); }
  654. };
  655. var activeDragOperation;
  656. function onTouchstart(e) {
  657. console.log("dnd-poly: global touchstart");
  658. if (activeDragOperation) {
  659. console.log("dnd-poly: drag operation already active");
  660. return;
  661. }
  662. var dragTarget = config.tryFindDraggableTarget(e);
  663. if (!dragTarget) {
  664. console.log("dnd-poly: no draggable at touchstart coordinates");
  665. return;
  666. }
  667. try {
  668. activeDragOperation = new DragOperationController(e, config, dragTarget, dragOperationEnded);
  669. }
  670. catch (err) {
  671. dragOperationEnded(config, e, 3);
  672. throw err;
  673. }
  674. }
  675. function onDelayTouchstart(evt) {
  676. console.log("dnd-poly: setup delayed dragstart..");
  677. var el = evt.target;
  678. var heldItem = function () {
  679. console.log("dnd-poly: starting delayed drag..");
  680. end.off();
  681. cancel.off();
  682. move.off();
  683. scroll.off();
  684. onTouchstart(evt);
  685. };
  686. var onReleasedItem = function (event) {
  687. console.log("dnd-poly: aborting delayed drag because of " + event.type);
  688. end.off();
  689. cancel.off();
  690. move.off();
  691. scroll.off();
  692. if (el) {
  693. el.dispatchEvent(new CustomEvent(EVENT_DRAG_DRAGSTART_CANCEL, { bubbles: true, cancelable: true }));
  694. }
  695. clearTimeout(timer);
  696. };
  697. if (el) {
  698. el.dispatchEvent(new CustomEvent(EVENT_DRAG_DRAGSTART_PENDING, { bubbles: true, cancelable: true }));
  699. }
  700. var timer = window.setTimeout(heldItem, config.holdToDrag);
  701. var end = onEvt(el, "touchend", onReleasedItem);
  702. var cancel = onEvt(el, "touchcancel", onReleasedItem);
  703. var move = onEvt(el, "touchmove", onReleasedItem);
  704. var scroll = onEvt(window, "scroll", onReleasedItem, true);
  705. }
  706. function dragOperationEnded(_config, event, state) {
  707. if (state === 0) {
  708. console.log("dnd-poly: Drag never started. Last event was " + event.type);
  709. if (_config.defaultActionOverride) {
  710. try {
  711. _config.defaultActionOverride(event);
  712. if (event.defaultPrevented) {
  713. console.log("dnd-poly: defaultActionOverride has taken care of triggering the default action. preventing default on original event");
  714. }
  715. }
  716. catch (e) {
  717. console.log("dnd-poly: error in defaultActionOverride: " + e);
  718. }
  719. }
  720. }
  721. activeDragOperation = null;
  722. }
  723. function polyfill(override) {
  724. if (override) {
  725. Object.keys(override).forEach(function (key) {
  726. config[key] = override[key];
  727. });
  728. }
  729. if (!config.forceApply) {
  730. var detectedFeatures = detectFeatures();
  731. if (detectedFeatures.userAgentSupportingNativeDnD
  732. && detectedFeatures.draggable
  733. && detectedFeatures.dragEvents) {
  734. return false;
  735. }
  736. }
  737. console.log("dnd-poly: Applying mobile drag and drop polyfill.");
  738. if (config.holdToDrag) {
  739. console.log("dnd-poly: holdToDrag set to " + config.holdToDrag);
  740. addDocumentListener("touchstart", onDelayTouchstart, false);
  741. }
  742. else {
  743. addDocumentListener("touchstart", onTouchstart, false);
  744. }
  745. return true;
  746. }
  747. exports.polyfill = polyfill;
  748. Object.defineProperty(exports, '__esModule', { value: true });
  749. })));
  750. //# sourceMappingURL=index.js.map