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
|
function exactLocationToUrl(exactLocation) {
const modulePath = exactLocation.modulePath;
const packageId = exactLocation.packageId.name + "-" + exactLocation.packageId.version;
let hash = "";
if(exactLocation.startLine != 1) {
hash = "#L" + exactLocation.startLine;
}
return "/package/"+packageId+"/show/"+modulePath+hash;
}
function hackageUrl(packageId,locationInfo) {
const dasherizedModuleName = locationInfo.moduleName.replace(/\./g,'-');
let key;
if(locationInfo.entity === "Val") {
key = "v";
} else {
key = "t";
}
let hash = "";
if(locationInfo.entity === "Val" || locationInfo.entity === "Typ") {
hash = "#"+key+":"+locationInfo.haddockAnchorId;
}
return "https://hackage.haskell.org/package/"+packageId+"/docs/"+dasherizedModuleName+".html"+hash;
}
function openUrl(buttonId,url) {
if(buttonId === 2) {//middle mouse button
window.open(url, '_blank');
} else if(buttonId == 1) {//left mouse button
window.location = url;
}
return false;
}
function saveCurrentLocation(currentLineNumber) {
if(currentLineNumber) {
const url = window.location.origin + window.location.pathname + "#L" + currentLineNumber;
if(location.href != url) {
window.location.hash = "#L" + currentLineNumber;
}
}
}
function goToDefinition(store,locationInfo,buttonId,currentLineNumber) {
if(locationInfo.tag === "ExactLocation") {
const url = exactLocationToUrl(locationInfo);
if(locationInfo.startLine !== currentLineNumber) {
saveCurrentLocation(currentLineNumber);
}
openUrl(buttonId,url);
} else if(locationInfo.tag === "ApproximateLocation") {
const packageId = locationInfo.packageId.name+"-"+locationInfo.packageId.version;
if(locationInfo.entity === "Mod") {
store.loadDefinitionSite(packageId,
locationInfo.moduleName,
locationInfo.componentId,
locationInfo.entity,
locationInfo.moduleName)
.then((defSite) => {
const packageId = defSite.location.packageId.name + "-" + defSite.location.packageId.version;
openUrl(buttonId,"/package/" + packageId + "/show/" + defSite.location.modulePath);
}).catch(() => {
openUrl(buttonId,hackageUrl(packageId,locationInfo));
});
} else {
store.loadDefinitionSite(packageId,
locationInfo.moduleName,
locationInfo.componentId,
locationInfo.entity,
locationInfo.name)
.then((definitionSite) => {
if(definitionSite.location.tag === "ExactLocation") {
const url = exactLocationToUrl(definitionSite.location);
if(locationInfo.startLine !== currentLineNumber) {
saveCurrentLocation(currentLineNumber);
}
openUrl(buttonId,url);
} else {
saveCurrentLocation(currentLineNumber);
openUrl(buttonId,hackageUrl(packageId,locationInfo));
}
}).catch((e) => {
console.log(e);
saveCurrentLocation(currentLineNumber);
openUrl(buttonId,hackageUrl(packageId,locationInfo));
});
}
} else {
alert('No location info');
}
}
export {
goToDefinition,openUrl
}
|