Yuki Takei 6 лет назад
Родитель
Сommit
eb008c7548
1 измененных файлов с 47 добавлено и 24 удалено
  1. 47 24
      src/client/js/components/TableOfContents.jsx

+ 47 - 24
src/client/js/components/TableOfContents.jsx

@@ -1,15 +1,19 @@
 import React from 'react';
 import PropTypes from 'prop-types';
+import loggerFactory from '@alias/logger';
 
 import { withTranslation } from 'react-i18next';
 
 import { debounce } from 'throttle-debounce';
+import StickyEvents from 'sticky-events';
 
 import AppContainer from '../services/AppContainer';
 import PageContainer from '../services/PageContainer';
 
 import { createSubscribedElement } from './UnstatedUtils';
 
+const logger = loggerFactory('growi:TableOfContents');
+
 // get these value with
 //   document.querySelector('.revision-toc').getBoundingClientRect().top
 const DEFAULT_REVISION_TOC_TOP_FOR_GROWI_LAYOUT = 190;
@@ -27,37 +31,54 @@ class TableOfContents extends React.Component {
   constructor(props) {
     super(props);
 
+    this.init = this.init.bind(this);
     this.resetScrollbarDebounced = debounce(100, this.resetScrollbar);
+
+    const { layoutType } = this.props.appContainer.config;
+
+    this.defaultRevisionTocTop = DEFAULT_REVISION_TOC_TOP_FOR_GROWI_LAYOUT;
+    if (layoutType === 'kibela') {
+      this.defaultRevisionTocTop = DEFAULT_REVISION_TOC_TOP_FOR_KIBELA_LAYOUT;
+    }
+  }
+
+  componentDidMount() {
+    this.init();
+    this.resetScrollbar();
   }
 
   componentDidUpdate() {
+    this.resetScrollbar();
+  }
+
+  init() {
     const { layoutType } = this.props.appContainer.config;
     if (layoutType === 'crowi') {
       return;
     }
 
-    let defaultRevisionTocTop = DEFAULT_REVISION_TOC_TOP_FOR_GROWI_LAYOUT;
-    if (layoutType === 'kibela') {
-      defaultRevisionTocTop = DEFAULT_REVISION_TOC_TOP_FOR_KIBELA_LAYOUT;
-    }
-
-    // initialize
-    this.resetScrollbar(defaultRevisionTocTop);
-
     /*
      * set event listener
      */
     // resize
     window.addEventListener('resize', (event) => {
-      this.resetScrollbarDebounced(defaultRevisionTocTop);
+      this.resetScrollbarDebounced(this.defaultRevisionTocTop);
+    });
+
+    // sticky
+    // See: https://github.com/ryanwalters/sticky-events
+    const stickyEvents = new StickyEvents({
+      stickySelector: '#revision-toc',
     });
-    // affix on
-    $('#revision-toc').on('affixed.bs.affix', () => {
-      this.resetScrollbar(this.getCurrentRevisionTocTop());
+    const { stickySelector } = stickyEvents;
+    const elem = document.querySelector(stickySelector);
+    elem.addEventListener(StickyEvents.STUCK, (event) => {
+      logger.debug('StickyEvents.STUCK detected');
+      this.resetScrollbar();
     });
-    // affix off
-    $('#revision-toc').on('affixed-top.bs.affix', () => {
-      this.resetScrollbar(defaultRevisionTocTop);
+    elem.addEventListener(StickyEvents.UNSTUCK, (event) => {
+      logger.debug('StickyEvents.UNSTUCK detected');
+      this.resetScrollbar(this.defaultRevisionTocTop);
     });
   }
 
@@ -67,29 +88,31 @@ class TableOfContents extends React.Component {
     return revisionTocElem.getBoundingClientRect().top;
   }
 
-  resetScrollbar(revisionTocTop) {
+  resetScrollbar(defaultRevisionTocTop) {
     const tocContentElem = document.querySelector('.revision-toc .markdownIt-TOC');
 
     if (tocContentElem == null) {
       return;
     }
 
+    const revisionTocTop = defaultRevisionTocTop || this.getCurrentRevisionTocTop();
     // window height - revisionTocTop - .system-version height
     const viewHeight = window.innerHeight - revisionTocTop - 20;
 
     const tocContentHeight = tocContentElem.getBoundingClientRect().height + 15; // add margin
 
+    logger.debug('viewHeight', viewHeight);
+    logger.debug('tocContentHeight', tocContentHeight);
+
     if (viewHeight < tocContentHeight) {
-      // FIXME: GW-1345
-      // $('#revision-toc-content').slimScroll({
-      //   railVisible: true,
-      //   position: 'right',
-      //   height: viewHeight,
-      // });
+      $('#revision-toc-content').slimScroll({
+        railVisible: true,
+        position: 'right',
+        height: viewHeight,
+      });
     }
     else {
-      // FIXME: GW-1345
-      // $('#revision-toc-content').slimScroll({ destroy: true });
+      $('#revision-toc-content').slimScroll({ destroy: true });
     }
   }