From 113f84283a066e1d697c701074e6ef3a6c5e73d6 Mon Sep 17 00:00:00 2001 From: makhnatkin Date: Thu, 3 Oct 2024 10:25:47 +0200 Subject: [PATCH] feat(srcDoc): added scroll to hash --- example/README.md | 5 ++++- example/index.js | 4 ++-- src/runtime/SrcDocIFrameController.ts | 28 ++++++++++++++++++++++++--- 3 files changed, 31 insertions(+), 6 deletions(-) diff --git a/example/README.md b/example/README.md index fb008b8..6adb10b 100644 --- a/example/README.md +++ b/example/README.md @@ -60,13 +60,16 @@ After html text ## Long text example ::: html + to bottom

Top

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque lobortis fermentum placerat. Quisque pretium sagittis laoreet. Curabitur eu sagittis tellus. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Donec laoreet eu enim nec pretium. Phasellus diam odio, porttitor sed pellentesque et, iaculis a nibh. Morbi sit amet ipsum in purus sagittis egestas. Quisque ut varius odio, id varius enim. Vestibulum venenatis turpis et ipsum gravida, vel consectetur nisi lobortis. Fusce turpis orci, facilisis condimentum lectus lobortis, aliquet imperdiet tortor. In placerat, eros id viverra efficitur, lectus justo auctor mauris, at vehicula massa diam ac ipsum. In eu tristique nisl. Duis aliquam maximus consectetur. Sed semper hendrerit lectus interdum iaculis.

Nulla facilisi. Vivamus rutrum vel sem et fringilla. Aliquam erat volutpat. Etiam vel placerat mauris, ac aliquam eros. Nunc accumsan elit ut dolor venenatis, porta laoreet metus euismod. Morbi rutrum dignissim neque ac aliquet. Nam facilisis ac massa non egestas. Pellentesque eu consectetur tellus. Maecenas scelerisque cursus lectus non tempor. Etiam non scelerisque quam. Cras a odio sodales, iaculis magna a, bibendum ex. In et arcu auctor urna placerat interdum ut vel ipsum. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Quisque sit amet mi lorem. Suspendisse potenti.

- Yandex site + target parent: Yandex site

Phasellus vitae posuere erat. Sed blandit nunc eget sapien ultrices fermentum. Aenean vestibulum facilisis elit sed aliquet. Phasellus posuere et leo id commodo. Praesent tincidunt egestas est a fermentum. Quisque maximus eros dolor, at condimentum eros faucibus in. In commodo augue id purus semper, non semper orci interdum. Phasellus luctus augue id ornare bibendum. Praesent dignissim nisi nec nisi imperdiet, vel pretium dui vestibulum. In condimentum magna odio, ac suscipit lectus accumsan non.

Donec imperdiet tortor vitae ipsum gravida euismod. Donec lobortis orci erat, rutrum consequat orci aliquet non. Curabitur non dui eget orci maximus dapibus id vitae orci. Praesent sed venenatis ipsum. Suspendisse bibendum tincidunt arcu, id tempor felis consectetur non. Sed sit amet purus ultrices, tristique enim eu, efficitur mauris. Curabitur sed efficitur ligula, et varius lectus. Morbi libero purus, eleifend in vehicula eu, sagittis eu lacus. Nulla nisi ligula, mollis eu neque ornare, scelerisque rutrum enim. Duis ut volutpat neque. Vivamus gravida, felis a laoreet auctor, leo lacus mattis lacus, non auctor elit tellus ut odio. Phasellus facilisis efficitur dolor, ut fermentum mi mattis in. Suspendisse potenti. Donec tincidunt nunc eu lacus ultricies, a imperdiet est congue. Maecenas non metus non purus lobortis dignissim. Nulla libero dolor, mattis sit amet massa sed, porttitor fringilla tellus.

+ target blank: Yandex site

Donec imperdiet tortor vitae ipsum gravida euismod. Donec lobortis orci erat, rutrum consequat orci aliquet non. Curabitur non dui eget orci maximus dapibus id vitae orci. Praesent sed venenatis ipsum. Suspendisse bibendum tincidunt arcu, id tempor felis consectetur non. Sed sit amet purus ultrices, tristique enim eu, efficitur mauris. Curabitur sed efficitur ligula, et varius lectus. Morbi libero purus, eleifend in vehicula eu, sagittis eu lacus. Nulla nisi ligula, mollis eu neque ornare, scelerisque rutrum enim. Duis ut volutpat neque. Vivamus gravida, felis a laoreet auctor, leo lacus mattis lacus, non auctor elit tellus ut odio. Phasellus facilisis efficitur dolor, ut fermentum mi mattis in. Suspendisse potenti. Donec tincidunt nunc eu lacus ultricies, a imperdiet est congue. Maecenas non metus non purus lobortis dignissim. Nulla libero dolor, mattis sit amet massa sed, porttitor fringilla tellus.

+

Bottom

Donec imperdiet tortor vitae ipsum gravida euismod. Donec lobortis orci erat, rutrum consequat orci aliquet non. Curabitur non dui eget orci maximus dapibus id vitae orci. Praesent sed venenatis ipsum. Suspendisse bibendum tincidunt arcu, id tempor felis consectetur non. Sed sit amet purus ultrices, tristique enim eu, efficitur mauris. Curabitur sed efficitur ligula, et varius lectus. Morbi libero purus, eleifend in vehicula eu, sagittis eu lacus. Nulla nisi ligula, mollis eu neque ornare, scelerisque rutrum enim. Duis ut volutpat neque. Vivamus gravida, felis a laoreet auctor, leo lacus mattis lacus, non auctor elit tellus ut odio. Phasellus facilisis efficitur dolor, ut fermentum mi mattis in. Suspendisse potenti. Donec tincidunt nunc eu lacus ultricies, a imperdiet est congue. Maecenas non metus non purus lobortis dignissim. Nulla libero dolor, mattis sit amet massa sed, porttitor fringilla tellus.

Donec imperdiet tortor vitae ipsum gravida euismod. Donec lobortis orci erat, rutrum consequat orci aliquet non. Curabitur non dui eget orci maximus dapibus id vitae orci. Praesent sed venenatis ipsum. Suspendisse bibendum tincidunt arcu, id tempor felis consectetur non. Sed sit amet purus ultrices, tristique enim eu, efficitur mauris. Curabitur sed efficitur ligula, et varius lectus. Morbi libero purus, eleifend in vehicula eu, sagittis eu lacus. Nulla nisi ligula, mollis eu neque ornare, scelerisque rutrum enim. Duis ut volutpat neque. Vivamus gravida, felis a laoreet auctor, leo lacus mattis lacus, non auctor elit tellus ut odio. Phasellus facilisis efficitur dolor, ut fermentum mi mattis in. Suspendisse potenti. Donec tincidunt nunc eu lacus ultricies, a imperdiet est congue. Maecenas non metus non purus lobortis dignissim. Nulla libero dolor, mattis sit amet massa sed, porttitor fringilla tellus.

to top diff --git a/example/index.js b/example/index.js index 096cdc5..6abdf2b 100644 --- a/example/index.js +++ b/example/index.js @@ -13,14 +13,14 @@ import {promisify} from 'node:util'; htmlPlugin.transform({ bundle: true, head: ` - + `, - embeddingMode: 'isolated', + embeddingMode: 'srcdoc', isolatedSandboxHost: 'http://localhost:5005/runtime.html', }), ], diff --git a/src/runtime/SrcDocIFrameController.ts b/src/runtime/SrcDocIFrameController.ts index 436e1dd..64c0f98 100644 --- a/src/runtime/SrcDocIFrameController.ts +++ b/src/runtime/SrcDocIFrameController.ts @@ -68,15 +68,15 @@ export class SrcDocIFrameController extends Disposable implements IEmbeddedConte async initialize() { await this.instantiateController(); - await this.setRootClassNames(this.config.classNames); await this.setRootStyles(this.config.styles); - this.addAnchorLinkHandlers(); - this.updateIFrameHeight( // eslint-disable-next-line @typescript-eslint/no-non-null-assertion this.host.contentWindow!.document.body.getBoundingClientRect().height, ); + + this.addAnchorLinkHandlers(); + this.handleHashChange(); } // finds all relative links (href^="#") and changes their click behavior @@ -96,6 +96,28 @@ export class SrcDocIFrameController extends Disposable implements IEmbeddedConte } } + private scrollToHash() { + const hash = window.location.hash.substring(1); + + if (hash) { + const document = this.host.contentWindow!.document; + const element = document.getElementById(hash); + if (element) { + element.scrollIntoView({ behavior: 'smooth' }); + } + } + } + + private async handleHashChange() { + await ensureIframeLoaded(this.host); + + this.scrollToHash(); + + const handleHashChange = () => this.scrollToHash(); + window.addEventListener('hashchange', handleHashChange); + this.dispose.add(() => window.removeEventListener('hashchange', handleHashChange)); + } + setRootClassNames(classNames: string[] | undefined) { return this.executeOnController((controller) => controller.setClassNames(classNames)); }