// ==UserScript==
// @name QQ/SB/SV Thread-Starter Highlighter
// @description Modified fork of "Xenforo 2 Thread-Starter Highlighter".
// @author ElDani, Imagination, Fizzfldt, C89sd
// @version 1.7
// @license Creative Commons BY-NC-SA
// @match https://forum.questionablequesting.com/threads/*
// @match https://forums.spacebattles.com/threads/*
// @match https://forums.sufficientvelocity.com/threads/*
// @encoding utf-8
// @grant none
// @noframes
// @nocompat Chrome
// @namespace https://greasyfork.org/users/1376767
// ==/UserScript==
const style = document.createElement('style');
style.textContent = `
@media (max-width: 650px) {
.mobile-only {
background-color: transparent !important;
}
}
`;
document.head.appendChild(style);
function LocalMain () {
var site = -1;
if (document.URL.indexOf("spacebattles.com") > -1) site=0;
if (document.URL.indexOf("sufficientvelocity.com") > -1) site=1;
if (document.URL.indexOf("questionablequesting.com") > -1) site=2;
if (site == -1) return;
var style;
var rgxp_style = /<link.*?href="css.php\?css=xenforo,form,public&style=(\d+)&/i
var match_style = rgxp_style.exec(document.documentElement.outerHTML);
if (match_style != null) {
style = match_style[1];
} else {
// Fake style
style = 2
}
var highlightColor = new Array();
highlightColor[0] = new Array();
highlightColor[0][2] = "#152E18"; // SB: SpaceBattles.com
highlightColor[0][4] = "#152E18"; // SB: Flexile Dark Standalone
highlightColor[0][6] = "#F5F6CE"; // SB: XenForo Default Style
highlightColor[1] = new Array();
highlightColor[1][1] = "#F5F6CE"; // SV: Default Style
highlightColor[1][2] = "#152E18"; // SV: Flexile Dark
highlightColor[1][3] = "#152E18"; // SV: Flexile Gold
highlightColor[1][5] = "#152E18"; // SV: Dark Wide
highlightColor[1][6] = "#152E18"; // SV: Gold Fixed
highlightColor[1][7] = "#424242"; // SV: Space
highlightColor[1][11] = "#152E18"; // SV: FlexileSpace
highlightColor[1][20] = "#152E18"; // SV: FlexileSpace
highlightColor[2] = new Array();
highlightColor[2][1] = "#F5F6CE"; // QQ: XenForo Default Style
highlightColor[2][2] = "#152E18"; // QQ: Blackend
highlightColor[2][3] = "#152E18"; // QQ: Blackend-Blue
highlightColor[2][4] = "#152E18"; // QQ: Blackend-Green
highlightColor[2][5] = "#152E18"; // QQ: Blackend-Purple
highlightColor[2][8] = "#152E18"; // QQ: Flexile Dark
highlightColor[2][9] = "#152E18"; // QQ: Dark Responsive (Green)
highlightColor[2][10] = "#152E18"; // QQ: Dark Responsive High Contrast
highlightColor[2][14] = "#F5F6CE"; // QQ: Light Responsive
highlightColor[2][18] = "#152E18"; // QQ: UI.X Dark
highlightColor[2][20] = "#152E18"; // QQ: UI.X Dark (Mobile)
highlightColor[2][21] = "#F5F6CE"; // QQ: UI.X Light
const darken = (hex, factor) => {
let [r, g, b] = hex.replace('#', '').match(/\w\w/g).map(c => parseInt(c, 16)); // Remove #, to hex
const toHex = c => Math.min(255, Math.max(0, Math.round(c * factor))).toString(16).padStart(2, '0');
return '#' + toHex(r) + toHex(g) + toHex(b);
};
var base = highlightColor[site][style];
var darker = darken(base, 0.4);
var lighter = darken(base, 2.3);
function rgbToHsl(r, g, b) {
r /= 255, g /= 255, b /= 255;
var max = Math.max(r, g, b), min = Math.min(r, g, b);
var h, s, l = (max + min) / 2;
if (max == min) {
h = s = 0; // achromatic
} else {
var d = max - min;
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
switch (max) {
case r: h = (g - b) / d + (g < b ? 6 : 0); break;
case g: h = (b - r) / d + 2; break;
case b: h = (r - g) / d + 4; break;
}
h /= 6;
}
return [ h, s, l ];
}
function hslToRgb(h, s, l) {
var r, g, b;
if (s == 0) {
r = g = b = l; // achromatic
} else {
function hue2rgb(p, q, t) {
if (t < 0) t += 1;
if (t > 1) t -= 1;
if (t < 1/6) return p + (q - p) * 6 * t;
if (t < 1/2) return q;
if (t < 2/3) return p + (q - p) * (2/3 - t) * 6;
return p;
}
var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
var p = 2 * l - q;
r = hue2rgb(p, q, h + 1/3);
g = hue2rgb(p, q, h);
b = hue2rgb(p, q, h - 1/3);
}
return [ r * 255, g * 255, b * 255 ];
}
const bgTintCache = new Map();
function applyBgTint(node) {
const rgb = getComputedStyle(node).backgroundColor;
if (bgTintCache.has(rgb)) {
node.style.backgroundColor = bgTintCache.get(rgb);
return;
}
const hex = base;
const [r1, g1, b1] = rgb.match(/\d+/g).map(Number);
const hexVal = hex.startsWith("#") ? hex.slice(1) : hex;
const r2 = parseInt(hexVal.slice(0, 2), 16);
const g2 = parseInt(hexVal.slice(2, 4), 16);
const b2 = parseInt(hexVal.slice(4, 6), 16);
const baseHsl = rgbToHsl(r2, g2, b2);
const rgbHsl = rgbToHsl(r1, g1, b1);
const out = hslToRgb(baseHsl[0], baseHsl[1], rgbHsl[2]);
const outputColor = `rgb(${out[0]}, ${out[1]}, ${out[2]})`;
bgTintCache.set(rgb, outputColor);
node.style.backgroundColor = outputColor;
}
var starter = document.getElementsByClassName("username u-concealed")[0].innerHTML;
var my_user = document.getElementsByClassName("p-navgroup-linkText")[0].innerHTML;
var messages = document.getElementsByClassName("message message--post js-post js-inlineModContainer");
var nr_messages = messages.length;
var username;
var starter_posts = 0;
var my_posts = 0;
for(var i=0; i<nr_messages; i++) {
//username = messages[i].getElementsByClassName("username");
username = messages[i].getAttribute("data-author");
if (starter == username) {
starter_posts++;
var user_anchor = messages[i].getElementsByClassName("username ")[0];
user_anchor.innerHTML = '<strong style="color:crimson">AUTHOR:</strong><br/> ' + user_anchor.innerHTML;
} else if (my_user == username) {
my_posts++;
} else if (messages[i].classList.contains('hasThreadmark')) {
// Sometimes, someone other than the starter is posting in the thread.
} else {
messages[i].style.backgroundColor=highlightColor[site][style];
var quotes = messages[i].querySelectorAll("blockquote");
for (quote of quotes) {
var quoteTitle = quote.querySelector("div.bbCodeBlock-title");
applyBgTint(quote);
if (quoteTitle) applyBgTint(quoteTitle);
}
var left = messages[i].querySelector("div.message-cell.message-cell--user");
var right = messages[i].querySelector("div.message-cell.message-cell--main");
if (left && right) left.style.backgroundColor = getComputedStyle(right).backgroundColor;
var reactionbar = messages[i].querySelector("div.reactionsBar");
if (reactionbar) applyBgTint(reactionbar);
var rating = messages[i].querySelector("div.sv-rating");
if (rating) applyBgTint(rating);
var icons = messages[i].querySelectorAll("div.sv-rating__count");
for (icon of icons) { applyBgTint(icon); }
if (site==0) {
var detail1 = messages[i].querySelector("div.message-userDetails");
var detail2 = messages[i].querySelector("div.message-userExtras");
if (detail1) {
applyBgTint(detail1);
detail1.classList.add('mobile-only');
}
if (detail2) {
applyBgTint(detail2);
detail2.classList.add('mobile-only');
}
}
}
}
var posts1;
if (starter_posts == 0) {
posts1 = "No posts";
} else if (starter_posts == 1) {
posts1 = "1 post";
} else {
posts1 = starter_posts + " posts";
}
var modify = document.getElementsByClassName("p-description")[0];
modify.innerHTML = modify.innerHTML + '<strong style="color:silver">' + posts1 + " by " + starter + "<br/>";
}
window.addEventListener ("load", LocalMain, false);