// ==UserScript==
// @name Enhanced MacRumors Spy
// @namespace sd.macrumors.spy
// @version 0.11c
// @author sammich (original), ShinyDren (small tweaks to the right-align mode)
// @match https://forums.macrumors.com/spy/
// @match https://forums.macrumors.com/spy/
// ==/UserScript==
/*
Doco is all at the link here:
https://gist.github.com/sammich/383a85b301bef328fd87
Notes:
- localStorage is assumed
- CSS3 transitions are assumed (fallback is no animation)
*/
// see the attached gist to see the unminified version
var styl = document.createElement('style');
var fadeInTimeMs = 300;
styl.textContent =
'#spyContents .location .major {font-size: smaller;}' +
'.mod_extras span, .mod_extras label {color: rgb(115, 126, 136);font-size: 12px;margin-left: 6px;}' +
'.itemWrapper.firstBatch {visibility: hidden;opacity: 0;-webkit-transition: opacity '+fadeInTimeMs+'ms ease-out;-moz-transition: opacity '+fadeInTimeMs+'ms ease-out;-o-transition: opacity '+fadeInTimeMs+'ms ease-out;transition: opacity '+fadeInTimeMs+'ms ease-out;}.itemWrapper.show {opacity: 1;visibility: visible;}' +
'.loggedInUserPost {background-color:rgb(242, 250, 237) !important; } .meta {float:right;color: rgb(115, 126, 136);font-size: smaller;}#spyContents{margin:0}.titleBar,.sectionHeaders > *,.sectionHeaders .event,#AjaxProgress,.listBlock.event { display:none !important; }.discussionListItem .prefix {position:relative;top:-1px;}.listBlock.info {padding:5px 10px;}.discussionListItem .listBlock {vertical-align:top !important;padding:5px 10px;}@media (max-width: 610px) {.discussionListItem .listBlock {border-right:none;}}.whoWhere{padding-bottom:0;}@media (max-width: 520px) {.discussionList .info > div {padding: 5px 5px 5px 8px !important;}}#ignoreForums textarea {border-radius: 4px; border: 1px solid rgb(198, 207, 220);padding: 3px;width: 100%;box-sizing: border-box;margin-top: 5px;}#ignoreForums textarea:focus {outline: none;}#ignoreForums span {color: rgb(115, 126, 136);font-size: 12px;margin-left: 6px;}';
document.body.appendChild(styl);
function spyInsert () {
function modPost(post) {
var tempEl = $(post);
var time = tempEl.find('.event .titleText dt').text(),
event = tempEl.find('.event .titleText h3').text(),
forum = tempEl.find('.location .major').text(); // grab the post info from the hidden column
var user = tempEl.find('.location .username').text(); // get the post user so we can highlight the current user's posts
var ignore = window.spymod_ignoreForums.indexOf(forum) > -1; // set the ignore status
if (event === 'New Thread') {
tempEl.find('.info .whoWhere a').prepend('<span class="prefix prefixGreen">+</span> '); // if the post is a new thread, add a tag to the post
}
if ( user === window.spymod_username ) {
tempEl.addClass('loggedInUserPost'); // if it's the user, add a class to highlight it with a faint green
}
if (!window.spymod_rightMode) {
tempEl.find('.location .whoWhere').prepend('<span class="meta">' + time + '</span>'); // add the new tag for the timestamp of the post
} else { // Right-aligned mode is enabled (on bottom of page).
tempEl.find('.info .whoWhere').prepend('<span class="meta">' + time + '</span>'); // add the new tag for the timestamp of the post
var snip = tempEl.find('.listBlock.location');
tempEl.find('.info').after(snip);
//--- START Code Group A ---// Comment this section and uncomment Group B section to flip which text is on top and change text sizes.
//snip = tempEl.find('.listBlock.location .major');
//tempEl.find('.listBlock.location .whoWhere').prepend(snip);
//--- END Code Group A ---//
//--- START Code Group B ---// Comment this section and uncomment Group A section to return which text is on top to original.
snip = tempEl.find('.listBlock.info .snippet');
snip.prev().before(snip);
tempEl.find('.location .major').css({fontWeight: "normal"}); // #spyContents .location .major {font-weight: normal;}
tempEl.find('.location .whoWhere .username').css({display: "block", textAlign: "right", fontSize: "x-small"}); // .location .whoWhere .username {display: block;text-align: right;font-size: x-small;}
tempEl.find('.listBlock.location').css("cssText", "vertical-align: middle !important;"); // .discussionListItem .listBlock.location {vertical-align: middle !important;}
tempEl.find('.info .meta').css({padding: "10px 0 0 5px", fontSize: "x-small"}); // .discussionListItem .info .meta {padding: 10px 0 0 5px;font-size: x-small;}
tempEl.find('.info .snippet').css({fontStyle: "normal", fontSize: "initial"}); // .discussionListItem .info .snippet {font-style: normal;font-size: initial;}
tempEl.find('.info .whoWhere a').css({display: "block", textAlign: "right", fontSize: "100%", fontStyle: "italic"}); // .discussionListItem .info .whoWhere a {display: block;text-align: right;font-size: 100%;font-style: italic;}
//--- END Code Group B ---//
}
return ignore ? null : tempEl; // don't return anything if the post isn't to be shown anyway
}
// for the intial run, we want to avoid the complex timeout loop prepending multiple posts
if (!window.spymod_insertHasRunOnce) {
window.spymod_insertHasRunOnce = true;
var fragment = spyItems.reverse().map(function (post) {
post = modPost(post);
return post ? '<div class="itemWrapper firstBatch" style="display:block">' + post[0].outerHTML + '</div>': '';
}).join('');
// add the posts
$('#spyContents .discussionListItems').html(fragment);
setTimeout(function () {
$('#spyContents .discussionListItems').find('.itemWrapper').addClass('show');
}, 50); // add a delay as there seems to be a judder when you run it too close to page load
// intialise the posts so that it skips the normal path below
spyItems = [];
}
if (spyItems.length) {
var post = modPost(spyItems.shift()); // create the fragment so we can inspect and modify it
// ignored posts will be falsey
if (post) {
// modified to use the modified HTML fragment
$('#spyContents .discussionListItems').prepend('<div class="itemWrapper">' + post[0].outerHTML + '</div>');
$('#spyContents .itemWrapper:first-child').slideDown(spyTiming / 3);
}
if ($('#spyContents .itemWrapper').length > 25) {
var lastChild = $('#spyContents .itemWrapper:last-child');
lastChild.slideUp(spyTiming / 2, function() {
lastChild.remove();
});
}
}
if (spyItems.length) { // This version does not show a syntax error in tampermonkey (still works the same as the original I think).
setTimeout(spyInsert, spyTiming);
} else {
spyTiming = 2E3;
setTimeout(getSpyItems, 5E3);
}
// spyItems.length ? setTimeout(spyInsert, spyTiming) : (spyTiming = 2E3, setTimeout(getSpyItems, 5E3)); // Original, shows syntax error in tampermonkey but still works.
}
function _runSpyMod() {
window.spymod_username = $('#header .accountUsername').text();
window.spyTiming = 0;
$('.breadBoxBottom').after(
// ignore forums input
'<div id="ignoreForums"><span>Ignore Forums (separate with semi-colons):</span><textarea placeholder="Forum 1;Forum 2"></textarea></div>' +
// right-mode spy
'<div class="mod_extras"><input type="checkbox" id="spymod_rightmode"><label for="spymod_rightmode">Right-aligned mode (reload page after setting)</label></div>'
);
// note that LS returns a string not the bool. Any truthy value is true
window.spymod_rightMode = !!localStorage.getItem('_mod_rightmode');
$('#spymod_rightmode')
.prop('checked', window.spymod_rightMode)
.change(function () {
if (this.checked) {
localStorage.setItem('_mod_rightmode', true);
} else {
localStorage.removeItem('_mod_rightmode');
}
});
// ignore setup
var ignored = localStorage.getItem('_mod_ignoredForums') || '';
window.spymod_ignoreForums = ignored.split(';');
$('#ignoreForums textarea')
.val(window.spymod_ignoreForums.join(';') + ';')
.on('paste change', function(e) {
var el = this;
// skip a beat because the paste event will otherwise give you the value before the paste
setTimeout(function() {
var ignore = el.value.split(';');
// remove any too short values like consecutive semi-colons
for (var i = 0; i < ignore.length; i++) {
if (ignore[i].length < 2) {
ignore.splice(i--, 1);
}
}
// save
localStorage.setItem('_mod_ignoredForums', ignore.join(';'));
// set global
window.spymod_ignoreForums = ignore;
// set display
el.value = window.spymod_ignoreForums.join(';') + ';';
// update spy
$('.itemWrapper .location .major').each(function() {
var el = $(this);
el.closest('.itemWrapper').toggle(window.spymod_ignoreForums.indexOf(el.text()) < 0); // Seems to work the same way. Removed the exclamation point and switched the comparison operator and value.
// el.closest('.itemWrapper').toggle(!window.spymod_ignoreForums.indexOf(el.text()) > -1); // Original, syntax warning in tampermonkey.
});
});
});
}
function _runSuperMod() {
$('body').append('<div id="mainview"><div id="spymod_col1"><div class="header">asdasd</div></div><div id="spymod_col1"><div class="header"><select name="" id="threadselector"></select></div></div><div id="threadbox"><iframe src="" frameborder="0" id="threadframe"></iframe></div></div>');
}
var script = document.createElement('script');
script.textContent = spyInsert.toString() + ';(' + _runSpyMod.toString() + ')()'; // + ';(' + _runSuperMod.toString() + ')()';
document.body.appendChild(script);