diff --git a/extensions/markdown-language-features/preview-src/index.ts b/extensions/markdown-language-features/preview-src/index.ts index 064c30ac969..90e96b6b304 100644 --- a/extensions/markdown-language-features/preview-src/index.ts +++ b/extensions/markdown-language-features/preview-src/index.ts @@ -12,7 +12,7 @@ import throttle = require('lodash.throttle'); declare let acquireVsCodeApi: any; -let scrollDisabled = true; +let scrollDisabledCount = 0; const marker = new ActiveLineMarker(); const settings = getSettings(); @@ -37,19 +37,39 @@ window.onload = () => { updateImageSizes(); }; + +function doAfterImagesLoaded(cb: () => void) { + const imgElements = document.getElementsByTagName('img'); + if (imgElements.length > 0) { + const ps = Array.from(imgElements).map(e => { + if (e.complete) { + return Promise.resolve(); + } else { + return new Promise((resolve) => { + e.addEventListener('load', () => resolve()); + e.addEventListener('error', () => resolve()); + }); + } + }); + Promise.all(ps).then(() => setImmediate(cb)); + } else { + setImmediate(cb); + } +} + onceDocumentLoaded(() => { const scrollProgress = state.scrollProgress; if (typeof scrollProgress === 'number' && !settings.fragment) { - setImmediate(() => { - scrollDisabled = true; + doAfterImagesLoaded(() => { + scrollDisabledCount += 1; window.scrollTo(0, scrollProgress * document.body.clientHeight); }); return; } if (settings.scrollPreviewWithEditor) { - setImmediate(() => { + doAfterImagesLoaded(() => { // Try to scroll to fragment if available if (settings.fragment) { state.fragment = undefined; @@ -57,12 +77,12 @@ onceDocumentLoaded(() => { const element = getLineElementForFragment(settings.fragment); if (element) { - scrollDisabled = true; + scrollDisabledCount += 1; scrollToRevealSourceLine(element.line); } } else { if (!isNaN(settings.line!)) { - scrollDisabled = true; + scrollDisabledCount += 1; scrollToRevealSourceLine(settings.line!); } } @@ -72,8 +92,8 @@ onceDocumentLoaded(() => { const onUpdateView = (() => { const doScroll = throttle((line: number) => { - scrollDisabled = true; - scrollToRevealSourceLine(line); + scrollDisabledCount += 1; + doAfterImagesLoaded(() => scrollToRevealSourceLine(line)); }, 50); return (line: number) => { @@ -109,7 +129,7 @@ let updateImageSizes = throttle(() => { }, 50); window.addEventListener('resize', () => { - scrollDisabled = true; + scrollDisabledCount += 1; updateScrollProgress(); updateImageSizes(); }, true); @@ -189,8 +209,8 @@ document.addEventListener('click', event => { window.addEventListener('scroll', throttle(() => { updateScrollProgress(); - if (scrollDisabled) { - scrollDisabled = false; + if (scrollDisabledCount > 0) { + scrollDisabledCount -= 1; } else { const line = getEditorLineNumberForPageOffset(window.scrollY); if (typeof line === 'number' && !isNaN(line)) { diff --git a/extensions/markdown-language-features/preview-src/scroll-sync.ts b/extensions/markdown-language-features/preview-src/scroll-sync.ts index e833862066e..4d1adcfb35c 100644 --- a/extensions/markdown-language-features/preview-src/scroll-sync.ts +++ b/extensions/markdown-language-features/preview-src/scroll-sync.ts @@ -143,6 +143,7 @@ export function scrollToRevealSourceLine(line: number) { const progressInElement = line - Math.floor(line); scrollTo = previousTop + (rect.height * progressInElement); } + scrollTo = Math.abs(scrollTo) < 1 ? Math.sign(scrollTo) : scrollTo; window.scroll(window.scrollX, Math.max(1, window.scrollY + scrollTo)); }