mirror of
https://github.com/desktop/desktop
synced 2024-10-02 14:23:59 +00:00
Merge pull request #14196 from desktop/fix-markdown-height-round-2
Fix Markdown height issue (round 2)
This commit is contained in:
commit
7eaca093c9
|
@ -44,6 +44,36 @@ export class SandboxedMarkdown extends React.PureComponent<
|
|||
> {
|
||||
private frameRef: HTMLIFrameElement | null = null
|
||||
private frameContainingDivRef: HTMLDivElement | null = null
|
||||
private contentDivRef: HTMLDivElement | null = null
|
||||
|
||||
/**
|
||||
* Resize observer used for tracking height changes in the markdown
|
||||
* content and update the size of the iframe container.
|
||||
*/
|
||||
private readonly resizeObserver: ResizeObserver
|
||||
private resizeDebounceId: number | null = null
|
||||
|
||||
public constructor(props: ISandboxedMarkdownProps) {
|
||||
super(props)
|
||||
|
||||
this.resizeObserver = new ResizeObserver(this.scheduleResizeEvent)
|
||||
}
|
||||
|
||||
private scheduleResizeEvent = () => {
|
||||
if (this.resizeDebounceId !== null) {
|
||||
cancelAnimationFrame(this.resizeDebounceId)
|
||||
this.resizeDebounceId = null
|
||||
}
|
||||
this.resizeDebounceId = requestAnimationFrame(this.onContentResized)
|
||||
}
|
||||
|
||||
private onContentResized = () => {
|
||||
if (this.frameRef === null) {
|
||||
return
|
||||
}
|
||||
|
||||
this.setFrameContainerHeight(this.frameRef)
|
||||
}
|
||||
|
||||
private onFrameRef = (frameRef: HTMLIFrameElement | null) => {
|
||||
this.frameRef = frameRef
|
||||
|
@ -70,6 +100,10 @@ export class SandboxedMarkdown extends React.PureComponent<
|
|||
}
|
||||
}
|
||||
|
||||
public componentWillUnmount() {
|
||||
this.resizeObserver.disconnect()
|
||||
}
|
||||
|
||||
/**
|
||||
* Since iframe styles are isolated from the rest of the app, we have a
|
||||
* markdown.css file that we added to app/static directory that we can read in
|
||||
|
@ -119,11 +153,33 @@ export class SandboxedMarkdown extends React.PureComponent<
|
|||
*/
|
||||
private setupFrameLoadListeners(frameRef: HTMLIFrameElement): void {
|
||||
frameRef.addEventListener('load', () => {
|
||||
this.setupContentDivRef(frameRef)
|
||||
this.setupLinkInterceptor(frameRef)
|
||||
this.setFrameContainerHeight(frameRef)
|
||||
})
|
||||
}
|
||||
|
||||
private setupContentDivRef(frameRef: HTMLIFrameElement): void {
|
||||
if (frameRef.contentDocument === null) {
|
||||
return
|
||||
}
|
||||
|
||||
/*
|
||||
* We added an additional wrapper div#content around the markdown to
|
||||
* determine a more accurate scroll height as the iframe's document or body
|
||||
* element was not adjusting it's height dynamically when new content was
|
||||
* provided.
|
||||
*/
|
||||
this.contentDivRef = frameRef.contentDocument.documentElement.querySelector(
|
||||
'#content'
|
||||
) as HTMLDivElement
|
||||
|
||||
if (this.contentDivRef !== null) {
|
||||
this.resizeObserver.disconnect()
|
||||
this.resizeObserver.observe(this.contentDivRef)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Iframes without much styling help will act like a block element that has a
|
||||
* predetermiend height and width and scrolling. We want our iframe to feel a
|
||||
|
@ -133,31 +189,17 @@ export class SandboxedMarkdown extends React.PureComponent<
|
|||
*/
|
||||
private setFrameContainerHeight(frameRef: HTMLIFrameElement): void {
|
||||
if (
|
||||
frameRef.contentDocument == null ||
|
||||
this.frameContainingDivRef == null
|
||||
frameRef.contentDocument === null ||
|
||||
this.frameContainingDivRef === null ||
|
||||
this.contentDivRef === null
|
||||
) {
|
||||
return
|
||||
}
|
||||
|
||||
/*
|
||||
* We added an additional wrapper div#content around the markdown to
|
||||
* determine a more accurate scroll height as the iframe's document or body
|
||||
* element was not adjusting it's height dynamically when new content was
|
||||
* provided.
|
||||
*/
|
||||
const docEl = frameRef.contentDocument.documentElement.querySelector(
|
||||
'#content'
|
||||
) as HTMLDivElement
|
||||
|
||||
if (docEl === null) {
|
||||
return
|
||||
}
|
||||
|
||||
// Not sure why the content height != body height exactly. But we need to
|
||||
// set the height explicitly to prevent scrollbar/content cut off.
|
||||
const divHeight = docEl.clientHeight
|
||||
const divHeight = this.contentDivRef.clientHeight
|
||||
this.frameContainingDivRef.style.height = `${divHeight}px`
|
||||
docEl.style.height = `${divHeight}px`
|
||||
this.props.onMarkdownParsed?.()
|
||||
}
|
||||
|
||||
|
|
|
@ -9,14 +9,6 @@ desktop font-size variables. (This is not meant to be an exhaustive list of
|
|||
changes from the original, just a note that this will not match 1-1)
|
||||
*/
|
||||
|
||||
#content {
|
||||
/*
|
||||
We need to set overflow-y to hidden to make sure this element calculates the
|
||||
right height to fit its content.
|
||||
*/
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
||||
.markdown-body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";
|
||||
font-size: var(--font-size);
|
||||
|
@ -37,11 +29,11 @@ changes from the original, just a note that this will not match 1-1)
|
|||
content: ""
|
||||
}
|
||||
|
||||
.markdown-body>*:first-child {
|
||||
.markdown-body>#content>*:first-child {
|
||||
margin-top: 0 !important
|
||||
}
|
||||
|
||||
.markdown-body>*:last-child {
|
||||
.markdown-body>#content>*:last-child {
|
||||
margin-bottom: 0 !important
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue