diff --git a/frontend/apps/remark42/app/styles/global.css b/frontend/apps/remark42/app/styles/global.css index d3cfd400..2b548833 100644 --- a/frontend/apps/remark42/app/styles/global.css +++ b/frontend/apps/remark42/app/styles/global.css @@ -2,7 +2,7 @@ body { -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; margin: 0; - padding: 6px; + padding: 0; font-family: system-ui; font-size: 14px; color: rgb(var(--primary-text-color)); diff --git a/frontend/apps/remark42/app/utils/post-message.spec.ts b/frontend/apps/remark42/app/utils/post-message.spec.ts new file mode 100644 index 00000000..9d200011 --- /dev/null +++ b/frontend/apps/remark42/app/utils/post-message.spec.ts @@ -0,0 +1,54 @@ +import { updateIframeHeight } from './post-message'; + +describe('updateIframeHeight', () => { + const postMessage = jest.fn(); + let originalParent: Window; + + beforeAll(() => { + originalParent = window.parent; + // postMessageToParent bails out when window.parent is window, which is the case in jsdom + Object.defineProperty(window, 'parent', { value: { postMessage }, writable: true, configurable: true }); + }); + + afterAll(() => { + Object.defineProperty(window, 'parent', { value: originalParent, writable: true, configurable: true }); + }); + + beforeEach(() => { + postMessage.mockClear(); + jest.spyOn(document.body, 'offsetHeight', 'get').mockReturnValue(500); + }); + + afterEach(() => { + jest.restoreAllMocks(); + }); + + it('should report the document height without adding to it', () => { + updateIframeHeight(); + + expect(postMessage).toHaveBeenCalledWith({ height: 500 }, '*'); + }); + + it('should report the dropdown height when it exceeds the document height', () => { + const dropdown = document.createElement('div'); + + jest.spyOn(dropdown, 'getBoundingClientRect').mockReturnValue({ top: 100 } as DOMRect); + jest.spyOn(dropdown, 'scrollHeight', 'get').mockReturnValue(600); + + updateIframeHeight(dropdown); + + // 20px allowance for the shadow under the dropdown + expect(postMessage).toHaveBeenCalledWith({ height: 720 }, '*'); + }); + + it('should report the document height when it exceeds the dropdown height', () => { + const dropdown = document.createElement('div'); + + jest.spyOn(dropdown, 'getBoundingClientRect').mockReturnValue({ top: 10 } as DOMRect); + jest.spyOn(dropdown, 'scrollHeight', 'get').mockReturnValue(50); + + updateIframeHeight(dropdown); + + expect(postMessage).toHaveBeenCalledWith({ height: 500 }, '*'); + }); +}); diff --git a/frontend/apps/remark42/app/utils/post-message.ts b/frontend/apps/remark42/app/utils/post-message.ts index 3ec62ad3..bee61e21 100644 --- a/frontend/apps/remark42/app/utils/post-message.ts +++ b/frontend/apps/remark42/app/utils/post-message.ts @@ -78,8 +78,8 @@ export function updateIframeHeight(dropdown?: HTMLElement) { scrollHeight = window.scrollY + Math.abs(top) + dropdown.scrollHeight + 20; } - // The size of vertical padding on body is 12px - const bodyHeight = document.body.offsetHeight + 12; + // offsetHeight already covers padding and border, so it is the full document height + const bodyHeight = document.body.offsetHeight; postMessageToParent({ height: Math.max(scrollHeight, bodyHeight) }); }