Yuki Takei 4 лет назад
Родитель
Сommit
233d1190eb

+ 22 - 22
packages/app/src/client/services/NavigationContainer.js

@@ -129,31 +129,31 @@ export default class NavigationContainer extends Container {
    * Function that implements the click event for realizing smooth scroll
    * @param {array} elements
    */
-  addSmoothScrollEvent(elements = {}) {
-    elements.forEach(link => link.addEventListener('click', (e) => {
-      // modify location.hash without scroll
-      e.preventDefault();
-      window.history.pushState({}, '', link.href);
-
-      // smooth scroll
-      const href = link.getAttribute('href').replace('#', '');
-      const targetDom = document.getElementById(href);
-      this.smoothScrollIntoView(targetDom, WIKI_HEADER_LINK);
-    }));
-  }
+  // addSmoothScrollEvent(elements = {}) {
+  //   elements.forEach(link => link.addEventListener('click', (e) => {
+  //     // modify location.hash without scroll
+  //     e.preventDefault();
+  //     window.history.pushState({}, '', link.href);
+
+  //     // smooth scroll
+  //     const href = link.getAttribute('href').replace('#', '');
+  //     const targetDom = document.getElementById(href);
+  //     this.smoothScrollIntoView(targetDom, WIKI_HEADER_LINK);
+  //   }));
+  // }
 
-  smoothScrollIntoView(element = null, offsetTop = 0) {
-    const targetElement = element || window.document.body;
+  // smoothScrollIntoView(element = null, offsetTop = 0) {
+  //   const targetElement = element || window.document.body;
 
-    // get the distance to the target element top
-    const rectTop = targetElement.getBoundingClientRect().top;
+  //   // get the distance to the target element top
+  //   const rectTop = targetElement.getBoundingClientRect().top;
 
-    const top = window.pageYOffset + rectTop - offsetTop;
+  //   const top = window.pageYOffset + rectTop - offsetTop;
 
-    window.scrollTo({
-      top,
-      behavior: 'smooth',
-    });
-  }
+  //   window.scrollTo({
+  //     top,
+  //     behavior: 'smooth',
+  //   });
+  // }
 
 }

+ 39 - 0
packages/app/src/client/util/smooth-scroll.ts

@@ -0,0 +1,39 @@
+const WIKI_HEADER_LINK = 120;
+
+export const smoothScrollIntoView = (element: HTMLElement, offsetTop = 0): void => {
+  const targetElement = element || window.document.body;
+
+  // get the distance to the target element top
+  const rectTop = targetElement.getBoundingClientRect().top;
+
+  const top = window.pageYOffset + rectTop - offsetTop;
+
+  window.scrollTo({
+    top,
+    behavior: 'smooth',
+  });
+};
+
+export const addSmoothScrollEvent = (elements: HTMLAnchorElement[]): void => {
+  elements.forEach((link) => {
+    const href = link.getAttribute('href');
+
+    if (href == null) {
+      return;
+    }
+
+    link.addEventListener('click', (e) => {
+      e.preventDefault();
+
+      // modify location.hash without scroll
+      window.history.pushState({}, '', link.href);
+
+      // smooth scroll
+      const elemId = href.replace('#', '');
+      const targetDom = document.getElementById(elemId);
+      if (targetDom != null) {
+        smoothScrollIntoView(targetDom, WIKI_HEADER_LINK);
+      }
+    });
+  });
+};

+ 6 - 7
packages/app/src/components/ContentLinkButtons.jsx

@@ -3,12 +3,12 @@ import PropTypes from 'prop-types';
 
 import { pagePathUtils } from '@growi/core';
 import AppContainer from '~/client/services/AppContainer';
-import NavigationContainer from '~/client/services/NavigationContainer';
 import PageContainer from '~/client/services/PageContainer';
 
 import { withUnstatedContainers } from './UnstatedUtils';
 
 import RecentlyCreatedIcon from './Icons/RecentlyCreatedIcon';
+import { smoothScrollIntoView } from '~/client/util/smooth-scroll';
 
 const { isTopPage } = pagePathUtils;
 
@@ -20,7 +20,7 @@ const WIKI_HEADER_LINK = 120;
  */
 const ContentLinkButtons = (props) => {
 
-  const { appContainer, navigationContainer, pageContainer } = props;
+  const { appContainer, pageContainer } = props;
   const { pageUser, path } = pageContainer.state;
   const { isPageExist } = pageContainer.state;
   const { isSharedUser } = appContainer;
@@ -39,7 +39,7 @@ const ContentLinkButtons = (props) => {
         <button
           type="button"
           className="btn btn-outline-secondary btn-sm btn-block"
-          onClick={() => navigationContainer.smoothScrollIntoView(getCommentListDom, WIKI_HEADER_LINK)}
+          onClick={() => smoothScrollIntoView(getCommentListDom, WIKI_HEADER_LINK)}
         >
           <i className="mr-2 icon-fw icon-bubbles"></i>
           <span>Comments</span>
@@ -53,7 +53,7 @@ const ContentLinkButtons = (props) => {
       <button
         type="button"
         className="btn btn-outline-secondary btn-sm px-2"
-        onClick={() => navigationContainer.smoothScrollIntoView(getBookMarkListHeaderDom, WIKI_HEADER_LINK)}
+        onClick={() => smoothScrollIntoView(getBookMarkListHeaderDom, WIKI_HEADER_LINK)}
       >
         <i className="mr-2 icon-star"></i>
         <span>Bookmarks</span>
@@ -67,7 +67,7 @@ const ContentLinkButtons = (props) => {
       <button
         type="button"
         className="btn btn-outline-secondary btn-sm px-3"
-        onClick={() => navigationContainer.smoothScrollIntoView(getRecentlyCreatedListHeaderDom, WIKI_HEADER_LINK)}
+        onClick={() => smoothScrollIntoView(getRecentlyCreatedListHeaderDom, WIKI_HEADER_LINK)}
       >
         <i className="grw-icon-container-recently-created mr-2"><RecentlyCreatedIcon /></i>
         <span>Recently Created</span>
@@ -90,8 +90,7 @@ const ContentLinkButtons = (props) => {
 
 ContentLinkButtons.propTypes = {
   appContainer: PropTypes.instanceOf(AppContainer).isRequired,
-  navigationContainer: PropTypes.instanceOf(NavigationContainer).isRequired,
   pageContainer: PropTypes.instanceOf(PageContainer).isRequired,
 };
 
-export default withUnstatedContainers(ContentLinkButtons, [AppContainer, NavigationContainer, PageContainer]);
+export default withUnstatedContainers(ContentLinkButtons, [AppContainer, PageContainer]);

+ 4 - 5
packages/app/src/components/Fab.jsx

@@ -5,7 +5,7 @@ import loggerFactory from '~/utils/logger';
 
 
 import AppContainer from '~/client/services/AppContainer';
-import NavigationContainer from '~/client/services/NavigationContainer';
+import { smoothScrollIntoView } from '~/client/util/smooth-scroll';
 import { usePageCreateModalOpened } from '~/stores/ui';
 
 import { withUnstatedContainers } from './UnstatedUtils';
@@ -15,7 +15,7 @@ import ReturnTopIcon from './Icons/ReturnTopIcon';
 const logger = loggerFactory('growi:cli:Fab');
 
 const Fab = (props) => {
-  const { navigationContainer, appContainer } = props;
+  const { appContainer } = props;
   const { currentUser } = appContainer;
 
   const { mutate: mutatePageCreateModalOpened } = usePageCreateModalOpened();
@@ -72,7 +72,7 @@ const Fab = (props) => {
         <button
           type="button"
           className={`btn btn-light btn-scroll-to-top rounded-circle p-0 ${buttonClasses}`}
-          onClick={() => navigationContainer.smoothScrollIntoView()}
+          onClick={() => smoothScrollIntoView()}
         >
           <ReturnTopIcon />
         </button>
@@ -84,7 +84,6 @@ const Fab = (props) => {
 
 Fab.propTypes = {
   appContainer: PropTypes.instanceOf(AppContainer).isRequired,
-  navigationContainer: PropTypes.instanceOf(NavigationContainer).isRequired,
 };
 
-export default withUnstatedContainers(Fab, [AppContainer, NavigationContainer]);
+export default withUnstatedContainers(Fab, [AppContainer]);

+ 4 - 5
packages/app/src/components/Page/RevisionRenderer.jsx

@@ -3,8 +3,8 @@ import PropTypes from 'prop-types';
 
 import { withUnstatedContainers } from '../UnstatedUtils';
 import AppContainer from '~/client/services/AppContainer';
-import NavigationContainer from '~/client/services/NavigationContainer';
 import GrowiRenderer from '~/client/util/GrowiRenderer';
+import { addSmoothScrollEvent } from '~/client/util/smooth-scroll';
 
 import RevisionBody from './RevisionBody';
 
@@ -35,7 +35,7 @@ class LegacyRevisionRenderer extends React.PureComponent {
 
   componentDidUpdate(prevProps) {
     const { markdown: prevMarkdown, highlightKeywords: prevHighlightKeywords } = prevProps;
-    const { markdown, highlightKeywords, navigationContainer } = this.props;
+    const { markdown, highlightKeywords } = this.props;
 
     // render only when props.markdown is updated
     if (markdown !== prevMarkdown || highlightKeywords !== prevHighlightKeywords) {
@@ -46,7 +46,7 @@ class LegacyRevisionRenderer extends React.PureComponent {
 
     const HeaderLink = document.getElementsByClassName('revision-head-link');
     const HeaderLinkArray = Array.from(HeaderLink);
-    navigationContainer.addSmoothScrollEvent(HeaderLinkArray);
+    addSmoothScrollEvent(HeaderLinkArray);
 
     const { interceptorManager } = this.props.appContainer;
 
@@ -119,7 +119,6 @@ class LegacyRevisionRenderer extends React.PureComponent {
 
 LegacyRevisionRenderer.propTypes = {
   appContainer: PropTypes.instanceOf(AppContainer).isRequired,
-  navigationContainer: PropTypes.instanceOf(NavigationContainer).isRequired,
   growiRenderer: PropTypes.instanceOf(GrowiRenderer).isRequired,
   markdown: PropTypes.string.isRequired,
   highlightKeywords: PropTypes.string,
@@ -129,7 +128,7 @@ LegacyRevisionRenderer.propTypes = {
 /**
  * Wrapper component for using unstated
  */
-const LegacyRevisionRendererWrapper = withUnstatedContainers(LegacyRevisionRenderer, [AppContainer, NavigationContainer]);
+const LegacyRevisionRendererWrapper = withUnstatedContainers(LegacyRevisionRenderer, [AppContainer]);
 
 
 // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types

+ 5 - 6
packages/app/src/components/TableOfContents.jsx

@@ -5,7 +5,7 @@ import loggerFactory from '~/utils/logger';
 
 
 import PageContainer from '~/client/services/PageContainer';
-import NavigationContainer from '~/client/services/NavigationContainer';
+import { addSmoothScrollEvent } from '~/client/util/smooth-scroll';
 
 import { withUnstatedContainers } from './UnstatedUtils';
 
@@ -20,7 +20,7 @@ const logger = loggerFactory('growi:TableOfContents');
  */
 const TableOfContents = (props) => {
 
-  const { t, pageContainer, navigationContainer } = props;
+  const { t, pageContainer } = props;
   const { pageUser } = pageContainer.state;
   const isUserPage = pageUser != null;
 
@@ -50,8 +50,8 @@ const TableOfContents = (props) => {
   useEffect(() => {
     const tocDom = document.getElementById('revision-toc-content');
     const anchorsInToc = Array.from(tocDom.getElementsByTagName('a'));
-    navigationContainer.addSmoothScrollEvent(anchorsInToc);
-  }, [tocHtml, navigationContainer]);
+    addSmoothScrollEvent(anchorsInToc);
+  }, [tocHtml]);
 
   return (
     <StickyStretchableScroller
@@ -85,13 +85,12 @@ const TableOfContents = (props) => {
 /**
  * Wrapper component for using unstated
  */
-const TableOfContentsWrapper = withUnstatedContainers(TableOfContents, [PageContainer, NavigationContainer]);
+const TableOfContentsWrapper = withUnstatedContainers(TableOfContents, [PageContainer]);
 
 TableOfContents.propTypes = {
   t: PropTypes.func.isRequired, // i18next
 
   pageContainer: PropTypes.instanceOf(PageContainer).isRequired,
-  navigationContainer: PropTypes.instanceOf(NavigationContainer).isRequired,
 };
 
 export default withTranslation()(TableOfContentsWrapper);