]> BookStack Code Mirror - bookstack/blobdiff - resources/assets/js/components/tri-layout.js
Update errors.php
[bookstack] / resources / assets / js / components / tri-layout.js
index d18d37d60318f606841057ec9f502825825e7ed6..905ca03b1020d566859366d6e2ecc8e851edc784 100644 (file)
@@ -3,18 +3,23 @@ class TriLayout {
 
     constructor(elem) {
         this.elem = elem;
-        this.middle = elem.querySelector('.tri-layout-middle');
-        this.right = elem.querySelector('.tri-layout-right');
-        this.left = elem.querySelector('.tri-layout-left');
 
         this.lastLayoutType = 'none';
         this.onDestroy = null;
+        this.scrollCache = {
+            'content': 0,
+            'info': 0,
+        };
+        this.lastTabShown = 'content';
 
+        // Bind any listeners
+        this.mobileTabClick = this.mobileTabClick.bind(this);
 
+        // Watch layout changes
         this.updateLayout();
         window.addEventListener('resize', event => {
             this.updateLayout();
-        });
+        }, {passive: true});
     }
 
     updateLayout() {
@@ -38,16 +43,15 @@ class TriLayout {
     }
 
     setupMobile() {
-        const mobileSidebarClickBound = this.mobileSidebarClick.bind(this);
-        const mobileContentClickBound = this.mobileContentClick.bind(this);
-        this.left.addEventListener('click', mobileSidebarClickBound);
-        this.right.addEventListener('click', mobileSidebarClickBound);
-        this.middle.addEventListener('click', mobileContentClickBound);
+        const layoutTabs = document.querySelectorAll('[tri-layout-mobile-tab]');
+        for (let tab of layoutTabs) {
+            tab.addEventListener('click', this.mobileTabClick);
+        }
 
         this.onDestroy = () => {
-            this.left.removeEventListener('click', mobileSidebarClickBound);
-            this.right.removeEventListener('click', mobileSidebarClickBound);
-            this.middle.removeEventListener('click', mobileContentClickBound);
+            for (let tab of layoutTabs) {
+                tab.removeEventListener('click', this.mobileTabClick);
+            }
         }
     }
 
@@ -55,27 +59,53 @@ class TriLayout {
         //
     }
 
+
     /**
-     * Slide the main content back into view if clicked and
-     * currently slid out of view.
+     * Action to run when the mobile info toggle bar is clicked/tapped
      * @param event
      */
-    mobileContentClick(event) {
-        this.elem.classList.remove('mobile-open');
+    mobileTabClick(event) {
+        const tab = event.target.getAttribute('tri-layout-mobile-tab');
+        this.showTab(tab);
     }
 
     /**
-     * On sidebar click, Show the content by sliding the main content out.
-     * @param event
+     * Show the content tab.
+     * Used by the page-display component.
+     */
+    showContent() {
+        this.showTab('content', false);
+    }
+
+    /**
+     * Show the given tab
+     * @param tabName
      */
-    mobileSidebarClick(event) {
-        if (this.elem.classList.contains('mobile-open')) {
-            this.elem.classList.remove('mobile-open');
-        } else {
-            event.preventDefault();
-            event.stopPropagation();
-            this.elem.classList.add('mobile-open');
+    showTab(tabName, scroll = true) {
+        this.scrollCache[this.lastTabShown] = document.documentElement.scrollTop;
+
+        // Set tab status
+        const tabs = document.querySelectorAll('.tri-layout-mobile-tab');
+        for (let tab of tabs) {
+            const isActive = (tab.getAttribute('tri-layout-mobile-tab') === tabName);
+            tab.classList.toggle('active', isActive);
         }
+
+        // Toggle section
+        const showInfo = (tabName === 'info');
+        this.elem.classList.toggle('show-info', showInfo);
+
+        // Set the scroll position from cache
+        if (scroll) {
+            const pageHeader = document.querySelector('header');
+            const defaultScrollTop = pageHeader.getBoundingClientRect().bottom;
+            document.documentElement.scrollTop = this.scrollCache[tabName] || defaultScrollTop;
+            setTimeout(() => {
+                document.documentElement.scrollTop = this.scrollCache[tabName] || defaultScrollTop;
+            }, 50);
+        }
+
+        this.lastTabShown = tabName;
     }
 
 }