Skip to content

Commit 5896861

Browse files
authored
Feature/line selections (#54)
* Add line highlighting. * Update cache for CSS
1 parent 8b627a0 commit 5896861

File tree

8 files changed

+159
-18
lines changed

8 files changed

+159
-18
lines changed

core/scanners.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ def validate_discord_token(token: str) -> bool:
6464
try:
6565
# Just check if the first part validates as a user ID
6666
(user_id, _, _) = token.split(".")
67-
user_id = int(base64.b64decode(user_id + "==", validate=True))
67+
user_id = int(base64.b64decode(user_id + "=" * (len(user_id) % 4), validate=True))
6868
except (ValueError, binascii.Error):
6969
return False
7070
else:

views/htmx.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,15 +80,19 @@ def highlight_code(self, *, files: list[dict[str, Any]]) -> str:
8080
length: int = len(line)
8181

8282
if next_pos is not None and position <= next_pos <= position + length:
83-
numbers.append(f"""<tr><td class="lineNumRow">{n}</td><td class="lineWarn"></td></tr>""")
83+
numbers.append(
84+
f"""<tr data-ln="{n}"><td class="lineNumRow" onclick="highlightLine(event, '{index}', '{n}')">{n}</td><td class="lineWarn"></td></tr>"""
85+
)
8486

8587
try:
8688
next_pos = positions.pop(0)
8789
except IndexError:
8890
next_pos = None
8991

9092
else:
91-
numbers.append(f"""<tr><td class="lineNumRow">{n}</td></tr>""")
93+
numbers.append(
94+
f"""<tr data-ln="{n}"><td class="lineNumRow" onclick="highlightLine(event, '{index}', '{n}')">{n}</td></tr>"""
95+
)
9296

9397
position += length + 1
9498

web/index.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
<!-- <link rel="preload" href="static/packages/htmx.min.js" as="script"> -->
1313
<!-- <link rel="preload" href="static/packages/highlight.min.js" as="script"> -->
1414
<!-- <link rel="preload" href="static/packages/highlight-ln.min.js" as="script"> -->
15-
<script src="static/packages/htmx.min.js"></script>
15+
<script src="/static/packages/htmx.min.js"></script>
1616

1717
<!-- SCRIPTS -->
1818
<script src="/static/scripts/initialTheme.js?v=1"></script>
@@ -24,7 +24,7 @@
2424
<!-- STYLESHEETS -->
2525
<!-- <link rel="preload" href="static/styles/global.css" as="style" /> -->
2626
<!-- <link rel="preload" href="static/styles/highlights.css" as="style" /> -->
27-
<link rel="stylesheet" type="text/css" href="/static/styles/global.css?v=8" />
27+
<link rel="stylesheet" type="text/css" href="/static/styles/global.css?v=9" />
2828

2929
<!-- FONTS -->
3030
<link rel="preconnect" href="https://fonts.googleapis.com">

web/maint.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
<!-- STYLESHEETS -->
1717
<!-- <link rel="preload" href="static/styles/global.css" as="style" /> -->
18-
<link rel="stylesheet" type="text/css" href="static/styles/global.css?v=8" />
18+
<link rel="stylesheet" type="text/css" href="static/styles/global.css?v=9" />
1919

2020

2121
<!-- FONTS -->

web/password.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
<!-- STYLESHEETS -->
2626
<!-- <link rel="preload" href="static/styles/global.css" as="style" /> -->
2727
<!-- <link rel="preload" href="static/styles/highlights.css" as="style" /> -->
28-
<link rel="stylesheet" type="text/css" href="/static/styles/global.css?v=8" />
28+
<link rel="stylesheet" type="text/css" href="/static/styles/global.css?v=9" />
2929
<link rel="stylesheet" type="text/css" href="/static/styles/highlights.css" />
3030

3131
<!-- FONTS -->

web/paste.html

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
<meta name="description" content="Easily share code and text." />
1010

1111
<!-- PACKAGES -->
12-
<script src="static/packages/htmx.min.js"></script>
12+
<script src="/static/packages/htmx.min.js"></script>
1313
<!-- <link rel="preload" href="static/packages/highlight.min.js" as="script"> -->
1414
<!-- <link rel="preload" href="static/packages/highlight-ln.min.js" as="script"> -->
1515
<script src="/static/packages/highlight.min.js"></script>
@@ -20,11 +20,12 @@
2020
<script src="/static/scripts/hidecopy.js?v=1" defer></script>
2121
<script src="/static/scripts/highlights.js?v=5" defer></script>
2222
<script src="/static/scripts/shortcuts.js?v=1" defer></script>
23+
<script src="/static/scripts/lineHighlights.js" defer></script>
2324

2425
<!-- STYLESHEETS -->
2526
<!-- <link rel="preload" href="static/styles/global.css" as="style" /> -->
2627
<!-- <link rel="preload" href="static/styles/highlights.css" as="style" /> -->
27-
<link rel="stylesheet" type="text/css" href="/static/styles/global.css?v=8" />
28+
<link rel="stylesheet" type="text/css" href="/static/styles/global.css?v=9" />
2829
<link rel="stylesheet" type="text/css" href="/static/styles/highlights.css" />
2930

3031
<!-- FONTS -->

web/static/scripts/lineHighlights.js

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
let selections = {};
2+
3+
function parseLines() {
4+
let params = new URLSearchParams(document.location.search);
5+
let param = params.get("lines");
6+
7+
if (!param) {
8+
return
9+
}
10+
11+
const regex = /F(\d+)-L(\d+)(?:-L(\d+))?/g;
12+
let match;
13+
while ((match = regex.exec(param)) !== null) {
14+
let file = parseInt(match[1]);
15+
let start = parseInt(match[2]);
16+
let end = match[3] ? parseInt(match[3]) : start;
17+
18+
if (isNaN(file) || isNaN(start) || isNaN(end)) {
19+
continue;
20+
}
21+
22+
highlightLine(null, file - 1, start);
23+
if (start !== end) {
24+
highlightLine(null, file - 1, end);
25+
}
26+
}
27+
}
28+
29+
parseLines();
30+
31+
function removeSelected(lines) {
32+
lines.forEach(line => {
33+
let child = line.querySelector("td.lineSelected");
34+
if (child) {
35+
line.removeChild(child);
36+
line.classList.remove("lineNumRowSelected");
37+
}
38+
});
39+
}
40+
41+
function updateParams() {
42+
const url = new URL(window.location);
43+
let param = Object.entries(selections).map(([key, value]) => {
44+
let end = value.end !== value.start ? `-L${value.end}_` : '';
45+
return `F${parseInt(key) + 1}-L${value.start}${end}`;
46+
}).join('');
47+
48+
url.searchParams.set("lines", param);
49+
url.searchParams.delete("pastePassword");
50+
51+
history.pushState(null, '', url);
52+
}
53+
54+
function replaceSelected(lines, idIndex, index, start, end) {
55+
let newLines = lines.slice(start, end);
56+
removeSelected(newLines);
57+
58+
let line = lines[index - 1];
59+
line.insertAdjacentHTML("beforeend", `<td class="lineSelected"></td>`);
60+
line.classList.add("lineNumRowSelected");
61+
62+
selections[idIndex] = { "start": index, "end": index };
63+
updateParams();
64+
}
65+
66+
function addLines(lines, idIndex, start, end) {
67+
let newLines = lines.slice(start - 1, end);
68+
newLines.forEach(line => {
69+
if (!line.querySelector("td.lineSelected")) {
70+
line.insertAdjacentHTML("beforeend", `<td class="lineSelected"></td>`);
71+
line.classList.add("lineNumRowSelected");
72+
}
73+
});
74+
75+
selections[idIndex] = { "start": start, "end": end };
76+
updateParams();
77+
}
78+
79+
function highlightLine(event, idI, selected) {
80+
let idIndex = parseInt(idI);
81+
let id = `__paste_c_${idIndex}`;
82+
let block = document.getElementById(id);
83+
84+
if (!block) {
85+
return;
86+
}
87+
88+
let lines = Array.from(block.querySelectorAll("tbody>tr"));
89+
let line = Math.min(parseInt(selected), lines.length);
90+
91+
let current = selections[idIndex];
92+
if (!current) {
93+
let selectedLine = lines[line - 1];
94+
selectedLine.insertAdjacentHTML("beforeend", `<td class="lineSelected"></td>`);
95+
selectedLine.classList.add("lineNumRowSelected");
96+
97+
selections[idIndex] = { "start": line, "end": line };
98+
updateParams();
99+
return;
100+
}
101+
102+
let { start, end } = current;
103+
104+
if (event && !event.shiftKey) {
105+
replaceSelected(lines, idIndex, line, start - 1, end);
106+
return;
107+
}
108+
109+
if (!event || event.shiftKey) {
110+
if (line < start) {
111+
removeSelected(lines.slice(start, end));
112+
addLines(lines, idIndex, line, start);
113+
} else if (line <= end) {
114+
replaceSelected(lines, idIndex, line, start - 1, end);
115+
} else {
116+
addLines(lines, idIndex, start, line);
117+
}
118+
}
119+
}

web/static/styles/global.css

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
--button--brightness: brightness(0.95);
1818
--button--brightness-hover: brightness(0.85);
1919
--button--brightness-active: brightness(0.95);
20+
--color-line-hover: rgb(237, 219, 85, 0.2);
21+
--color-line-selected: rgb(237, 219, 85, 0.2);
2022

2123
.keyboardLight {
2224
display: none !important;
@@ -70,6 +72,8 @@
7072
--button--brightness: brightness(1.2);
7173
--button--brightness-hover: brightness(1.1);
7274
--button--brightness-active: brightness(1.1);
75+
--color-line-hover: rgb(237, 219, 85, 0.1);
76+
--color-line-selected: rgb(237, 219, 85, 0.1);
7377

7478
.keyboardDark {
7579
display: none !important;
@@ -461,10 +465,6 @@ textarea {
461465
font-family: "JetBrains Mono", monospace;
462466
}
463467

464-
.code {
465-
font-family: "JetBrains Mono", monospace;
466-
}
467-
468468
.pre {
469469
font-family: "JetBrains Mono", monospace;
470470
}
@@ -566,8 +566,8 @@ textarea {
566566
border-spacing: 0;
567567
border: none;
568568
font-family: "JetBrains Mono", monospace;
569-
font-size: 0.8rem;
570-
line-height: 1.2rem;
569+
font-size: 0.75rem;
570+
line-height: 1.1rem;
571571
user-select: none;
572572
}
573573

@@ -577,19 +577,36 @@ textarea {
577577
opacity: 0.7;
578578
}
579579

580+
.lineNumRow:hover {
581+
cursor: pointer;
582+
background-color: var(--color-line-hover);
583+
}
584+
585+
.lineNumRowSelected {
586+
background: var(--color-line-selected);
587+
}
588+
589+
.lineSelected {
590+
background: var(--color-line-selected);
591+
position: absolute;
592+
width: 100%;
593+
z-index: 1;
594+
height: 1.1rem;
595+
}
596+
580597
.lineWarn {
581598
background: var(--color-error);
582599
position: absolute;
583600
width: 100%;
584601
z-index: 1;
585-
height: 1rem;
602+
height: 1.1rem;
586603
opacity: 0.4;
587604
}
588605

589606
code {
590607
font-family: "JetBrains Mono", monospace;
591-
font-size: 0.8rem;
592-
line-height: 1.2rem;
608+
font-size: 0.75rem;
609+
line-height: 1.1rem;
593610
z-index: 2;
594611
}
595612

0 commit comments

Comments
 (0)