summaryrefslogtreecommitdiffstats
path: root/packages/gitbook-core/src/actions
diff options
context:
space:
mode:
authorSamy Pesse <samypesse@gmail.com>2016-09-26 17:26:36 +0200
committerSamy Pesse <samypesse@gmail.com>2016-09-26 17:26:36 +0200
commitff42b58f7702b101bf71feb09a83396e7b51dd09 (patch)
tree52193bcc3cc766cbb2de6f032f326e235dcc4db9 /packages/gitbook-core/src/actions
parent7fa3e34f9fe433ee99f797c745ef0f54b5efd89a (diff)
downloadgitbook-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.js106
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
};