Change:
Thanks for the quick turnaround on preserving the open attribute! I'm still a little curious about the scrolling sync: I don't see anything in that looks like it would address the issue I'm seeing "scrolling past" a collapsed block where the code cursor makes the preview act as if it's much further down, seemingly by about as much as the length of the expanded . I can now leave my expanded to re-enable sync'd scrolling, but I was wondering if the intent was to not change the behavior when they're closed? Or, would it be helpful if I broke that part out into a new issue? Originally posted by in
Thanks. I've extracted this to it's own issue and will push a fix shortly
<!-- AUTHORVERIFICATIONREQUEST --This bug has been fixed in the latest release of ! you can help us out by commenting if things are now working as expected. If things still don't seem right, please ensure you're on version of Insiders (today's or later - you can use in the command palette to check), and leave a comment letting us know what isn't working as expected. Happy Coding!

Discussion:
const codeLineClass = 'code-line'; <del> export interface CodeLineElement { element: HTMLElement; line: number; codeElement?: HTMLElement; </del> <ins> export class CodeLineElement { private readonly _detailParentElements: readonly HTMLDetailsElement[]; constructor( readonly element: HTMLElement, readonly line: number, readonly codeElement?: HTMLElement, ) { this._detailParentElements = Array.from(getParentsWithTagName<HTMLDetailsElement>(element, 'DETAILS')); } get isVisible(): boolean { return !this._detailParentElements.some(x => !x.open); } </ins> } const getCodeLineElements = (() => {

return (documentVersion: number) => { if (!cachedElements || documentVersion !== cachedVersion) { cachedVersion = documentVersion; <del> cachedElements = [{ element: document.body, line: -1 }]; </del> <ins> cachedElements = [new CodeLineElement(document.body, -1)]; </ins> for (const element of document.getElementsByClassName(codeLineClass)) { <ins> if (!(element instanceof HTMLElement)) { continue; } </ins> const line = +element.getAttribute('data-line')!; if (isNaN(line)) { continue; } if (element.tagName === 'CODE' && element.parentElement && element.parentElement.tagName === 'PRE') { // Fenced code blocks are a special case since the `code-line` can only be marked on // the `<code>` element and not the parent `<pre>` element. <del> cachedElements.push({ element: element.parentElement as HTMLElement, line: line, codeElement: element as HTMLElement }); </del> <ins> cachedElements.push(new CodeLineElement(element.parentElement, line, element)); </ins> } else if (element.tagName === 'UL' || element.tagName === 'OL') { // Skip adding list elements since the first child has the same code line (and should be preferred) } else { <del> cachedElements.push({ element: element as HTMLElement, line }); </del> <ins> cachedElements.push(new CodeLineElement(element, line)); </ins> } } }

* Find the html elements that are at a specific pixel offset on the page. */ export function getLineElementsAtPageOffset(offset: number, documentVersion: number): { previous: CodeLineElement; next?: CodeLineElement } { <del> const lines = getCodeLineElements(documentVersion); </del> <ins> const lines = getCodeLineElements(documentVersion).filter(x => x.isVisible); </ins> const position = offset - window.scrollY; let lo = -1; let hi = lines.length - 1;

window.scroll(window.scrollX, Math.max(1, window.scrollY + scrollTo)); } <del> export function getEditorLineNumberForPageOffset(offset: number, documentVersion: number) { </del> <ins> export function getEditorLineNumberForPageOffset(offset: number, documentVersion: number): number | null { </ins> const { previous, next } = getLineElementsAtPageOffset(offset, documentVersion); if (previous) { <ins> if (previous.line < 0) { return 0; } </ins> const previousBounds = getElementBounds(previous); const offsetFromPrevious = (offset - window.scrollY - previousBounds.top); if (next) {

return element.element.id === fragment; }); } <ins> function* getParentsWithTagName<T extends HTMLElement>(element: HTMLElement, tagName: string): Iterable<T> { for (let parent = element.parentElement; parent; parent = parent.parentElement) { if (parent.tagName === tagName) { yield parent as T; } } } </ins>