aab3bc05c913bf797933639202210d15f2e95db9
[hnim.git] / hnim.js
1 (() => {
2 const comments = document.querySelectorAll("tr.comtr");
3 const items = document.querySelectorAll("table.itemlist tr.athing");
4 const morelink = document.querySelectorAll("a.morelink");
5
6 const elements = [
7 ...Array.from(items),
8 ...Array.from(comments),
9 ...Array.from(morelink),
10 ];
11
12 let elementsIndex = 0;
13 let selectedElement = elements[elementsIndex];
14 selectedElement.style.outline = '1px dashed black';
15
16 const visible = (element) => {
17 let bounds = element.getBoundingClientRect();
18 return Math.abs(bounds.bottom - bounds.top) > window.innerHeight || bounds.top >= 0 && bounds.bottom <= window.innerHeight;
19 }
20
21 const changeWithVisibleCallback = (comment, callback) => {
22 if (comment == null) {
23 return;
24 }
25 selectedElement.style.outline = '';
26 selectedElement = comment;
27 selectedElement.style.outline = '1px dashed black';
28 while (!visible(comment)) {
29 callback();
30 }
31 }
32
33 const change = (comment) => {
34 elementsIndex = elements.indexOf(comment);
35 changeWithVisibleCallback(comment, () => {});
36 }
37
38 // Curry callback for moving downpage
39 const changeDownpage = () => {
40 elementsIndex = Math.min(elementsIndex + 1, elements.length - 1);
41 changeWithVisibleCallback(elements[elementsIndex], () => {window.scrollTo(0, window.scrollY + selectedElement.offsetHeight)});
42 }
43
44 // Curry callback for moving up page
45 const changeUppage = () => {
46 elementsIndex = Math.max(elementsIndex - 1, 0);
47 changeWithVisibleCallback(elements[elementsIndex], () => {window.scrollTo(0, window.scrollY - selectedElement.offsetHeight)});
48 }
49
50 document.addEventListener("click", (e) => {
51 change(e.target.closest("tr.athing"));
52 })
53 document.addEventListener("keydown", (e) => {
54 if (e.target.type === 'textarea' || e.isComposing) {
55 return;
56 }
57 switch (e.key) {
58 case "j":
59 do {
60 changeDownpage();
61 } while (selectedElement.classList.contains("noshow"));
62 break;
63 case "k":
64 do {
65 changeUppage();
66 } while (selectedElement.classList.contains("noshow"));
67 break;
68 case "m":
69 case "Enter":
70 let togg = selectedElement.querySelector(".togg");
71 if (togg) {
72 togg.click();
73 }
74 else if (elementsIndex == elements.length - 1) {
75 selectedElement.click();
76 }
77 break;
78 case "o":
79 window.location.href = "https://news.ycombinator.com/item?id=" + selectedElement.id;
80 case "p":
81 while (selectedElement.querySelector("td.ind").firstElementChild.width != 0) {
82 changeUppage();
83 }
84 break;
85 default:
86 //noop
87 }
88 })
89 })();