fluoride: Fix syntax and formatting
[bloat] / static / fluoride.js
1 // @license magnet:?xt=urn:btih:90dc5c0be029de84e523b9b3922520e79e0e6f08&dn=cc0.txt CC0
2
3 var reverseActions = {
4         "like": "unlike",
5         "unlike": "like",
6         "retweet": "unretweet",
7         "unretweet": "retweet"
8 };
9
10 function getCSRFToken() {
11         var tag = document.querySelector("meta[name='csrf_token']");
12         if (tag)
13                 return tag.getAttribute("content");
14         return "";
15 }
16
17 function http(method, url, body, type, success, error) {
18         var req = new XMLHttpRequest();
19         req.onload = function() {
20                 if (this.status === 200 && typeof success === "function") {
21                         success(this.responseText, this.responseType);
22                 } else if (typeof error === "function") {
23                         error(this.responseText);
24                 }
25         };
26         req.onerror = function() {
27                 if (typeof error === "function") {
28                         error(this.responseText);
29                 }
30         };
31         req.open(method, url);
32         req.setRequestHeader("Content-Type", type);
33         req.send(body);
34 }
35
36 function updateActionForm(id, f, action) {
37         f.querySelector("[type='submit']").value = action;
38         f.action = "/" + action + "/" + id;
39         f.dataset.action = action;
40 }
41
42 function handleLikeForm(id, f) {
43         f.onsubmit = function(event) {
44                 event.preventDefault();
45
46                 var action = f.dataset.action;
47                 var forms = document.
48                         querySelectorAll(".status-"+id+" .status-like");
49                 for (var i = 0; i < forms.length; i++) {
50                         updateActionForm(id, forms[i], reverseActions[action]);
51                 }
52
53                 var body = "csrf_token=" + encodeURIComponent(getCSRFToken());
54                 var contentType = "application/x-www-form-urlencoded";
55                 http("POST", "/fluoride/" + action + "/" + id, 
56                         body, contentType, function(res, type) {
57
58                         var data = JSON.parse(res);
59                         var count = data.data;
60                         if (count === 0)
61                                 count = "";
62                         var counts = document.
63                                 querySelectorAll(".status-"+id+" .status-like-count");
64                         for (var i = 0; i < counts.length; i++) {
65                                 if (count > 0) {
66                                         counts[i].innerHTML = "(" + count + ")";
67                                 } else {
68                                         counts[i].innerHTML = "";
69                                 }
70                         }
71                 }, function(err) {
72                         for (var i = 0; i < forms.length; i++) {
73                                 updateActionForm(id, forms[i], action);
74                         }
75                 });
76         }
77 }
78
79 function handleRetweetForm(id, f) {
80         f.onsubmit = function(event) {
81                 event.preventDefault();
82
83                 var action = f.dataset.action;
84                 var forms = document.
85                         querySelectorAll(".status-"+id+" .status-retweet");
86                 for (var i = 0; i < forms.length; i++) {
87                         updateActionForm(id, forms[i], reverseActions[action]);
88                 }
89
90                 var body = "csrf_token=" + encodeURIComponent(getCSRFToken());
91                 var contentType = "application/x-www-form-urlencoded";
92                 http("POST", "/fluoride/" + action + "/" + id, 
93                         body, contentType, function(res, type) {
94
95                         var data = JSON.parse(res);
96                         var count = data.data;
97                         if (count === 0)
98                                 count = "";
99                         var counts = document.
100                                 querySelectorAll(".status-"+id+" .status-retweet-count");
101                         for (var i = 0; i < counts.length; i++) {
102                                 if (count > 0) {
103                                         counts[i].innerHTML = "(" + count + ")";
104                                 } else {
105                                         counts[i].innerHTML = "";
106                                 }
107                         }
108                 }, function(err) {
109                         for (var i = 0; i < forms.length; i++) {
110                                 updateActionForm(id, forms[i], action);
111                         }
112                 });
113         }
114 }
115
116 function isInView(el) {
117         var ract = el.getBoundingClientRect();
118         if (ract.top > 0 && ract.bottom < window.innerHeight)
119                 return true;
120         return false;
121 }
122
123 function handleReplyToLink(div) {
124         if (!div)
125                 return;
126         var id = div.firstElementChild.getAttribute("href");
127         if (!id || id[0] != "#")
128                 return;
129         div.firstElementChild.onmouseenter = function(event) {
130                 var id = event.target.getAttribute("href");
131                 var status = document.querySelector(id);
132                 if (!status)
133                         return;
134                 if (isInView(status)) {
135                         status.classList.add("highlight");
136                 } else {
137                         var copy = status.cloneNode(true);
138                         copy.id = "reply-to-popup";
139                         var ract = event.target.getBoundingClientRect();
140                         if (ract.top > window.innerHeight / 2) {
141                                 copy.style.bottom = (window.innerHeight - 
142                                         window.scrollY - ract.top) + "px";
143                         }
144                         event.target.parentElement.appendChild(copy);
145                 }
146         }
147         div.firstElementChild.onmouseleave = function(event) {
148                 var popup = document.getElementById("reply-to-popup");
149                 if (popup) {
150                         event.target.parentElement.removeChild(popup);    
151                 } else {
152                         var id = event.target.getAttribute("href");
153                         document.querySelector(id)
154                                 .classList.remove("highlight");
155                 }
156         }
157 }
158
159 function handleReplyLink(div) {
160         div.firstElementChild.onmouseenter = function(event) {
161                 var id = event.target.getAttribute("href");
162                 var status = document.querySelector(id);
163                 if (!status)
164                         return;
165                 if (isInView(status)) {
166                         status.classList.add("highlight");
167                 } else {
168                         var copy = status.cloneNode(true);
169                         copy.id = "reply-popup";
170                         var ract = event.target.getBoundingClientRect();
171                         if (ract.left > window.innerWidth / 2) {
172                                 copy.style.right = (window.innerWidth -
173                                         ract.right - 12) + "px";
174                         }
175                         event.target.parentElement.appendChild(copy);
176                 }
177         }
178         div.firstElementChild.onmouseleave = function(event) {
179                 var popup = document.getElementById("reply-popup");
180                 if (popup) {
181                         event.target.parentElement.removeChild(popup);
182                 } else {
183                         var id = event.target.getAttribute("href");
184                         document.querySelector(id).classList.remove("highlight");
185                 }
186         }
187 }
188
189 function handleStatusLink(a) {
190         if (a.classList.contains("mention"))
191                 return;
192         a.target = "_blank";
193 }
194
195 document.addEventListener("DOMContentLoaded", function() { 
196         var statuses = document.querySelectorAll(".status-container");
197         for (var i = 0; i < statuses.length; i++) {
198                 var s = statuses[i];
199                 var id = s.dataset.id;
200
201                 var likeForm = s.querySelector(".status-like");
202                 handleLikeForm(id, likeForm);
203
204                 var retweetForm = s.querySelector(".status-retweet");
205                 handleRetweetForm(id, retweetForm);
206
207                 var replyToLink = s.querySelector(".status-reply-to");
208                 handleReplyToLink(replyToLink);
209
210                 var replyLinks = s.querySelectorAll(".status-reply");
211                 for (var j = 0; j < replyLinks.length; j++) {
212                         handleReplyLink(replyLinks[j]);
213                 }
214
215                 var links = s.querySelectorAll(".status-content a");
216                 for (var j = 0; j < links.length; j++) {
217                         handleStatusLink(links[j]);
218                 }
219         }
220 });
221
222 // @license-end