bug: stop scrolling page when moving through search results
authorxangelo <git@xangelo.ca>
Wed, 25 Jan 2023 18:43:20 +0000 (13:43 -0500)
committerxangelo <git@xangelo.ca>
Wed, 25 Jan 2023 18:47:33 +0000 (13:47 -0500)
Disable scrolling the page when moving through search results. Will
auto-focus on result if it is off screen.

public/assets/bundle.js
src/cursor.ts
src/dom.ts [new file with mode: 0644]
src/search.ts

index 0a39e1d968874cc047f453eeb1b8289a5e6528a8..ae072e4fac40d3a45b5f7e0df776b525a3615939 100644 (file)
@@ -18624,12 +18624,13 @@ save();
 /*!***********************!*\
   !*** ./src/cursor.ts ***!
   \***********************/
-/***/ ((__unused_webpack_module, exports) => {
+/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
 
 "use strict";
 
 Object.defineProperty(exports, "__esModule", ({ value: true }));
 exports.Cursor = void 0;
+const dom_1 = __webpack_require__(/*! dom */ "./src/dom.ts");
 class Cursor {
     constructor() {
     }
@@ -18650,7 +18651,7 @@ class Cursor {
         const el = document.querySelector(elementId);
         if (el) {
             el.classList.add('cursor');
-            if (!this.isVisible(elementId)) {
+            if (!(0, dom_1.isVisible)(el)) {
                 el.scrollIntoView(true);
             }
         }
@@ -18669,18 +18670,32 @@ class Cursor {
     isNodeExpanded() {
         return this.get().classList.contains('expanded');
     }
-    isVisible(elementId) {
-        const el = document.querySelector(elementId);
-        var rect = el.getBoundingClientRect();
-        return (rect.top >= 0 &&
-            rect.left >= 0 &&
-            rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
-            rect.right <= (window.innerWidth || document.documentElement.clientWidth));
-    }
 }
 exports.Cursor = Cursor;
 
 
+/***/ }),
+
+/***/ "./src/dom.ts":
+/*!********************!*\
+  !*** ./src/dom.ts ***!
+  \********************/
+/***/ ((__unused_webpack_module, exports) => {
+
+"use strict";
+
+Object.defineProperty(exports, "__esModule", ({ value: true }));
+exports.isVisible = void 0;
+function isVisible(element) {
+    const rect = element.getBoundingClientRect();
+    return (rect.top >= 0 &&
+        rect.left >= 0 &&
+        rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
+        rect.right <= (window.innerWidth || document.documentElement.clientWidth));
+}
+exports.isVisible = isVisible;
+
+
 /***/ }),
 
 /***/ "./src/help.ts":
@@ -19058,6 +19073,7 @@ exports.Search = void 0;
 const lyra_1 = __webpack_require__(/*! @lyrasearch/lyra */ "./node_modules/@lyrasearch/lyra/dist/cjs/index.cjs");
 const lodash_1 = __webpack_require__(/*! lodash */ "./node_modules/lodash/lodash.js");
 const keyboardjs_1 = __importDefault(__webpack_require__(/*! keyboardjs */ "./node_modules/keyboardjs/dist/keyboard.js"));
+const dom_1 = __webpack_require__(/*! dom */ "./src/dom.ts");
 const searchModal = `
 <div class="modal">
 <div class="modal-content" id="search">
@@ -19086,18 +19102,26 @@ class Search {
                 keyboardjs_1.default.setContext('navigation');
             });
             keyboardjs_1.default.bind('down', e => {
+                e.preventDefault();
                 document.getElementById('search-query').blur();
                 const el = document.querySelector('.search-result.selected');
                 if (el.nextElementSibling) {
                     el.classList.remove('selected');
                     el.nextElementSibling.classList.add('selected');
+                    if (!(0, dom_1.isVisible)(el.nextElementSibling)) {
+                        el.nextElementSibling.scrollIntoView();
+                    }
                 }
             });
-            keyboardjs_1.default.bind('up', () => {
+            keyboardjs_1.default.bind('up', e => {
+                e.preventDefault();
                 const el = document.querySelector('.search-result.selected');
                 if (el.previousElementSibling) {
                     el.classList.remove('selected');
                     el.previousElementSibling.classList.add('selected');
+                    if (!(0, dom_1.isVisible)(el.previousElementSibling)) {
+                        el.previousElementSibling.scrollIntoView();
+                    }
                 }
             });
             keyboardjs_1.default.bind('enter', e => {
index 4dc7cc704723b9546d5a13cc46928f02644f1a49..cd44b6d69539a691ef419ac84245c752c081cf1c 100644 (file)
@@ -1,3 +1,5 @@
+import {isVisible} from "dom";
+
 export class Cursor {
   constructor() {
 
@@ -20,11 +22,11 @@ export class Cursor {
 
   set(elementId: string) {
     this.unset();
-    const el = document.querySelector(elementId);
+    const el = document.querySelector(elementId) as HTMLElement;
 
     if(el) {
       el.classList.add('cursor');
-      if(!this.isVisible(elementId)) {
+      if(!isVisible(el)) {
         el.scrollIntoView(true);
       }
     }
@@ -47,15 +49,4 @@ export class Cursor {
   isNodeExpanded(): boolean {
     return this.get().classList.contains('expanded');
   }
-
-  isVisible(elementId: string) {
-    const el = document.querySelector(elementId) as HTMLElement;
-    var rect = el.getBoundingClientRect();
-    return (
-        rect.top >= 0 &&
-        rect.left >= 0 &&
-        rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&     
-        rect.right <= (window.innerWidth || document.documentElement.clientWidth)
-    );
-  }
 }
diff --git a/src/dom.ts b/src/dom.ts
new file mode 100644 (file)
index 0000000..481c5ed
--- /dev/null
@@ -0,0 +1,9 @@
+export function isVisible(element: HTMLElement): boolean {
+    const rect = element.getBoundingClientRect();
+    return (
+        rect.top >= 0 &&
+        rect.left >= 0 &&
+        rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&     
+        rect.right <= (window.innerWidth || document.documentElement.clientWidth)
+    );
+}
index 9bbff3c92fb3414de3bbe43db690294064abb011..0329c2f408a9c52016c6f05b7f36df362ea71a3a 100644 (file)
@@ -2,6 +2,7 @@ import { create, insert, insertBatch, search } from '@lyrasearch/lyra';
 import { map } from 'lodash';
 import { OutlineNode } from 'outline';
 import keyboardJS from 'keyboardjs';
+import {isVisible} from 'dom';
 
 const searchModal = `
 <div class="modal">
@@ -38,19 +39,27 @@ export class Search {
       });
 
       keyboardJS.bind('down', e => {
+        e.preventDefault();
         document.getElementById('search-query').blur();
         const el = document.querySelector('.search-result.selected');
         if(el.nextElementSibling) {
           el.classList.remove('selected');
           el.nextElementSibling.classList.add('selected');
+          if(!isVisible(el.nextElementSibling as HTMLElement)) {
+            el.nextElementSibling.scrollIntoView();
+          }
         }
       });
 
-      keyboardJS.bind('up', () => {
+      keyboardJS.bind('up', e => {
+        e.preventDefault();
         const el = document.querySelector('.search-result.selected');
         if(el.previousElementSibling) {
           el.classList.remove('selected');
           el.previousElementSibling.classList.add('selected');
+          if(!isVisible(el.previousElementSibling as HTMLElement)) {
+            el.previousElementSibling.scrollIntoView();
+          }
         }
       })