diff --git a/src/components/inputField.ts b/src/components/inputField.ts index 225f15305..8cba1c041 100644 --- a/src/components/inputField.ts +++ b/src/components/inputField.ts @@ -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(//, ''); html = html.replace(//, ''); @@ -218,16 +218,28 @@ let init = () => { richValue.entities = richValue.entities.filter((entity) => entity._ !== 'messageEntityCustomEmoji'); } - { // * fix extra new lines appearing from

(can have them from some sources, like macOS Terminal) + /* if(false) */ { // * fix extra new lines appearing from

(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) { diff --git a/src/helpers/dom/getRichElementValue.ts b/src/helpers/dom/getRichElementValue.ts index c4175ce01..aeb5be232 100644 --- a/src/helpers/dom/getRichElementValue.ts +++ b/src/helpers/dom/getRichElementValue.ts @@ -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; } diff --git a/src/helpers/dom/getRichValueWithCaret.ts b/src/helpers/dom/getRichValueWithCaret.ts index e2e18d563..0c3e674bb 100644 --- a/src/helpers/dom/getRichValueWithCaret.ts +++ b/src/helpers/dom/getRichValueWithCaret.ts @@ -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); }