1010import 'whatwg-fetch' ;
1111import React from 'react' ;
1212import ReactDOM from 'react-dom' ;
13- import { Router } from 'react-router' ;
13+ import { Router } from 'react-router' ;
1414import deepForceUpdate from 'react-deep-force-update' ;
15- import { createPath } from 'history/PathUtils' ;
15+ import { createPath } from 'history/PathUtils' ;
1616import history from './history' ;
1717import App from './components/App' ;
1818import createFetch from './createFetch' ;
@@ -24,76 +24,67 @@ theme._insertCss();
2424// Global (context) variables that can be easily accessed from any React component
2525// https://facebook.github.io/react/docs/context.html
2626const context = {
27- // Enables critical path CSS rendering
28- // https://github.com/kriasoft/isomorphic-style-loader
29- insertCss : ( ...styles ) => {
30- // eslint-disable-next-line no-underscore-dangle
31- const removeCss = styles . map ( x => x . _insertCss ( ) ) ;
32- return ( ) => {
33- removeCss . forEach ( f => f ( ) ) ;
34- } ;
35- } ,
36- // Universal HTTP client
37-
38- fetch : createFetch ( fetch , {
39- baseUrl : window . App . apiUrl ,
40- } ) ,
41- // Initialize a new Redux store
42- // http://redux.js.org/docs/basics/UsageWithReact.html
43- store : configureStore ( window . App . state , { history } ) ,
44- storeSubscription : null ,
27+ // Enables critical path CSS rendering
28+ // https://github.com/kriasoft/isomorphic-style-loader
29+ insertCss : ( ...styles ) => {
30+ // eslint-disable-next-line no-underscore-dangle
31+ const removeCss = styles . map ( x => x . _insertCss ( ) ) ;
32+ return ( ) => {
33+ removeCss . forEach ( f => f ( ) ) ;
34+ } ;
35+ } ,
36+ // Universal HTTP client
37+
38+ fetch : createFetch ( fetch , {
39+ baseUrl : window . App . apiUrl ,
40+ } ) ,
41+ // Initialize a new Redux store
42+ // http://redux.js.org/docs/basics/UsageWithReact.html
43+ store : configureStore ( window . App . state , { history} ) ,
44+ storeSubscription : null ,
4545} ;
4646
4747// Switch off the native scroll restoration behavior and handle it manually
4848// https://developers.google.com/web/updates/2015/09/history-api-scroll-restoration
4949const scrollPositionsHistory = { } ;
5050if ( window . history && 'scrollRestoration' in window . history ) {
51- window . history . scrollRestoration = 'manual' ;
51+ window . history . scrollRestoration = 'manual' ;
5252}
5353
5454let onRenderComplete = function initialRenderComplete ( ) {
55- const elem = document . getElementById ( 'css' ) ;
56- if ( elem ) elem . parentNode . removeChild ( elem ) ;
57-
58- // philip: this method updates scroll position and handles google analytics.
59- // not related to actual rendering
60- onRenderComplete = function renderComplete ( location ) {
61- let scrollX = 0 ;
62- let scrollY = 0 ;
63- const pos = scrollPositionsHistory [ location . key ] ;
64- if ( pos ) {
65- scrollX = pos . scrollX ;
66- scrollY = pos . scrollY ;
67- } else {
68- const targetHash = location . hash . substr ( 1 ) ;
69- if ( targetHash ) {
70- const target = document . getElementById (
71- targetHash ,
72- ) ;
73- if ( target ) {
74- scrollY =
75- window . pageYOffset +
76- target . getBoundingClientRect ( )
77- . top ;
78- }
79- }
80- }
81-
82- // Restore the scroll position if it was saved into the state
83- // or scroll to the given #hash anchor
84- // or scroll to top of the page
85- window . scrollTo ( scrollX , scrollY ) ;
86-
87- // Google Analytics tracking. Don't send 'pageview' event after
88- // the initial rendering, as it was already sent
89- if ( window . ga ) {
90- window . ga (
91- 'send' ,
92- 'pageview' ,
93- createPath ( location ) ,
94- ) ;
95- }
96- } ;
55+ const elem = document . getElementById ( 'css' ) ;
56+ if ( elem ) elem . parentNode . removeChild ( elem ) ;
57+
58+ // philip: this method updates scroll position and handles google analytics.
59+ // not related to actual rendering
60+ onRenderComplete = function renderComplete ( location ) {
61+ let scrollX = 0 ;
62+ let scrollY = 0 ;
63+ const pos = scrollPositionsHistory [ location . key ] ;
64+ if ( pos ) {
65+ scrollX = pos . scrollX ;
66+ scrollY = pos . scrollY ;
67+ } else {
68+ const targetHash = location . hash . substr ( 1 ) ;
69+ if ( targetHash ) {
70+ const target = document . getElementById ( targetHash ) ;
71+ if ( target ) {
72+ scrollY = window . pageYOffset + target . getBoundingClientRect ( ) . top ;
73+ }
74+ }
75+ }
76+
77+ // Restore the scroll position if it was saved into the state
78+ // or scroll to the given #hash anchor
79+ // or scroll to top of the page
80+ window . scrollTo ( scrollX , scrollY ) ;
81+
82+ // Google Analytics tracking. Don't send 'pageview' event after
83+ // the initial rendering, as it was already sent
84+ if ( window . ga ) {
85+ window . ga ( 'send' , 'pageview' , createPath ( location ) ) ;
86+ }
87+ } ;
9788} ;
9889
9990const container = document . getElementById ( 'app' ) ;
@@ -102,45 +93,42 @@ let currentLocation = history.location;
10293
10394// Re-render the app when window.location changes
10495async function onLocationChange ( location , action ) {
105- // Remember the latest scroll position for the previous location
106- scrollPositionsHistory [ currentLocation . key ] = {
107- scrollX : window . pageXOffset ,
108- scrollY : window . pageYOffset ,
109- } ;
110- // Delete stored scroll position for next page if any
111- if ( action === 'PUSH' ) {
112- delete scrollPositionsHistory [ location . key ] ;
113- }
114- currentLocation = location ;
115-
116- try {
117- // Prevent multiple page renders during the routing process
118- if ( currentLocation . key !== location . key ) {
119- return ;
120- }
121-
122- appInstance = ReactDOM . render (
123- < Router history = { history } >
124- < App
125- store = { context . store }
126- context = { context }
127- />
128- </ Router > ,
129- container ,
130- ( ) => onRenderComplete ( location ) ,
131- ) ;
132- } catch ( error ) {
133- if ( __DEV__ ) {
134- throw error ;
135- }
136-
137- console . error ( error ) ;
138-
139- // Do a full page reload if error occurs during client-side navigation
140- if ( action && currentLocation . key === location . key ) {
141- window . location . reload ( ) ;
142- }
143- }
96+ // Remember the latest scroll position for the previous location
97+ scrollPositionsHistory [ currentLocation . key ] = {
98+ scrollX : window . pageXOffset ,
99+ scrollY : window . pageYOffset ,
100+ } ;
101+ // Delete stored scroll position for next page if any
102+ if ( action === 'PUSH' ) {
103+ delete scrollPositionsHistory [ location . key ] ;
104+ }
105+ currentLocation = location ;
106+
107+ try {
108+ // Prevent multiple page renders during the routing process
109+ if ( currentLocation . key !== location . key ) {
110+ return ;
111+ }
112+
113+ appInstance = ReactDOM . render (
114+ < Router history = { history } >
115+ < App store = { context . store } context = { context } />
116+ </ Router > ,
117+ container ,
118+ ( ) => onRenderComplete ( location ) ,
119+ ) ;
120+ } catch ( error ) {
121+ if ( __DEV__ ) {
122+ throw error ;
123+ }
124+
125+ console . error ( error ) ;
126+
127+ // Do a full page reload if error occurs during client-side navigation
128+ if ( action && currentLocation . key === location . key ) {
129+ window . location . reload ( ) ;
130+ }
131+ }
144132}
145133
146134// Handle client-side navigation by using HTML5 History API
@@ -150,12 +138,12 @@ onLocationChange(currentLocation);
150138
151139// Enable Hot Module Replacement (HMR)
152140if ( module . hot ) {
153- module . hot . accept ( './components/App' , ( ) => {
154- if ( appInstance ) {
155- // Force-update the whole tree, including components that refuse to update
156- deepForceUpdate ( appInstance ) ;
157- }
158-
159- onLocationChange ( currentLocation ) ;
160- } ) ;
141+ module . hot . accept ( './components/App' , ( ) => {
142+ if ( appInstance ) {
143+ // Force-update the whole tree, including components that refuse to update
144+ deepForceUpdate ( appInstance ) ;
145+ }
146+
147+ onLocationChange ( currentLocation ) ;
148+ } ) ;
161149}
0 commit comments