Преглед изворни кода

refactor AppContainer

* init() method was devided to initApp() and initContents()
Yuki Takei пре 5 година
родитељ
комит
7250d7611f

+ 2 - 0
src/client/js/admin.jsx

@@ -45,6 +45,8 @@ import { appContainer, componentMappings } from './base';
 
 const logger = loggerFactory('growi:admin');
 
+appContainer.initContents();
+
 const { i18n } = appContainer;
 const websocketContainer = appContainer.getContainer('WebsocketContainer');
 

+ 2 - 0
src/client/js/app.jsx

@@ -44,6 +44,8 @@ import { appContainer, componentMappings } from './base';
 
 const logger = loggerFactory('growi:cli:app');
 
+appContainer.initContents();
+
 const { i18n } = appContainer;
 const websocketContainer = appContainer.getContainer('WebsocketContainer');
 

+ 1 - 2
src/client/js/base.jsx

@@ -20,8 +20,7 @@ const appContainer = new AppContainer();
 // eslint-disable-next-line no-unused-vars
 const websocketContainer = new WebsocketContainer(appContainer);
 
-appContainer.init();
-appContainer.injectToWindow();
+appContainer.initApp();
 
 logger.info('AppContainer has been initialized');
 

+ 9 - 8
src/client/js/components/LoginForm.jsx

@@ -4,8 +4,8 @@ import ReactCardFlip from 'react-card-flip';
 
 import { withTranslation } from 'react-i18next';
 
+import AppContainer from '../services/AppContainer';
 import { withUnstatedContainers } from './UnstatedUtils';
-import NoLoginContainer from '../services/NoLoginContainer';
 
 class LoginForm extends React.Component {
 
@@ -35,12 +35,12 @@ class LoginForm extends React.Component {
 
   handleLoginWithExternalAuth(e) {
     const auth = e.currentTarget.id;
-    const csrf = this.props.noLoginContainer.csrfToken;
+    const { csrf } = this.props.appContainer;
     window.location.href = `/passport/${auth}?_csrf=${csrf}`;
   }
 
   renderLocalOrLdapLoginForm() {
-    const { t, noLoginContainer, isLdapStrategySetup } = this.props;
+    const { t, appContainer, isLdapStrategySetup } = this.props;
 
     return (
       <form role="form" action="/login" method="post">
@@ -70,7 +70,7 @@ class LoginForm extends React.Component {
         </div>
 
         <div className="input-group my-4">
-          <input type="hidden" name="_csrf" value={noLoginContainer.csrfToken} />
+          <input type="hidden" name="_csrf" value={appContainer.csrfToken} />
           <button type="submit" id="login" className="btn btn-fill rounded-0 login mx-auto">
             <div className="eff"></div>
             <span className="btn-label">
@@ -147,10 +147,10 @@ class LoginForm extends React.Component {
   renderRegisterForm() {
     const {
       t,
+      appContainer,
       username,
       name,
       email,
-      noLoginContainer,
       registrationMode,
       registrationWhiteList,
     } = this.props;
@@ -220,7 +220,7 @@ class LoginForm extends React.Component {
           </div>
 
           <div className="input-group justify-content-center my-4">
-            <input type="hidden" name="_csrf" value={noLoginContainer.csrfToken} />
+            <input type="hidden" name="_csrf" value={appContainer.csrfToken} />
             <button type="submit" className="btn btn-fill rounded-0" id="register">
               <div className="eff"></div>
               <span className="btn-label">
@@ -293,12 +293,13 @@ class LoginForm extends React.Component {
 /**
  * Wrapper component for using unstated
  */
-const LoginFormWrapper = withUnstatedContainers(LoginForm, [NoLoginContainer]);
+const LoginFormWrapper = withUnstatedContainers(LoginForm, [AppContainer]);
 
 LoginForm.propTypes = {
   // i18next
   t: PropTypes.func.isRequired,
-  noLoginContainer: PropTypes.instanceOf(NoLoginContainer).isRequired,
+  appContainer: PropTypes.instanceOf(AppContainer).isRequired,
+
   isRegistering: PropTypes.bool,
   username: PropTypes.string,
   name: PropTypes.string,

+ 2 - 4
src/client/js/nologin.jsx

@@ -5,7 +5,6 @@ import { I18nextProvider } from 'react-i18next';
 
 import i18nFactory from './util/i18n';
 
-import NoLoginContainer from './services/NoLoginContainer';
 import AppContainer from './services/AppContainer';
 
 import InstallerForm from './components/InstallerForm';
@@ -31,9 +30,8 @@ if (installerFormElem) {
 // render loginForm
 const loginFormElem = document.getElementById('login-form');
 if (loginFormElem) {
-  const noLoginContainer = new NoLoginContainer();
   const appContainer = new AppContainer();
-  appContainer.init();
+  appContainer.initApp();
 
   const username = loginFormElem.dataset.username;
   const name = loginFormElem.dataset.name;
@@ -62,7 +60,7 @@ if (loginFormElem) {
 
   ReactDOM.render(
     <I18nextProvider i18n={i18n}>
-      <Provider inject={[noLoginContainer, appContainer]}>
+      <Provider inject={[appContainer]}>
         <LoginForm
           username={username}
           name={name}

+ 45 - 34
src/client/js/services/AppContainer.js

@@ -39,7 +39,7 @@ export default class AppContainer extends Container {
     const { localStorage } = window;
 
     this.state = {
-      editorMode: null,
+      // minimalized states for app
       isDeviceSmallerThanMd: null,
       preferDarkModeByMediaQuery: false,
       preferDarkModeByUser: localStorage.preferDarkModeByUser === 'true',
@@ -49,37 +49,22 @@ export default class AppContainer extends Container {
       isDrawerMode: null,
       isDrawerOpened: false,
 
+      // stetes for contents
+      editorMode: null,
       isPageCreateModalShown: false,
-
       recentlyUpdatedPages: [],
     };
 
     const body = document.querySelector('body');
 
-    this.isAdmin = body.dataset.isAdmin === 'true';
     this.csrfToken = body.dataset.csrftoken;
-    this.isPluginEnabled = body.dataset.pluginEnabled === 'true';
     this.isLoggedin = document.querySelector('body.nologin') == null;
 
     this.config = JSON.parse(document.getElementById('growi-context-hydrate').textContent || '{}');
 
-    const currentUserElem = document.getElementById('growi-current-user');
-    if (currentUserElem != null) {
-      this.currentUser = JSON.parse(currentUserElem.textContent);
-    }
-
     const userAgent = window.navigator.userAgent.toLowerCase();
     this.isMobile = /iphone|ipad|android/.test(userAgent);
 
-    this.isDocSaved = true;
-
-    this.originRenderer = new GrowiRenderer(this);
-
-    this.interceptorManager = new InterceptorManager();
-    this.interceptorManager.addInterceptor(new DetachCodeBlockInterceptor(this), 10); // process as soon as possible
-    this.interceptorManager.addInterceptor(new DrawioInterceptor(this), 20);
-    this.interceptorManager.addInterceptor(new RestoreCodeBlockInterceptor(this), 900); // process as late as possible
-
     const userlang = body.dataset.userlang;
     this.i18n = i18nFactory(userlang);
 
@@ -108,6 +93,45 @@ export default class AppContainer extends Container {
 
     this.openPageCreateModal = this.openPageCreateModal.bind(this);
     this.closePageCreateModal = this.closePageCreateModal.bind(this);
+  }
+
+  /**
+   * Workaround for the mangling in production build to break constructor.name
+   */
+  static getClassName() {
+    return 'AppContainer';
+  }
+
+  initApp() {
+    this.initDeviceSize();
+    this.initMediaQueryForColorScheme();
+
+    this.injectToWindow();
+  }
+
+  initContents() {
+    const body = document.querySelector('body');
+
+    const currentUserElem = document.getElementById('growi-current-user');
+    if (currentUserElem != null) {
+      this.currentUser = JSON.parse(currentUserElem.textContent);
+    }
+
+    this.isAdmin = body.dataset.isAdmin === 'true';
+
+    this.isDocSaved = true;
+
+    this.originRenderer = new GrowiRenderer(this);
+
+    this.interceptorManager = new InterceptorManager();
+    this.interceptorManager.addInterceptor(new DetachCodeBlockInterceptor(this), 10); // process as soon as possible
+    this.interceptorManager.addInterceptor(new DrawioInterceptor(this), 20);
+    this.interceptorManager.addInterceptor(new RestoreCodeBlockInterceptor(this), 900); // process as late as possible
+
+    const isPluginEnabled = body.dataset.pluginEnabled === 'true';
+    if (isPluginEnabled) {
+      this.initPlugins();
+    }
 
     window.addEventListener('keydown', (event) => {
       const target = event.target;
@@ -122,19 +146,8 @@ export default class AppContainer extends Container {
         this.setState({ isPageCreateModalShown: true });
       }
     });
-  }
 
-  /**
-   * Workaround for the mangling in production build to break constructor.name
-   */
-  static getClassName() {
-    return 'AppContainer';
-  }
-
-  init() {
-    this.initDeviceSize();
-    this.initMediaQueryForColorScheme();
-    this.initPlugins();
+    this.injectToWindow();
   }
 
   initDeviceSize() {
@@ -170,10 +183,8 @@ export default class AppContainer extends Container {
   }
 
   initPlugins() {
-    if (this.isPluginEnabled) {
-      const growiPlugin = window.growiPlugin;
-      growiPlugin.installAll(this, this.originRenderer);
-    }
+    const growiPlugin = window.growiPlugin;
+    growiPlugin.installAll(this, this.originRenderer);
   }
 
   injectToWindow() {

+ 0 - 23
src/client/js/services/NoLoginContainer.js

@@ -1,23 +0,0 @@
-import { Container } from 'unstated';
-
-/**
- * Service container related to Nologin (installer, login)
- * @extends {Container} unstated Container
- */
-export default class NoLoginContainer extends Container {
-
-  constructor() {
-    super();
-
-    const body = document.querySelector('body');
-    this.csrfToken = body.dataset.csrftoken;
-  }
-
-  /**
-   * Workaround for the mangling in production build to break constructor.name
-   */
-  static getClassName() {
-    return 'NoLoginContainer';
-  }
-
-}