浏览代码

Change menu buttons to links. (#219)

* Change menu buttons to links.

This allows right-click/middle-click etc. to work properly.

* Clean up javascript in response to review comments.

Also fix error in handling of Enter key.

* Simplify regular expression construction from selection.
Sanjay Ghemawat 7 年前
父节点
当前提交
b101f53cc1
共有 1 个文件被更改,包括 65 次插入55 次删除
  1. 65
    55
      internal/driver/webhtml.go

+ 65
- 55
internal/driver/webhtml.go 查看文件

104
   margin-top: 0px;
104
   margin-top: 0px;
105
   margin-bottom: 0px;
105
   margin-bottom: 0px;
106
 }
106
 }
107
-.menu button {
107
+.menu a, .menu button {
108
   display: block;
108
   display: block;
109
   width: 100%;
109
   width: 100%;
110
   margin: 0px;
110
   margin: 0px;
111
+  padding: 2px 0px 2px 0px;
111
   text-align: left;
112
   text-align: left;
112
-  padding-left: 2px;
113
-  background-color: #fff;
113
+  text-decoration: none;
114
+  color: #000;
115
+  background-color: #f8f8f8;
114
   font-size: 12pt;
116
   font-size: 12pt;
115
   border: none;
117
   border: none;
116
 }
118
 }
120
 .menu-header:hover .menu {
122
 .menu-header:hover .menu {
121
   display: block;
123
   display: block;
122
 }
124
 }
123
-.menu button:hover {
125
+.menu a:hover, .menu button:hover {
124
   background-color: #ccc;
126
   background-color: #ccc;
125
 }
127
 }
128
+.menu a.disabled {
129
+  color: gray;
130
+  pointer-events: none;
131
+}
126
 #searchbox {
132
 #searchbox {
127
   margin-left: 10pt;
133
   margin-left: 10pt;
128
 }
134
 }
174
 <div class="menu-header">
180
 <div class="menu-header">
175
 View
181
 View
176
 <div class="menu">
182
 <div class="menu">
177
-<button title="{{.Help.top}}" id="topbtn">Top</button>
178
-<button title="{{.Help.graph}}" id="graphbtn">Graph</button>
179
-<button title="{{.Help.peek}}" id="peek">Peek</button>
180
-<button title="{{.Help.list}}" id="list">Source</button>
181
-<button title="{{.Help.disasm}}" id="disasm">Disassemble</button>
183
+<a title="{{.Help.top}}"  href="/top" id="topbtn">Top</a>
184
+<a title="{{.Help.graph}}" href="/" id="graphbtn">Graph</a>
185
+<a title="{{.Help.peek}}" href="/peek" id="peek">Peek</a>
186
+<a title="{{.Help.list}}" href="/source" id="list">Source</a>
187
+<a title="{{.Help.disasm}}" href="/disasm" id="disasm">Disassemble</a>
182
 <hr>
188
 <hr>
183
 <button title="{{.Help.details}}" id="details">Details</button>
189
 <button title="{{.Help.details}}" id="details">Details</button>
184
 </div>
190
 </div>
187
 <div class="menu-header">
193
 <div class="menu-header">
188
 Refine
194
 Refine
189
 <div class="menu">
195
 <div class="menu">
190
-<button title="{{.Help.focus}}" id="focus">Focus</button>
191
-<button title="{{.Help.ignore}}" id="ignore">Ignore</button>
192
-<button title="{{.Help.hide}}" id="hide">Hide</button>
193
-<button title="{{.Help.show}}" id="show">Show</button>
196
+<a title="{{.Help.focus}}" href="{{.BaseURL}}" id="focus">Focus</a>
197
+<a title="{{.Help.ignore}}" href="{{.BaseURL}}" id="ignore">Ignore</a>
198
+<a title="{{.Help.hide}}" href="{{.BaseURL}}" id="hide">Hide</a>
199
+<a title="{{.Help.show}}" href="{{.BaseURL}}" id="show">Show</a>
194
 <hr>
200
 <hr>
195
-<button title="{{.Help.reset}}" id="reset">Reset</button>
201
+<a title="{{.Help.reset}}" href="{{.BaseURL}}">Reset</a>
196
 </div>
202
 </div>
197
 </div>
203
 </div>
198
 
204
 
471
     if (detailsText != null) detailsText.style.display = "none"
477
     if (detailsText != null) detailsText.style.display = "none"
472
   }
478
   }
473
 
479
 
474
-  function handleReset() { window.location.href = baseUrl }
475
-  function handleTop() { navigate("/top", "f") }
476
-  function handleGraph() { navigate("/", "f") }
477
-  function handleList() { navigate("/source", "f") }
478
-  function handleDisasm() { navigate("/disasm", "f") }
479
-  function handlePeek() { navigate("/peek", "f") }
480
-  function handleFocus() { navigate(baseUrl, "f") }
481
-  function handleShow() { navigate(baseUrl, "s") }
482
-  function handleIgnore() { navigate(baseUrl, "i") }
483
-  function handleHide() { navigate(baseUrl, "h") }
484
-
485
   function handleKey(e) {
480
   function handleKey(e) {
486
     if (e.keyCode != 13) return
481
     if (e.keyCode != 13) return
487
-    handleFocus()
482
+    window.location.href =
483
+        updateUrl(new URL({{.BaseURL}}, window.location.href), "f")
488
     e.preventDefault()
484
     e.preventDefault()
489
   }
485
   }
490
 
486
 
607
     return str.replace(/([\\\.?+*\[\](){}|^$])/g, '\\$1')
603
     return str.replace(/([\\\.?+*\[\](){}|^$])/g, '\\$1')
608
   }
604
   }
609
 
605
 
610
-  // Navigate to specified path with current selection reflected
611
-  // in the named parameter.
612
-  function navigate(path, param) {
613
-    // The selection can be in one of two modes: regexp-based or
614
-    // list-based.  Construct regular expression depending on mode.
615
-    let re = regexpActive ? search.value : ""
616
-    if (!regexpActive) {
617
-      selected.forEach(function(v, key) {
618
-        if (re != "") re += "|"
619
-        re += quotemeta(nodes[key])
620
-      })
606
+  // Update id's href to reflect current selection whenever it is
607
+  // liable to be followed.
608
+  function makeLinkDynamic(id) {
609
+    const elem = document.getElementById(id)
610
+    if (elem == null) return
611
+
612
+    // Most links copy current selection into the "f" parameter,
613
+    // but Refine menu links are different.
614
+    let param = "f"
615
+    if (id == "ignore") param = "i"
616
+    if (id == "hide") param = "h"
617
+    if (id == "show") param = "s"
618
+
619
+    // We update on mouseenter so middle-click/right-click work properly.
620
+    elem.addEventListener("mouseenter", updater)
621
+    elem.addEventListener("touchstart", updater)
622
+
623
+    function updater() {
624
+      elem.href = updateUrl(new URL(elem.href), param)
621
     }
625
     }
626
+  }
622
 
627
 
623
-    const url = new URL(window.location.href)
624
-    url.pathname = path
628
+  // Update URL to reflect current selection.
629
+  function updateUrl(url, param) {
625
     url.hash = ""
630
     url.hash = ""
626
 
631
 
632
+    // The selection can be in one of two modes: regexp-based or
633
+    // list-based.  Construct regular expression depending on mode.
634
+    let re = regexpActive
635
+        ? search.value
636
+        : Array.from(selected.keys()).map(key => quotemeta(nodes[key])).join("|")
637
+
638
+    // Copy params from this page's URL.
639
+    const params = url.searchParams
640
+    for (const p of new URLSearchParams(window.location.search)) {
641
+      params.set(p[0], p[1])
642
+    }
643
+
627
     if (re != "") {
644
     if (re != "") {
628
       // For focus/show, forget old parameter.  For others, add to re.
645
       // For focus/show, forget old parameter.  For others, add to re.
629
-      const params = url.searchParams
630
       if (param != "f" && param != "s" && params.has(param)) {
646
       if (param != "f" && param != "s" && params.has(param)) {
631
         const old = params.get(param)
647
         const old = params.get(param)
632
-        if (old != "") {
648
+         if (old != "") {
633
           re += "|" + old
649
           re += "|" + old
634
         }
650
         }
635
       }
651
       }
636
       params.set(param, re)
652
       params.set(param, re)
637
     }
653
     }
638
 
654
 
639
-    window.location.href = url.toString()
655
+    return url.toString()
640
   }
656
   }
641
 
657
 
642
   function handleTopClick(e) {
658
   function handleTopClick(e) {
671
     if (buttonsEnabled == enable) return
687
     if (buttonsEnabled == enable) return
672
     buttonsEnabled = enable
688
     buttonsEnabled = enable
673
     for (const id of ["focus", "ignore", "hide", "show"]) {
689
     for (const id of ["focus", "ignore", "hide", "show"]) {
674
-      const btn = document.getElementById(id)
675
-      if (btn != null) {
676
-        btn.disabled = !enable
690
+      const link = document.getElementById(id)
691
+      if (link != null) {
692
+        link.classList.toggle("disabled", !enable)
677
       }
693
       }
678
     }
694
     }
679
   }
695
   }
690
     toptable.addEventListener("touchstart", handleTopClick)
706
     toptable.addEventListener("touchstart", handleTopClick)
691
   }
707
   }
692
 
708
 
709
+  const ids = ["topbtn", "graphbtn", "peek", "list", "disasm",
710
+               "focus", "ignore", "hide", "show"]
711
+  ids.forEach(makeLinkDynamic)
712
+
693
   // Bind action to button with specified id.
713
   // Bind action to button with specified id.
694
   function addAction(id, action) {
714
   function addAction(id, action) {
695
     const btn = document.getElementById(id)
715
     const btn = document.getElementById(id)
701
 
721
 
702
   addAction("details", handleDetails)
722
   addAction("details", handleDetails)
703
   addAction("closedetails", handleCloseDetails)
723
   addAction("closedetails", handleCloseDetails)
704
-  addAction("topbtn", handleTop)
705
-  addAction("graphbtn", handleGraph)
706
-  addAction("reset", handleReset)
707
-  addAction("peek", handlePeek)
708
-  addAction("list", handleList)
709
-  addAction("disasm", handleDisasm)
710
-  addAction("focus", handleFocus)
711
-  addAction("ignore", handleIgnore)
712
-  addAction("hide", handleHide)
713
-  addAction("show", handleShow)
714
 
724
 
715
   search.addEventListener("input", handleSearch)
725
   search.addEventListener("input", handleSearch)
716
   search.addEventListener("keydown", handleKey)
726
   search.addEventListener("keydown", handleKey)