Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
 
 
 
 

154 строки
5.0 KiB

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