mirror of
https://github.com/GitbookIO/gitbook.git
synced 2026-09-20 17:43:24 +00:00
Correctly update page when url changed
This commit is contained in:
@@ -7,6 +7,7 @@ module.exports = {
|
||||
NAVIGATION_ACTIVATE: 'navigation/activate',
|
||||
NAVIGATION_DEACTIVATE: 'navigation/deactivate',
|
||||
NAVIGATION_LISTEN: 'navigation/listen',
|
||||
NAVIGATION_UPDATE: 'navigation/update',
|
||||
PAGE_FETCH_START: 'navigation/fetch:start',
|
||||
PAGE_FETCH_END: 'navigation/fetch:end',
|
||||
PAGE_FETCH_ERROR: 'navigation/fetch:error',
|
||||
|
||||
@@ -14,9 +14,27 @@ const SUPPORTED = (
|
||||
*/
|
||||
function activate() {
|
||||
return (dispatch, getState) => {
|
||||
|
||||
dispatch({
|
||||
type: ACTION_TYPES.NAVIGATION_ACTIVATE,
|
||||
listener: () => dispatch(emit())
|
||||
listener: (location) => {
|
||||
location = Location.fromNative(location);
|
||||
const prevLocation = getState().navigation.location;
|
||||
|
||||
// Fetch page if required
|
||||
if (!prevLocation || location.pathname !== prevLocation.pathname) {
|
||||
dispatch(fetchPage(location.pathname));
|
||||
}
|
||||
|
||||
// Signal location to listener
|
||||
dispatch(emit());
|
||||
|
||||
// Update the location
|
||||
dispatch({
|
||||
type: ACTION_TYPES.NAVIGATION_UPDATE,
|
||||
location
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Trigger for existing listeners
|
||||
@@ -116,24 +134,14 @@ function listen(listener) {
|
||||
|
||||
/**
|
||||
* Fetch a new page and update the store accordingly
|
||||
* @param {String} uri
|
||||
* @param {Boolean} options.replace
|
||||
* @param {String} pathname
|
||||
* @return {Action} action
|
||||
*/
|
||||
function fetchPage(uri, options = {}) {
|
||||
const shouldReplace = options.replace;
|
||||
|
||||
function fetchPage(pathname) {
|
||||
return (dispatch, getState) => {
|
||||
const prevURI = location.href;
|
||||
dispatch({ type: ACTION_TYPES.PAGE_FETCH_START });
|
||||
|
||||
if (shouldReplace) {
|
||||
dispatch(replace(uri));
|
||||
} else {
|
||||
dispatch(push(uri));
|
||||
}
|
||||
|
||||
window.fetch(uri, {
|
||||
window.fetch(pathname, {
|
||||
credentials: 'include'
|
||||
})
|
||||
.then(
|
||||
@@ -154,9 +162,8 @@ function fetchPage(uri, options = {}) {
|
||||
)
|
||||
.catch(
|
||||
error => {
|
||||
dispatch(replace(prevURI));
|
||||
dispatch(redirect(uri));
|
||||
|
||||
// dispatch(redirect(pathname));
|
||||
console.error(error);
|
||||
dispatch({ type: ACTION_TYPES.PAGE_FETCH_ERROR, error });
|
||||
}
|
||||
);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
const React = require('react');
|
||||
const ReactRedux = require('react-redux');
|
||||
const navigation = require('../actions/navigation');
|
||||
const Navigation = require('../actions/navigation');
|
||||
|
||||
/**
|
||||
* Check if an element is inside a link
|
||||
@@ -61,7 +61,7 @@ function getHrefForEvent(event) {
|
||||
if (link.getAttribute('data-nopjax'))
|
||||
return;
|
||||
|
||||
return link.href;
|
||||
return link.pathname;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -83,25 +83,15 @@ const PJAXWrapper = React.createClass({
|
||||
}
|
||||
|
||||
event.preventDefault();
|
||||
dispatch(navigation.fetchPage(href));
|
||||
|
||||
},
|
||||
|
||||
onPopState(event) {
|
||||
const { dispatch } = this.props;
|
||||
event.preventDefault();
|
||||
|
||||
dispatch(navigation.fetchPage(location.href, { replace: true }));
|
||||
dispatch(Navigation.push(href));
|
||||
},
|
||||
|
||||
componentDidMount() {
|
||||
document.addEventListener('click', this.onClick, false);
|
||||
window.addEventListener('popstate', this.onPopState, false);
|
||||
},
|
||||
|
||||
componentWillUnmount() {
|
||||
document.removeEventListener('click', this.onClick, false);
|
||||
window.removeEventListener('popstate', this.onPopState, false);
|
||||
},
|
||||
|
||||
render() {
|
||||
|
||||
@@ -10,6 +10,11 @@ const DEFAULTS = {
|
||||
};
|
||||
|
||||
class Location extends Record(DEFAULTS) {
|
||||
|
||||
/**
|
||||
* Return search query as a string
|
||||
* @return {String}
|
||||
*/
|
||||
get search() {
|
||||
const { query } = this;
|
||||
return query.size === 0 ?
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
const { Record } = require('immutable');
|
||||
|
||||
const DEFAULTS = {
|
||||
title: '',
|
||||
content: '',
|
||||
dir: 'ltr',
|
||||
depth: 1,
|
||||
level: '',
|
||||
previous: null,
|
||||
next: null
|
||||
};
|
||||
|
||||
class Page extends Record(DEFAULTS) {
|
||||
static create(state) {
|
||||
return state instanceof Page ?
|
||||
state : new Page({
|
||||
...state
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Page;
|
||||
@@ -5,16 +5,18 @@ const ACTION_TYPES = require('../actions/TYPES');
|
||||
const isServerSide = (typeof window === 'undefined');
|
||||
|
||||
const NavigationState = Record({
|
||||
// Current location
|
||||
location: null,
|
||||
// Are we loading a new page
|
||||
loading: Boolean(false),
|
||||
loading: Boolean(false),
|
||||
// Did we fail loading a page?
|
||||
error: null,
|
||||
error: null,
|
||||
// Listener for history changes
|
||||
listeners: List(),
|
||||
// Function to call to stop listening
|
||||
unlisten: null,
|
||||
unlisten: null,
|
||||
// History instance
|
||||
history: null
|
||||
history: null
|
||||
});
|
||||
|
||||
function reduceNavigation(state, action) {
|
||||
@@ -58,6 +60,11 @@ function reduceNavigation(state, action) {
|
||||
unlisten: null
|
||||
});
|
||||
|
||||
case ACTION_TYPES.NAVIGATION_UPDATE:
|
||||
return state.merge({
|
||||
location: action.location
|
||||
});
|
||||
|
||||
case ACTION_TYPES.NAVIGATION_LISTEN:
|
||||
return state.merge({
|
||||
listeners: state.listeners.push(action.listener)
|
||||
|
||||
@@ -1,26 +1,8 @@
|
||||
const { Record } = require('immutable');
|
||||
const ACTION_TYPES = require('../actions/TYPES');
|
||||
|
||||
const DEFAULTS = {
|
||||
title: '',
|
||||
content: '',
|
||||
dir: 'ltr',
|
||||
depth: 1,
|
||||
level: '',
|
||||
previous: null
|
||||
};
|
||||
|
||||
class PageState extends Record(DEFAULTS) {
|
||||
static create(state) {
|
||||
return state instanceof PageState ?
|
||||
state : new PageState({
|
||||
...state
|
||||
});
|
||||
}
|
||||
}
|
||||
const Page = require('../models/Page');
|
||||
|
||||
module.exports = (state, action) => {
|
||||
state = PageState.create(state);
|
||||
state = Page.create(state);
|
||||
|
||||
switch (action.type) {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user