SHOW:
|
|
- or go back to the newest paste.
| 1 | /* | |
| 2 | * q.js v2018.3-6.1 | |
| 3 | * http://anonsw.github.io/8chjs/ | |
| 4 | */ | |
| 5 | ||
| 6 | //IMAGE BLACKLIST CODING | |
| 7 | var imageBlacklist = [] ; | |
| 8 | function loadImageBlacklist() { JSON.parse(localStorage.imageBlacklist || "[]").forEach(addToImageBlaclist); }
| |
| 9 | function saveImageBlacklist() { localStorage.imageBlacklist = JSON.stringify(imageBlacklist); }
| |
| 10 | function addToImageBlaclist(md5) { if (md5 && -1 === imageBlacklist.indexOf(md5)) imageBlacklist.push(md5); }
| |
| 11 | function blacklistPostImages(post) { $(post).find('img.post-image').each(function (i, el) { var md5 = el.getAttribute('data-md5'); addToImageBlaclist(md5); el.remove(); }); }
| |
| 12 | function removeBlacklistedImages() { var removed = 0; $('img.post-image').each(function (i, el) { if (-1 !== imageBlacklist.indexOf(el.getAttribute('data-md5'))) { el.remove(); removed += 1; } }); return removed; }
| |
| 13 | function onNopeClicked(event) { event.preventDefault(); event.stopPropagation(); loadImageBlacklist(); var post = $(event.target).closest('.post'); blacklistPostImages(post); removeBlacklistedImages(); saveImageBlacklist(); }
| |
| 14 | function addNopeButtons() { $('.post').each(function(i, post) { if ($(post).find('.nope').length === 0) { $(post).prepend("<input type='button' class='nope' onClick='onNopeClicked(event)' value='Nope'></input>"); } }) }
| |
| 15 | ||
| 16 | setInterval(function () { loadImageBlacklist(); removeBlacklistedImages(); addNopeButtons(); }, 500);
| |
| 17 | ||
| 18 | ||
| 19 | /* Display a replies counter overlay in the top right corner */ | |
| 20 | $(function(){
| |
| 21 | $('head').append('<style>#thread_stats_posts_ovl { '+
| |
| 22 | 'position:fixed;top:35px;right:35px;'+ | |
| 23 | 'font:38px sans-serif;opacity:0.5;color:#f60;}</style>'); | |
| 24 | $('body').append('<div id="thread_stats_posts_ovl"/>');
| |
| 25 | function copyStats() { $('#thread_stats_posts_ovl').
| |
| 26 | text($('#thread_stats_posts').text());}
| |
| 27 | $(document).on('new_post',copyStats); copyStats();});
| |
| 28 | ||
| 29 | // User Settings | |
| 30 | var anonsw = {
| |
| 31 | qflair: '', // Examples: REAL, → | |
| 32 | - | qcolor: '#9fd8e0', |
| 32 | + | qcolor: '#90c45a', |
| 33 | - | youcolor: '#9fd8e0', |
| 33 | + | youcolor: '#5a78c4', |
| 34 | scrollcolor: 'rgba(153, 153, 153, 0.6)', | |
| 35 | scrollbackcolor: '#333', | |
| 36 | scrolltime: 400, // ms | |
| 37 | updateDelay: 200, // ms | |
| 38 | sidenavWidth: 30, // px | |
| 39 | ||
| 40 | floodEnabled: false, | |
| 41 | floodThreshold: 15, // min # posts before beginning fade | |
| 42 | floodVanish: 25, // max # posts before completed fade/hide | |
| 43 | floodBehavior: 'fade', // hide, fade | |
| 44 | fadenametripregex: /^(Anon(ymous)?-.*|.*-!!mG7VJxZNCI)$/i, | |
| 45 | fadenametripfloodvalue: -1, // Effective post count for fading, or -1 for auto of floodThreshold+post count | |
| 46 | strikeThroughNameFags: true, | |
| 47 | ||
| 48 | rateHistoryLen: 50, // Data points on chart | |
| 49 | rateAvgLen: 10 // Number of data points to average for instantaneous rate | |
| 50 | ||
| 51 | // Suggestions from 589388.html#590283 | |
| 52 | // ...shill detection features, such as | |
| 53 | // easily knowing the proportion of posts from a user that don't link. | |
| 54 | // I'd want to know any ID that was posting > 1/3 posts targetting noone. | |
| 55 | ||
| 56 | // TODO: Behavior for post hover should be to show original post visual before all q.js mods | |
| 57 | // TODO: Add flags to turn on/off features | |
| 58 | // TODO: Custom-regex -> post color/fade (auto-filter by selecting text and choosing new menu item?) | |
| 59 | // Examples: daily reminder, guys, check this out, shill, get out, filtered, tell us more, archive everything | |
| 60 | // TODO: Manual shade | |
| 61 | // TODO: remove Q trip codes from post content? | |
| 62 | // TODO: remove Q from end of post content if not a Q post? | |
| 63 | // TODO: recognize all of known Q trip codes? (make to sure to exclude known comps) | |
| 64 | // TODO: Links to reset on current Q/(you) post | |
| 65 | // TODO: Link to go to latest post (end key doesn't always work, but try capturing that as well?) | |
| 66 | // TODO: Keyboard shortcuts for navigation | |
| 67 | // TODO: Current/Total overall post navigation | |
| 68 | // TODO: Remap end key to always go to end of page | |
| 69 | // TODO: Check box for each post to mark as "read", "spam", ? | |
| 70 | // TODO: Autocorrect all-caps posts (50% threshold)? | |
| 71 | // TODO: Correct broken links but remove referral when clicked? | |
| 72 | // TODO: Make flood post fading non-linear to give leniency to posters just passing flood threshold | |
| 73 | // TODO: Penalize reposts in flood detection (if id's different, merge?) ? | |
| 74 | // TODO: Scorecard of posters ordered by post count (post rate, reply count, ...)? | |
| 75 | // TODO: Color/shade posts where there are no references and no question marks | |
| 76 | // TODO: If Q or trip used in name field, strike them out or replace with Anonymous? | |
| 77 | // TODO: embedded posts in Q posts don't have background-color and inherit Q color, fix? | |
| 78 | }; | |
| 79 | ||
| 80 | (function( anonsw_main, $, undefined ) {
| |
| 81 | // House keeping variables | |
| 82 | var qposts = []; | |
| 83 | var allqposts = []; | |
| 84 | var currq = -1; | |
| 85 | var youposts = []; | |
| 86 | var curryou = -1; | |
| 87 | var qnavposts = []; | |
| 88 | var younavposts = []; | |
| 89 | var ctx; | |
| 90 | var borderSz; | |
| 91 | var scrollWd; | |
| 92 | var minheight; | |
| 93 | var ratehistory = []; | |
| 94 | ||
| 95 | // On scroll stop. SO #9144560 | |
| 96 | (function ($) {
| |
| 97 | var on = $.fn.on, timer; | |
| 98 | $.fn.on = function () {
| |
| 99 | var args = Array.apply(null, arguments); | |
| 100 | var last = args[args.length - 1]; | |
| 101 | ||
| 102 | if (isNaN(last) || (last === 1 && args.pop())) return on.apply(this, args); | |
| 103 | ||
| 104 | var delay = args.pop(); | |
| 105 | var fn = args.pop(); | |
| 106 | ||
| 107 | args.push(function () {
| |
| 108 | var self = this, params = arguments; | |
| 109 | clearTimeout(timer); | |
| 110 | timer = setTimeout(function () {
| |
| 111 | fn.apply(self, params); | |
| 112 | }, delay); | |
| 113 | }); | |
| 114 | ||
| 115 | return on.apply(this, args); | |
| 116 | }; | |
| 117 | }(this.jQuery || this.Zepto)); | |
| 118 | ||
| 119 | // Case insensitive contains selector for finding yous. SO #8746882 | |
| 120 | $.expr[":"].icontains = jQuery.expr.createPseudo(function (arg) {
| |
| 121 | return function (elem) {
| |
| 122 | return jQuery(elem).text().toUpperCase().indexOf(arg.toUpperCase()) >= 0; | |
| 123 | }; | |
| 124 | }); | |
| 125 | ||
| 126 | // Get non-child text. SO #3442394 | |
| 127 | function immediateText(el) {
| |
| 128 | return el.contents().not(el.children()).text(); | |
| 129 | } | |
| 130 | ||
| 131 | // Scroll to element | |
| 132 | function myScrollTo(el) {
| |
| 133 | $('html, body').animate({
| |
| 134 | scrollTop: $(el).offset().top - $('div.boardlist').height()
| |
| 135 | }, anonsw.scrolltime); | |
| 136 | } | |
| 137 | ||
| 138 | // Highlight (you) posts/references | |
| 139 | function highlightYous() {
| |
| 140 | $(youposts).each(function() {
| |
| 141 | $(this).css('background-color', anonsw.youcolor);
| |
| 142 | }); | |
| 143 | return $.Deferred().resolve(); | |
| 144 | } | |
| 145 | ||
| 146 | // Remove invalid (you)'s | |
| 147 | function removeInvalidYous() {
| |
| 148 | $('div.body:icontains("(You)")').each(function() {
| |
| 149 | $(this).find(':not(small)').contents().filter(function() { return this.nodeType == 3 }).each(function() {
| |
| 150 | this.textContent = this.textContent.replace(/\(+ *You *\)+/ig, "you"); | |
| 151 | }); | |
| 152 | }); | |
| 153 | return $.Deferred().resolve(); | |
| 154 | } | |
| 155 | ||
| 156 | // Highlight Q posts | |
| 157 | function highlightQ() {
| |
| 158 | $(allqposts).each(function(idx,val) {
| |
| 159 | if($(val).css('background-color') !== anonsw.qcolor) {
| |
| 160 | if(anonsw.qflair !== "") {
| |
| 161 | $(val).find('p.intro > label > span.trip').first().prepend(anonsw.qflair + " ");
| |
| 162 | } | |
| 163 | $(val).css('background-color', anonsw.qcolor);
| |
| 164 | } | |
| 165 | }); | |
| 166 | return $.Deferred().resolve(); | |
| 167 | } | |
| 168 | ||
| 169 | // Scroll to next Q | |
| 170 | anonsw_main.nextq = function() {
| |
| 171 | if(qposts.length > 0) {
| |
| 172 | if(currq < qposts.length-1) {
| |
| 173 | currq++; | |
| 174 | } | |
| 175 | myScrollTo($(qposts).get(currq)); | |
| 176 | } | |
| 177 | }; | |
| 178 | ||
| 179 | // Scroll to last Q | |
| 180 | anonsw_main.lastq = function() {
| |
| 181 | if(qposts.length > 0) {
| |
| 182 | currq = qposts.length - 1; | |
| 183 | myScrollTo($(qposts).get(currq)); | |
| 184 | } | |
| 185 | }; | |
| 186 | ||
| 187 | // Scroll to previous Q | |
| 188 | anonsw_main.prevq = function() {
| |
| 189 | if(qposts.length > 0) {
| |
| 190 | if(currq > 0) {
| |
| 191 | currq--; | |
| 192 | } | |
| 193 | myScrollTo($(qposts).get(currq)); | |
| 194 | } | |
| 195 | }; | |
| 196 | ||
| 197 | // Scroll to first Q | |
| 198 | anonsw_main.firstq = function() {
| |
| 199 | if(qposts.length > 0) {
| |
| 200 | currq = 0; | |
| 201 | myScrollTo($(qposts).get(currq)); | |
| 202 | } | |
| 203 | }; | |
| 204 | ||
| 205 | // Scroll to next (You) | |
| 206 | anonsw_main.nextyou = function() {
| |
| 207 | if(youposts.length > 0) {
| |
| 208 | if(curryou < youposts.length-1) {
| |
| 209 | curryou++; | |
| 210 | } | |
| 211 | myScrollTo($(youposts).get(curryou)); | |
| 212 | } | |
| 213 | }; | |
| 214 | ||
| 215 | // Scroll to last (You) | |
| 216 | anonsw_main.lastyou = function() {
| |
| 217 | if(youposts.length > 0) {
| |
| 218 | curryou = youposts.length - 1; | |
| 219 | myScrollTo($(youposts).get(curryou)); | |
| 220 | } | |
| 221 | }; | |
| 222 | ||
| 223 | // Scroll to previous (You) | |
| 224 | anonsw_main.prevyou = function() {
| |
| 225 | if(youposts.length > 0) {
| |
| 226 | if(curryou > 0) {
| |
| 227 | curryou--; | |
| 228 | } | |
| 229 | myScrollTo($(youposts).get(curryou)); | |
| 230 | } | |
| 231 | }; | |
| 232 | ||
| 233 | // Scroll to first (You) | |
| 234 | anonsw_main.firstyou = function() {
| |
| 235 | if(youposts.length > 0) {
| |
| 236 | curryou = 0; | |
| 237 | myScrollTo($(youposts).get(curryou)); | |
| 238 | } | |
| 239 | }; | |
| 240 | ||
| 241 | // Inserts Q navigation links | |
| 242 | function qnav() {
| |
| 243 | $('div.boardlist').append('<span>[ <a href="javascript:anonsw_main.firstq();"><i class="fa fa-step-backward"></i></a> <a href="javascript:anonsw_main.prevq();"><i class="fa fa-backward"></i></a> <span style="filter:brightness(70%);">Q</span> <span class="qcount">(?:?)</span> <a href="javascript:anonsw_main.nextq();"><i class="fa fa-forward"></i></a> <a href="javascript:anonsw_main.lastq();"><i class="fa fa-step-forward"></i></a> ]</span>');
| |
| 244 | } | |
| 245 | ||
| 246 | // Inserts (You) navigation links | |
| 247 | function younav() {
| |
| 248 | $('div.boardlist').append('<span>[ <a href="javascript:anonsw_main.firstyou();"><i class="fa fa-step-backward"></i></a> <a href="javascript:anonsw_main.prevyou();"><i class="fa fa-backward"></i></a> <span style="filter:brightness(70%);">(You)</span> <span class="youcount">(?:?)</span> </span><a href="javascript:anonsw_main.nextyou();"><i class="fa fa-forward"></i></a> <a href="javascript:anonsw_main.lastyou();"><i class="fa fa-step-forward"></i></a> ]</span>');
| |
| 249 | } | |
| 250 | ||
| 251 | // Inserts feature toggle links | |
| 252 | function togglenav() {
| |
| 253 | $('div.boardlist').append('<span>[ <a href="javascript:anonsw_main.toggleFlood();">Turn Post Fading <span class="toggleFloodState">Off</span></a> ]</span>')
| |
| 254 | } | |
| 255 | ||
| 256 | // Inserts post rate count/chart | |
| 257 | function postratenav() {
| |
| 258 | var height = $('div.boardlist').height() - 1;
| |
| 259 | $('div.boardlist').append('<span>[ Post Rate: <span class="postRate">0</span> posts/min <canvas class="postRateChart"></canvas>]</span>')
| |
| 260 | $('.postRate').css('color', $('div.boardlist a').css('color'));
| |
| 261 | var charts = $('.postRateChart');
| |
| 262 | $(charts).each(function() {
| |
| 263 | $(this).css('width', '100px');
| |
| 264 | $(this).css('height', height);
| |
| 265 | $(this).css('vertical-align', 'middle');
| |
| 266 | //$(this).css('border', '1px solid');
| |
| 267 | //$(this).css('border-color', $('div.boardlist').css('color'));
| |
| 268 | var gctx = $(this).get(0).getContext('2d');
| |
| 269 | gctx.canvas.height = 20; | |
| 270 | gctx.canvas.width = 100; | |
| 271 | }); | |
| 272 | } | |
| 273 | ||
| 274 | // Inserts side navigation (bird's eye) | |
| 275 | function sidenav() {
| |
| 276 | $('body').append('<canvas id="sidenav"></canvas>');
| |
| 277 | var nav = $('#sidenav');
| |
| 278 | $(nav).css('position', 'fixed');
| |
| 279 | $(nav).css('top', $('div.boardlist').height());
| |
| 280 | $(nav).css('right', 0);
| |
| 281 | $(nav).css('width', anonsw.sidenavWidth);
| |
| 282 | $(nav).css('height', $(window).height() - $('div.boardlist').height());
| |
| 283 | $(nav).css('background-color', anonsw.scrollbackcolor);
| |
| 284 | $('body').css('margin-right', anonsw.sidenavWidth);
| |
| 285 | ctx = $('#sidenav').get(0).getContext('2d');
| |
| 286 | //ctx.canvas.height = $(document).height() - $('div.boardlist').height();
| |
| 287 | ctx.canvas.height = 2048; | |
| 288 | ctx.canvas.width = anonsw.sidenavWidth; | |
| 289 | borderSz = 1; | |
| 290 | scrollWd = ctx.canvas.width / 2; | |
| 291 | } | |
| 292 | ||
| 293 | // Update navigation counts | |
| 294 | function updateNavCounts() {
| |
| 295 | var fontSize = -1; | |
| 296 | var lineHeight; | |
| 297 | ||
| 298 | if(currq > qposts.length) { currq = qposts.length; }
| |
| 299 | if(curryou > youposts.length) { curryou = youposts.length; }
| |
| 300 | ||
| 301 | for(i=0; i<qposts.length; i++) {
| |
| 302 | var el = $(qposts).get(i); | |
| 303 | if(fontSize == -1) {
| |
| 304 | fontSize = $(el).css('font-size');
| |
| 305 | lineHeight = Math.floor(parseInt(fontSize.replace('px', '')) * 1.5);
| |
| 306 | } | |
| 307 | if(($(el).offset().top + $(el).height() - 2.25*lineHeight) > $(window).scrollTop()) {
| |
| 308 | currq = i; | |
| 309 | break; | |
| 310 | } | |
| 311 | } | |
| 312 | ||
| 313 | for(i=0; i<youposts.length; i++) {
| |
| 314 | var el = $(youposts).get(i); | |
| 315 | if(fontSize == -1) {
| |
| 316 | fontSize = $(el).css('font-size');
| |
| 317 | lineHeight = Math.floor(parseInt(fontSize.replace('px', '')) * 1.5);
| |
| 318 | } | |
| 319 | if(($(el).offset().top + $(el).height() - 2.25*lineHeight) > $(window).scrollTop()) {
| |
| 320 | curryou = i; | |
| 321 | break; | |
| 322 | } | |
| 323 | } | |
| 324 | ||
| 325 | // TODO: check for duplicates and remove from counts | |
| 326 | $('.qcount').text("(" + (currq+1) + ":" + qposts.length + ")");
| |
| 327 | $('.youcount').text("(" + (curryou+1) + ":" + youposts.length + ")");
| |
| 328 | } | |
| 329 | ||
| 330 | // Update navigation graphics | |
| 331 | function updateNavGraphics() {
| |
| 332 | var sidenav = $('#sidenav');
| |
| 333 | if(sidenav.length) {
| |
| 334 | $(sidenav).css('height', $(window).height() - $('div.boardlist').height());
| |
| 335 | minheight = ctx.canvas.height / ($(window).height() - $('div.boardlist').height()); // 1px
| |
| 336 | ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); | |
| 337 | ||
| 338 | // Draw nav q posts | |
| 339 | qnavposts = []; | |
| 340 | ctx.fillStyle = anonsw.qcolor; | |
| 341 | for (i = 0; i < qposts.length; i++) {
| |
| 342 | // TODO: check if we have already added post, don't draw it again | |
| 343 | var el = $(qposts).get(i); | |
| 344 | var height = $(el).height() / $(document).height() * ctx.canvas.height; | |
| 345 | if(height < minheight) height = minheight; | |
| 346 | qnavposts[i] = {
| |
| 347 | x : borderSz, | |
| 348 | y : $(el).offset().top / $(document).height() * ctx.canvas.height, | |
| 349 | width : ctx.canvas.width - borderSz*2, | |
| 350 | height : height | |
| 351 | }; | |
| 352 | ctx.fillRect(qnavposts[i].x, qnavposts[i].y, qnavposts[i].width, qnavposts[i].height); | |
| 353 | } | |
| 354 | ||
| 355 | // Draw nav you posts | |
| 356 | younavposts = []; | |
| 357 | ctx.fillStyle = anonsw.youcolor; | |
| 358 | for (i = 0; i < youposts.length; i++) {
| |
| 359 | // TODO: check if we have already added post, don't add it again | |
| 360 | var el = $(youposts).get(i); | |
| 361 | var height = $(el).height() / $(document).height() * ctx.canvas.height; | |
| 362 | if(height < minheight) height = minheight; | |
| 363 | younavposts[i] = {
| |
| 364 | x : borderSz, | |
| 365 | y : $(el).offset().top / $(document).height() * ctx.canvas.height, | |
| 366 | width : ctx.canvas.width - borderSz*2, | |
| 367 | height : height | |
| 368 | }; | |
| 369 | ctx.fillRect(younavposts[i].x, younavposts[i].y, younavposts[i].width, younavposts[i].height); | |
| 370 | } | |
| 371 | ||
| 372 | // Update nav window | |
| 373 | ctx.fillStyle = anonsw.scrollcolor; | |
| 374 | ctx.fillRect( | |
| 375 | scrollWd / 2, | |
| 376 | $(window).scrollTop() / $(document).height() * ctx.canvas.height, | |
| 377 | scrollWd, | |
| 378 | $(window).height() / $(document).height() * ctx.canvas.height | |
| 379 | ); | |
| 380 | ||
| 381 | // Add red marker at bottom of >750 posts | |
| 382 | if($('#thread_stats_posts').text() > 750) {
| |
| 383 | var barHeight = (4 * 2048) / ($(window).height() - $('div.boardlist').height());
| |
| 384 | ctx.fillStyle = '#f66'; | |
| 385 | ctx.fillRect( | |
| 386 | 0, | |
| 387 | ctx.canvas.height - barHeight, | |
| 388 | ctx.canvas.width, | |
| 389 | barHeight | |
| 390 | ); | |
| 391 | } | |
| 392 | } | |
| 393 | } | |
| 394 | ||
| 395 | // Updates post rate count/chart | |
| 396 | function updateNavPostRate() {
| |
| 397 | var posts = $('div.post').not('.post-hover');
| |
| 398 | var startPost = posts.length - (anonsw.rateHistoryLen + anonsw.rateAvgLen) + 1; | |
| 399 | if(startPost < 1) startPost = 1; | |
| 400 | var start = $($($(posts).get(0)).find('.intro time').get(0)).attr('unixtime'); //$('div.post:first .intro time').attr('unixtime');
| |
| 401 | ratehistory = []; | |
| 402 | timehistory = []; | |
| 403 | for(var i=startPost; i<posts.length; i++) {
| |
| 404 | // TODO: check if we have already added post, don't add it again | |
| 405 | var step = $($($(posts).get(i)).find('.intro time').get(0)).attr('unixtime'); //$($('div.post .intro time').get(i)).attr('unixtime');
| |
| 406 | timehistory[timehistory.length] = step; | |
| 407 | if(timehistory.length - anonsw.rateAvgLen - 1 >= 0) {
| |
| 408 | var avgend = timehistory[timehistory.length - 1]; | |
| 409 | var avgstart = timehistory[timehistory.length - anonsw.rateAvgLen - 1]; | |
| 410 | ratehistory[ratehistory.length] = anonsw.rateAvgLen / ((avgend - avgstart) / 60); | |
| 411 | } else {
| |
| 412 | ratehistory[ratehistory.length] = 0; | |
| 413 | } | |
| 414 | } | |
| 415 | //console.log(ratehistory); | |
| 416 | ||
| 417 | $('.postRate').text(ratehistory[ratehistory.length-1].toFixed(1));
| |
| 418 | ||
| 419 | if(ratehistory.length > anonsw.rateAvgLen) {
| |
| 420 | var maxRate = Math.max.apply(null, ratehistory); | |
| 421 | var minRate = Math.min.apply(null, ratehistory); | |
| 422 | //console.log("Max: " + maxRate);
| |
| 423 | //console.log("Min: " + minRate);
| |
| 424 | if(minRate > (maxRate - 0.5)) {
| |
| 425 | minRate = maxRate - 0.5; | |
| 426 | maxRate = maxRate + 0.5; | |
| 427 | } | |
| 428 | if(minRate < 0) {
| |
| 429 | minRate = 0; | |
| 430 | } | |
| 431 | var maxTime = timehistory[timehistory.length-1]; | |
| 432 | var minTime = timehistory[anonsw.rateAvgLen]; | |
| 433 | $('.postRateChart').each(function() {
| |
| 434 | var gctx = $(this).get(0).getContext('2d');
| |
| 435 | gctx.clearRect(0, 0, gctx.canvas.width, gctx.canvas.height); | |
| 436 | gctx.strokeStyle = $('div.boardlist a').css('color');
| |
| 437 | gctx.beginPath(); | |
| 438 | var x = 0; | |
| 439 | var y = gctx.canvas.height - (ratehistory[anonsw.rateAvgLen] - minRate)/(maxRate - minRate) * gctx.canvas.height; | |
| 440 | gctx.moveTo(x, y); | |
| 441 | for(var i=anonsw.rateAvgLen+1; i<ratehistory.length; i++) {
| |
| 442 | x = (timehistory[i] - minTime)/(maxTime - minTime) * gctx.canvas.width; | |
| 443 | y = gctx.canvas.height - (ratehistory[i] - minRate)/(maxRate - minRate) * gctx.canvas.height; | |
| 444 | gctx.lineTo(x, y); | |
| 445 | } | |
| 446 | gctx.stroke(); | |
| 447 | gctx.closePath(); | |
| 448 | }); | |
| 449 | } | |
| 450 | } | |
| 451 | ||
| 452 | // Update navigation | |
| 453 | function updateNav() {
| |
| 454 | updateNavCounts(); | |
| 455 | updateNavGraphics(); | |
| 456 | updateNavPostRate(); | |
| 457 | } | |
| 458 | ||
| 459 | // Update nav when scrolling stops | |
| 460 | $(window).on('scroll', function(e) {
| |
| 461 | updateNavCounts(); | |
| 462 | updateNavGraphics(); | |
| 463 | }, anonsw.updateDelay); | |
| 464 | ||
| 465 | // Update nav when resize stops | |
| 466 | $(window).on('resize', function(e) {
| |
| 467 | updateNav(); | |
| 468 | }, anonsw.updateDelay); | |
| 469 | ||
| 470 | // Set which posts are Q posts | |
| 471 | function setQPosts() {
| |
| 472 | qposts = $.map($('div.post:not(.post-hover) > p.intro > label > span.trip:contains("!!mG7VJxZNCI")'), function(el) {
| |
| 473 | return $(el).closest('div.post');
| |
| 474 | }); | |
| 475 | allqposts = $.map($('div.post:not(.post-hover) > p.intro > label > span.trip:contains("!!mG7VJxZNCI")'), function(el) {
| |
| 476 | return $(el).closest('div.post');
| |
| 477 | }); | |
| 478 | return $.Deferred().resolve(); | |
| 479 | } | |
| 480 | ||
| 481 | // Set which posts are (you) posts | |
| 482 | function setYouPosts() {
| |
| 483 | youposts = $.map($('div.post:not(.post-hover) > p.intro > label span.name > span.own_post, div.post:not(.post-hover) > div.body > p.body-line > small:icontains("(You)")'), function(el) {
| |
| 484 | return $(el).closest('div.post');
| |
| 485 | }); | |
| 486 | return $.Deferred().resolve(); | |
| 487 | } | |
| 488 | ||
| 489 | // Set flood posts | |
| 490 | function setFloodPosts() {
| |
| 491 | if(anonsw.floodEnabled) {
| |
| 492 | var stats = {};
| |
| 493 | var firstId = null; | |
| 494 | //console.log("==[ Name Fags ]=================================================");
| |
| 495 | var posts = $('div.post:not(.post-hover)').not('.you');
| |
| 496 | $(posts).each(function () {
| |
| 497 | var id = $(this).find('p > span.poster_id').first().text();
| |
| 498 | if(firstId != null) {
| |
| 499 | if (!(id in stats)) {
| |
| 500 | stats[id] = {count: 0, namefag: false, floodcount: 0};
| |
| 501 | } | |
| 502 | stats[id].count++; | |
| 503 | if(!stats[id].namefag) {
| |
| 504 | var name = immediateText($(this).find('p > label span.name').first());
| |
| 505 | var trip = $(this).find('p > label > span.trip').first().text();
| |
| 506 | stats[id].namefag = !anonsw.fadenametripregex.test(name+'-'+trip); | |
| 507 | //if(stats[id].namefag) {
| |
| 508 | // console.log(id + '=' + stats[id].namefag + ', ' + name + ', ' + trip); | |
| 509 | //} | |
| 510 | } | |
| 511 | if(stats[id].namefag) {
| |
| 512 | if(anonsw.fadenametripfloodvalue < 0) {
| |
| 513 | stats[id].floodcount = anonsw.floodThreshold + stats[id].count; | |
| 514 | } else {
| |
| 515 | stats[id].floodcount = anonsw.fadenametripfloodvalue; | |
| 516 | } | |
| 517 | } else {
| |
| 518 | stats[id].floodcount = stats[id].count; | |
| 519 | } | |
| 520 | } | |
| 521 | if (firstId == null) {
| |
| 522 | firstId = id; | |
| 523 | } | |
| 524 | }); | |
| 525 | $.each(stats, function (key, value) {
| |
| 526 | if (key !== firstId) {
| |
| 527 | var ids = $('span.poster_id:contains("' + key + '")');
| |
| 528 | if (value.floodcount > anonsw.floodThreshold || value.namefag) {
| |
| 529 | if(anonsw.strikeThroughNameFags && value.namefag) {
| |
| 530 | $(ids).each(function() {
| |
| 531 | $(this).closest('div.post').find('p > label span.name').first().css('text-decoration','line-through');
| |
| 532 | }); | |
| 533 | } | |
| 534 | if (anonsw.floodBehavior === 'fade') {
| |
| 535 | var intensity = value.floodcount; | |
| 536 | if (intensity > anonsw.floodVanish) {
| |
| 537 | intensity = anonsw.floodVanish; | |
| 538 | } | |
| 539 | intensity = ((anonsw.floodVanish - anonsw.floodThreshold) - (intensity - anonsw.floodThreshold)) / (anonsw.floodVanish - anonsw.floodThreshold); | |
| 540 | if (intensity < 0.1) {
| |
| 541 | intensity = 0.1; | |
| 542 | } | |
| 543 | $(ids).each(function () {
| |
| 544 | $(this).closest('div.post').css('opacity', intensity);
| |
| 545 | $(this).closest('div.post').hover(function () {
| |
| 546 | $(this).animate({opacity: 1.0}, anonsw.updateDelay);
| |
| 547 | }, function () {
| |
| 548 | $(this).animate({opacity: intensity}, anonsw.updateDelay);
| |
| 549 | }); | |
| 550 | }); | |
| 551 | } else if (anonsw.floodBehavior === 'hide') {
| |
| 552 | if (value.count >= anonsw.floodVanish) {
| |
| 553 | $(ids).each(function () {
| |
| 554 | $(this).closest('div.post').hide();
| |
| 555 | }); | |
| 556 | } | |
| 557 | } | |
| 558 | } else {
| |
| 559 | $(ids).each(function () {
| |
| 560 | $(this).closest('div.post').css('opacity', 1.0);
| |
| 561 | }); | |
| 562 | } | |
| 563 | } | |
| 564 | }); | |
| 565 | } | |
| 566 | return $.Deferred().resolve(); | |
| 567 | } | |
| 568 | ||
| 569 | // Toggle post flooding | |
| 570 | anonsw_main.toggleFlood = function() {
| |
| 571 | if(anonsw.floodEnabled) {
| |
| 572 | anonsw.floodEnabled = false; | |
| 573 | $('.toggleFloodState').text('On');
| |
| 574 | if(anonsw.floodBehavior === 'fade') {
| |
| 575 | $('span.poster_id').each(function () {
| |
| 576 | $(this).closest('div.post').css('opacity', 1);
| |
| 577 | $(this).closest('div.post').off('mouseenter mouseleave');
| |
| 578 | }); | |
| 579 | } else if(anonsw.floodBehavior === 'hide') {
| |
| 580 | $(this).closest('div.post').show();
| |
| 581 | } | |
| 582 | } else {
| |
| 583 | anonsw.floodEnabled = true; | |
| 584 | $('.toggleFloodState').text('Off');
| |
| 585 | runq() | |
| 586 | } | |
| 587 | }; | |
| 588 | ||
| 589 | // Helper to run snippets in the right order | |
| 590 | function runq() {
| |
| 591 | setQPosts() | |
| 592 | .done(highlightQ) | |
| 593 | .done(removeInvalidYous) | |
| 594 | .done(setYouPosts) | |
| 595 | .done(highlightYous) | |
| 596 | .done(setFloodPosts) | |
| 597 | .done(updateNav); | |
| 598 | } | |
| 599 | ||
| 600 | anonsw_main.Q = function() {
| |
| 601 | qnav(); | |
| 602 | younav(); | |
| 603 | togglenav(); | |
| 604 | postratenav(); | |
| 605 | sidenav(); | |
| 606 | runq(); | |
| 607 | ||
| 608 | // Select the node that will be observed for mutations | |
| 609 | var targetNode = $('div.thread')[0];
| |
| 610 | ||
| 611 | // Options for the observer (which mutations to observe) | |
| 612 | var config = { childList: true };
| |
| 613 | ||
| 614 | // Callback function to execute when mutations are observed | |
| 615 | var callback = function(mutationsList) {
| |
| 616 | for(var mutation in mutationsList) {
| |
| 617 | if (mutationsList[mutation].type == 'childList') {
| |
| 618 | runq(); | |
| 619 | break; | |
| 620 | } | |
| 621 | } | |
| 622 | }; | |
| 623 | ||
| 624 | // Create an observer instance linked to the callback function | |
| 625 | var observer = new MutationObserver(callback); | |
| 626 | ||
| 627 | // Start observing the target node for configured mutations | |
| 628 | observer.observe(targetNode, config); | |
| 629 | }; | |
| 630 | }( window.anonsw_main = window.anonsw_main || {}, jQuery ));
| |
| 631 | ||
| 632 | // Attach snippets to ready/change events | |
| 633 | $(document).ready(anonsw_main.Q); |