fix(frontend): no_footer scrollbar regression introduced in v1.16.0 (#2076)
* fix(frontend): no_footer scrollbar regression introduced in v1.16.0
Two unrelated changes in v1.16.0 combined to surface a scrollbar in
no_footer=true mode:
1. c26f45e5 removed the deprecated `scrolling="no"` iframe attribute
on the grounds that "overflow is already hidden via CSS". That CSS
(`overflow: hidden` in createIframe styles) is on the iframe ELEMENT
in the parent page; it has no effect on the iframe DOCUMENT's own
scrollbars. The spec-correct replacement is `overflow: hidden` on
the iframe document's body — added here to global.css.
2. The negative `margin-bottom: -24px` on `.thread:last-child` was a
trick to tighten the gap to the footer (combined with the footer's
`margin-top: 48px` it collapsed to a 24px net gap). With no_footer
the negative margin had no positive-margin sibling to collapse
against and instead propagated up through .root, leaving body
~24px shorter than the visual content. The iframe height calc
(`body.offsetHeight + 12`) then sized the iframe below the visible
bottom of the last thread → scrollbar.
Replace the negative-margin trick with a straight `margin-top: 24px`
on `.copyright`. Same 24px visual gap when the footer is shown, no
propagation when it isn't. The mix={styles.thread} on Thread becomes
a dead reference and is dropped.
Closes #2073
* fix(frontend): drop dead Thread.mix prop after root.tsx removed its only caller
Both Copilot and umputun flagged this in PR review: after the parent
commit on this branch dropped `mix={styles.thread}` from root.tsx, the
`mix?: string` prop and the corresponding entry in the clsx() call in
thread.tsx are dead code — no caller passes it (the recursive Thread
render in thread.tsx:82 never did either). Remove the prop, the
destructure, and the clsx entry.
This commit is contained in:
@@ -31,18 +31,12 @@
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.thread {
|
||||
&:last-child {
|
||||
margin-bottom: -24px;
|
||||
}
|
||||
}
|
||||
|
||||
.threads {
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.copyright {
|
||||
margin: 48px 0 0;
|
||||
margin: 24px 0 0;
|
||||
font-size: 12px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
@@ -301,9 +301,7 @@ function Comments({ isLoading, topComments, commentsShown, showMore }: CommentsP
|
||||
) : (
|
||||
<>
|
||||
{topComments.length > 0 &&
|
||||
renderComments.map((id) => (
|
||||
<Thread key={`thread-${id}`} id={id} mix={styles.thread} level={0} getPreview={getPreview} />
|
||||
))}
|
||||
renderComments.map((id) => <Thread key={`thread-${id}`} id={id} level={0} getPreview={getPreview} />)}
|
||||
{isShowMoreButtonVisible && (
|
||||
<Button className={styles.moreComments} onClick={showMore}>
|
||||
<FormattedMessage id="root.show-more" defaultMessage="Show more" />
|
||||
|
||||
@@ -19,7 +19,6 @@ interface Props {
|
||||
id: CommentInterface['id'];
|
||||
childs?: CommentInterface['id'][];
|
||||
level: number;
|
||||
mix?: string;
|
||||
|
||||
getPreview(text: string): Promise<string>;
|
||||
}
|
||||
@@ -34,7 +33,7 @@ const commentSelector = (id: string) => (state: StoreState) => {
|
||||
return { comment, childs, collapsed, theme };
|
||||
};
|
||||
|
||||
export const Thread: FunctionComponent<Props> = ({ id, level, mix, getPreview }) => {
|
||||
export const Thread: FunctionComponent<Props> = ({ id, level, getPreview }) => {
|
||||
const dispatch = useAppDispatch();
|
||||
const intl = useIntl();
|
||||
const { collapsed, comment, childs, theme } = useAppSelector(commentSelector(id), shallowEqual);
|
||||
@@ -53,8 +52,7 @@ export const Thread: FunctionComponent<Props> = ({ id, level, mix, getPreview })
|
||||
styles.root,
|
||||
indented && styles.indented,
|
||||
level === 6 && styles.level6,
|
||||
theme === 'dark' && styles.themeDark,
|
||||
mix
|
||||
theme === 'dark' && styles.themeDark
|
||||
)}
|
||||
role={['listitem'].concat(!collapsed && !!repliesCount ? 'list' : []).join(' ')}
|
||||
aria-expanded={!collapsed}
|
||||
|
||||
@@ -8,6 +8,13 @@ body {
|
||||
color: rgb(var(--primary-text-color));
|
||||
background: transparent;
|
||||
box-sizing: border-box;
|
||||
|
||||
/* parent resizes the iframe element to fit content via postMessage, so the
|
||||
iframe document never needs its own scrollbar. spec-correct replacement
|
||||
for the deprecated `scrolling="no"` attribute removed in c26f45e5 — the
|
||||
`overflow:hidden` on the iframe ELEMENT doesn't control the iframe
|
||||
DOCUMENT's scrollbars, that has to be set inside the document. */
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
input,
|
||||
|
||||
Reference in New Issue
Block a user