瀏覽代碼

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 年之前
父節點
當前提交
aa2869ad6d
共有 1 個檔案被更改,包括 58 行新增4 行删除
  1. 58
    4
      internal/driver/webhtml.go

+ 58
- 4
internal/driver/webhtml.go 查看文件

85
   position: relative;
85
   position: relative;
86
   display: inline-block;
86
   display: inline-block;
87
   padding: 2px 2px;
87
   padding: 2px 2px;
88
-  cursor: default;
89
   font-size: 14pt;
88
   font-size: 14pt;
90
 }
89
 }
91
 .menu {
90
 .menu {
99
   left: 0px;
98
   left: 0px;
100
   min-width: 5em;
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
 .menu hr {
108
 .menu hr {
103
   background-color: #fff;
109
   background-color: #fff;
104
   margin-top: 0px;
110
   margin-top: 0px;
119
 .menu-header:hover {
125
 .menu-header:hover {
120
   background-color: #ccc;
126
   background-color: #ccc;
121
 }
127
 }
122
-.menu-header:hover .menu {
123
-  display: block;
124
-}
125
 .menu a:hover, .menu button:hover {
128
 .menu a:hover, .menu button:hover {
126
   background-color: #ccc;
129
   background-color: #ccc;
127
 }
130
 }
460
   svg.addEventListener("wheel", handleWheel, true)
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
 function viewer(baseUrl, nodes) {
514
 function viewer(baseUrl, nodes) {
464
   'use strict';
515
   'use strict';
465
 
516
 
658
         }
709
         }
659
       }
710
       }
660
       params.set(param, re)
711
       params.set(param, re)
712
+    } else {
713
+      params.delete(param)
661
     }
714
     }
662
 
715
 
663
     return url.toString()
716
     return url.toString()
706
   updateButtons()
759
   updateButtons()
707
 
760
 
708
   // Setup event handlers
761
   // Setup event handlers
762
+  initMenus()
709
   if (svg != null) {
763
   if (svg != null) {
710
     initPanAndZoom(svg, toggleSvgSelect)
764
     initPanAndZoom(svg, toggleSvgSelect)
711
   }
765
   }