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