Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.

HTML5Backend.js 23 KiB

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