View difference between Paste ID: varhspD9 and jCfbUjiL
SHOW: | | - or go back to the newest paste.
1
// ==UserScript==
2
// @name        Puzzling.SE Empuzzler
3
// @namespace   https://greasyfork.org/users/5615-doppelgreener
4
// @description Hide answers and comments on Puzzling.SE questions until you want to see them.
5
// @grant       none
6
// @include     http://puzzling.stackexchange.com/questions/*
7
// @version     0.5
8
// ==/UserScript==
9
10
// Changelog:
11
// 0.5.1    By Joe: Directly navigation to a comment or answer now doesn't hide anything, as you've already seen
12
//                  the content anyway and hiding it is just annoying.
13
// 0.5      By Joe: Added the option to only enable Empuzzler on specific tags, and the option to automatically
14
//                  show all spoilers.
15
// 0.4.1    By Joe: Don't bother hiding the comments section when there are none, and same for answers.
16
// 0.4      By Joe: Less stuff gets hidden (eg. post-answer box), moved hide/show answers beneath #answers-header,
17
//                  fixed English grammar on buttons, show number of comments that have been hidden, stopped a button
18
//                  showing if there is nothing for it to reveal (no answers means show-answer button never appears)
19
// 0.3      Buttons made larger. Added auto-update. Merged clean-up by Joe (Puzzling.SE user 2518).
20
// 0.2      Show Everything button added.
21
// 0.1      First version, with show comments/answers buttons only.
22
23
(function() {
24
25
    /**
26
     * If you'd like to only enable Empuzzler if a question has a particular tag, then
27
     * just fill up this array with the exact tags you want to match (case-sensitive):
28
     *     var tags = [ 'riddle', 'challenge' ];
29
     * If you instead choose to leave this empty:
30
     *     var tags = [ ];
31
     * then Empuzzler will be enabled on every question on Puzzling.SE
32
     */
33
    var tags = [ ];
34
35
    /**
36
     * If you'd like to remove spoiler-tags, enable this setting. It will affect every
37
     * single spoiler tag on the whole site, and just turns them into standard quotes
38
     * ie. if someone made this post:
39
     *     >! Spoilers in here!
40
     * it will appear as if they'd made this post:
41
     *     > Spoilers in here!
42
     */
43
    var despoil = false;
44
45
    /****************************************************************************************
46
     * DON'T TOUCH ANYTHING BELOW THIS LINE :-)                                             *
47
     ***************************************************************************************/
48
49
    var main = function() {
50
51
        var identifiers,
52
            styles,
53
            questionCommentsCount = $('#question').find('.comment').length,
54
            answersCount = $('#answers').find('.answer').length,
55
            commentsButton,
56
            answersButton,
57
            showAllButton;
58
59
        if ($('#question').find('.comments-link.js-show-link b').length) {
60
            questionCommentsCount += parseInt( $('#question').find('.comments-link.js-show-link b').text() );
61
        }
62
63
        identifiers = {
64
            'comments': 'show-comments',
65
            'answers': 'show-answers'
66
        };
67
        identifiers.both = identifiers.comments + ' ' + identifiers.answers
68
69
        styles = {
70
            'hide-comments': [
71
                'body:not(.' + identifiers.comments + ') #question .comments            { display: none; }',
72
                'body:not(.' + identifiers.comments + ') #question .comments-link       { display: none; }',
73
                'body:not(.' + identifiers.comments + ') #question .comments-link ~ *   { display: none; }',
74
                'body:not(.' + identifiers.comments + ') #question .bounty-link         { display: none; }',
75
                'body.' + identifiers.comments + ' .' + identifiers.comments + '        { display: none; }'  // hide the button(s)
76
            ],
77
            'hide-answers': [
78
                'body:not(.' + identifiers.answers + ') #answers .answer                { display: none; }',
79
                'body:not(.' + identifiers.answers + ') #answers-header + .empuzzler    { margin-top: 1em; }',
80
                'body.' + identifiers.answers + ' .' + identifiers.answers + '          { display: none; }'  // hide the button(s)
81
            ],
82
            'empuzzler-misc': [
83
                '.empuzzler button { margin: 0.5em; padding: 0.5em; }',
84
                '.empuzzler button:first-child { margin-left: 0; }'
85
            ]
86
        };
87
88
        // Creates a button with chosen type, text and affecting certain classes
89
        function makeButton(buttonText, classesToAdd) {
90
            return $('<button/>')
91
                .text(buttonText)
92
                .addClass(classesToAdd)
93
                .on('click', function() {
94
                    $('body').addClass(classesToAdd);
95
                });
96
        }
97
98
        // Create a container for the buttons and insert it after the question
99
        if (questionCommentsCount) {
100
            commentsButton = makeButton(
101
                'Show the ' + questionCommentsCount + ' comment' + (~-questionCommentsCount ? 's' : '') + ' on this question',
102
                identifiers.comments
103
            ).on('click', function() {
104
                $('#question').find('.comments-link.js-show-link').trigger('click');
105
            });
106
            showAllButton = makeButton('Show me everything!', identifiers.both)
107
                .addClass('button')
108
                .on('click', function() {
109
                    commentsButton.trigger('click');
110
                });
111
112
            $('<div/>')
113
                .addClass('empuzzler ' + identifiers.comments)
114
                .append(
115
                    commentsButton,
116
                    answersCount ? $('<span/>').addClass(identifiers.both).text(' or ') : '',
117
                    answersCount ? showAllButton : ''
118
                )
119
                .insertAfter('#question');
120
        } else {
121
            $('body').addClass( identifiers.comments );
122
        }
123
124
        if (answersCount) {
125
            answersButton = makeButton('Show me the answer' + (~-answersCount ? 's' : ''), identifiers.answers);
126
127
            $('<blockquote/>')
128
                .addClass('empuzzler ' + identifiers.answers)
129
                .append(
130
                    $('<p/>').text(
131
                        (~-answersCount ? 'These answers have' : 'This answer has')
132
                        + ' been hidden by Empuzzler so you don\'t accidentally spoil the question for yourself. To bring '
133
                        + (~-answersCount ? 'them' : 'it')
134
                        + ' back, just click...'
135
                    ),
136
                    answersButton
137
                )
138
                .insertAfter('#answers-header');
139
        } else {
140
            $('body').addClass( identifiers.answers );
141
        }
142
143
        // Add the CSS to the page
144
        for (var i in styles) {
145
            if (styles.hasOwnProperty(i)) {
146
                el = document.createElement('style');
147
                el.id = 'empuzzler-styles';
148
                el.type = 'text/css';
149
                el.textContent = styles[i].join("\n");
150
                (document.head || document.documentElement).appendChild(el);
151
            }
152
        }
153
154
    };
155
156
    // If we're directly viewing a comment/answer then don't hide anything
157
    if ( location.hash.match(/^#(?:comment)?[0-9]+(?:[_0-9]+)?$/) ) {
158
        return;
159
    }
160
161
    // Always kick in if tags is empty
162
    var kickIn = ! tags.length;
163
    
164
    if ( ! kickIn) {
165
        // Find out what tags are on the post
166
        var postTags = [];
167
        $('#mainbar')
168
            .find('.post-taglist a')
169
            .each( function() {
170
                postTags.push( $(this).text() );
171
            } );
172
173
        // Should we hide answers, based on target tags?
174
        $.each(tags, function(i, tag) {
175
            if (~$.inArray(tag, postTags)) {
176
                kickIn = true;
177
                return false;
178
            }
179
        } );
180
    }
181
182
    if (kickIn) {
183
        // Add the JS to the page
184
        var el = document.createElement('script');
185
        el.type = 'text/javascript';
186
        el.id = 'empuzzler-script'
187
        el.textContent = '(' + main.toString() + ')();';
188
        document.body.appendChild(el);
189
    }
190
191
    // Unhide spoiler tags?
192
    if (despoil) {
193
        $('.answer').find('blockquote.spoiler').removeClass('spoiler');
194
    }
195
196
} )();