Skip to content

Commit

Permalink
feat(srcDoc): added scroll to hash
Browse files Browse the repository at this point in the history
  • Loading branch information
makhnatkin committed Oct 4, 2024
1 parent 6811f7c commit 113f842
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 6 deletions.
5 changes: 4 additions & 1 deletion example/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,16 @@ After html text
## Long text example

::: html
<a href="#bottom">to bottom</a>
<h2 id="top">Top</h2>
<p>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.</p>
<p>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.</p>
<a href="https://yandex.com">Yandex site</a>
<a href="https://yandex.com">target parent: Yandex site</a>
<p>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.</p>
<p>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.</p>
<a target="_blank" href="https://yandex.com">target blank: Yandex site</a>
<p>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.</p>
<h2 id="bottom">Bottom</h2>
<p>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.</p>
<p>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.</p>
<a href="#top">to top</a>
Expand Down
4 changes: 2 additions & 2 deletions example/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@ import {promisify} from 'node:util';
htmlPlugin.transform({
bundle: true,
head: `
<base target="_blank" />
<base target="_parent" />
<style>
h2 {
color: gray;
}
</style>
`,
embeddingMode: 'isolated',
embeddingMode: 'srcdoc',
isolatedSandboxHost: 'http://localhost:5005/runtime.html',
}),
],
Expand Down
28 changes: 25 additions & 3 deletions src/runtime/SrcDocIFrameController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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));
}
Expand Down

0 comments on commit 113f842

Please sign in to comment.