mirror of
https://github.com/GitbookIO/gitbook.git
synced 2026-09-29 05:29:02 +00:00
Update url when scrolling in default theme
This commit is contained in:
@@ -4,10 +4,81 @@ const { React } = GitBook;
|
||||
const Page = require('./Page');
|
||||
const Toolbar = require('./Toolbar');
|
||||
|
||||
const HEADINGS_SELECTOR = 'h1[id],h2[id],h3[id],h4[id]';
|
||||
|
||||
/**
|
||||
* Get offset of an element relative to a parent container.
|
||||
* @param {DOMElement} container
|
||||
* @param {DOMElement} element
|
||||
* @return {Number} offset
|
||||
*/
|
||||
function getOffset(container, element, type = 'Top') {
|
||||
const parent = element.parentElement;
|
||||
let base = 0;
|
||||
|
||||
if (parent != container) {
|
||||
base = getOffset(container, parent, type);
|
||||
}
|
||||
|
||||
return base + element[`offset${type}`];
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the current heading anchor for a scroll position.
|
||||
* @param {DOMElement} container
|
||||
* @param {Number} top
|
||||
* @return {String}
|
||||
*/
|
||||
function getHeadingID(container, top) {
|
||||
let id;
|
||||
const headings = container.querySelectorAll(HEADINGS_SELECTOR);
|
||||
|
||||
headings.forEach(heading => {
|
||||
if (id) {
|
||||
return;
|
||||
}
|
||||
|
||||
const offset = getOffset(container, heading);
|
||||
|
||||
if (offset > top) {
|
||||
id = heading.getAttribute('id');
|
||||
}
|
||||
});
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
const Body = React.createClass({
|
||||
propTypes: {
|
||||
page: GitBook.PropTypes.Page,
|
||||
readme: GitBook.PropTypes.Readme
|
||||
page: GitBook.PropTypes.Page,
|
||||
readme: GitBook.PropTypes.Readme,
|
||||
history: GitBook.PropTypes.History,
|
||||
updateURI: React.PropTypes.func
|
||||
},
|
||||
|
||||
/**
|
||||
* User is scrolling the page, update the location with current section's ID.
|
||||
*/
|
||||
onScroll(event) {
|
||||
const { history, updateURI } = this.props;
|
||||
const { location } = history;
|
||||
const container = event.target;
|
||||
|
||||
// Find the id matching the current scroll position
|
||||
const hash = getHeadingID(container, container.scrollTop);
|
||||
|
||||
// Update url if changed
|
||||
if (hash !== location.hash) {
|
||||
updateURI(location.merge({ hash }));
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Component has been updated with a new location,
|
||||
* scroll to the right anchor.
|
||||
*/
|
||||
componentDidUpdate() {
|
||||
|
||||
},
|
||||
|
||||
render() {
|
||||
@@ -15,7 +86,10 @@ const Body = React.createClass({
|
||||
|
||||
return (
|
||||
<GitBook.InjectedComponent matching={{ role: 'body:wrapper' }}>
|
||||
<div className="Body page-wrapper">
|
||||
<div
|
||||
className="Body page-wrapper"
|
||||
onScroll={this.onScroll}
|
||||
>
|
||||
<GitBook.InjectedComponent matching={{ role: 'toolbar:wrapper' }}>
|
||||
<Toolbar title={page.title} readme={readme} />
|
||||
</GitBook.InjectedComponent>
|
||||
@@ -28,4 +102,13 @@ const Body = React.createClass({
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = Body;
|
||||
module.exports = GitBook.connect(Body,
|
||||
() => {
|
||||
return {};
|
||||
},
|
||||
({ History }, dispatch) => {
|
||||
return {
|
||||
updateURI: (location) => dispatch(History.replace(location))
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
@@ -38,7 +38,11 @@ const Theme = React.createClass({
|
||||
<Sidebar key={0} summary={summary} />
|
||||
) : null}
|
||||
<div key={1} className="Body-Flex">
|
||||
<Body page={page} readme={readme} />
|
||||
<Body
|
||||
page={page}
|
||||
readme={readme}
|
||||
history={history}
|
||||
/>
|
||||
</div>
|
||||
</ReactCSSTransitionGroup>
|
||||
</GitBook.FlexBox>
|
||||
|
||||
Reference in New Issue
Block a user