-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
120 lines (97 loc) · 4.68 KB
/
index.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
document.addEventListener("DOMContentLoaded", e => {
const diagramArea = document.getElementById("diagramArea");
const uriArea = document.getElementById("uriArea");
const errorArea = document.getElementById("errorArea");
if (uriArea.textContent.length === 0 && location.search.length > 0) {
uriArea.textContent = decodeURIComponent(location.search.substr(1));
}
else {
uriArea.textContent = "https://user:pass@example.com:8080/path/parts?a=b&c=d#fragment";
}
uriAreaChanged();
function clearError() {
errorArea.textContent = "";
}
function handleError(error) {
errorArea.textContent = error.message;
}
function updateUri() {
const encodedUri = encodeURIComponent(uriArea.textContent);
if (location.search.length === 0 || location.search.substr(1) !== encodedUri) {
history.replaceState({}, "URI Diagram", "?" + encodedUri);
}
}
function renderDiagram(inEntries) {
function spaces(count) {
if (count > 0) {
return Array(count).fill(" ", 0, count).join("");
}
return "";
}
function dashes(count) {
if (count > 0) {
return Array(count).fill("-", 0, count).join("");
}
return "";
}
function inRange(min, value, max) { return min <= value && value <= max; }
const entries = inEntries.map(e => {
const entry = {
name: e.n,
start: e.l.start.column - 1,
end: e.l.end.column - 1,
};
entry.length = entry.end - entry.start;
entry.nameLength = entry.name.length;
entry.maxLength = Math.max(entry.length, entry.nameLength);
entry.nameStart = Math.max(Math.floor(entry.start + ((entry.length / 2) - (entry.nameLength / 2))), 0);
entry.minStart = Math.min(entry.start, entry.nameStart);
entry.nameEnd = entry.nameStart + entry.nameLength;
entry.maxEnd = Math.max(entry.end, entry.nameEnd);
return entry;
}).sort((left, right) => {
return right.minStart !== left.minStart ?
left.minStart - right.minStart : // sort first by starting position then by length
right.maxLength - left.maxLength; // reverse sort to have longest at front
});
let lines = [];
let currentLineTop = { start: Infinity, end: -Infinity, value: "" };
let currentLineBottom = { start: Infinity, end: -Infinity, value: "" };
for (let count = 0; count < entries.length; ++count) {
if (inRange(Math.min(currentLineTop.start, currentLineBottom.start), entries[count].minStart, Math.max(currentLineTop.end - 1, currentLineBottom.end - 1)) ||
inRange(Math.min(currentLineTop.start - 1, currentLineBottom.start - 1), entries[count].maxEnd, Math.max(currentLineTop.end, currentLineBottom.end)))
{
lines.push(currentLineTop.value);
lines.push(currentLineBottom.value);
currentLineTop = { start: Infinity, end: -Infinity, value: "" };
currentLineBottom = { start: Infinity, end: -Infinity, value: "" };
}
currentLineTop.start = Math.min(entries[count].nameStart, currentLineTop.start);
currentLineTop.end = Math.max(entries[count].nameEnd, currentLineTop.end);
currentLineTop.value += spaces(entries[count].nameStart - currentLineTop.value.length);
currentLineTop.value += entries[count].name;
currentLineBottom.start = Math.min(entries[count].start, currentLineBottom.start);
currentLineBottom.end = Math.max(entries[count].end, currentLineBottom.end);
currentLineBottom.value += spaces(entries[count].start - currentLineBottom.value.length);
currentLineBottom.value += "/" + dashes(entries[count].length - 2) + "\\";
}
if (currentLineTop.start !== Infinity) {
lines.push(currentLineTop.value);
lines.push(currentLineBottom.value);
}
return lines.join("\n");
}
function uriAreaChanged() {
try {
clearError();
updateUri();
const result = diagramUriParser.parse(uriArea.textContent.trim());
diagramArea.textContent = renderDiagram(result);
}
catch (e) {
handleError(e);
}
}
uriArea.addEventListener("keyup", uriAreaChanged);
uriArea.addEventListener("clear", uriAreaChanged);
});