Fix missing newlines when pasting unique text

Fix breaking entities when fixing extra newlines
This commit is contained in:
Eduard Kuzmenko 2023-02-05 13:47:48 +04:00
parent 6b77fa2f4d
commit 992ec48451
3 changed files with 58 additions and 21 deletions

View File

@ -177,7 +177,7 @@ let init = () => {
const peerId = (input.dataset.peerId || NULL_PEER_ID).toPeerId();
if(html.trim()) {
// console.log(html.replace(/ (style|class|id)=".+?"/g, ''));
console.log(html.replace(/ (style|class|id)=".+?"/g, ''));
html = html.replace(/<style([\s\S]*)<\/style>/, '');
html = html.replace(/<!--([\s\S]*)-->/, '');
@ -218,16 +218,28 @@ let init = () => {
richValue.entities = richValue.entities.filter((entity) => entity._ !== 'messageEntityCustomEmoji');
}
{ // * fix extra new lines appearing from <p> (can have them from some sources, like macOS Terminal)
/* if(false) */ { // * fix extra new lines appearing from <p> (can have them from some sources, like macOS Terminal)
const lines = richValue.value.split('\n');
let textLength = 0;
for(let i = 0; i < lines.length; ++i) {
const line = lines[i];
for(let lineIndex = 0; lineIndex < lines.length; ++lineIndex) {
const line = lines[lineIndex];
textLength += line.length;
const index = textLength;
if(plainText[index] !== '\n' && i !== (lines.length - 1)) {
lines[i] = line + lines.splice(i + 1, 1)[0];
if(plainText[index] !== '\n' && lineIndex !== (lines.length - 1)) {
const nextLine = lines.splice(lineIndex + 1, 1)[0];
lines[lineIndex] = line + nextLine;
// fix entities
richValue.entities.forEach((entity) => {
if(entity.offset >= index) {
entity.offset -= 1;
}
});
textLength += nextLine.length;
}
textLength += 1;
}
@ -247,6 +259,8 @@ let init = () => {
entities2 = entities2.filter(filterEntity);
mergeEntities(entities, entities2);
}
console.log('usePlainText', usePlainText);
}
if(usePlainText) {

View File

@ -91,12 +91,13 @@ const BLOCK_TAGS = new Set([
'UL'
]);
const INSERT_NEW_LINE_TAGS = new Set([
'OL',
'UL'
]);
// const INSERT_NEW_LINE_TAGS = new Set([
// 'OL',
// 'UL'
// ]);
const BOM_REG_EXP = new RegExp(BOM, 'g');
export const SELECTION_SEPARATOR = '\x01';
function checkNodeForEntity(node: Node, value: string, entities: MessageEntity[], offset: {offset: number}) {
const parentElement = node.parentElement;
@ -146,6 +147,19 @@ function checkNodeForEntity(node: Node, value: string, entities: MessageEntity[]
}
}
function isLineEmpty(line: string[]) {
const {length} = line;
if(!length) {
return true;
}
if(line[length - 1] === SELECTION_SEPARATOR && length === SELECTION_SEPARATOR.length) {
return true;
}
return false;
}
export default function getRichElementValue(
node: HTMLElement,
lines: string[],
@ -170,12 +184,12 @@ export default function getRichElementValue(
if(nodeValue) {
if(selNode === node) {
line.push(nodeValue.substr(0, selOffset) + '\x01' + nodeValue.substr(selOffset));
line.push(nodeValue.substr(0, selOffset) + SELECTION_SEPARATOR + nodeValue.substr(selOffset));
} else {
line.push(nodeValue);
}
} else if(selNode === node) {
line.push('\x01');
line.push(SELECTION_SEPARATOR);
}
if(entities && nodeValue.length && node.parentNode) {
@ -220,23 +234,33 @@ export default function getRichElementValue(
}
if(isSelected && !selOffset) {
line.push('\x01');
line.push(SELECTION_SEPARATOR);
}
const isTableCell = node.matches(tabulationMatch);
const wasEntitiesLength = entities?.length;
const wasLinesLength = lines.length;
let wasNodeEmpty = true;
let curChild = node.firstChild as HTMLElement;
while(curChild) {
getRichElementValue(curChild, lines, line, selNode, selOffset, entities, offset);
curChild = curChild.nextSibling as any;
if(!isLineEmpty(line)) {
wasNodeEmpty = false;
}
}
if(wasNodeEmpty && lines.length !== wasLinesLength) {
wasNodeEmpty = false;
}
if(isSelected && selOffset) {
line.push('\x01');
line.push(SELECTION_SEPARATOR);
}
if(isTableCell && node.nextSibling && line.length) {
if(isTableCell && node.nextSibling && !isLineEmpty(line)) {
line.push(' ');
++offset.offset;
@ -248,14 +272,13 @@ export default function getRichElementValue(
}
}
const wasLength = line.length;
if(isBlock && wasLength) {
if(isBlock && !wasNodeEmpty) {
lines.push(line.join(''));
line.splice(0, wasLength);
line.length = 0;
++offset.offset;
}
if(wasLength && node.tagName === 'P' && node.nextSibling) {
if(!wasNodeEmpty && node.tagName === 'P' && node.nextSibling) {
lines.push('');
++offset.offset;
}

View File

@ -13,7 +13,7 @@ import {MOUNT_CLASS_TO} from '../../config/debug';
import {MessageEntity} from '../../layer';
import combineSameEntities from '../../lib/richTextProcessor/combineSameEntities';
import sortEntities from '../../lib/richTextProcessor/sortEntities';
import getRichElementValue from './getRichElementValue';
import getRichElementValue, {SELECTION_SEPARATOR} from './getRichElementValue';
export function getCaretPos(field: HTMLElement) {
const sel = window.getSelection();
@ -79,7 +79,7 @@ export default function getRichValueWithCaret(
}
let value = lines.join('\n');
const caretPos = value.indexOf('\x01');
const caretPos = value.indexOf(SELECTION_SEPARATOR);
if(caretPos !== -1) {
value = value.substr(0, caretPos) + value.substr(caretPos + 1);
}