diff --git a/src/components/middle/message/Message.tsx b/src/components/middle/message/Message.tsx index b90a19250..15238291f 100644 --- a/src/components/middle/message/Message.tsx +++ b/src/components/middle/message/Message.tsx @@ -3,7 +3,6 @@ import React, { memo, useCallback, useEffect, - useLayoutEffect, useMemo, useRef, } from '../../../lib/teact/teact'; @@ -168,9 +167,9 @@ type DispatchProps = Pick' }; // eslint-disable-next-line max-len -const APPENDIX_NOT_OWN = ''; +const APPENDIX_NOT_OWN = { __html: '' }; const APPEARANCE_DELAY = 10; const NO_MEDIA_CORNERS_THRESHOLD = 18; @@ -233,8 +232,7 @@ const Message: FC = ({ const ref = useRef(null); // eslint-disable-next-line no-null/no-null const bottomMarkerRef = useRef(null); - // eslint-disable-next-line no-null/no-null - const appendixRef = useRef(null); + const lang = useLang(); useOnIntersect(bottomMarkerRef, observeIntersectionForBottom); @@ -405,13 +403,6 @@ const Message: FC = ({ message.id, ); useFocusMessage(ref, chatId, isFocused, focusDirection, noFocusHighlight, isResizingContainer); - useLayoutEffect(() => { - if (!appendixRef.current) { - return; - } - - appendixRef.current.innerHTML = isOwn ? APPENDIX_OWN : APPENDIX_NOT_OWN; - }, [isOwn, withAppendix]); let style = ''; let calculatedWidth; @@ -766,7 +757,9 @@ const Message: FC = ({ ) : undefined} {withCommentButton && } - {withAppendix &&
} + {withAppendix && ( +
+ )}
{message.inlineButtons && ( diff --git a/src/lib/teact/teact-dom.ts b/src/lib/teact/teact-dom.ts index 83ed5207b..a49c8966a 100644 --- a/src/lib/teact/teact-dom.ts +++ b/src/lib/teact/teact-dom.ts @@ -223,7 +223,9 @@ function createNode($element: VirtualElement): Node { } Object.keys(props).forEach((key) => { - addAttribute(element, key, props[key]); + if (props[key] !== undefined) { + setAttribute(element, key, props[key]); + } }); $element.children = children.map(($child, i) => ( @@ -395,31 +397,31 @@ function updateAttributes($current: VirtualRealElement, $new: VirtualRealElement const newKeys = Object.keys($new.props); currentKeys.forEach((key) => { - if ($current.props[key] !== undefined && $new.props[key] === undefined) { - removeAttribute(element, key, $current.props[key]); + const currentValue = $current.props[key]; + const newValue = $new.props[key]; + + if ( + currentValue !== undefined + && ( + newValue === undefined + || (currentValue !== newValue && key.startsWith('on')) + ) + ) { + removeAttribute(element, key, currentValue); } }); newKeys.forEach((key) => { - if ($new.props[key] === undefined) { - return; - } + const currentValue = $current.props[key]; + const newValue = $new.props[key]; - if ($current.props[key] !== $new.props[key]) { - if ($current.props[key] === undefined) { - addAttribute(element, key, $new.props[key]); - } else { - updateAttribute(element, key, $current.props[key], $new.props[key]); - } + if (newValue !== undefined && newValue !== currentValue) { + setAttribute(element, key, newValue); } }); } -function addAttribute(element: HTMLElement, key: string, value: any) { - if (value === undefined) { - return; - } - +function setAttribute(element: HTMLElement, key: string, value: any) { // An optimization attempt if (key === 'className') { element.className = value; @@ -428,6 +430,9 @@ function addAttribute(element: HTMLElement, key: string, value: any) { (element as HTMLInputElement).value = value; } else if (key === 'style') { element.style.cssText = value; + } else if (key === 'dangerouslySetInnerHTML') { + // eslint-disable-next-line no-underscore-dangle + element.innerHTML = value.__html; } else if (key.startsWith('on')) { addEventListener(element, key, value, key.endsWith('Capture')); } else if (key.startsWith('data-') || HTML_ATTRIBUTES.has(key)) { @@ -444,6 +449,8 @@ function removeAttribute(element: HTMLElement, key: string, value: any) { (element as HTMLInputElement).value = ''; } else if (key === 'style') { element.style.cssText = ''; + } else if (key === 'dangerouslySetInnerHTML') { + element.innerHTML = ''; } else if (key.startsWith('on')) { removeEventListener(element, key, value, key.endsWith('Capture')); } else if (key.startsWith('data-') || HTML_ATTRIBUTES.has(key)) { @@ -453,16 +460,6 @@ function removeAttribute(element: HTMLElement, key: string, value: any) { } } -function updateAttribute(element: HTMLElement, key: string, oldValue: any, newValue: any) { - if (key === 'value') { - // Removing and adding value causes a cursor jump - (element as HTMLInputElement).value = newValue !== undefined ? newValue : ''; - } else { - removeAttribute(element, key, oldValue); - addAttribute(element, key, newValue); - } -} - // eslint-disable-next-line @typescript-eslint/naming-convention function DEBUG_addToVirtualTreeSize($current: VirtualRealElement | VirtualDomHead) { DEBUG_virtualTreeSize += $current.children.length;