diff options
author | Samy Pesse <samypesse@gmail.com> | 2016-09-26 17:26:36 +0200 |
---|---|---|
committer | Samy Pesse <samypesse@gmail.com> | 2016-09-26 17:26:36 +0200 |
commit | ff42b58f7702b101bf71feb09a83396e7b51dd09 (patch) | |
tree | 52193bcc3cc766cbb2de6f032f326e235dcc4db9 /packages/gitbook-core/src/actions | |
parent | 7fa3e34f9fe433ee99f797c745ef0f54b5efd89a (diff) | |
download | gitbook-ff42b58f7702b101bf71feb09a83396e7b51dd09.zip gitbook-ff42b58f7702b101bf71feb09a83396e7b51dd09.tar.gz gitbook-ff42b58f7702b101bf71feb09a83396e7b51dd09.tar.bz2 |
Add basic for pjax navigation
Diffstat (limited to 'packages/gitbook-core/src/actions')
-rw-r--r-- | packages/gitbook-core/src/actions/navigation.js | 106 |
1 files changed, 105 insertions, 1 deletions
diff --git a/packages/gitbook-core/src/actions/navigation.js b/packages/gitbook-core/src/actions/navigation.js index 0d00687..af0fdff 100644 --- a/packages/gitbook-core/src/actions/navigation.js +++ b/packages/gitbook-core/src/actions/navigation.js @@ -1,13 +1,116 @@ +const ACTION_TYPES = require('./TYPES'); +const getPayload = require('../lib/getPayload'); +const SUPPORTED = ( + typeof window !== 'undefined' && + window.history && window.history.pushState && window.history.replaceState && + // pushState isn't reliable on iOS until 5. + !navigator.userAgent.match(/((iPod|iPhone|iPad).+\bOS\s+[1-4]\D|WebApps\/.+CFNetwork)/) +); + +let PUSH_ID = 0; + +/** + * Generate a new state to be pushed or replaced + * @param {Object} + */ +function genState() { + return { + id: (PUSH_ID++) + }; +} + +/** + * Push a new url into the navigation + * @param {String} uri + * @return {Action} action + */ +function pushURI(uri) { + return () => { + const state = genState(); + + if (SUPPORTED) { + window.history.pushState(state, '', uri); + } else { + redirect(uri); + } + }; +} + +/** + * Replace current state in navigation + * @param {String} uri + * @return {Action} action + */ +function replaceURI(uri) { + return () => { + const state = genState(); + + if (SUPPORTED) { + window.history.replaceState(state, '', uri); + } else { + redirect(uri); + } + }; +} + +/** + * Hard redirection + * @param {String} uri + * @return {Action} action + */ +function redirect(uri) { + return () => { + window.location.href = uri; + }; +} /** * Fetch a new page and update the store accordingly * @param {String} uri + * @param {Boolean} options.replace * @return {Action} action */ -function fetchPage(uri) { +function fetchPage(uri, options) { + const { replace } = options; + return (dispatch, getState) => { + const prevURI = location.href; + dispatch({ type: ACTION_TYPES.PAGE_FETCH_START }); + + if (replace) { + dispatch(replaceURI(uri)); + } else { + dispatch(pushURI(uri)); + } + + window.fetch(uri, { + credentials: 'include' + }) + .then( + response => { + return response.text(); + } + ) + .then( + html => { + const payload = getPayload(html); + + if (!payload) { + throw new Error('No payload found in page'); + } + + dispatch({ type: ACTION_TYPES.PAGE_FETCH_END, payload }); + } + ) + .catch( + error => { + dispatch(replaceURI(prevURI)); + dispatch(redirect(uri)); + dispatch({ type: ACTION_TYPES.PAGE_FETCH_ERROR, error }); + } + ); }; } @@ -21,6 +124,7 @@ function fetchArticle(article) { } module.exports = { + pushURI, fetchPage, fetchArticle }; |