NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript==
// @name DISQUS
// @namespace
// @version 3.3.2
// @description DISQUS Enhancer https://openuserjs.org/install/Joeviocoe/DISQUS.user.js
// @include https://disqus.com/home/discussion*
// @include https://disqus.com/home/inbox/
// @include https://disqus.com/home/
// @include https://disqus.com/by/*
// @include https://disqus.com/
// @copyright 2017+, Joeviocoe
// @license MIT
// @require https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js
// @updateURL https://openuserjs.org/install/Joeviocoe/DISQUS.user.js
// @downloadURL https://openuserjs.org/install/Joeviocoe/DISQUS.user.js
// @icon https://www.google.com/s2/favicons?domain=disqus.com
// @grant none
// @noframes
// ==/UserScript==
// Copyright (c) 2017, Joeviocoe
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of Joeviocoe nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
/*jslint browser: true*/
/*global $, jQuery, alert */
///// Declare Global Variables /////
var search, currPosition, nextPost, destPosition, first_time = true;
var searchbox = document.createElement("INPUT");
var searching = document.createElement("p");
var substr = '';
//var recognition = new webkitSpeechRecognition(), recording = false;
var dsq = $('iframe[id*="dsq"]').last().attr("id");
var body = ''; if ( typeof dsq == 'undefined') { body = $('body'); } else { body = $("#"+dsq).contents(); }
var win = ''; if ( typeof dsq == 'undefined') { win = $('window'); } else { win = $("#"+dsq)[0].contentWindow; }
var sel_start = ""; var sel_finish = "";
var api = "E8Uh5l5fHZ6gD8U3KycjAIAk46f68Zw7C6eW8WSjZvCLXebZ7p0r1yrYDrLilk2F";
////////////////////////////////////////////////////////////////////////////////////////////////////////
function waitFor(selector, inside, callback) {
if ( $(inside).contents().find(selector).length ) {
callback();
} else {
setTimeout(function() {
waitFor(selector, inside, callback);
}, 250);
}
}
function repeater(callback, delay, repetitions) {
var x = 0;
var intervalID = window.setInterval(function () {
callback();
if (++x === repetitions) {
window.clearInterval(intervalID);
}
}, delay);
}
function SetName() {
$('.site-nav__logo').parent().attr("href", "/home/discussions/");
$('.icon-home').parent().parent().attr("href", "/home/discussions/");
if ( window.location.href.indexOf('//disqus.com/by') >= 0 ) {
searchbox.setAttribute("placeholder", "Search comments for " + $('.cover-profile-name').text() + "...");
}
if ( window.location.href.indexOf('//disqus.com/home/inbox/') >= 0 ) {
searchbox.setAttribute("placeholder", "Search my comments and replies...");
}
if ( window.location.href.indexOf('//disqus.com/home/discussions/') >= 0 ) {
searchbox.setAttribute("placeholder", "Search article summaries...");
}
}
function RemoveTrollAvatar() {
body.find('img[src*="avatar92.jpg?1500479976"]').attr('src','//a.disquscdn.com/1523321660/images/noavatar92.png');
body.find('img[src*="avatar92.jpg?1513645725"]').attr('src','//a.disquscdn.com/1523321660/images/noavatar92.png');
body.find('img[src*="avatar92.jpg?1546868353"]').attr('src','//a.disquscdn.com/1523321660/images/noavatar92.png');
body.find('#reactions__container').remove();
}
function unReferLinks() {
setTimeout(function() {
body.find('.comment-policy').remove();
if ( window.location.href.indexOf('//disqus.com/home/inbox/') >= 0 || window.location.href.indexOf('//disqus.com/by/') >= 0 ) {
$('a.view-comment').not('.cloned').addClass('cloned').each(function() {
$(this).clone().addClass('all-comments').appendTo( $(this).parent() );
$(this).children('span:contains("View in discussion")').text("View Comment");
});
$('a.all-comments').each(function(){
$(this).attr("href",$(this).attr("href").split("#")[0]);
$(this).children('span:contains("View in discussion")').text("View Discussion");
});
}
body.find('a[href*="disq.us"]').each(function(){
$(this).attr("href", decodeURIComponent($(this).attr("href")).replace("/url","/").split("disq.us/?url=")[1].split(":").slice(0,2).join(':') );
$(this).attr("href", $(this).attr("href").split("&key=")[0] );
});
}, 1000);
}
function expandMargins() {
if ( $(".card__content").length == 1 && $('.discussion__content').width() < 1000 ) {
console.log( "DE: Expanding Margins");
$(".module--plain").hide();
setTimeout(function() {
$('.discussion__content').css("width", "1222px");
$('.col-middle').css('margin-left', '0px');
$('.col-middle').css('margin-right', '0px');
$('.-centered').css('margin-left', '0px');
$('.card-link-description').text( $('.card-link-description').attr("title") );
$('iframe[id*="dsq"]').each(function() { $(this).css("width","180%"); });
}, 500);
}
}
function expandTruncate() {
waitFor('.truncate', 'body', function() {
if ( $('.truncate').length > 0 || $('.truncate-line').length > 0 ) {
$('.truncate').each(function() { $(this).text( $(this).attr("title") ); });
$(".truncate").removeClass("truncate"); $(".truncate-line").removeClass("truncate-line").removeAttr("href");
}
});
}
function expandComments() {
var expand_timer = setInterval (function() {
if ( body.find('.load-more[style!="display: none;"]').length == 1 ) {
console.log("DE: Expanding Comments");
body.find(".load-more__button").get(0).click();
} else {
clearInterval(expand_timer);
}
}, 1000);
}
function onSearch() {
if ( $('input')[0].value != search) { first_time = true; }
search = $('input')[0].value;
if ( search.length === 0 ) {
first_time = true;
$('.searching').hide();
$('mark').contents().unwrap();
return false;
}
if ( search.length < 3 ) {
$('input')[0].placeholder = "Minimum of 3 characters"; $('input')[0].value = "";
setTimeout (function() { SetName(); }, 3000);
return false;
}
if ( first_time === true ) {
$("html, body").animate({ scrollTop: 0 }, 400);
}
// Search
console.log("DE: Searching for " + search);
$('.searching').hide();
if ( first_time === false ) { currPosition = $(document).scrollTop(); } else { currPosition = 0; }
nextPost = 0; destPosition = 0; first_time = false;
var Posts = $("p:Contains('" + search + "'), a:Contains('" + search + "'), header:Contains('" + search + "'), .truncate:Contains('" + search + "'), blockquote:Contains('" + search + "')");
// If no match found
if ( !Posts.offset() ) {
$('.searching').show(); animate( $('.searching') );
// And other pages exist
if ( !$('.more-wrapper').children('.button').get(0) ) {
$('input')[0].placeholder = "Search string NOT FOUND"; $('input')[0].value = "";
$('.searching').hide();
setTimeout (function() { SetName(); }, 8000);
return false;
}
$('.more-wrapper').children('.button').get(0).click();
setTimeout (function() { onSearch(); }, 5000);
return false;
}
// Iterate through all loaded elements & Highlight matches
setTimeout(function() {
Posts.each(function() {
$('mark').has('mark').contents().unwrap();
var regex1 = new RegExp(search, "gi");
var regex2 = new RegExp(search, "i");
$(this)[0].innerHTML = $(this)[0].innerHTML.replace(regex1, '<mark>' + $(this)[0].innerHTML.match(regex2) + '</mark>');
});
}, 1000);
// Iterate through all loaded elements & Scroll to next
Posts.each(function() {
destPosition = $(this).offset().top - 50;
if ( destPosition > currPosition + 70 ) {
nextPost = destPosition;
return false;
}
});
// If more matches found below
if ( destPosition < currPosition + 70 ) {
$('.searching').show(); animate( $('.searching') );
// And if cannot scroll lower
if ( !$('.more-wrapper').children('.button').get(0) ) {
$('input')[0].placeholder = "End of Search"; $('input')[0].value = "";
$('.searching').hide();
setTimeout (function() { SetName(); }, 5000);
return false;
}
$('.more-wrapper').children('.button').get(0).click();
setTimeout (function() { onSearch(); }, 2000);
return false;
}
// If window is scrolled to very bottom
if ( currPosition == $(document).height()-$(window).height() ) {
$('input')[0].placeholder = "End of User's Comments"; $('input')[0].value = "";
$('.searching').hide();
setTimeout (function() { SetName(); }, 5000);
return false;
}
// Scroll down to next match
if (nextPost > 10) {
$('html, body').animate({scrollTop:nextPost}, 1200);
}
}
function searchComments() {
jQuery.expr[":"].Contains = jQuery.expr.createPseudo(function(arg) {
return function(elem) { return jQuery(elem).text().toUpperCase().indexOf(arg.toUpperCase()) >= 0; };
});
searching.innerHTML = "Searching...";
searching.setAttribute("class", "searching");
searching.setAttribute("style", "margin-top: 10px; margin-left: 10px;");
searchbox.setAttribute("type", "search");
searchbox.setAttribute("class", "search");
searchbox.onsearch = function(){ onSearch(); };
searchbox.setAttribute("required", "true");
searchbox.setAttribute("placeholder", "Search comments for " + name + "...");
searchbox.setAttribute("style", "width: 256px; height: 30px; margin-top: 10px;");
SetName();
$('.site-nav--secondary')[0].appendChild(searchbox);
$('.site-nav--secondary')[0].appendChild(searching);
$('.searching').hide();
}
function animate() {
$('.searching').animate({ opacity: 0.10, }, 500, function() { }); $('.searching').animate({ opacity: 1.00, }, 500, function() { });
$('.searching').animate({ opacity: 0.10, }, 500, function() { }); $('.searching').animate({ opacity: 1.00, }, 500, function() { });
}
function Downvotes(){
body.find('.vote-down[dvmark!="1"]').attr('dvmark','1').each(function(){
if ( $(this).attr('class').indexOf('count-') >= 0 ) {
var dv = $(this).attr('class').split('count-')[1].split(' ')[0];
if ( dv > 0 ) {
$(this).append("<span class='updatable count' data-role='likes' style='color: gray;position: relative;top: -3px;font-size: 13px;'> " + dv + "</span>");
}
}
});
}
function showDetails(username){
var userdetails = [];
var req = "https://disqus.com/api/3.0/users/details?user=username%3A"+username+"&api_key="+api;
$.get(req, function(data) {
var arr = data.response;
userdetails.push("Name: "+arr["name"]);
userdetails.push("Username: "+arr["username"]);
userdetails.push("Joined: "+arr["joinedAt"].replace('T',' '));
userdetails.push("Private: "+arr["isPrivate"]);
userdetails.push("ID: "+arr["id"]+"\n");
userdetails.push("Posts: "+arr["numPosts"]);
userdetails.push("Upvotes: "+arr["numLikesReceived"]);
userdetails.push("Reputation: "+arr["reputationLabel"]+" ("+arr["rep"]+")");
userdetails.push("Followers: "+arr["numFollowers"]);
userdetails.push("Following: "+arr["numFollowing"]);
userdetails.push("Forums: "+arr["numForumsFollowing"]+"\n");
userdetails.push("Primary: "+arr["isPrimary"]);
userdetails.push("Anonymous: "+arr["isAnonymous"]);
userdetails.push("Moderator: "+arr["isPowerContributor"]);
userdetails.push("disable3rdPartyTrackers: "+arr["disable3rdPartyTrackers"]+"\n");
userdetails.push("ProfileUrl: "+arr["profileUrl"]);
userdetails.push("URL: "+arr["url"]);
userdetails.push("SignedUrl: "+arr["signedUrl"]);
userdetails.push("Location: "+arr["location"]);
userdetails.push("About: "+arr["about"]);
alert(userdetails.join('\n'));
console.log(userdetails.join('\n'));
});
}
function downvote(username){
(function () {
var downvote = "";
console.log("DE: Downvoting " + username);
if ( window.location.href.indexOf('//disqus.com/home/discussion/') >= 0 ) {
downvote = body.find('a.profile_details[data-username="'+username+'"]').parents('div.post-body').find('.vote-down').not('.active').not('.downvoted');
} else if ( window.location.href.indexOf('//disqus.com/by/') >= 0 ) {
downvote = body.find('.vote-down').not('.active').not('.downvoted');
}
downvote.each(function (index) {
var that = $(this);
setTimeout(function () {
console.log($(that));
$(that).get(0).click();
}, 1500 * index);
});
}());
}
function upvote(username){
(function () {
var upvote = "";
console.log("DE: Upvoting " + username);
if ( window.location.href.indexOf('//disqus.com/home/discussion/') >= 0 ) {
upvote = body.find('a.profile_details[data-username="'+username+'"]').parents('div.post-body').find('.vote-up').not('.active').not('.upvoted');
} else if ( window.location.href.indexOf('//disqus.com/by/') >= 0 ) {
upvote = body.find('.vote-up').not('.active').not('.upvoted');
}
upvote.each(function (index) {
var that = $(this);
setTimeout(function () {
console.log($(that));
$(that).get(0).click();
}, 1500 * index);
});
}());
}
function reportPosts(arr,reason){
if ( arr.length == 0 || reason == null ) { return }
var post = arr[0];
$.ajax({
url: "https://disqus.com/api/3.0/posts/report.json",
method: "POST",
async: false,
data: {
reason: reason,
post: post,
api_key: api
}
}).success(function(data, status){
console.log("Reported: " + post + "\nStatus: " + status);
arr.shift();
reportPosts(arr,reason);
}).error(function(data,status){
console.log("DE: Waiting on ratelimit for post " + post + "\n" + arr.length + " remaining");
setTimeout(function(){
reportPosts(arr,reason);
},35000);
});
}
function reportUser(username,reason){
if ( reason == null ) { return }
var getreq = "https://disqus.com/api/3.0/users/details?user=username%3A"+username+"&api_key="+api;
$.get(getreq, function(data) {
var resp = data.response;
$.post("https://disqus.com/api/3.0/users/report.json", {
reason: reason,
user: resp["id"],
api_key: api
},function(data, status){
console.log("DE Reported: " + username + "\nStatus: " + status);
});
});
var arr = [];
if ( window.location.href.indexOf('//disqus.com/by/') >= 0 ) {
body.find('a.view-comment').each(function(){
var id = $(this).attr("href").split('comment-')[1];
arr.push(id);
});
}
if ( window.location.href.indexOf('//disqus.com/home/discussion/') >= 0 ) {
body.find('a.profile_details[data-username="'+username+'"]').each(function(){
var id = $(this).parents('div.post-body').find('a.time-ago').attr("href").split('comment-')[1];
arr.push(id);
});
}
arr = arr.filter(function(e){return e});
console.log("DE Reporting posts:\n" + arr);
reportPosts(arr,reason);
}
function getDetails(){
body.find('span.author').children('a[data-action="profile"][cloned!="1"]').attr('cloned','1').each(function(){
var button = $(this).clone();
var username = button.attr('data-username');
placeInfoButton($(this),button,username);
});
body.find('a.name[cloned!="1"]').attr('cloned','1').each(function(){
var button = $(this).clone();
var username = button.attr('href').split('/by/')[1].replace('/','');
placeInfoButton($(this),button,username);
});
body.find('div.cover-attribute-details[cloned!="1"]').attr('cloned','1').each(function(){
var button = $(this).clone();
var username = button.children('p.profile-cover-username').text().split('@')[1];
placeInfoButton($(this),button,username);
});
}
function placeInfoButton(orig,button,username){
button.attr('class','profile_details').insertAfter(orig).text("ℹ").removeAttr('data-action').removeAttr('href').removeClass("vote-up");
button.css('padding-top','4px').css('padding-left','12px').css('padding-right','20px'); button[0].style.setProperty( 'color', 'gray', 'important' );
button.off().on('click',function(evt){
if ( evt.ctrlKey ) {
var reason = prompt("Report/Vote for what reason?\n\n d = DOWNvote \n u = UPvote \n\n 0 = Harassment \n 1 = Spam \n 2 = Inappropriate profile \n 3 = Threatening content \n 4 = Impersonation \n 5 = Private information \n 6 = Disagree","d");
if ( reason == "d" ) {
downvote(username);
} else if ( reason == "u" ) {
upvote(username);
} else {
reportUser(username,reason);
}
} else {
showDetails(username);
}
});
}
function getUpvotes(){
body.find('a.vote-up[cloned!="1"]').attr('cloned','1').each(function() {
if ( parseInt($(this).get(0).innerText) > 0 ) {
var button = $(this).clone();
button.attr('class','vote-up showvoted').insertAfter( $(this) ).text("ℹ").removeAttr('href').removeAttr('data-action').removeClass("vote-up");
button.css('padding-top','4px'); button[0].style.setProperty( 'color', 'gray', 'important' );
button.off().on('click',function(evt){
var thread = button.siblings('a.view-comment').attr('data-thread-id') || $('meta[content*="threads"]').attr("content");
thread = thread.split("threads/")[1] || thread;
var post = button.siblings('a.view-comment').attr('href') || button.parents('li.post').attr('id');
post = post.split("comment-")[1] || post.split('post-')[1];
console.log("DSQ: Parse upvotes for thread " + thread + " post " + post);
var req = "https://disqus.com/api/3.0/posts/listUsersVotedPost?post="+post+"&thread="+thread+"&vote=1&limit=50&api_key="+api;
$.get( req, function( data ) {
if ( evt.ctrlKey ) {
var reason = prompt("Report all upvoted users for what reason?\n\n 0 = Harassment \n 1 = Spam \n 2 = Inappropriate profile \n 3 = Threatening content \n 4 = Impersonation \n 5 = Private information \n 6 = Disagree",1);
for ( i=0; i<data.response.length; i++ ){
var upvoter = data.response[i];
reportUser(upvoter["username"],reason);
}
} else {
for ( i=0; i<data.response.length; i++ ){
var upvoter = data.response[i];
showDetails(upvoter["username"]);
}
}
});
});
}
});
}
function orderFeeds() {
waitFor('.card[age]', 'body', function() {
var timearray = ["second","minute","hour","day","month"];
$.each(timearray, function(i, time) {
for (i=1; i<60; i++) {
if ( i == 1 ) { j="a" } else { j=i }
if ( i == 1 && time == "hour" ) { j="an" }
$('.card[age*="'+j+" "+time+'"]').detach().appendTo('.layout__content.homepage-feed');
}
});
});
}
function feedFrame(id, src, name){
$('div[data-jester-area="feed"]').remove();
$('<iframe>', {
id: id,
src: src,
class: 'feedframe',
width: $(window).width(),
height: 1,
frameborder: 0,
scrolling: 'no'
}).appendTo('#container-page').on('load',function(){
repeater(function() {
$('iframe#'+id).contents().find('.card.card-profile.card-profile-forum').attr("forum",name).detach().appendTo('.layout__content.homepage-feed');
$('.card[forum="'+name+'"]').find('.card-reason').each(function() {
$(this).text( $(this).text().replace("Recent activity", ""+name+": ") );
$(this).parents('.card.card-profile.card-profile-forum').attr("age",$(this).text().split(": ")[1].trim());
});
orderFeeds();
expandTruncate();
}, 1000, 30);
});
}
function feedFrames(){
var name = $('.name')[0].href.split("/")[4];
var req = "https://disqus.com/api/3.0/users/listFollowingForums?limit=100&user=username:"+name+"&order=desc&cursor=&api_key="+api;
$.get( req, function( data ) {
for ( i=0; i<data.response.length; i++ ){
var id = data.response[i].id;
var src = "https://disqus.com/home/forum/"+id+"/";
var name = data.response[i].name;
feedFrame(id, src, name);
}
});
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
function getFrame(){
dsq = $('iframe[id*="dsq"]').last().attr("id");
body = ''; if ( typeof dsq == 'undefined') { body = $('body'); } else { body = $("#"+dsq).contents(); }
win = ''; if ( typeof dsq == 'undefined') { win = $('window'); } else { win = $("#"+dsq)[0].contentWindow; }
}
function Initialize(){
body = ''; if ( typeof dsq == 'undefined') { body = $('body'); } else { body = $("#"+dsq).contents(); }
console.log("DE: DSQ Defined: " + dsq);
SetName();
$(".card-content__summary").find('strong:contains("Comments")').prepend('<a id=ExpandComments >Show all</a>');
$("#ExpandComments").on('click', function(e) { e.preventDefault(); expandComments(); });
window.addEventListener('scroll', function() {
RemoveTrollAvatar();
getUpvotes();
getDetails();
});
body.off().on('click', function() {
console.log("DE: Click");
RemoveTrollAvatar();
expandTruncate();
expandMargins();
unReferLinks();
Downvotes();
getUpvotes();
getDetails();
});
body.click();
if (window.location.href.indexOf('//disqus.com/by') >= 0 ||
window.location.href.indexOf('//disqus.com/home/inbox/') >= 0 ||
window.location.href.indexOf('//disqus.com/home/discussions/') >= 0 ) {
searchComments();
}
if (window.location.href.indexOf('//disqus.com/home/discussions/') >=0 ) {
feedFrames();
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
console.log( "DE: Start of DISQUS_ENHANCER" );
setTimeout (function() {
var expand_timer = setInterval (function() {
console.log( "DE: Waiting" );
dsq = $('iframe[id*="dsq"]').last().attr("id"); console.log("DE: DSQ IFrame Set: " + dsq);
body = ''; if ( typeof dsq == 'undefined') { body = $('body'); } else { body = $("#"+dsq).contents(); }
win = ''; if ( typeof dsq == 'undefined') { win = $('window'); } else { win = $("#"+dsq)[0].contentWindow; }
if ( $(".card__content").length > 0 || $(".card-profile").length > 0 ) {
clearInterval(expand_timer);
console.log( "DE: Initializing" );
Initialize();
}
}, 1000);
}, 1000);
setTimeout( function() {
console.clear();
window.addEventListener('click', function() {
if ( counter === 0 ) {
setTimeout (function() { getFrame(); counter = 0; }, 500);
}
counter++;
});
window.addEventListener('scroll', function() {
if ( counter === 0 ) {
setTimeout (function() { getFrame(); counter = 0; }, 500);
}
counter++;
});
var counter = 0;
getFrame();
},2000);