/ imgtop / banned_dev.js
banned_dev.js
  1  var Parser = {}
  2  
  3  Parser.init = function() {
  4    var staticPath = '//static.4chan.org/image/';
  5    
  6    var tail = window.devicePixelRatio >= 2 ? '@2x.gif' : '.gif';
  7    
  8    this.icons = {
  9      admin: staticPath + 'adminicon' + tail,
 10      mod: staticPath + 'modicon' + tail,
 11      dev: staticPath + 'developericon' + tail,
 12      del: staticPath + 'filedeleted-res' + tail
 13    };
 14  };
 15  
 16  function buildHTMLFromJSON(data) {
 17    var
 18      container = document.createElement('div'),
 19      isOP = false,
 20      
 21      userId,
 22      fileDims = '',
 23      imgSrc = '',
 24      fileBuildStart = '',
 25      fileBuildEnd = '',
 26      fileInfo = '',
 27      fileHtml = '',
 28      fileThumb,
 29      fileSize = '',
 30      fileClass = '',
 31      shortFile = '',
 32      longFile = '',
 33      tripcode = '',
 34      capcodeStart = '',
 35      capcodeClass = '',
 36      capcode = '',
 37      flag,
 38      highlight = '',
 39      emailStart = '',
 40      emailEnd = '',
 41      name,
 42      subject,
 43      noLink,
 44      quoteLink,
 45      noFilename,
 46      maxSize = 150,
 47      ratio, imgWidth, imgHeight,
 48      
 49      imgDir = '//images.4chan.org/' + data.board + '/src';
 50    
 51    noLink = 'res/' + data.resto + '#p' + data.no;
 52    quoteLink = 'res/' + data.resto + '#q' + data.no;
 53    
 54    if (!data.capcode && data.id) {
 55      userId = ' <span class="posteruid id_'
 56        + data.id + '">(ID: <span class="hand" title="Highlight posts by this ID">'
 57        + data.id + '</span>)</span> ';
 58    }
 59    else {
 60      userId = '';
 61    }
 62    
 63    switch (data.capcode) {
 64      case 'admin_highlight':
 65        highlight = ' highlightPost';
 66      case 'admin':
 67        capcodeStart = ' <strong class="capcode hand id_admin"'
 68          + 'title="Highlight posts by the Administrator">## Admin</strong>';
 69        capcodeClass = ' capcodeAdmin';
 70        
 71        capcode = ' <img src="' + Parser.icons.admin + '" '
 72          + 'alt="This user is the 4chan Administrator." '
 73          + 'title="This user is the 4chan Administrator." class="identityIcon">';
 74        break;
 75      case 'mod':
 76        capcodeStart = ' <strong class="capcode hand id_mod" '
 77          + 'title="Highlight posts by Moderators">## Mod</strong>';
 78        capcodeClass = ' capcodeMod';
 79        
 80        capcode = ' <img src="' + Parser.icons.mod + '" '
 81          + 'alt="This user is a 4chan Moderator." '
 82          + 'title="This user is a 4chan Moderator." class="identityIcon">';
 83        break;
 84      case 'developer':
 85        capcodeStart = ' <strong class="capcode hand id_developer" '
 86          + 'title="Highlight posts by Developers">## Developer</strong>';
 87        capcodeClass = ' capcodeDeveloper';
 88        
 89        capcode = ' <img src="' + Parser.icons.dev + '" '
 90          + 'alt="This user is a 4chan Developer." '
 91          + 'title="This user is a 4chan Developer." class="identityIcon">';
 92        break;
 93    }
 94    
 95    if (data.email) {
 96      emailStart = '<a href="mailto:' + data.email.replace(/ /g, '%20') + '" class="useremail">';
 97      emailEnd = '</a>';
 98    }
 99    
100    if (data.country) {
101      flag = ' <img src="//static.4chan.org/image/country/'
102        + (data.board == 'pol' ? 'troll/' : '')
103        + data.country.toLowerCase() + '.gif" alt="'
104        + data.country + '" title="' + data.country_name + '" class="countryFlag">';
105    }
106    else {
107      flag = '';
108    }
109  
110    if (data.ext) {
111      shortFile = longFile = data.filename + data.ext;
112      if (data.filename.length > 30) {
113        shortFile = data.filename.slice(0, 25) + '(...)' + data.ext;
114      }
115  
116      if (!data.tn_w && !data.tn_h && data.ext == '.gif') {
117        data.tn_w = data.w;
118        data.tn_h = data.h;
119      }
120      if (data.fsize >= 1048576) {
121        fileSize = ((0 | (data.fsize / 1048576 * 100 + 0.5)) / 100) + ' M';
122      }
123      else if (data.fsize > 1024) {
124        fileSize = (0 | (data.fsize / 1024 + 0.5)) + ' K';
125      }
126      else {
127        fileSize = data.fsize + ' ';
128      }
129      
130      fileThumb = '//images.4chan.org/bans/thumb/' + data.board + '/' + data.thumb + 's.jpg';
131      
132      imgWidth = data.tn_w;
133      imgHeight = data.tn_h;
134      
135      if (imgWidth > maxSize) {
136        ratio = maxSize / imgWidth;
137        imgWidth = maxSize;
138        imgHeight = imgHeight * ratio;
139      }
140      if (imgHeight > maxSize) {
141        ratio = maxSize / imgHeight;
142        imgWidth = imgWidth * ratio;
143        imgHeight = maxSize;
144      }
145      
146      imgSrc = '<a class="fileThumb' + fileClass + '" href="' + imgDir + '/'
147        + data.tim + data.ext + '" target="_blank"><img src="' + fileThumb
148        + '" alt="' + fileSize + 'B" data-md5="' + data.md5
149        + '" style="height: ' + imgHeight + 'px; width: '
150        + imgWidth + 'px;"></a>';
151      
152      fileDims = data.ext == '.pdf' ? 'PDF' : data.w + 'x' + data.h;
153      fileInfo = '<span class="fileText" id="fT' + data.no
154        + '">File: <a href="' + imgDir + '/' + data.tim + data.ext
155        + '" target="_blank">' + data.tim + data.ext + '</a>-(' + fileSize
156        + 'B, ' + fileDims
157        + (noFilename ? '' : (', <span title="' + longFile + '">'
158        + shortFile + '</span>')) + ')</span>';
159      
160      fileBuildStart = fileInfo ? '<div class="fileInfo">' : '';
161      fileBuildEnd = fileInfo ? '</div>' : '';
162      
163      fileHtml = '<div id="f' + data.no + '" class="file">'
164        + fileBuildStart + fileInfo + fileBuildEnd + imgSrc + '</div>';
165    }
166    else if (data.filedeleted) {
167      fileHtml = '<div id="f' + data.no + '" class="file"><span class="fileThumb"><img src="'
168        + Parser.icons.del + '" class="fileDeletedRes" alt="File deleted."></span></div>';
169    }
170    
171    if (data.trip) {
172      tripcode = ' <span class="postertrip">' + data.trip + '</span>';
173    }
174    
175    name = data.name || '';
176    
177    subject = data.sub || '';
178    
179    container.id = 'p' + data.no;
180    container.className = 'post reply' + highlight + (data.ws_board ? ' ws' : ' nws');
181    container.innerHTML =
182      '<div class="postInfo desktop" id="pi' + data.no + '">' +
183        '<input type="checkbox" name="' + data.no + '" value="delete"> ' +
184        '<span class="subject">' + subject + '</span> ' +
185        '<span class="nameBlock' + capcodeClass + '">' + emailStart +
186          '<span class="name">' + name + '</span>' +
187          tripcode + capcodeStart + emailEnd + capcode + userId + flag +
188        ' </span> ' +
189        '<span class="dateTime" data-utc="' + data.time + '">' + data.now + '</span> ' +
190        '<span class="postNum desktop">' +
191          '<a href="' + noLink + '" title="Highlight this post">No.</a><a href="' +
192          quoteLink + '" title="Quote this post">' + data.no + '</a>' +
193        '</span>' +
194      '</div>' + fileHtml +
195      '<blockquote class="postMessage" id="m' + data.no + '">'
196      + (data.com || '') + '</blockquote>';
197    
198    return container;
199  }
200  
201  function showPreview(e) {
202      var rect, postHeight, doc, docWidth, style, pos, top, scrollTop, link, post, match, bid;
203      
204      if (e.target.nodeName == 'A' && (match = e.target.className.match(/^bannedPost_([0-9]+)/))) {
205        link = e.target;
206        bid = match[1];
207      }
208      else {
209        return;
210      }
211      
212      post = buildHTMLFromJSON(window['banjson_' + bid]);
213      
214      post.id = 'quote-preview';
215      
216      rect = link.getBoundingClientRect();
217      doc = document.documentElement;
218      docWidth = doc.offsetWidth;
219      style = post.style;
220      
221      document.body.appendChild(post);
222      
223      if ((docWidth - rect.right) < (0 | (docWidth * 0.3))) {
224        pos = docWidth - rect.left;
225        style.right = pos + 5 + 'px';
226      }
227      else {
228        pos = rect.left + rect.width;
229        style.left = pos + 5 + 'px';
230      }
231      
232      top = rect.top + link.offsetHeight + window.pageYOffset
233        - post.offsetHeight / 2 - rect.height / 2;
234      
235      postHeight = post.getBoundingClientRect().height;
236      
237      if (doc.scrollTop != document.body.scrollTop) {
238        scrollTop = doc.scrollTop + document.body.scrollTop;
239      } else {
240        scrollTop = document.body.scrollTop;
241      }
242      
243      if (top < scrollTop) {
244        style.top = scrollTop + 'px';
245      }
246      else if (top + postHeight > scrollTop + doc.clientHeight) {
247        style.top = scrollTop + doc.clientHeight - postHeight + 'px';
248      }
249      else {
250        style.top = top + 'px';
251      }
252  }
253  
254  function removePreview() {
255    if (cnt = document.getElementById('quote-preview')) {
256      document.body.removeChild(cnt);
257    }
258  }
259  
260  function run() { 
261    Parser.init();
262    addCSS();
263    document.addEventListener('mouseover', showPreview, false);
264    document.addEventListener('mouseout', removePreview, false);
265  }
266  
267  function addCSS() {
268    var style;
269    
270    style = document.createElement('style');
271    style.setAttribute('type', 'text/css');
272    style.textContent = '\
273  #quote-preview {\
274    display: block;\
275    position: absolute;\
276    padding: 3px 6px 6px 3px;\
277    margin: 0;\
278    text-align: left;\
279    border-width: 1px 2px 2px 1px;\
280    border-style: solid;\
281  }\
282  #quote-preview.nws {\
283    color: #800000;\
284    border-color: #D9BFB7;\
285  }\
286  #quote-preview.ws {\
287    color: #000;\
288    border-color: #B7C5D9;\
289  }\
290  #quote-preview.ws a {\
291    color: #34345C;\
292  }\
293  #quote-preview input {\
294    margin: 3px 3px 3px 4px;\
295  }\
296  .ws.reply {\
297    background-color: #D6DAF0;\
298  }\
299  .nws.reply {\
300    background-color: #F0E0D6;\
301  }\
302  .subject {\
303    font-weight: bold;\
304  }\
305  .ws .subject {\
306    color: #0F0C5D;\
307  }\
308  .nws .subject {\
309    color: #CC1105;\
310  }\
311  .quote {\
312    color: #789922;\
313  }\
314  .quotelink,\
315  .deadlink {\
316    color: #789922 !important;\
317  }\
318  .ws .useremail .postertrip,\
319  .ws .useremail .name {\
320    color: #34345C !important;\
321  }\
322  .nws .useremail .postertrip,\
323  .nws .useremail .name {\
324    color: #0000EE !important;\
325  }\
326  .nameBlock {\
327    display: inline-block;\
328  }\
329  .name {\
330    color: #117743;\
331    font-weight: bold;\
332  }\
333  .postertrip {\
334    color: #117743;\
335    font-weight: normal !important;\
336  }\
337  .postNum a {\
338    text-decoration: none;\
339  }\
340  .ws .postNum a {\
341    color: #000 !important;\
342  }\
343  .nws .postNum a {\
344    color: #800000 !important;\
345  }\
346  .fileInfo {\
347    margin-left: 20px;\
348  }\
349  .fileThumb {\
350    float: left;\
351    margin: 3px 20px 5px;\
352  }\
353  .fileThumb img {\
354    border: none;\
355    float: left;\
356  }\
357  s {\
358    background-color: #000000 !important;\
359  }\
360  .capcode {\
361    font-weight: bold !important;\
362  }\
363  .nameBlock.capcodeAdmin span.name, span.capcodeAdmin span.name a, span.capcodeAdmin span.postertrip, span.capcodeAdmin strong.capcode {\
364    color: #FF0000 !important;\
365  }\
366  .nameBlock.capcodeMod span.name, span.capcodeMod span.name a, span.capcodeMod span.postertrip, span.capcodeMod strong.capcode {\
367    color: #800080 !important;\
368  }\
369  .nameBlock.capcodeDeveloper span.name, span.capcodeDeveloper span.name a, span.capcodeDeveloper span.postertrip, span.capcodeDeveloper strong.capcode {\
370    color: #0000F0 !important;\
371  }\
372  .identityIcon {\
373    height: 16px;\
374    margin-bottom: -3px;\
375    width: 16px;\
376  }\
377  .postMessage {\
378    margin: 13px 40px 13px 40px;\
379  }\
380  .countryFlag {\
381    margin-bottom: -1px;\
382    padding-top: 1px;\
383  }\
384  .fileDeletedRes {\
385    height: 13px;\
386    width: 127px;\
387  }\
388  span.fileThumb, span.fileThumb img {\
389    float: none !important;\
390    margin-bottom: 0 !important;\
391    margin-top: 0 !important;\
392  }\
393  ';
394    
395    (document.head || document.getElementsByTagName('head')[0]).appendChild(style);
396  }
397  
398  document.addEventListener('DOMContentLoaded', run, false);