Explorar el Código

Add sample index selector to web ui (#414)

This is a follow up change to #412 which adds a selector to the web
ui for selecting the sample index of a profile to view. The selector
is hidden for profiles with only a single sample type.
Nathan VanBenschoten hace 6 años
padre
commit
d723c7237b
Se han modificado 2 ficheros con 66 adiciones y 34 borrados
  1. 54
    24
      internal/driver/webhtml.go
  2. 12
    10
      internal/driver/webui.go

+ 54
- 24
internal/driver/webhtml.go Ver fichero

@@ -249,6 +249,21 @@ table tr td {
249 249
     </div>
250 250
   </div>
251 251
 
252
+  {{$sampleLen := len .SampleTypes}}
253
+  {{if gt $sampleLen 1}}
254
+  <div id="sample" class="menu-item">
255
+    <div class="menu-name">
256
+      Sample
257
+      <i class="downArrow"></i>
258
+    </div>
259
+    <div class="submenu">
260
+      {{range .SampleTypes}}
261
+      <a href="?si={{.}}" id="{{.}}">{{.}}</a>
262
+      {{end}}
263
+    </div>
264
+  </div>
265
+  {{end}}
266
+
252 267
   <div id="refine" class="menu-item">
253 268
     <div class="menu-name">
254 269
       Refine
@@ -718,9 +733,18 @@ function viewer(baseUrl, nodes) {
718 733
     return str.replace(/([\\\.?+*\[\](){}|^$])/g, '\\$1');
719 734
   }
720 735
 
736
+  function setSampleIndexLink(id) {
737
+    const elem = document.getElementById(id);
738
+    if (elem != null) {
739
+      setHrefParams(elem, function (params) {
740
+        params.set("si", id);
741
+      });
742
+    }
743
+  }
744
+
721 745
   // Update id's href to reflect current selection whenever it is
722 746
   // liable to be followed.
723
-  function makeLinkDynamic(id) {
747
+  function makeSearchLinkDynamic(id) {
724 748
     const elem = document.getElementById(id);
725 749
     if (elem == null) return;
726 750
 
@@ -736,40 +760,43 @@ function viewer(baseUrl, nodes) {
736 760
     elem.addEventListener('touchstart', updater);
737 761
 
738 762
     function updater() {
739
-      elem.href = updateUrl(new URL(elem.href), param);
763
+      // The selection can be in one of two modes: regexp-based or
764
+      // list-based.  Construct regular expression depending on mode.
765
+      let re = regexpActive
766
+        ? search.value
767
+        : Array.from(selected.keys()).map(key => quotemeta(nodes[key])).join('|');
768
+
769
+      setHrefParams(elem, function (params) {
770
+        if (re != '') {
771
+          // For focus/show, forget old parameter.  For others, add to re.
772
+          if (param != 'f' && param != 's' && params.has(param)) {
773
+            const old = params.get(param);
774
+            if (old != '') {
775
+              re += '|' + old;
776
+            }
777
+          }
778
+          params.set(param, re);
779
+        } else {
780
+          params.delete(param);
781
+        }
782
+      });
740 783
     }
741 784
   }
742 785
 
743
-  // Update URL to reflect current selection.
744
-  function updateUrl(url, param) {
786
+  function setHrefParams(elem, paramSetter) {
787
+    let url = new URL(elem.href);
745 788
     url.hash = '';
746 789
 
747
-    // The selection can be in one of two modes: regexp-based or
748
-    // list-based.  Construct regular expression depending on mode.
749
-    let re = regexpActive
750
-      ? search.value
751
-      : Array.from(selected.keys()).map(key => quotemeta(nodes[key])).join('|');
752
-
753 790
     // Copy params from this page's URL.
754 791
     const params = url.searchParams;
755 792
     for (const p of new URLSearchParams(window.location.search)) {
756 793
       params.set(p[0], p[1]);
757 794
     }
758 795
 
759
-    if (re != '') {
760
-      // For focus/show, forget old parameter.  For others, add to re.
761
-      if (param != 'f' && param != 's' && params.has(param)) {
762
-        const old = params.get(param);
763
-         if (old != '') {
764
-          re += '|' + old;
765
-        }
766
-      }
767
-      params.set(param, re);
768
-    } else {
769
-      params.delete(param);
770
-    }
796
+    // Give the params to the setter to modify.
797
+    paramSetter(params);
771 798
 
772
-    return url.toString();
799
+    elem.href = url.toString();
773 800
   }
774 801
 
775 802
   function handleTopClick(e) {
@@ -826,7 +853,10 @@ function viewer(baseUrl, nodes) {
826 853
 
827 854
   const ids = ['topbtn', 'graphbtn', 'peek', 'list', 'disasm',
828 855
                'focus', 'ignore', 'hide', 'show'];
829
-  ids.forEach(makeLinkDynamic);
856
+  ids.forEach(makeSearchLinkDynamic);
857
+
858
+  const sampleIDs = [{{range .SampleTypes}}'{{.}}', {{end}}];
859
+  sampleIDs.forEach(setSampleIndexLink);
830 860
 
831 861
   // Bind action to button with specified id.
832 862
   function addAction(id, action) {

+ 12
- 10
internal/driver/webui.go Ver fichero

@@ -69,16 +69,17 @@ func (ec *errorCatcher) PrintErr(args ...interface{}) {
69 69
 
70 70
 // webArgs contains arguments passed to templates in webhtml.go.
71 71
 type webArgs struct {
72
-	Title      string
73
-	Errors     []string
74
-	Total      int64
75
-	Legend     []string
76
-	Help       map[string]string
77
-	Nodes      []string
78
-	HTMLBody   template.HTML
79
-	TextBody   string
80
-	Top        []report.TextItem
81
-	FlameGraph template.JS
72
+	Title       string
73
+	Errors      []string
74
+	Total       int64
75
+	SampleTypes []string
76
+	Legend      []string
77
+	Help        map[string]string
78
+	Nodes       []string
79
+	HTMLBody    template.HTML
80
+	TextBody    string
81
+	Top         []report.TextItem
82
+	FlameGraph  template.JS
82 83
 }
83 84
 
84 85
 func serveWebInterface(hostport string, p *profile.Profile, o *plugin.Options) error {
@@ -264,6 +265,7 @@ func (ui *webInterface) render(w http.ResponseWriter, tmpl string,
264 265
 	data.Title = file + " " + profile
265 266
 	data.Errors = errList
266 267
 	data.Total = rpt.Total()
268
+	data.SampleTypes = sampleTypes(ui.prof)
267 269
 	data.Legend = legend
268 270
 	data.Help = ui.help
269 271
 	html := &bytes.Buffer{}