custom-app
Version:
ITIMS��Ʒ�鿪��ר��React���,�Dz��ý��ּ�dhcc-app���������
165 lines (139 loc) • 6.63 kB
JavaScript
/**
* Copyright (c) 2013-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule editOnPaste
* @format
*
*/
'use strict';
var BlockMapBuilder = require('./BlockMapBuilder');
var CharacterMetadata = require('./CharacterMetadata');
var DataTransfer = require('fbjs/lib/DataTransfer');
var DraftModifier = require('./DraftModifier');
var DraftPasteProcessor = require('./DraftPasteProcessor');
var EditorState = require('./EditorState');
var RichTextEditorUtil = require('./RichTextEditorUtil');
var getEntityKeyForSelection = require('./getEntityKeyForSelection');
var getTextContentFromFiles = require('./getTextContentFromFiles');
var isEventHandled = require('./isEventHandled');
var splitTextIntoTextBlocks = require('./splitTextIntoTextBlocks');
/**
* Paste content.
*/
function editOnPaste(editor, e) {
e.preventDefault();
var data = new DataTransfer(e.clipboardData);
// Get files, unless this is likely to be a string the user wants inline.
if (!data.isRichText()) {
var files = data.getFiles();
var defaultFileText = data.getText();
if (files.length > 0) {
// Allow customized paste handling for images, etc. Otherwise, fall
// through to insert text contents into the editor.
if (editor.props.handlePastedFiles && isEventHandled(editor.props.handlePastedFiles(files))) {
return;
}
getTextContentFromFiles(files, function ( /*string*/fileText) {
fileText = fileText || defaultFileText;
if (!fileText) {
return;
}
var editorState = editor._latestEditorState;
var blocks = splitTextIntoTextBlocks(fileText);
var character = CharacterMetadata.create({
style: editorState.getCurrentInlineStyle(),
entity: getEntityKeyForSelection(editorState.getCurrentContent(), editorState.getSelection())
});
var currentBlockType = RichTextEditorUtil.getCurrentBlockType(editorState);
var text = DraftPasteProcessor.processText(blocks, character, currentBlockType);
var fragment = BlockMapBuilder.createFromArray(text);
var withInsertedText = DraftModifier.replaceWithFragment(editorState.getCurrentContent(), editorState.getSelection(), fragment);
editor.update(EditorState.push(editorState, withInsertedText, 'insert-fragment'));
});
return;
}
}
var textBlocks = [];
var text = data.getText();
var html = data.getHTML();
var editorState = editor._latestEditorState;
if (editor.props.handlePastedText && isEventHandled(editor.props.handlePastedText(text, html, editorState))) {
return;
}
if (text) {
textBlocks = splitTextIntoTextBlocks(text);
}
if (!editor.props.stripPastedStyles) {
// If the text from the paste event is rich content that matches what we
// already have on the internal clipboard, assume that we should just use
// the clipboard fragment for the paste. This will allow us to preserve
// styling and entities, if any are present. Note that newlines are
// stripped during comparison -- this is because copy/paste within the
// editor in Firefox and IE will not include empty lines. The resulting
// paste will preserve the newlines correctly.
var internalClipboard = editor.getClipboard();
if (data.isRichText() && internalClipboard) {
if (
// If the editorKey is present in the pasted HTML, it should be safe to
// assume this is an internal paste.
html.indexOf(editor.getEditorKey()) !== -1 ||
// The copy may have been made within a single block, in which case the
// editor key won't be part of the paste. In this case, just check
// whether the pasted text matches the internal clipboard.
textBlocks.length === 1 && internalClipboard.size === 1 && internalClipboard.first().getText() === text) {
editor.update(insertFragment(editor._latestEditorState, internalClipboard));
return;
}
} else if (internalClipboard && data.types.includes('com.apple.webarchive') && !data.types.includes('text/html') && areTextBlocksAndClipboardEqual(textBlocks, internalClipboard)) {
// Safari does not properly store text/html in some cases.
// Use the internalClipboard if present and equal to what is on
// the clipboard. See https://bugs.webkit.org/show_bug.cgi?id=19893.
editor.update(insertFragment(editor._latestEditorState, internalClipboard));
return;
}
// If there is html paste data, try to parse that.
if (html) {
var htmlFragment = DraftPasteProcessor.processHTML(html, editor.props.blockRenderMap);
if (htmlFragment) {
var contentBlocks = htmlFragment.contentBlocks,
entityMap = htmlFragment.entityMap;
if (contentBlocks) {
var htmlMap = BlockMapBuilder.createFromArray(contentBlocks);
editor.update(insertFragment(editor._latestEditorState, htmlMap, entityMap));
return;
}
}
}
// Otherwise, create a new fragment from our pasted text. Also
// empty the internal clipboard, since it's no longer valid.
editor.setClipboard(null);
}
if (textBlocks.length) {
var character = CharacterMetadata.create({
style: editorState.getCurrentInlineStyle(),
entity: getEntityKeyForSelection(editorState.getCurrentContent(), editorState.getSelection())
});
var currentBlockType = RichTextEditorUtil.getCurrentBlockType(editorState);
var textFragment = DraftPasteProcessor.processText(textBlocks, character, currentBlockType);
var textMap = BlockMapBuilder.createFromArray(textFragment);
editor.update(insertFragment(editor._latestEditorState, textMap));
}
}
function insertFragment(editorState, fragment, entityMap) {
var newContent = DraftModifier.replaceWithFragment(editorState.getCurrentContent(), editorState.getSelection(), fragment);
// TODO: merge the entity map once we stop using DraftEntity
// like this:
// const mergedEntityMap = newContent.getEntityMap().merge(entityMap);
return EditorState.push(editorState, newContent.set('entityMap', entityMap), 'insert-fragment');
}
function areTextBlocksAndClipboardEqual(textBlocks, blockMap) {
return textBlocks.length === blockMap.size && blockMap.valueSeq().every(function (block, ii) {
return block.getText() === textBlocks[ii];
});
}
module.exports = editOnPaste;