Composition area: Only paste HTML that originated in Signal
Co-authored-by: Chris Svenningsen <chris@carbonfive.com>
This commit is contained in:
parent
98da8746e8
commit
7af2284c6b
6 changed files with 148 additions and 77 deletions
|
@ -6,10 +6,8 @@ import * as React from 'react';
|
|||
import Delta from 'quill-delta';
|
||||
import ReactQuill from 'react-quill';
|
||||
import classNames from 'classnames';
|
||||
import emojiRegex from 'emoji-regex';
|
||||
import { Manager, Reference } from 'react-popper';
|
||||
import Quill, { KeyboardStatic, RangeStatic } from 'quill';
|
||||
import Op from 'quill-delta/dist/Op';
|
||||
|
||||
import { MentionCompletion } from '../quill/mentions/completion';
|
||||
import { EmojiBlot, EmojiCompletion } from '../quill/emoji';
|
||||
|
@ -22,6 +20,7 @@ import {
|
|||
matchEmojiImage,
|
||||
matchEmojiBlot,
|
||||
matchReactEmoji,
|
||||
matchEmojiText,
|
||||
} from '../quill/emoji/matchers';
|
||||
import { matchMention } from '../quill/mentions/matchers';
|
||||
import { MemberRepository } from '../quill/memberRepository';
|
||||
|
@ -30,6 +29,8 @@ import {
|
|||
getTextAndMentionsFromOps,
|
||||
isMentionBlot,
|
||||
getDeltaToRestartMention,
|
||||
insertMentionOps,
|
||||
insertEmojiOps,
|
||||
} from '../quill/util';
|
||||
import { SignalClipboard } from '../quill/signal-clipboard';
|
||||
|
||||
|
@ -117,70 +118,6 @@ export const CompositionInput: React.ComponentType<Props> = props => {
|
|||
new MemberRepository()
|
||||
);
|
||||
|
||||
const insertMentionOps = (
|
||||
incomingOps: Array<Op>,
|
||||
bodyRanges: Array<BodyRangeType>
|
||||
) => {
|
||||
const ops = [...incomingOps];
|
||||
|
||||
// Working backwards through bodyRanges (to avoid offsetting later mentions),
|
||||
// Shift off the op with the text to the left of the last mention,
|
||||
// Insert a mention based on the current bodyRange,
|
||||
// Unshift the mention and surrounding text to leave the ops ready for the next range
|
||||
bodyRanges
|
||||
.sort((a, b) => b.start - a.start)
|
||||
.forEach(({ start, length, mentionUuid, replacementText }) => {
|
||||
const op = ops.shift();
|
||||
|
||||
if (op) {
|
||||
const { insert } = op;
|
||||
|
||||
if (typeof insert === 'string') {
|
||||
const left = insert.slice(0, start);
|
||||
const right = insert.slice(start + length);
|
||||
|
||||
const mention = {
|
||||
uuid: mentionUuid,
|
||||
title: replacementText,
|
||||
};
|
||||
|
||||
ops.unshift({ insert: right });
|
||||
ops.unshift({ insert: { mention } });
|
||||
ops.unshift({ insert: left });
|
||||
} else {
|
||||
ops.unshift(op);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return ops;
|
||||
};
|
||||
|
||||
const insertEmojiOps = (incomingOps: Array<Op>): Array<Op> => {
|
||||
return incomingOps.reduce((ops, op) => {
|
||||
if (typeof op.insert === 'string') {
|
||||
const text = op.insert;
|
||||
const re = emojiRegex();
|
||||
let index = 0;
|
||||
let match: RegExpExecArray | null;
|
||||
|
||||
// eslint-disable-next-line no-cond-assign
|
||||
while ((match = re.exec(text))) {
|
||||
const [emoji] = match;
|
||||
ops.push({ insert: text.slice(index, match.index) });
|
||||
ops.push({ insert: { emoji } });
|
||||
index = match.index + emoji.length;
|
||||
}
|
||||
|
||||
ops.push({ insert: text.slice(index, text.length) });
|
||||
} else {
|
||||
ops.push(op);
|
||||
}
|
||||
|
||||
return ops;
|
||||
}, [] as Array<Op>);
|
||||
};
|
||||
|
||||
const generateDelta = (
|
||||
text: string,
|
||||
bodyRanges: Array<BodyRangeType>
|
||||
|
@ -258,7 +195,7 @@ export const CompositionInput: React.ComponentType<Props> = props => {
|
|||
|
||||
quill.setText('');
|
||||
|
||||
const historyModule: HistoryStatic = quill.getModule('history');
|
||||
const historyModule = quill.getModule('history');
|
||||
|
||||
if (historyModule === undefined) {
|
||||
return;
|
||||
|
@ -544,6 +481,7 @@ export const CompositionInput: React.ComponentType<Props> = props => {
|
|||
['IMG', matchEmojiImage],
|
||||
['IMG', matchEmojiBlot],
|
||||
['SPAN', matchReactEmoji],
|
||||
[Node.TEXT_NODE, matchEmojiText],
|
||||
['SPAN', matchMention(memberRepositoryRef)],
|
||||
],
|
||||
},
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue