a150b2b8c1ac3d5f3d9203a668017120ae80a5e2
[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.querySelectorAll(".status-"+id+" .status-like");
48                 for (var i = 0; i < forms.length; i++) {
49                         updateActionForm(id, forms[i], reverseActions[action]);
50                 }
51
52                 var body = "csrf_token=" + encodeURIComponent(getCSRFToken());
53                 var contentType = "application/x-www-form-urlencoded";
54                 http("POST", "/fluoride/" + action + "/" + id, body, contentType, function(res, type) {
55                         var data = JSON.parse(res);
56                         var count = data.data;
57                         if (count === 0) {
58                                 count = "";
59                         }
60                         var counts = document.querySelectorAll(".status-"+id+" .status-like-count");
61                         for (var i = 0; i < counts.length; i++) {
62                                 if (count > 0) {
63                                         counts[i].innerHTML = "(" + count + ")";
64                                 } else {
65                                         counts[i].innerHTML = "";
66                                 }
67                         }
68                 }, function(err) {
69                         for (var i = 0; i < forms.length; i++) {
70                                 updateActionForm(id, forms[i], action);
71                         }
72                 });
73         }
74 }
75
76 function handleRetweetForm(id, f) {
77         f.onsubmit = function(event) {
78                 event.preventDefault();
79
80                 var action = f.dataset.action;
81                 var forms = document.querySelectorAll(".status-"+id+" .status-retweet");
82                 for (var i = 0; i < forms.length; i++) {
83                         updateActionForm(id, forms[i], reverseActions[action]);
84                 }
85
86                 var body = "csrf_token=" + encodeURIComponent(getCSRFToken());
87                 var contentType = "application/x-www-form-urlencoded";
88                 http("POST", "/fluoride/" + action + "/" + id, body, contentType, function(res, type) {
89                         var data = JSON.parse(res);
90                         var count = data.data;
91                         if (count === 0) {
92                                 count = "";
93                         }
94                         var counts = document.querySelectorAll(".status-"+id+" .status-retweet-count");
95                         for (var i = 0; i < counts.length; i++) {
96                                 if (count > 0) {
97                                         counts[i].innerHTML = "(" + count + ")";
98                                 } else {
99                                         counts[i].innerHTML = "";
100                                 }
101                         }
102                 }, function(err) {
103                         for (var i = 0; i < forms.length; i++) {
104                                 updateActionForm(id, forms[i], action);
105                         }
106                 });
107         }
108 }
109
110 function isInView(el) {
111         var ract = el.getBoundingClientRect();
112         if (ract.top > 0 && ract.bottom < window.innerHeight) {
113                 return true;
114         }
115         return false;
116 }
117
118 function handleReplyToLink(div) {
119         if (!div) {
120                 return;
121         }
122         var id = div.firstElementChild.getAttribute('href');
123         if (!id || id[0] != '#') {
124                 return;
125         }
126         div.firstElementChild.onmouseenter = function(event) {
127                 var id = event.target.getAttribute('href');
128                 var status = document.querySelector(id);
129                 if (!status) {
130                         return;
131                 }
132                 if (isInView(status)) {
133                         status.classList.add("highlight");
134                 } else {
135                         var copy = status.cloneNode(true);
136                         copy.id = "reply-to-popup";
137                         var ract = event.target.getBoundingClientRect();
138                         if (ract.top > window.innerHeight / 2) {
139                                 copy.style.bottom = (window.innerHeight - 
140                                         window.scrollY - ract.top) + 'px';
141                         }
142                         event.target.parentElement.appendChild(copy);
143                 }
144         }
145         div.firstElementChild.onmouseleave = function(event) {
146                 var popup = document.getElementById("reply-to-popup");
147                 if (popup) {
148                         event.target.parentElement.removeChild(popup);    
149                 } else {
150                         var id = event.target.getAttribute('href');
151                         document.querySelector(id)
152                                 .classList.remove("highlight");
153                 }
154         }
155 }
156
157 function handleReplyLink(div) {
158         div.firstElementChild.onmouseenter = function(event) {
159                 var id = event.target.getAttribute('href');
160                 var status = document.querySelector(id);
161                 if (!status) {
162                         return;
163                 }
164                 if (isInView(status)) {
165                         status.classList.add("highlight");
166                 } else {
167                         var copy = status.cloneNode(true);
168                         copy.id = "reply-popup";
169                         var ract = event.target.getBoundingClientRect();
170                         if (ract.left > window.innerWidth / 2) {
171                                 copy.style.right = (window.innerWidth -
172                                         ract.right - 12) + 'px';;
173                         }
174                         event.target.parentElement.appendChild(copy);
175                 }
176         }
177         div.firstElementChild.onmouseleave = function(event) {
178                 var popup = document.getElementById("reply-popup");
179                 if (popup) {
180                         event.target.parentElement.removeChild(popup);    
181                 } else {
182                         var id = event.target.getAttribute('href');
183                         document.querySelector(id)
184                                 .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