You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

пре 3 година
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. /**
  2. * Copyright (c) Facebook, Inc. and its affiliates.
  3. *
  4. * This source code is licensed under the MIT license found in the
  5. * LICENSE file in the root directory of this source tree.
  6. *
  7. * @format
  8. *
  9. * @emails oncall+draft_js
  10. */
  11. 'use strict';
  12. var DataTransfer = require("fbjs/lib/DataTransfer");
  13. var DraftModifier = require("./DraftModifier");
  14. var EditorState = require("./EditorState");
  15. var findAncestorOffsetKey = require("./findAncestorOffsetKey");
  16. var getCorrectDocumentFromNode = require("./getCorrectDocumentFromNode");
  17. var getTextContentFromFiles = require("./getTextContentFromFiles");
  18. var getUpdatedSelectionState = require("./getUpdatedSelectionState");
  19. var getWindowForNode = require("./getWindowForNode");
  20. var isEventHandled = require("./isEventHandled");
  21. var nullthrows = require("fbjs/lib/nullthrows");
  22. /**
  23. * Get a SelectionState for the supplied mouse event.
  24. */
  25. function getSelectionForEvent(event, editorState) {
  26. var node = null;
  27. var offset = null;
  28. var eventTargetDocument = getCorrectDocumentFromNode(event.currentTarget);
  29. /* $FlowFixMe(>=0.68.0 site=www,mobile) This comment suppresses an error
  30. * found when Flow v0.68 was deployed. To see the error delete this comment
  31. * and run Flow. */
  32. if (typeof eventTargetDocument.caretRangeFromPoint === 'function') {
  33. /* $FlowFixMe(>=0.68.0 site=www,mobile) This comment suppresses an error
  34. * found when Flow v0.68 was deployed. To see the error delete this comment
  35. * and run Flow. */
  36. var dropRange = eventTargetDocument.caretRangeFromPoint(event.x, event.y);
  37. node = dropRange.startContainer;
  38. offset = dropRange.startOffset;
  39. } else if (event.rangeParent) {
  40. node = event.rangeParent;
  41. offset = event.rangeOffset;
  42. } else {
  43. return null;
  44. }
  45. node = nullthrows(node);
  46. offset = nullthrows(offset);
  47. var offsetKey = nullthrows(findAncestorOffsetKey(node));
  48. return getUpdatedSelectionState(editorState, offsetKey, offset, offsetKey, offset);
  49. }
  50. var DraftEditorDragHandler = {
  51. /**
  52. * Drag originating from input terminated.
  53. */
  54. onDragEnd: function onDragEnd(editor) {
  55. editor.exitCurrentMode();
  56. endDrag(editor);
  57. },
  58. /**
  59. * Handle data being dropped.
  60. */
  61. onDrop: function onDrop(editor, e) {
  62. var data = new DataTransfer(e.nativeEvent.dataTransfer);
  63. var editorState = editor._latestEditorState;
  64. var dropSelection = getSelectionForEvent(e.nativeEvent, editorState);
  65. e.preventDefault();
  66. editor._dragCount = 0;
  67. editor.exitCurrentMode();
  68. if (dropSelection == null) {
  69. return;
  70. }
  71. var files = data.getFiles();
  72. if (files.length > 0) {
  73. if (editor.props.handleDroppedFiles && isEventHandled(editor.props.handleDroppedFiles(dropSelection, files))) {
  74. return;
  75. }
  76. /* $FlowFixMe This comment suppresses an error found DataTransfer was
  77. * typed. getFiles() returns an array of <Files extends Blob>, not Blob
  78. */
  79. getTextContentFromFiles(files, function (fileText) {
  80. fileText && editor.update(insertTextAtSelection(editorState, dropSelection, fileText));
  81. });
  82. return;
  83. }
  84. var dragType = editor._internalDrag ? 'internal' : 'external';
  85. if (editor.props.handleDrop && isEventHandled(editor.props.handleDrop(dropSelection, data, dragType))) {// handled
  86. } else if (editor._internalDrag) {
  87. editor.update(moveText(editorState, dropSelection));
  88. } else {
  89. editor.update(insertTextAtSelection(editorState, dropSelection, data.getText()));
  90. }
  91. endDrag(editor);
  92. }
  93. };
  94. function endDrag(editor) {
  95. editor._internalDrag = false; // Fix issue #1383
  96. // Prior to React v16.5.0 onDrop breaks onSelect event:
  97. // https://github.com/facebook/react/issues/11379.
  98. // Dispatching a mouseup event on DOM node will make it go back to normal.
  99. var editorNode = editor.editorContainer;
  100. if (editorNode) {
  101. var mouseUpEvent = new MouseEvent('mouseup', {
  102. view: getWindowForNode(editorNode),
  103. bubbles: true,
  104. cancelable: true
  105. });
  106. editorNode.dispatchEvent(mouseUpEvent);
  107. }
  108. }
  109. function moveText(editorState, targetSelection) {
  110. var newContentState = DraftModifier.moveText(editorState.getCurrentContent(), editorState.getSelection(), targetSelection);
  111. return EditorState.push(editorState, newContentState, 'insert-fragment');
  112. }
  113. /**
  114. * Insert text at a specified selection.
  115. */
  116. function insertTextAtSelection(editorState, selection, text) {
  117. var newContentState = DraftModifier.insertText(editorState.getCurrentContent(), selection, text, editorState.getCurrentInlineStyle());
  118. return EditorState.push(editorState, newContentState, 'insert-fragment');
  119. }
  120. module.exports = DraftEditorDragHandler;