Sfoglia il codice sorgente

Show menu on click, not hover. (#243)

* Show menu on click, not hover.

Previously, users had to be careful to not move the mouse
outside the menu (otherwise it would disappear unintentionally).

Also fixed a minor bug where we were not overwriting URL
parameters correctly when no selection was made.

* Use vendor prefixes for user-select.
Sanjay Ghemawat 7 anni fa
parent
commit
aa2869ad6d
1 ha cambiato i file con 58 aggiunte e 4 eliminazioni
  1. 58
    4
      internal/driver/webhtml.go

+ 58
- 4
internal/driver/webhtml.go Vedi File

@@ -85,7 +85,6 @@ button {
85 85
   position: relative;
86 86
   display: inline-block;
87 87
   padding: 2px 2px;
88
-  cursor: default;
89 88
   font-size: 14pt;
90 89
 }
91 90
 .menu {
@@ -99,6 +98,13 @@ button {
99 98
   left: 0px;
100 99
   min-width: 5em;
101 100
 }
101
+.menu-header, .menu {
102
+  cursor: default;
103
+  user-select: none;
104
+  -moz-user-select: none;
105
+  -ms-user-select: none;
106
+  -webkit-user-select: none;
107
+}
102 108
 .menu hr {
103 109
   background-color: #fff;
104 110
   margin-top: 0px;
@@ -119,9 +125,6 @@ button {
119 125
 .menu-header:hover {
120 126
   background-color: #ccc;
121 127
 }
122
-.menu-header:hover .menu {
123
-  display: block;
124
-}
125 128
 .menu a:hover, .menu button:hover {
126 129
   background-color: #ccc;
127 130
 }
@@ -460,6 +463,54 @@ function initPanAndZoom(svg, clickHandler) {
460 463
   svg.addEventListener("wheel", handleWheel, true)
461 464
 }
462 465
 
466
+function initMenus() {
467
+  'use strict';
468
+
469
+  let activeMenu = null;
470
+  let activeMenuHdr = null;
471
+
472
+  function cancelActiveMenu() {
473
+    if (activeMenu == null) return;
474
+    activeMenu.style.display = "none";
475
+    activeMenu = null;
476
+    activeMenuHdr = null;
477
+  }
478
+
479
+  // Set click handlers on every menu header.
480
+  for (const menu of document.getElementsByClassName("menu")) {
481
+    const hdr = menu.parentElement;
482
+    if (hdr == null) return;
483
+    function showMenu(e) {
484
+      // menu is a child of hdr, so this event can fire for clicks
485
+      // inside menu. Ignore such clicks.
486
+      if (e.target != hdr) return;
487
+      activeMenu = menu;
488
+      activeMenuHdr = hdr;
489
+      menu.style.display = "block";
490
+    }
491
+    hdr.addEventListener("mousedown", showMenu);
492
+    hdr.addEventListener("touchstart", showMenu);
493
+  }
494
+
495
+  // If there is an active menu and a down event outside, retract the menu.
496
+  for (const t of ["mousedown", "touchstart"]) {
497
+    document.addEventListener(t, (e) => {
498
+      // Note: to avoid unnecessary flicker, if the down event is inside
499
+      // the active menu header, do not retract the menu.
500
+      if (activeMenuHdr != e.target.closest(".menu-header")) {
501
+        cancelActiveMenu();
502
+      }
503
+    }, { passive: true, capture: true });
504
+  }
505
+
506
+  // If there is an active menu and an up event inside, retract the menu.
507
+  document.addEventListener("mouseup", (e) => {
508
+    if (activeMenu == e.target.closest(".menu")) {
509
+      cancelActiveMenu();
510
+    }
511
+  }, { passive: true, capture: true });
512
+}
513
+
463 514
 function viewer(baseUrl, nodes) {
464 515
   'use strict';
465 516
 
@@ -658,6 +709,8 @@ function viewer(baseUrl, nodes) {
658 709
         }
659 710
       }
660 711
       params.set(param, re)
712
+    } else {
713
+      params.delete(param)
661 714
     }
662 715
 
663 716
     return url.toString()
@@ -706,6 +759,7 @@ function viewer(baseUrl, nodes) {
706 759
   updateButtons()
707 760
 
708 761
   // Setup event handlers
762
+  initMenus()
709 763
   if (svg != null) {
710 764
     initPanAndZoom(svg, toggleSvgSelect)
711 765
   }