go-hep.org/x/hep@v0.38.1/groot/cmd/root-srv/page.go (about)

     1  // Copyright ©2017 The go-hep Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package main
     6  
     7  const page = `<html>
     8  <head>
     9      <title>go-hep/groot file inspector</title>
    10  	<meta name="viewport" content="width=device-width, initial-scale=1">
    11  	<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" />
    12  	<link rel="stylesheet" href="https://www.w3schools.com/w3css/3/w3.css">
    13  	<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
    14  	<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/jstree/3.3.7/themes/default/style.min.css" />
    15  	<script src="https://cdnjs.cloudflare.com/ajax/libs/jstree/3.3.7/jstree.min.js"></script>
    16  	<style>
    17  	input[type=file] {
    18  		display: none;
    19  	}
    20  	input[type=submit] {
    21  		background-color: #F44336;
    22  		padding:5px 15px;
    23  		border:0 none;
    24  		cursor:pointer;
    25  		-webkit-border-radius: 5px;
    26  		border-radius: 5px;
    27  	}
    28  	.flex-container {
    29  		display: -webkit-flex;
    30  		display: flex;
    31  	}
    32  	.flex-item {
    33  		margin: 5px;
    34  	}
    35  	.groot-file-upload {
    36  		color: white;
    37  		background-color: #0091EA;
    38  		padding:5px 15px;
    39  		border:0 none;
    40  		cursor:pointer;
    41  		-webkit-border-radius: 5px;
    42  	}
    43  
    44  	.loader {
    45  		border: 16px solid #f3f3f3;
    46  		border-radius: 50%;
    47  		border-top: 16px solid #3498db;
    48  		width: 120px;
    49  		height: 120px;
    50  		-webkit-animation: spin 2s linear infinite; /* Safari */
    51  		animation: spin 2s linear infinite;
    52  	}
    53  
    54  	/* Safari */
    55  	@-webkit-keyframes spin {
    56  		0% { -webkit-transform: rotate(0deg); }
    57  		100% { -webkit-transform: rotate(360deg); }
    58  	}
    59  
    60  	@keyframes spin {
    61  		0% { transform: rotate(0deg); }
    62  		100% { transform: rotate(360deg); }
    63  	}
    64  	</style>
    65  <script type="text/javascript">
    66  	"use strict"
    67  
    68  {{if .Local}}
    69  	function openROOTFile() {
    70  		var uri = $("#groot-open-form-input").val();
    71  		$("#groot-open-form-input").val("");
    72  		var data = new FormData();
    73  		data.append("uri", uri);
    74  		$.ajax({
    75  			url: "/root-file-open",
    76  			method: "POST",
    77  			data: data,
    78  			processData: false,
    79  			contentType: false,
    80  			success: displayFileTree,
    81  			error: function(e){
    82  				alert("open failed: "+e);
    83  			}
    84  		});
    85  	}
    86  {{- end}}
    87  
    88  	function uuidv4() {
    89  		return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
    90  			var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
    91  			return v.toString(16);
    92  		});
    93  	}
    94  
    95  	$(function () {
    96  		document.getElementById("groot-file-upload").onchange = function() {
    97  			var data = new FormData($("#groot-upload-form")[0]);
    98  			var dst = data.get("groot-file").name;
    99  			dst = "upload://"+dst.substring(dst.lastIndexOf('/')+1);
   100  			data.append("groot-dst", dst);
   101  			$.ajax({
   102  				url: "/root-file-upload",
   103  				method: "POST",
   104  				data: data,
   105  				processData: false,
   106  				contentType: false,
   107  				success: displayFileTree,
   108  				error: function(er){
   109  					alert("upload failed: "+er);
   110  				}
   111  			});
   112  		}
   113  
   114  {{if .Local}}
   115  		$('#groot-open-form-input').keypress(function(event) {
   116  			if (event.keyCode == 13) {
   117  				openROOTFile();
   118  			}
   119  		});
   120  /*
   121  	$('#groot-test-form').dialog({
   122          modal: true,
   123  		show: false,
   124          buttons: {
   125              'Open-1': function () {
   126                  var name = $('input[name="uri"]').val();
   127                  $.post({
   128  					url: "/file-open",
   129  					method: "POST",
   130  					data: {"uri": name},
   131  					processData: false,
   132  					contentType: "application/json",
   133  					dataType: "json",
   134  					success: displayFileTree,
   135  					error: function(er){
   136  						alert("open failed: "+JSON.stringify(er));
   137  					}
   138  				})
   139                  $(this).dialog('close');
   140              },
   141  			'Cancel': function () {
   142                  $(this).dialog('close');
   143              }
   144          }
   145      });
   146  */
   147  {{- end}}
   148  
   149  		$('#groot-file-tree').jstree();
   150  		$("#groot-file-tree").on("select_node.jstree",
   151  			function(evt, data){
   152  				data.instance.toggle_node(data.node);
   153  				if (data.node.a_attr.plot) {
   154  					data.instance.deselect_node(data.node);
   155  					data.instance.disable_node(data.node);
   156  					var id = uuidv4();
   157  					plotPlaceholder(id);
   158  					$.post({
   159  						type: 'POST',
   160  						url: data.node.a_attr.href,
   161  						data: data.node.a_attr.cmd,
   162  						success: function(data, status) {
   163  							plotCallback(data, status, id);
   164  						},
   165  						contentType: "application/json",
   166  						dataType: 'json',
   167  					}).always(function() {
   168  						data.instance.enable_node(data.node);
   169  					});
   170  				}
   171  			}
   172  		);
   173  		$.ajax({
   174  			url: "/refresh",
   175  			method: "GET",
   176  			processData: false,
   177  			contentType: false,
   178  			success: displayFileTree,
   179  			error: function(er){
   180  				alert("refresh failed: "+er);
   181  			}
   182  		});
   183  	});
   184  
   185  	function displayFileTree(data) {
   186  		$('#groot-file-tree').jstree(true).settings.core.data = JSON.parse(data);
   187  		$("#groot-file-tree").jstree(true).refresh();
   188  	};
   189  
   190  	var spinner = function() {
   191  		var top = "<div class=\"w3-cell-row\">";
   192  		var left = "<div class=\"w3-container w3-white w3-cell\"></div>";
   193  		var right = "<div class=\"w3-container w3-white w3-cell\"></div>";
   194  		var middle = "<div class=\"w3-container w3-white w3-cell\" style=\"width: 20%\">"
   195  			+"<div class=\"loader w3-white\" style=\"display: block;\"><p></div></div>";
   196  		return top+left+middle+right+"</div>";
   197  	}();
   198  
   199  	function plotPlaceholder(id) {
   200  		var node = $("<div></div>");
   201  		node.attr("id", id);
   202  		node.addClass("w3-panel w3-white w3-card-2 w3-display-container w3-content w3-center");
   203  		node.css("width","100%");
   204  		node.html(spinner);
   205  
   206  		$("#groot-display").prepend(node);
   207  		updateHeight();
   208  	};
   209  
   210  	function plotCallback(data, status, id) {
   211  		var img = data;
   212  		var node = $("#"+id);
   213  		node.html(
   214  			""
   215  			+atob(img.data)
   216  			+"<span onclick=\"this.parentElement.style.display='none'; updateHeight();\" class=\"w3-button w3-display-topright w3-hover-red w3-tiny\">X</span>"
   217  		);
   218  		updateHeight();
   219  	};
   220  
   221  	function updateHeight() {
   222  		var hmenu = $("#groot-sidebar").height();
   223  		var hcont = $("#groot-container").height();
   224  		var hdisp = $("#groot-display").height();
   225  		if (hdisp > hcont) {
   226  			$("#groot-container").height(hdisp);
   227  		}
   228  		if (hdisp < hmenu && hcont > hmenu) {
   229  			$("#groot-container").height(hmenu);
   230  		}
   231  	};
   232  </script>
   233  </head>
   234  <body>
   235  
   236  <!-- Sidebar -->
   237  <div id="groot-sidebar" class="w3-sidebar w3-bar-block w3-card-4 w3-light-grey" style="width:25%">
   238  	<div class="w3-bar-item w3-card-2 w3-black">
   239  		<h2>go-hep/groot ROOT file inspector</h2>
   240  	</div>
   241  	<div class="w3-bar-item">
   242  
   243  	{{if .Local}}
   244  	<div>
   245  		File: <input id="groot-open-form-input" type="text" name="uri" value placeholder="URI to local or remote file">
   246  		<label for="groot-open-button" class="groot-file-upload" style="font-size:16px" onclick="openROOTFile()">
   247  		<i class="fa fa-folder-open" aria-hidden="true" style="font-size:16px"></i> Open
   248  		</label>
   249  		<input id="groot-open-button" type="hidden" value="Open" onclick="openROOTFile()">
   250  	</div>
   251  	<br>
   252  	{{- end}}
   253  
   254  	<form id="groot-upload-form" enctype="multipart/form-data" action="/root-file-upload" method="post">
   255  		<label for="groot-file-upload" class="groot-file-upload" style="font-size:16px">
   256  		<i class="fa fa-cloud-upload" aria-hidden="true" style="font-size:16px"></i> Upload
   257  		</label>
   258  		<input id="groot-file-upload" type="file" name="groot-file"/>
   259  		<input type="hidden" name="token" value="{{.Token}}"/>
   260  		<input type="hidden" value="upload" />
   261  	</form>
   262  
   263  	</div>
   264  	<div id="groot-file-tree" class="w3-bar-item">
   265  	</div>
   266  </div>
   267  
   268  <!-- Page Content -->
   269  <div style="margin-left:25%; height:100%" class="w3-grey" id="groot-container">
   270  	<div class="w3-container w3-content w3-cell w3-cell-middle w3-cell-row w3-center w3-justify w3-grey" style="width:100%" id="groot-display">
   271  	</div>
   272  </div>
   273  
   274  </body>
   275  </html>
   276  `