-
Notifications
You must be signed in to change notification settings - Fork 24
/
code.js
147 lines (129 loc) · 4.5 KB
/
code.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
var packages = null // array of packages.Package JSON objects
var path = null // path from root to selected package (elements are indices in 'packages')
var broken = null // array of 2-arrays of int, the node ids of broken edges.
function onLoad() {
// Grab data from server: package graph, "directory" tree, broken edges.
jQuery.ajax({url: "/data", success: onData})
}
// onData is called shortly after page load with the result of the /data request.
function onData(data) {
// Save array of Package objects.
packages = data.Packages
// Show initial packages.
$('#initial').text(data.Initial.map(i => packages[i].PkgPath).join("\n"))
// Show broken edges.
broken = data.Broken
var html = ""
for (var i in broken) {
edge = broken[i]
html += "<button type='button' onclick='unbreak(" + edge[0] + ", " + edge[1] + ")'>unbreak</button> "
+ "<code>" + packages[edge[0]].PkgPath + "</code> ⟶ "
+ "<code>" + packages[edge[1]].PkgPath + "</code><br/>"
}
$('#broken').html(html)
// Populate package/module "directory" tree.
$('#tree').jstree({
"core": {
"animation": 0,
"check_callback": true,
'data': data.Tree,
},
"types": {
"#": {
},
"root": {
"icon": "/static/3.3.11/assets/images/tree_icon.png"
},
"module": {
"icon": "https://jstree.com/static/3.3.11/assets/images/tree_icon.png"
},
"default": {
},
"pkg": {
"icon": "https://old.jstree.com//static/v.1.0pre/_demo/file.png"
}
},
"plugins": ["search", "state", "types", "wholerow"],
"search": {
"case_sensitive": false,
"show_only_matches": true,
}
})
// Show package info when a node is clicked.
$('#tree').on("changed.jstree", function (e, data) {
if (data.node) {
selectPkg(data.node.original)
}
})
// Search the tree when the user types in the search box.
$("#search").keyup(function () {
var searchString = $(this).val();
$('#tree').jstree('search', searchString);
});
}
// selectPkg shows package info (if any) about the clicked node.
function selectPkg(json) {
if (json.Package < 0) {
// Non-package "directory" node: clear the fields.
$('#pkgname').text("none")
$('#doc').text("")
$('#imports').html("")
$('#importedBy').html("")
$('#path').text("")
return
}
// A package node was selected.
var pkg = packages[json.Package]
// Show selected package.
$('#pkgname').text(pkg.PkgPath)
// Set link to Go package documentation.
$('#doc').html("<a title='doc' target='_blank' href='https://pkg.go.dev/" + pkg.PkgPath + "'><img src='https://pkg.go.dev/favicon.ico' width='16' height='16'/></a>")
// Show imports in a drop-down menu.
// Selecting an import acts like clicking on that package in the tree.
addImports($('#imports'), json.Imports)
addImports($('#importedBy'), json.ImportedBy)
// Show "break edges" buttons.
var html = ""
var path = [].concat(json.Path).reverse() // from root to selected package
for (var i in path) {
var p = packages[path[i]]
if (i > 0) {
html += "<button type='button' onclick='breakedge(" + path[i-1] + ", " + path[i] + ", false)'>break</button> "
+ "<button type='button' onclick='breakedge(" + path[i-1] + ", " + path[i] + ", true)'>break all</button> "
+ "⟶ "
}
html += "<code class='" + (json.Dominators.includes(path[i]) ? "dom" : "") + "'>" + p.PkgPath + "</code><br/>"
}
$('#path').html(html)
}
function breakedge(i, j, all) {
// Must reload the page since the graph has changed.
document.location = "/break?from=" + i + "&to=" + j + "&all=" + all
}
function unbreak(i, j) {
// Must reload the page since the graph has changed.
document.location = "/unbreak?from=" + i + "&to=" + j
}
// addImports adds option elements to the select element,
// one per package index in the packageIDs array.
function addImports(select, packageIDs) {
select.html("")
var option = document.createElement("option")
option.textContent = "..."
option.value = "-1"
select.append(option)
for (var i in packageIDs) {
var imp = packageIDs[i]
option = document.createElement("option")
option.textContent = packages[imp].PkgPath
option.value = "" + imp // package index, used by onSelectImport
select.append(option)
}
}
// onSelectImport is called by the imports dropdown.
function onSelectImport(sel) {
if (sel.value >= 0) {
// Simulate a click on a tree node corresponding to the selected import.
$('#tree').jstree('select_node', 'node' + sel.value);
}
}