PageRenderTime 885ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/react-dnd/dragSource/node_modules/react-dnd-html5-backend/lib/HTML5Backend.js

https://github.com/liangklfangl/react-article-bucket
JavaScript | 651 lines | 500 code | 92 blank | 59 comment | 69 complexity | 45e8f759f96bc12fc80926dd7b140a2f MD5 | raw file
Possible License(s): 0BSD, BSD-2-Clause, JSON, GPL-2.0, CC0-1.0, MIT, Apache-2.0, Unlicense, CC-BY-SA-3.0, CC-BY-4.0, BSD-3-Clause
  1. 'use strict';
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
  6. var _defaults = require('lodash/defaults');
  7. var _defaults2 = _interopRequireDefault(_defaults);
  8. var _shallowEqual = require('./shallowEqual');
  9. var _shallowEqual2 = _interopRequireDefault(_shallowEqual);
  10. var _EnterLeaveCounter = require('./EnterLeaveCounter');
  11. var _EnterLeaveCounter2 = _interopRequireDefault(_EnterLeaveCounter);
  12. var _BrowserDetector = require('./BrowserDetector');
  13. var _OffsetUtils = require('./OffsetUtils');
  14. var _NativeDragSources = require('./NativeDragSources');
  15. var _NativeTypes = require('./NativeTypes');
  16. var NativeTypes = _interopRequireWildcard(_NativeTypes);
  17. function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
  18. function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  19. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  20. var HTML5Backend = function () {
  21. function HTML5Backend(manager) {
  22. _classCallCheck(this, HTML5Backend);
  23. this.actions = manager.getActions();
  24. this.monitor = manager.getMonitor();
  25. this.registry = manager.getRegistry();
  26. this.context = manager.getContext();
  27. this.sourcePreviewNodes = {};
  28. this.sourcePreviewNodeOptions = {};
  29. this.sourceNodes = {};
  30. this.sourceNodeOptions = {};
  31. this.enterLeaveCounter = new _EnterLeaveCounter2.default();
  32. this.dragStartSourceIds = [];
  33. this.dropTargetIds = [];
  34. this.dragEnterTargetIds = [];
  35. this.currentNativeSource = null;
  36. this.currentNativeHandle = null;
  37. this.currentDragSourceNode = null;
  38. this.currentDragSourceNodeOffset = null;
  39. this.currentDragSourceNodeOffsetChanged = false;
  40. this.altKeyPressed = false;
  41. this.getSourceClientOffset = this.getSourceClientOffset.bind(this);
  42. this.handleTopDragStart = this.handleTopDragStart.bind(this);
  43. this.handleTopDragStartCapture = this.handleTopDragStartCapture.bind(this);
  44. this.handleTopDragEndCapture = this.handleTopDragEndCapture.bind(this);
  45. this.handleTopDragEnter = this.handleTopDragEnter.bind(this);
  46. this.handleTopDragEnterCapture = this.handleTopDragEnterCapture.bind(this);
  47. this.handleTopDragLeaveCapture = this.handleTopDragLeaveCapture.bind(this);
  48. this.handleTopDragOver = this.handleTopDragOver.bind(this);
  49. this.handleTopDragOverCapture = this.handleTopDragOverCapture.bind(this);
  50. this.handleTopDrop = this.handleTopDrop.bind(this);
  51. this.handleTopDropCapture = this.handleTopDropCapture.bind(this);
  52. this.handleSelectStart = this.handleSelectStart.bind(this);
  53. this.endDragIfSourceWasRemovedFromDOM = this.endDragIfSourceWasRemovedFromDOM.bind(this);
  54. this.endDragNativeItem = this.endDragNativeItem.bind(this);
  55. this.asyncEndDragNativeItem = this.asyncEndDragNativeItem.bind(this);
  56. }
  57. _createClass(HTML5Backend, [{
  58. key: 'setup',
  59. value: function setup() {
  60. if (this.window === undefined) {
  61. return;
  62. }
  63. if (this.window.__isReactDndBackendSetUp) {
  64. // eslint-disable-line no-underscore-dangle
  65. throw new Error('Cannot have two HTML5 backends at the same time.');
  66. }
  67. this.window.__isReactDndBackendSetUp = true; // eslint-disable-line no-underscore-dangle
  68. this.addEventListeners(this.window);
  69. }
  70. }, {
  71. key: 'teardown',
  72. value: function teardown() {
  73. if (this.window === undefined) {
  74. return;
  75. }
  76. this.window.__isReactDndBackendSetUp = false; // eslint-disable-line no-underscore-dangle
  77. this.removeEventListeners(this.window);
  78. this.clearCurrentDragSourceNode();
  79. if (this.asyncEndDragFrameId) {
  80. this.window.cancelAnimationFrame(this.asyncEndDragFrameId);
  81. }
  82. }
  83. }, {
  84. key: 'addEventListeners',
  85. value: function addEventListeners(target) {
  86. target.addEventListener('dragstart', this.handleTopDragStart);
  87. target.addEventListener('dragstart', this.handleTopDragStartCapture, true);
  88. target.addEventListener('dragend', this.handleTopDragEndCapture, true);
  89. target.addEventListener('dragenter', this.handleTopDragEnter);
  90. target.addEventListener('dragenter', this.handleTopDragEnterCapture, true);
  91. target.addEventListener('dragleave', this.handleTopDragLeaveCapture, true);
  92. target.addEventListener('dragover', this.handleTopDragOver);
  93. target.addEventListener('dragover', this.handleTopDragOverCapture, true);
  94. target.addEventListener('drop', this.handleTopDrop);
  95. target.addEventListener('drop', this.handleTopDropCapture, true);
  96. }
  97. }, {
  98. key: 'removeEventListeners',
  99. value: function removeEventListeners(target) {
  100. target.removeEventListener('dragstart', this.handleTopDragStart);
  101. target.removeEventListener('dragstart', this.handleTopDragStartCapture, true);
  102. target.removeEventListener('dragend', this.handleTopDragEndCapture, true);
  103. target.removeEventListener('dragenter', this.handleTopDragEnter);
  104. target.removeEventListener('dragenter', this.handleTopDragEnterCapture, true);
  105. target.removeEventListener('dragleave', this.handleTopDragLeaveCapture, true);
  106. target.removeEventListener('dragover', this.handleTopDragOver);
  107. target.removeEventListener('dragover', this.handleTopDragOverCapture, true);
  108. target.removeEventListener('drop', this.handleTopDrop);
  109. target.removeEventListener('drop', this.handleTopDropCapture, true);
  110. }
  111. }, {
  112. key: 'connectDragPreview',
  113. value: function connectDragPreview(sourceId, node, options) {
  114. var _this = this;
  115. this.sourcePreviewNodeOptions[sourceId] = options;
  116. this.sourcePreviewNodes[sourceId] = node;
  117. return function () {
  118. delete _this.sourcePreviewNodes[sourceId];
  119. delete _this.sourcePreviewNodeOptions[sourceId];
  120. };
  121. }
  122. }, {
  123. key: 'connectDragSource',
  124. value: function connectDragSource(sourceId, node, options) {
  125. var _this2 = this;
  126. this.sourceNodes[sourceId] = node;
  127. this.sourceNodeOptions[sourceId] = options;
  128. var handleDragStart = function handleDragStart(e) {
  129. return _this2.handleDragStart(e, sourceId);
  130. };
  131. var handleSelectStart = function handleSelectStart(e) {
  132. return _this2.handleSelectStart(e, sourceId);
  133. };
  134. node.setAttribute('draggable', true);
  135. node.addEventListener('dragstart', handleDragStart);
  136. node.addEventListener('selectstart', handleSelectStart);
  137. return function () {
  138. delete _this2.sourceNodes[sourceId];
  139. delete _this2.sourceNodeOptions[sourceId];
  140. node.removeEventListener('dragstart', handleDragStart);
  141. node.removeEventListener('selectstart', handleSelectStart);
  142. node.setAttribute('draggable', false);
  143. };
  144. }
  145. }, {
  146. key: 'connectDropTarget',
  147. value: function connectDropTarget(targetId, node) {
  148. var _this3 = this;
  149. var handleDragEnter = function handleDragEnter(e) {
  150. return _this3.handleDragEnter(e, targetId);
  151. };
  152. var handleDragOver = function handleDragOver(e) {
  153. return _this3.handleDragOver(e, targetId);
  154. };
  155. var handleDrop = function handleDrop(e) {
  156. return _this3.handleDrop(e, targetId);
  157. };
  158. node.addEventListener('dragenter', handleDragEnter);
  159. node.addEventListener('dragover', handleDragOver);
  160. node.addEventListener('drop', handleDrop);
  161. return function () {
  162. node.removeEventListener('dragenter', handleDragEnter);
  163. node.removeEventListener('dragover', handleDragOver);
  164. node.removeEventListener('drop', handleDrop);
  165. };
  166. }
  167. }, {
  168. key: 'getCurrentSourceNodeOptions',
  169. value: function getCurrentSourceNodeOptions() {
  170. var sourceId = this.monitor.getSourceId();
  171. var sourceNodeOptions = this.sourceNodeOptions[sourceId];
  172. return (0, _defaults2.default)(sourceNodeOptions || {}, {
  173. dropEffect: this.altKeyPressed ? 'copy' : 'move'
  174. });
  175. }
  176. }, {
  177. key: 'getCurrentDropEffect',
  178. value: function getCurrentDropEffect() {
  179. if (this.isDraggingNativeItem()) {
  180. // It makes more sense to default to 'copy' for native resources
  181. return 'copy';
  182. }
  183. return this.getCurrentSourceNodeOptions().dropEffect;
  184. }
  185. }, {
  186. key: 'getCurrentSourcePreviewNodeOptions',
  187. value: function getCurrentSourcePreviewNodeOptions() {
  188. var sourceId = this.monitor.getSourceId();
  189. var sourcePreviewNodeOptions = this.sourcePreviewNodeOptions[sourceId];
  190. return (0, _defaults2.default)(sourcePreviewNodeOptions || {}, {
  191. anchorX: 0.5,
  192. anchorY: 0.5,
  193. captureDraggingState: false
  194. });
  195. }
  196. }, {
  197. key: 'getSourceClientOffset',
  198. value: function getSourceClientOffset(sourceId) {
  199. return (0, _OffsetUtils.getNodeClientOffset)(this.sourceNodes[sourceId]);
  200. }
  201. }, {
  202. key: 'isDraggingNativeItem',
  203. value: function isDraggingNativeItem() {
  204. var itemType = this.monitor.getItemType();
  205. return Object.keys(NativeTypes).some(function (key) {
  206. return NativeTypes[key] === itemType;
  207. });
  208. }
  209. }, {
  210. key: 'beginDragNativeItem',
  211. value: function beginDragNativeItem(type) {
  212. this.clearCurrentDragSourceNode();
  213. var SourceType = (0, _NativeDragSources.createNativeDragSource)(type);
  214. this.currentNativeSource = new SourceType();
  215. this.currentNativeHandle = this.registry.addSource(type, this.currentNativeSource);
  216. this.actions.beginDrag([this.currentNativeHandle]);
  217. // On Firefox, if mouseover fires, the drag is over but browser failed to tell us.
  218. // See https://bugzilla.mozilla.org/show_bug.cgi?id=656164
  219. // This is not true for other browsers.
  220. if ((0, _BrowserDetector.isFirefox)()) {
  221. this.window.addEventListener('mouseover', this.asyncEndDragNativeItem, true);
  222. }
  223. }
  224. }, {
  225. key: 'asyncEndDragNativeItem',
  226. value: function asyncEndDragNativeItem() {
  227. this.asyncEndDragFrameId = this.window.requestAnimationFrame(this.endDragNativeItem);
  228. if ((0, _BrowserDetector.isFirefox)()) {
  229. this.window.removeEventListener('mouseover', this.asyncEndDragNativeItem, true);
  230. this.enterLeaveCounter.reset();
  231. }
  232. }
  233. }, {
  234. key: 'endDragNativeItem',
  235. value: function endDragNativeItem() {
  236. if (!this.isDraggingNativeItem()) {
  237. return;
  238. }
  239. this.actions.endDrag();
  240. this.registry.removeSource(this.currentNativeHandle);
  241. this.currentNativeHandle = null;
  242. this.currentNativeSource = null;
  243. }
  244. }, {
  245. key: 'endDragIfSourceWasRemovedFromDOM',
  246. value: function endDragIfSourceWasRemovedFromDOM() {
  247. var node = this.currentDragSourceNode;
  248. if (document.body.contains(node)) {
  249. return;
  250. }
  251. if (this.clearCurrentDragSourceNode()) {
  252. this.actions.endDrag();
  253. }
  254. }
  255. }, {
  256. key: 'setCurrentDragSourceNode',
  257. value: function setCurrentDragSourceNode(node) {
  258. this.clearCurrentDragSourceNode();
  259. this.currentDragSourceNode = node;
  260. this.currentDragSourceNodeOffset = (0, _OffsetUtils.getNodeClientOffset)(node);
  261. this.currentDragSourceNodeOffsetChanged = false;
  262. // Receiving a mouse event in the middle of a dragging operation
  263. // means it has ended and the drag source node disappeared from DOM,
  264. // so the browser didn't dispatch the dragend event.
  265. this.window.addEventListener('mousemove', this.endDragIfSourceWasRemovedFromDOM, true);
  266. }
  267. }, {
  268. key: 'clearCurrentDragSourceNode',
  269. value: function clearCurrentDragSourceNode() {
  270. if (this.currentDragSourceNode) {
  271. this.currentDragSourceNode = null;
  272. this.currentDragSourceNodeOffset = null;
  273. this.currentDragSourceNodeOffsetChanged = false;
  274. this.window.removeEventListener('mousemove', this.endDragIfSourceWasRemovedFromDOM, true);
  275. return true;
  276. }
  277. return false;
  278. }
  279. }, {
  280. key: 'checkIfCurrentDragSourceRectChanged',
  281. value: function checkIfCurrentDragSourceRectChanged() {
  282. var node = this.currentDragSourceNode;
  283. if (!node) {
  284. return false;
  285. }
  286. if (this.currentDragSourceNodeOffsetChanged) {
  287. return true;
  288. }
  289. this.currentDragSourceNodeOffsetChanged = !(0, _shallowEqual2.default)((0, _OffsetUtils.getNodeClientOffset)(node), this.currentDragSourceNodeOffset);
  290. return this.currentDragSourceNodeOffsetChanged;
  291. }
  292. }, {
  293. key: 'handleTopDragStartCapture',
  294. value: function handleTopDragStartCapture() {
  295. this.clearCurrentDragSourceNode();
  296. this.dragStartSourceIds = [];
  297. }
  298. }, {
  299. key: 'handleDragStart',
  300. value: function handleDragStart(e, sourceId) {
  301. this.dragStartSourceIds.unshift(sourceId);
  302. }
  303. }, {
  304. key: 'handleTopDragStart',
  305. value: function handleTopDragStart(e) {
  306. var _this4 = this;
  307. var dragStartSourceIds = this.dragStartSourceIds;
  308. this.dragStartSourceIds = null;
  309. var clientOffset = (0, _OffsetUtils.getEventClientOffset)(e);
  310. // Don't publish the source just yet (see why below)
  311. this.actions.beginDrag(dragStartSourceIds, {
  312. publishSource: false,
  313. getSourceClientOffset: this.getSourceClientOffset,
  314. clientOffset: clientOffset
  315. });
  316. var dataTransfer = e.dataTransfer;
  317. var nativeType = (0, _NativeDragSources.matchNativeItemType)(dataTransfer);
  318. if (this.monitor.isDragging()) {
  319. if (typeof dataTransfer.setDragImage === 'function') {
  320. // Use custom drag image if user specifies it.
  321. // If child drag source refuses drag but parent agrees,
  322. // use parent's node as drag image. Neither works in IE though.
  323. var sourceId = this.monitor.getSourceId();
  324. var sourceNode = this.sourceNodes[sourceId];
  325. var dragPreview = this.sourcePreviewNodes[sourceId] || sourceNode;
  326. var _getCurrentSourcePrev = this.getCurrentSourcePreviewNodeOptions(),
  327. anchorX = _getCurrentSourcePrev.anchorX,
  328. anchorY = _getCurrentSourcePrev.anchorY;
  329. var anchorPoint = { anchorX: anchorX, anchorY: anchorY };
  330. var dragPreviewOffset = (0, _OffsetUtils.getDragPreviewOffset)(sourceNode, dragPreview, clientOffset, anchorPoint);
  331. dataTransfer.setDragImage(dragPreview, dragPreviewOffset.x, dragPreviewOffset.y);
  332. }
  333. try {
  334. // Firefox won't drag without setting data
  335. dataTransfer.setData('application/json', {});
  336. } catch (err) {}
  337. // IE doesn't support MIME types in setData
  338. // Store drag source node so we can check whether
  339. // it is removed from DOM and trigger endDrag manually.
  340. this.setCurrentDragSourceNode(e.target);
  341. // Now we are ready to publish the drag source.. or are we not?
  342. var _getCurrentSourcePrev2 = this.getCurrentSourcePreviewNodeOptions(),
  343. captureDraggingState = _getCurrentSourcePrev2.captureDraggingState;
  344. if (!captureDraggingState) {
  345. // Usually we want to publish it in the next tick so that browser
  346. // is able to screenshot the current (not yet dragging) state.
  347. //
  348. // It also neatly avoids a situation where render() returns null
  349. // in the same tick for the source element, and browser freaks out.
  350. setTimeout(function () {
  351. return _this4.actions.publishDragSource();
  352. });
  353. } else {
  354. // In some cases the user may want to override this behavior, e.g.
  355. // to work around IE not supporting custom drag previews.
  356. //
  357. // When using a custom drag layer, the only way to prevent
  358. // the default drag preview from drawing in IE is to screenshot
  359. // the dragging state in which the node itself has zero opacity
  360. // and height. In this case, though, returning null from render()
  361. // will abruptly end the dragging, which is not obvious.
  362. //
  363. // This is the reason such behavior is strictly opt-in.
  364. this.actions.publishDragSource();
  365. }
  366. } else if (nativeType) {
  367. // A native item (such as URL) dragged from inside the document
  368. this.beginDragNativeItem(nativeType);
  369. } else if (!dataTransfer.types && (!e.target.hasAttribute || !e.target.hasAttribute('draggable'))) {
  370. // Looks like a Safari bug: dataTransfer.types is null, but there was no draggable.
  371. // Just let it drag. It's a native type (URL or text) and will be picked up in
  372. // dragenter handler.
  373. return; // eslint-disable-line no-useless-return
  374. } else {
  375. // If by this time no drag source reacted, tell browser not to drag.
  376. e.preventDefault();
  377. }
  378. }
  379. }, {
  380. key: 'handleTopDragEndCapture',
  381. value: function handleTopDragEndCapture() {
  382. if (this.clearCurrentDragSourceNode()) {
  383. // Firefox can dispatch this event in an infinite loop
  384. // if dragend handler does something like showing an alert.
  385. // Only proceed if we have not handled it already.
  386. this.actions.endDrag();
  387. }
  388. }
  389. }, {
  390. key: 'handleTopDragEnterCapture',
  391. value: function handleTopDragEnterCapture(e) {
  392. this.dragEnterTargetIds = [];
  393. var isFirstEnter = this.enterLeaveCounter.enter(e.target);
  394. if (!isFirstEnter || this.monitor.isDragging()) {
  395. return;
  396. }
  397. var dataTransfer = e.dataTransfer;
  398. var nativeType = (0, _NativeDragSources.matchNativeItemType)(dataTransfer);
  399. if (nativeType) {
  400. // A native item (such as file or URL) dragged from outside the document
  401. this.beginDragNativeItem(nativeType);
  402. }
  403. }
  404. }, {
  405. key: 'handleDragEnter',
  406. value: function handleDragEnter(e, targetId) {
  407. this.dragEnterTargetIds.unshift(targetId);
  408. }
  409. }, {
  410. key: 'handleTopDragEnter',
  411. value: function handleTopDragEnter(e) {
  412. var _this5 = this;
  413. var dragEnterTargetIds = this.dragEnterTargetIds;
  414. this.dragEnterTargetIds = [];
  415. if (!this.monitor.isDragging()) {
  416. // This is probably a native item type we don't understand.
  417. return;
  418. }
  419. this.altKeyPressed = e.altKey;
  420. if (!(0, _BrowserDetector.isFirefox)()) {
  421. // Don't emit hover in `dragenter` on Firefox due to an edge case.
  422. // If the target changes position as the result of `dragenter`, Firefox
  423. // will still happily dispatch `dragover` despite target being no longer
  424. // there. The easy solution is to only fire `hover` in `dragover` on FF.
  425. this.actions.hover(dragEnterTargetIds, {
  426. clientOffset: (0, _OffsetUtils.getEventClientOffset)(e)
  427. });
  428. }
  429. var canDrop = dragEnterTargetIds.some(function (targetId) {
  430. return _this5.monitor.canDropOnTarget(targetId);
  431. });
  432. if (canDrop) {
  433. // IE requires this to fire dragover events
  434. e.preventDefault();
  435. e.dataTransfer.dropEffect = this.getCurrentDropEffect();
  436. }
  437. }
  438. }, {
  439. key: 'handleTopDragOverCapture',
  440. value: function handleTopDragOverCapture() {
  441. this.dragOverTargetIds = [];
  442. }
  443. }, {
  444. key: 'handleDragOver',
  445. value: function handleDragOver(e, targetId) {
  446. this.dragOverTargetIds.unshift(targetId);
  447. }
  448. }, {
  449. key: 'handleTopDragOver',
  450. value: function handleTopDragOver(e) {
  451. var _this6 = this;
  452. var dragOverTargetIds = this.dragOverTargetIds;
  453. this.dragOverTargetIds = [];
  454. if (!this.monitor.isDragging()) {
  455. // This is probably a native item type we don't understand.
  456. // Prevent default "drop and blow away the whole document" action.
  457. e.preventDefault();
  458. e.dataTransfer.dropEffect = 'none';
  459. return;
  460. }
  461. this.altKeyPressed = e.altKey;
  462. this.actions.hover(dragOverTargetIds, {
  463. clientOffset: (0, _OffsetUtils.getEventClientOffset)(e)
  464. });
  465. var canDrop = dragOverTargetIds.some(function (targetId) {
  466. return _this6.monitor.canDropOnTarget(targetId);
  467. });
  468. if (canDrop) {
  469. // Show user-specified drop effect.
  470. e.preventDefault();
  471. e.dataTransfer.dropEffect = this.getCurrentDropEffect();
  472. } else if (this.isDraggingNativeItem()) {
  473. // Don't show a nice cursor but still prevent default
  474. // "drop and blow away the whole document" action.
  475. e.preventDefault();
  476. e.dataTransfer.dropEffect = 'none';
  477. } else if (this.checkIfCurrentDragSourceRectChanged()) {
  478. // Prevent animating to incorrect position.
  479. // Drop effect must be other than 'none' to prevent animation.
  480. e.preventDefault();
  481. e.dataTransfer.dropEffect = 'move';
  482. }
  483. }
  484. }, {
  485. key: 'handleTopDragLeaveCapture',
  486. value: function handleTopDragLeaveCapture(e) {
  487. if (this.isDraggingNativeItem()) {
  488. e.preventDefault();
  489. }
  490. var isLastLeave = this.enterLeaveCounter.leave(e.target);
  491. if (!isLastLeave) {
  492. return;
  493. }
  494. if (this.isDraggingNativeItem()) {
  495. this.endDragNativeItem();
  496. }
  497. }
  498. }, {
  499. key: 'handleTopDropCapture',
  500. value: function handleTopDropCapture(e) {
  501. this.dropTargetIds = [];
  502. e.preventDefault();
  503. if (this.isDraggingNativeItem()) {
  504. this.currentNativeSource.mutateItemByReadingDataTransfer(e.dataTransfer);
  505. }
  506. this.enterLeaveCounter.reset();
  507. }
  508. }, {
  509. key: 'handleDrop',
  510. value: function handleDrop(e, targetId) {
  511. this.dropTargetIds.unshift(targetId);
  512. }
  513. }, {
  514. key: 'handleTopDrop',
  515. value: function handleTopDrop(e) {
  516. var dropTargetIds = this.dropTargetIds;
  517. this.dropTargetIds = [];
  518. this.actions.hover(dropTargetIds, {
  519. clientOffset: (0, _OffsetUtils.getEventClientOffset)(e)
  520. });
  521. this.actions.drop({ dropEffect: this.getCurrentDropEffect() });
  522. if (this.isDraggingNativeItem()) {
  523. this.endDragNativeItem();
  524. } else {
  525. this.endDragIfSourceWasRemovedFromDOM();
  526. }
  527. }
  528. }, {
  529. key: 'handleSelectStart',
  530. value: function handleSelectStart(e) {
  531. var target = e.target;
  532. // Only IE requires us to explicitly say
  533. // we want drag drop operation to start
  534. if (typeof target.dragDrop !== 'function') {
  535. return;
  536. }
  537. // Inputs and textareas should be selectable
  538. if (target.tagName === 'INPUT' || target.tagName === 'SELECT' || target.tagName === 'TEXTAREA' || target.isContentEditable) {
  539. return;
  540. }
  541. // For other targets, ask IE
  542. // to enable drag and drop
  543. e.preventDefault();
  544. target.dragDrop();
  545. }
  546. }, {
  547. key: 'window',
  548. get: function get() {
  549. if (this.context && this.context.window) {
  550. return this.context.window;
  551. } else if (typeof window !== 'undefined') {
  552. return window;
  553. }
  554. return undefined;
  555. }
  556. }]);
  557. return HTML5Backend;
  558. }();
  559. exports.default = HTML5Backend;