// ==UserScript==
// @name karaunlocker
// @namespace karachan.org
// @description A po szkole wchodziliśmy na kurahen :)
// @version 1.3
// @downloadURL https://gist.github.com/lanceq1337
// @grant GM_addStyle
// @match *://*.karachan.org/*
// @exclude http://www.karachan.org/*/src/*
// @exclude https://www.karachan.org/*/src/*
// @exclude http://karachan.org/*/src/*
// @exclude https://karachan.org/*/src/*
// @match *://*.karachan.co/*
// @exclude http://www.karachan.co/*/src/*
// @exclude https://www.karachan.co/*/src/*
// @exclude http://karachan.co/*/src/*
// @exclude https://karachan.co/*/src/*
// @match *://96.8.113.203/*
// @exclude http://96.8.113.203/*/src/*
// @exclude https://96.8.113.203/*/src/*
// @exclude http://96.8.113.203/*/src/*
// @exclude https://96.8.113.203/*/src/*
// ==/UserScript==
/*jshint curly:true, noarg:true, indent:4, trailing:true, forin:true, noempty:true, quotmark:single, eqeqeq:true,
undef:true, bitwise:true, browser:true, devel:true, nonbsp:true */
/*global GM_addStyle:false */
document.cookie="usuń=to";
localStorage.xD ="xD";
document.cookie="zjedzmielone=1";
var FormValidator = (function () {
function FormValidator() {
this.setSubmitAction();
}
FormValidator.prototype.setSubmitAction = function () {
var _this = this;
document.getElementById('submit').addEventListener('click', function (ev) {
if (!_this.isFileInputFilled() && !_this.isPostTextFilled()) {
ev.preventDefault();
alert('Napisz post lub dodaj śmieszny obrazek');
return;
}
if (document.cookie.indexOf('in_mod') === -1 && _this.getCaptchaFieldTextLenght() !== 6) {
ev.preventDefault();
alert('Ale kapcze to popraw');
return;
}
if (_this.getFileSize() > _this.getMaxFileSize()) {
ev.preventDefault();
alert('Plik zbyt duży');
return;
}
if (UrlChecker.isCurrentWebpageThread()) {
if (_this.isFileInputFilled() && !_this.isAllowedFileExt()) {
_this.reactToNotAllowedFileExt(ev);
}
return;
}
if (!_this.isNoFileAllowed() && !_this.isFileInputFilled()) {
ev.preventDefault();
alert('Wybierz plik');
return;
}
if (!_this.isFileInputFilled() && !_this.isNoFileChecked()) {
if (confirm('Wysłać bez pliku?')) {
_this.setNoFile();
} else {
ev.preventDefault();
}
return;
}
if (_this.isFileInputFilled() && !_this.isAllowedFileExt()) {
_this.reactToNotAllowedFileExt(ev);
}
});
};
FormValidator.prototype.reactToNotAllowedFileExt = function (ev) {
if (!confirm('Plik najprawdopodobniej nie jest obsługiwany, pomimo to chcesz procedować dalej?')) {
ev.preventDefault();
}
};
FormValidator.prototype.isPostTextFilled = function () {
return this.getPostTextLength() > 0;
};
FormValidator.prototype.getPostTextLength = function () {
return document.getElementsByName('com')[0].value.length;
};
FormValidator.prototype.isFileInputFilled = function () {
var fileFile = document.getElementById('postFile');
if (fileFile) {
return fileFile.value !== '';
} else {
return false;
}
};
FormValidator.prototype.getFileSize = function () {
if (!this.isFileInputFilled()) {
return 0;
}
return document.getElementById('postFile').files[0].size;
};
FormValidator.prototype.getMaxFileSize = function () {
var maxFileList = document.getElementsByName('MAX_FILE_SIZE');
if (maxFileList.length === 0) {
return 0;
}
var valStr = maxFileList[0].value;
return parseInt(valStr);
};
FormValidator.prototype.getCaptchaFieldTextLenght = function () {
var captchaField = document.getElementById('captchaField');
if (captchaField) {
return captchaField.value.length;
} else {
return 0;
}
};
FormValidator.prototype.isNoFileChecked = function () {
if (this.isNoFileAllowed()) {
return document.getElementById('nofile').checked;
} else {
return false;
}
};
FormValidator.prototype.isNoFileAllowed = function () {
if (document.getElementById('nofile')) {
return true;
} else {
return false;
}
};
FormValidator.prototype.isAllowedFileExt = function () {
if (!this.isFileInputFilled()) {
return false;
}
var fileName = document.getElementById('postFile').files[0].name;
var ext = fileName.split('.').pop().toLowerCase();
for (var i = 0; i < allowedFileExtensions.length; i++) {
if (ext === allowedFileExtensions[i]) {
return true;
}
}
return false;
};
FormValidator.prototype.setNoFile = function () {
document.getElementById('nofile').checked = true;
};
return FormValidator;
})();
var KurahenPremium = (function () {
function KurahenPremium() {
this.formValidator = new FormValidator();
var currentBoardName = UrlChecker.getCurrentBoardName();
if (currentBoardName === '' || UrlChecker.isCurrentPage404()) {
return;
} else if (currentBoardName === 'b') {
this.changeBoardTitle(customBBoardTitle);
}
this.updatePageTitle();
this.disableNightStyle();
this.setCookie('regulamin', 'accepted');
this.insertButtonBar();
this.replaceEmailFieldWithSelect();
this.showAllPostersEmails();
this.fixScrollingToTarget();
this.fixAllExternalLinks();
this.fixAllHiders();
this.fixAllExpanders();
if (boardsWithId.indexOf(currentBoardName) > -1 && UrlChecker.isCurrentWebpageThread()) {
this.colorizeAndNamePosters();
}
if (enableBetterFonts) {
this.changeFonts();
}
if (deleteTextUnderPostForm) {
this.removeTextUnderPostForm();
}
if (biggerOnlineCountFont) {
this.enlargeOnlineCountFont();
}
/* variable used to change "highlight posts" button state */
this.nowHighlightedPostsUserId = false;
this.threadsWatcher = new ThreadsWatcher();
}
KurahenPremium.prototype.changeBoardTitle = function (newTitle) {
document.title = newTitle;
document.getElementsByClassName('boardTitle')[0].textContent = newTitle;
};
KurahenPremium.prototype.updatePageTitle = function () {
var page = parseInt(window.location.pathname.split('/')[2]);
var prefix = '';
if (UrlChecker.isCurrentWebpageThread()) {
prefix = this.getTopicFromFirstPostContent();
} else if (!isNaN(page)) {
prefix = 'Strona ' + page;
}
if (prefix.length > 0) {
prefix += ' - ';
}
document.title = prefix + document.title;
};
KurahenPremium.prototype.setCookie = function (name, value) {
document.cookie = encodeURIComponent(name) + '=' + encodeURIComponent(value) + '; path=/; max-age=2592000';
};
KurahenPremium.prototype.changeFonts = function () {
var newLink = document.createElement('link');
newLink.href = '//fonts.googleapis.com/css?family=Roboto:400,700&subset=latin,latin-ext';
newLink.rel = 'stylesheet';
var existingLink = document.getElementsByTagName('link')[0];
existingLink.parentNode.insertBefore(newLink, existingLink);
document.body.style.fontFamily = 'Roboto, "Helvetica Neue", Helvetica, Arial, sans-serif';
};
KurahenPremium.prototype.getTopicFromFirstPostContent = function () {
var postMessage = document.querySelector('.thread .postMessage').cloneNode(true);
var backlinks = postMessage.getElementsByClassName('backlink');
if (backlinks.length > 0) {
postMessage.removeChild(backlinks[0]);
}
var links = postMessage.getElementsByClassName('postlink');
for (var i = 0; i < links.length; i++) {
links[i].parentNode.removeChild(links[i]);
}
var quoteLinks = postMessage.getElementsByClassName('quotelink');
for (var j = 0; j < quoteLinks.length; j++) {
postMessage.removeChild(quoteLinks[i]);
}
var postContent = postMessage.textContent.trim();
if (postContent === '') {
return '(brak treści posta)';
}
return postContent.substr(0, Math.min(postContent.length, 70));
};
KurahenPremium.prototype.disableNightStyle = function () {
var optionNight = document.querySelector('#stylechanger option[value$="night.css"]');
optionNight.disabled = true;
var optionNight2 = document.querySelector('#stylechanger option[value$="night2.css"]');
optionNight2.disabled = true;
};
KurahenPremium.prototype.replaceEmailFieldWithSelect = function () {
var emailField = document.querySelector('#postform input[name="email"]');
var select = document.createElement('select');
select.name = 'email';
select.style.margin = '0';
select.style.width = '236px';
select.addEventListener('change', function () {
// noinspection JSPotentiallyInvalidUsageOfThis
if (this.options[this.selectedIndex].value === 'custom') {
var textField = document.createElement('input');
textField.type = 'text';
textField.className = 'board-input';
textField.name = 'email';
select.parentNode.replaceChild(textField, select);
textField.focus();
}
}, false);
var optionBump = document.createElement('option');
optionBump.value = '';
optionBump.selected = true;
optionBump.textContent = 'Podbij';
select.appendChild(optionBump);
var optionSage = document.createElement('option');
optionSage.value = 'sage';
optionSage.textContent = 'Saguj';
select.appendChild(optionSage);
var optionCustom = document.createElement('option');
optionCustom.value = 'custom';
optionCustom.textContent = 'Wpisz własny...';
select.appendChild(optionCustom);
emailField.parentNode.replaceChild(select, emailField);
};
KurahenPremium.prototype.showAllPostersEmails = function () {
var postersEmails = document.getElementsByClassName('useremail');
for (var i = 0; i < postersEmails.length; i++) {
postersEmails[i].textContent += ' (' + this.parseMailto(postersEmails[i].getAttribute('href')) + ') ';
postersEmails[i].removeAttribute('href');
}
};
KurahenPremium.prototype.fixScrollingToTarget = function () {
if (window.location.hash.length > 1) {
setTimeout(function () {
document.querySelector(window.location.hash).scrollIntoView(true);
}, 1000);
}
};
KurahenPremium.prototype.fixAllHiders = function () {
var hiders = document.getElementsByClassName('hider');
for (var i = 0; i < hiders.length; i++) {
var hiderTextContent = hiders[i].textContent;
if (hiderTextContent === '[-]') {
hiders[i].textContent = '[—]';
} else if (hiderTextContent === '[+]') {
hiders[i].textContent = '[ + ]';
}
}
};
KurahenPremium.prototype.fixAllExpanders = function () {
var expanders = document.getElementsByClassName('expander');
for (var i = 0; i < expanders.length; i++) {
expanders[i].textContent = 'Rozwiń';
}
};
KurahenPremium.prototype.fixAllExternalLinks = function () {
var links = document.getElementsByClassName('postlink');
for (var i = 0; i < links.length; i++) {
links[i].setAttribute('href', links[i].getAttribute('href').replace('https://href.li/?', ''));
links[i].setAttribute('target', '_blank');
links[i].setAttribute('rel', 'noreferrer');
}
this.inlineVideoAndAudioLinks(links);
};
/**
* @private
*/
KurahenPremium.prototype.parseMailto = function (mailto) {
return mailto.replace('mailto:', '');
};
/**
* @private
*/
KurahenPremium.prototype.inlineVideoAndAudioLinks = function (links) {
for (var i = 0; i < links.length; i++) {
var url = links[i].getAttribute('href');
if (url.indexOf('http://vocaroo.com') > -1) {
var vocarooId = url.substr(url.length - 12, 12);
var vocarooContainer = document.createElement('div');
vocarooContainer.innerHTML = '';
if (links[i].nextSibling) {
links[i].parentNode.insertBefore(vocarooContainer, links[i].nextSibling);
} else {
links[i].parentNode.appendChild(vocarooContainer);
}
links[i].style.display = 'none';
}
}
};
KurahenPremium.prototype.colorizeAndNamePosters = function () {
var postersIds = document.getElementsByClassName('posteruid');
var postersStats = {};
var opId;
for (var i = 0; i < postersIds.length; i++) {
var posterId = this.parsePosterId(postersIds[i].textContent);
postersIds[i].title = posterId;
posterId = posterId.replace(/[\.|\/|\+|\-]/g, '_');
if (i === 0) {
opId = posterId;
}
postersIds[i].className += ' poster-id-' + posterId;
if (roundedIdBackground) {
postersIds[i].className += ' id-rounded';
}
if (posterId === opId) {
postersIds[i].textContent = '\u00a0OP nitki';
} else {
postersIds[i].textContent = '\u00a0' + posterId;
}
if (typeof postersStats[posterId] === 'undefined') {
postersStats[posterId] = [postersIds[i]];
} else {
postersStats[posterId].push(postersIds[i]);
}
}
var style = '';
for (var id in postersStats) {
if (postersStats.hasOwnProperty(id) && postersStats[id].length > 1) {
style += '.poster-id-' + id + '{color:#000;background-color: ' + this.getNextColor() + ';}\n';
var numeral;
if (postersStats[id].length < 5) {
numeral = ' posty';
} else {
numeral = ' postów';
}
if (showPostCountNearId) {
style += '.poster-id-' + id + ':after{content:" (';
style += postersStats[id].length + numeral + ')\u00a0"}\n';
}
if (enableHighlightPostsButton) {
this.setHighlightPostsButton(postersStats[id], id);
}
if (enableJumpButtons) {
this.setJumpButtons(postersStats[id]);
}
}
}
if (roundedIdBackground) {
style += '.id-rounded { font-size: 11px; border-radius: 6px; padding: 0px 6px 0px 2px;}\n';
}
style += '.small-icon { font-size: 16px; vertical-align: middle }\n';
style += '.post-animated { transition: opacity 0.4s}\n';
style += '.hiden-post { opacity: ' + unhighlightedPostOpacity + '}\n';
style += '.highlighting-button { font-size: 11px; cursor:pointer}\n';
style += '.highlighting-button:hover { color: orange;}\n';
GM_addStyle(style);
var allUserPosts = document.getElementsByClassName('postContainer');
for (i = 0; i < allUserPosts.length; i++) {
allUserPosts[i].classList.add('post-animated');
}
var firstPostBar = document.querySelector('.opContainer .postInfo');
var threadPostersStats = document.createElement('span');
threadPostersStats.textContent = ' (' + postersIds.length + ' postów od ' + Object.keys(postersStats).length +
' anonów)';
firstPostBar.appendChild(threadPostersStats);
};
/**
* @private
*/
KurahenPremium.prototype.getNextColor = function () {
if (colors.length > 0) {
return colors.shift();
} else {
return '#' + Math.random().toString(16).substr(-6);
}
};
/**
* @private
*/
KurahenPremium.prototype.parsePosterId = function (text) {
return text.trim().substr(5, 8);
};
/**
* @private
*/
KurahenPremium.prototype.getPostNo = function (userPost) {
var id = userPost.parentNode.parentNode.getAttribute('id');
return id.substr(2, id.length - 2);
};
KurahenPremium.prototype.setButtonLabelsForId = function (userId, buttonLabel, newTitle) {
var buttons = document.querySelectorAll('[highlight-button-id="' + userId + '"]');
for (var i = 0; i < buttons.length; i++) {
buttons[i].textContent = buttonLabel;
buttons[i].title = newTitle;
}
};
KurahenPremium.prototype.highlightPostsById = function (userId) {
if (this.nowHighlightedPostsUserId) {
var showPostsStr = ' Pokaż posty';
if (showPostCountNearHighlightPostsButton) {
showPostsStr += ' (' + document.getElementsByClassName('poster-id-' + userId).length + ')';
}
this.setButtonLabelsForId(this.nowHighlightedPostsUserId, showPostsStr, 'Podświetl posty tego użytkownika');
}
if (this.nowHighlightedPostsUserId === userId) {
this.showAllPosts();
this.nowHighlightedPostsUserId = false;
} else {
this.setButtonLabelsForId(userId, ' Pokaż wszystkie', 'Wróć do widoku wszystkich postów');
this.hideAllPostsExcept(userId);
this.nowHighlightedPostsUserId = userId;
}
};
KurahenPremium.prototype.hideAllPostsExcept = function (userId) {
// lower opacity for all posts except these with given id
var allPosts = document.getElementsByClassName('postContainer');
for (var i = 0; i < allPosts.length; i++) {
if (this.getIdFromPostContainer(allPosts[i]) === userId) {
allPosts[i].classList.remove('hiden-post');
continue;
}
allPosts[i].classList.add('hiden-post');
}
};
KurahenPremium.prototype.showAllPosts = function () {
// set normal opacity for all posts
var allPosts = document.getElementsByClassName('postContainer');
for (var i = 0; i < allPosts.length; i++) {
allPosts[i].classList.remove('hiden-post');
}
};
KurahenPremium.prototype.getIdFromPostContainer = function (postContainer) {
// depends on modified page src
var idElement = postContainer.getElementsByClassName('posteruid')[0];
for (var i = 0; idElement.classList.length; i++) {
if (idElement.classList.item(i).indexOf('poster-id-') > -1) {
return idElement.classList.item(i).substr('poster-id-'.length, 8);
}
}
return null;
};
KurahenPremium.prototype.setHighlightPostsButton = function (userPosts, userId) {
var self = this;
var highlightPostsCallback = function () {
self.highlightPostsById(userId);
};
for (var i = 0; i < userPosts.length; i++) {
var showPostsButton = document.createElement('span');
var showPostsStr = ' Pokaż posty';
if (showPostCountNearHighlightPostsButton) {
showPostsStr += ' (' + userPosts.length + ')';
}
showPostsButton.textContent = showPostsStr;
showPostsButton.title = 'Podświetl posty tego użytkownika';
showPostsButton.className = 'highlighting-button';
showPostsButton.setAttribute('highlight-button-id', userId);
showPostsButton.addEventListener('click', highlightPostsCallback, false);
userPosts[i].parentNode.appendChild(showPostsButton);
}
};
KurahenPremium.prototype.setJumpButtonForPost = function (post, prev, next) {
var newButtonsContainer = document.createElement('span');
newButtonsContainer.style.marginLeft = '3px';
if (prev !== null) {
var upButton = document.createElement('a');
upButton.className = 'fa fa-chevron-up small-icon';
upButton.title = 'Poprzedni post tego użytkownika';
upButton.href = '#p' + prev;
newButtonsContainer.appendChild(upButton);
}
if (next !== null) {
var downButton = document.createElement('a');
downButton.className = 'fa fa-chevron-down small-icon';
downButton.title = 'Następny post tego użytkownika';
downButton.href = '#p' + next;
newButtonsContainer.appendChild(downButton);
}
post.parentNode.appendChild(newButtonsContainer);
};
KurahenPremium.prototype.setJumpButtons = function (userPosts) {
var postsNo = [];
for (var i = 0; i < userPosts.length; i++) {
postsNo.push(this.getPostNo(userPosts[i]));
}
this.setJumpButtonForPost(userPosts[0], null, postsNo[1]);
this.setJumpButtonForPost(userPosts[userPosts.length - 1], postsNo[postsNo.length - 2], null);
for (i = 1; i < userPosts.length - 1; i++) {
this.setJumpButtonForPost(userPosts[i], postsNo[i - 1], postsNo[i + 1]);
}
};
KurahenPremium.prototype.insertButtonBar = function () {
var postForm = document.getElementById('postform');
var textarea = document.querySelector('#postform textarea');
var buttonBar = document.createElement('div');
buttonBar.style.textAlign = 'center';
this.insertTextFormattingButtons(textarea, buttonBar);
this.insertSpecialCharButtons(textarea, buttonBar);
this.insertWordfilterList(textarea, buttonBar);
postForm.insertBefore(buttonBar, postForm.firstChild);
};
/**
* @private
*/
KurahenPremium.prototype.insertTextFormattingButtons = function (textarea, buttonBar) {
var onButtonClick = function () {
var startTag = '[' + this.value + ']';
var endTag = '[/' + this.value + ']';
var textBeforeSelection = textarea.value.substring(0, textarea.selectionStart);
var selectedText = textarea.value.substring(textarea.selectionStart, textarea.selectionEnd);
var textAfterSelection = textarea.value.substring(textarea.selectionEnd, textarea.value.length);
textarea.value = textBeforeSelection + startTag + selectedText + endTag + textAfterSelection;
textarea.focus();
textarea.selectionStart += startTag.length;
textarea.selectionEnd = textarea.selectionStart + selectedText.length;
};
for (var i = 0; i < bbCodes.length; i++) {
var button = document.createElement('input');
button.type = 'button';
button.value = bbCodes[i];
button.style.padding = '0 7px';
button.addEventListener('click', onButtonClick, false);
buttonBar.appendChild(button);
}
};
/**
* @private
*/
KurahenPremium.prototype.insertWordfilterList = function (textarea, buttonBar) {
var wordfiltersSelect = document.createElement('select');
var defaultOption = document.createElement('option');
defaultOption.value = '';
defaultOption.disabled = true;
defaultOption.selected = true;
defaultOption.textContent = 'WORDFILTRY';
wordfiltersSelect.appendChild(defaultOption);
wordfiltersSelect.addEventListener('change', function () {
// noinspection JSPotentiallyInvalidUsageOfThis
var textToInsert = this.options[this.selectedIndex].value;
var textBeforeEndOfSelection = textarea.value.substring(0, textarea.selectionEnd);
var textAfterEndOfSelection = textarea.value.substring(textarea.selectionEnd, textarea.value.length);
textarea.value = textBeforeEndOfSelection + textToInsert + textAfterEndOfSelection;
textarea.focus();
textarea.selectionStart = textBeforeEndOfSelection.length + textToInsert.length;
textarea.selectionEnd = textarea.selectionStart;
// noinspection JSPotentiallyInvalidUsageOfThis
this.selectedIndex = 0;
}, false);
for (var j = 0; j < wordfilters.length; j++) {
var option = document.createElement('option');
option.value = wordfilters[j][0];
option.textContent = wordfilters[j][1];
wordfiltersSelect.appendChild(option);
}
buttonBar.appendChild(wordfiltersSelect);
};
/**
* @private
*/
KurahenPremium.prototype.insertSpecialCharButtons = function (textarea, buttonBar) {
var onButtonClick = function () {
var injectedChar;
for (var i = 0; i < specialCharacters.length; i++) {
if (specialCharacters[i].buttonLabel === this.value) {
injectedChar = specialCharacters[i].contentToInsert;
break;
}
}
var beforeSelect = textarea.value.substring(0, textarea.selectionStart);
var afterSelect = textarea.value.substring(textarea.selectionStart, textarea.value.length);
textarea.value = beforeSelect + injectedChar + afterSelect;
textarea.focus();
textarea.selectionStart += 1;
textarea.selectionEnd = textarea.selectionStart;
};
for (var i = 0; i < specialCharacters.length; i++) {
var button = document.createElement('input');
button.type = 'button';
button.value = specialCharacters[i].buttonLabel;
button.title = specialCharacters[i].buttonTitle;
button.style.padding = '0 7px';
button.addEventListener('click', onButtonClick, false);
buttonBar.appendChild(button);
}
};
/**
* @private
*/
KurahenPremium.prototype.removeTextUnderPostForm = function () {
var rules = document.querySelector('tr.rules');
if (rules !== null) {
rules.parentNode.removeChild(rules);
}
};
/**
* @private
*/
KurahenPremium.prototype.enlargeOnlineCountFont = function () {
var counter = document.getElementById('counter');
var online = counter.lastChild.textContent;
counter.removeChild(counter.lastChild);
var newElement = document.createElement('b');
newElement.textContent = online;
counter.appendChild(newElement);
var container = counter.parentElement;
container.style.fontSize = '20px';
};
return KurahenPremium;
})();
var UrlChecker;
(function (UrlChecker) {
'use strict';
function isCurrentWebpageThread() {
return window.location.pathname.split('/')[2] === 'res';
}
UrlChecker.isCurrentWebpageThread = isCurrentWebpageThread;
function isCurrentPage404() {
return document.title === '404 Not Found';
}
UrlChecker.isCurrentPage404 = isCurrentPage404;
function getCurrentBoardName() {
var shouldBeBoard = window.location.pathname.split('/')[1];
if (shouldBeBoard === 'menu.html') {
return '';
}
if (shouldBeBoard === 'news.html') {
return '';
}
return shouldBeBoard;
}
UrlChecker.getCurrentBoardName = getCurrentBoardName;
})(UrlChecker || (UrlChecker = {}));
var ThreadsWatcher = (function () {
function ThreadsWatcher() {
this.loadWatchedThreads();
this.insertThreadsListWindow();
this.addWatchButtonsToPosts();
}
ThreadsWatcher.prototype.loadWatchedThreads = function () {
var item = localStorage.getItem('KurahenPremium_WatchedThreads');
if (item === null || item === 'null') {
this.watchedThreads = {};
} else {
this.watchedThreads = JSON.parse(item);
}
};
ThreadsWatcher.prototype.saveWatchedThreads = function () {
// Protection from concurrent modification
var savedWatchedThreads = JSON.parse(localStorage.getItem('KurahenPremium_WatchedThreads')) || {};
this.mergeWatchedThreads(savedWatchedThreads, this.watchedThreads);
localStorage.setItem('KurahenPremium_WatchedThreads', JSON.stringify(savedWatchedThreads));
};
ThreadsWatcher.prototype.getWatchedThreadsWindowTopPosition = function () {
var item = localStorage.getItem('KurahenPremium_WatchedThreads_Top');
if (item === null || item === '') {
return '35px';
} else {
return item;
}
};
ThreadsWatcher.prototype.setWatchedThreadsWindowTopPosition = function (position) {
localStorage.setItem('KurahenPremium_WatchedThreads_Top', position);
};
ThreadsWatcher.prototype.getWatchedThreadsWindowLeftPosition = function () {
var item = localStorage.getItem('KurahenPremium_WatchedThreads_Left');
if (item === null || item === '') {
return '4px';
} else {
return item;
}
};
ThreadsWatcher.prototype.setWatchedThreadsWindowLeftPosition = function (position) {
localStorage.setItem('KurahenPremium_WatchedThreads_Left', position);
};
ThreadsWatcher.prototype.getWatchedThreadsWindowCssPosition = function () {
var item = localStorage.getItem('KurahenPremium_WatchedThreads_CSS_Position');
if (item === null || item === '') {
return 'absolute';
} else {
return item;
}
};
ThreadsWatcher.prototype.setWatchedThreadsWindowCssPosition = function (positionProperity) {
localStorage.setItem('KurahenPremium_WatchedThreads_CSS_Position', positionProperity);
};
/**
* @private
*/
ThreadsWatcher.prototype.mergeWatchedThreads = function (originalObject, objectToAppend) {
for (var item in objectToAppend) {
if (objectToAppend.hasOwnProperty(item)) {
// Add not removed threads
if (objectToAppend[item] !== null) {
originalObject[item] = objectToAppend[item];
} else if (originalObject[item] !== null) {
delete originalObject[item];
}
}
}
};
ThreadsWatcher.prototype.getThreadObject = function (postId, boardName) {
return this.watchedThreads['th_' + boardName + '_' + postId];
};
ThreadsWatcher.prototype.addThreadObject = function (postId, boardName, lastReadPostId, topic) {
this.watchedThreads['th_' + boardName + '_' + postId] = {
'id': postId,
'boardName': boardName,
'lastReadPostId': lastReadPostId,
'topic': topic
};
};
ThreadsWatcher.prototype.updateThreadObject = function (postId, boardName, lastReadPostId) {
this.watchedThreads['th_' + boardName + '_' + postId].lastReadPostId = lastReadPostId;
};
ThreadsWatcher.prototype.removeThreadObject = function (postId, boardName) {
this.watchedThreads['th_' + boardName + '_' + postId] = null;
};
ThreadsWatcher.prototype.threadObjectExists = function (postId, boardName) {
return typeof this.watchedThreads['th_' + boardName + '_' + postId] === 'object' && this.watchedThreads['th_' +
boardName + '_' + postId] !== null;
};
ThreadsWatcher.prototype.threadsSize = function () {
return Object.keys(this.watchedThreads).length;
};
ThreadsWatcher.prototype.getWatchedThreadsList = function () {
return this.watchedThreads;
};
ThreadsWatcher.prototype.insertThreadsListWindow = function () {
var _this = this;
this.threadsListWindow = document.createElement('div');
this.threadsListWindow.id = 'watcher_box';
this.threadsListWindow.className = 'movable';
this.threadsListWindow.style.height = 'auto';
this.threadsListWindow.style.minHeight = '100px';
this.threadsListWindow.style.width = 'auto';
this.threadsListWindow.style.minWidth = '250px';
this.threadsListWindow.style.position = this.getWatchedThreadsWindowCssPosition();
this.threadsListWindow.style.top = this.getWatchedThreadsWindowTopPosition();
this.threadsListWindow.style.left = this.getWatchedThreadsWindowLeftPosition();
this.threadsListWindow.style.padding = '5px';
var threadsListWindowTitle = document.createElement('small');
threadsListWindowTitle.textContent = 'Obserwowane nitki';
this.threadsListWindow.appendChild(threadsListWindowTitle);
var threadsListWindowSticker = document.createElement('img');
threadsListWindowSticker.src = '/img/sticky.gif';
threadsListWindowSticker.style.position = 'absolute';
if (this.threadsListWindow.style.position === 'absolute') {
threadsListWindowSticker.style.opacity = '0.25';
} else {
threadsListWindowSticker.style.opacity = '1.0';
}
threadsListWindowSticker.style.right = '0px';
threadsListWindowSticker.style.cursor = 'default';
threadsListWindowSticker.onclick = function (ev) {
var stick = ev.toElement;
if (stick.style.opacity === '1') {
stick.style.opacity = '0.25';
_this.threadsListWindow.style.position = 'absolute';
_this.setWatchedThreadsWindowCssPosition('absolute');
var newtop = parseInt(_this.threadsListWindow.style.top) + document.body.scrollTop;
_this.threadsListWindow.style.top = newtop + 'px';
} else {
stick.style.opacity = '1';
_this.threadsListWindow.style.position = 'fixed';
_this.setWatchedThreadsWindowCssPosition('fixed');
newtop = parseInt(_this.threadsListWindow.style.top) - document.body.scrollTop;
_this.threadsListWindow.style.top = newtop + 'px';
}
};
this.threadsListWindow.appendChild(threadsListWindowSticker);
this.threadsHtmlList = document.createElement('ul');
this.threadsHtmlList.id = 'watched_list';
this.threadsListWindow.appendChild(this.threadsHtmlList);
var threads = this.getWatchedThreadsList();
for (var item in threads) {
if (threads.hasOwnProperty(item) && threads[item] !== null) {
this.addThreadListWindowEntry(threads[item].id, threads[item].boardName, threads[item].lastReadPostId, -1,
threads[item].topic);
}
}
var self = this;
this.threadsListWindow.addEventListener('mouseout', function () {
self.setWatchedThreadsWindowTopPosition(self.threadsListWindow.style.top);
self.setWatchedThreadsWindowLeftPosition(self.threadsListWindow.style.left);
}, false);
document.body.appendChild(this.threadsListWindow);
var script = document.createElement('script');
script.textContent = '$("#watcher_box").drags();';
document.body.appendChild(script);
};
ThreadsWatcher.prototype.addThreadListWindowEntry = function (id, boardName, lastReadPostId, unreadPostsNumber,
topic) {
var entry = document.createElement('li');
entry.id = 'wl_' + boardName + '_' + id;
var link = document.createElement('a');
link.href = '/' + boardName + '/res/' + id + '.html#p' + lastReadPostId;
entry.appendChild(link);
var unreadPostsSpan = document.createElement('span');
unreadPostsSpan.className = 'unreadPostsNumber';
unreadPostsSpan.textContent = '[' + (unreadPostsNumber >= 0 ? unreadPostsNumber : 'Ładowanie...') + '] ';
link.appendChild(unreadPostsSpan);
var linkTextSpan = document.createElement('span');
linkTextSpan.textContent = '/' + boardName + '/' + id + ': ' + topic;
link.appendChild(linkTextSpan);
this.threadsHtmlList.appendChild(entry);
var self = this;
if (this.getCurrentBoardName() === boardName && id === this.getCurrentThreadId()) {
lastReadPostId = this.getNewestPostIdFromThread(id);
unreadPostsSpan.textContent = '[0] ';
self.updateThreadObject(id, boardName, lastReadPostId);
this.saveWatchedThreads();
} else if (unreadPostsNumber < 0) {
this.getNumberOfNewPosts(boardName, id, lastReadPostId, function (boardName, threadId, lastReadPostId,
numberOfNewPosts, forceUpdate, status) {
if (status === 200 && (numberOfNewPosts > 0 || !hideThreadsWithNoNewPosts)) {
self.updateThreadListWindowEntry(threadId, boardName, lastReadPostId, numberOfNewPosts);
} else if (status === 200 && hideThreadsWithNoNewPosts && numberOfNewPosts === 0) {
self.removeThreadListWindowEntry(threadId, boardName);
} else if (status === 404) {
self.removeThreadListWindowEntry(threadId, boardName);
self.removeThreadObject(threadId, boardName);
self.saveWatchedThreads();
} else {
unreadPostsSpan.textContent = '[?] ';
}
if (forceUpdate) {
self.updateThreadObject(threadId, boardName, lastReadPostId);
self.saveWatchedThreads();
}
});
}
};
ThreadsWatcher.prototype.updateThreadListWindowEntry = function (id, boardName, lastReadPostId, unreadPostsNumber) {
var entry = document.getElementById('wl_' + boardName + '_' + id);
if (entry === null) {
console.error('Cannot update nonexistent thread /' + boardName + '/' + id);
return;
}
var link = entry.querySelector('a');
link.href = '/' + boardName + '/res/' + id + '.html#p' + lastReadPostId;
var unreadPostsSpan = link.querySelector('.unreadPostsNumber');
unreadPostsSpan.textContent = '[' + (unreadPostsNumber >= 0 ? unreadPostsNumber : 'Ładowanie...') + '] ';
};
ThreadsWatcher.prototype.removeThreadListWindowEntry = function (id, boardName) {
var entry = document.getElementById('wl_' + boardName + '_' + id);
if (entry === null) {
return;
}
this.threadsHtmlList.removeChild(entry);
};
ThreadsWatcher.prototype.addWatchButtonsToPosts = function () {
var postsBars = document.querySelectorAll('.opContainer .postInfo');
var self = this;
var toggleWatchLabel = function () {
if (this.textContent === 'Nie obserwuj') {
this.textContent = 'Obserwuj';
} else {
this.textContent = 'Nie obserwuj';
}
self.addRemoveWatchedThread(parseInt(this.getAttribute('data-post-id')), self.getCurrentBoardName());
};
for (var i = 0; i < postsBars.length; i++) {
var postId = this.parsePostId(postsBars[i]);
var watchButton = document.createElement('a');
watchButton.style.cursor = 'pointer';
watchButton.setAttribute('data-post-id', postId.toString());
watchButton.addEventListener('click', toggleWatchLabel, false);
var watchButtonContainer = document.createElement('span');
watchButtonContainer.className = 'watch-button-container';
watchButtonContainer.appendChild(watchButton);
var currentBoardName = this.getCurrentBoardName();
if (this.threadObjectExists(postId, currentBoardName)) {
watchButton.textContent = 'Nie obserwuj';
} else {
watchButton.textContent = 'Obserwuj';
}
var postNum = postsBars[i].querySelector('span.postNum');
postNum.insertBefore(watchButtonContainer, postNum.querySelector('span'));
}
GM_addStyle('.watch-button-container:before {content: " [";}\n' + '.watch-button-container:after{content: "] ";}');
};
ThreadsWatcher.prototype.addRemoveWatchedThread = function (postId, boardName) {
// Add new thread to watchlist
if (!this.threadObjectExists(postId, boardName)) {
var newestPostId = this.getNewestPostIdFromThread(postId);
var topic = this.getTopicOfThread(postId);
this.addThreadObject(postId, boardName, newestPostId, topic);
this.addThreadListWindowEntry(postId, boardName, newestPostId, 0, topic);
} else {
this.removeThreadListWindowEntry(postId, boardName);
this.removeThreadObject(postId, boardName);
}
this.saveWatchedThreads();
};
ThreadsWatcher.prototype.getNewestPostIdFromThread = function (threadId) {
var posts = document.querySelectorAll('.thread[id$="' + threadId + '"] .postContainer');
return parseInt(posts[posts.length - 1].id.substr(2));
};
ThreadsWatcher.prototype.getNumberOfNewPosts = function (boardName, threadId, lastPostId, callback) {
var request = new XMLHttpRequest();
request.open('GET', '/' + boardName + '/res/' + threadId + '.html', true);
var self = this;
request.onload = function () {
var forceUpdate = false;
// On error
if (request.status !== 200) {
callback(boardName, threadId, lastPostId, -1, forceUpdate, request.status);
return;
}
// On success
var parser = new DOMParser();
var doc = parser.parseFromString(request.responseText, 'text/html');
var postsContainers = doc.getElementsByClassName('postContainer');
var numberOfNewPosts = 0;
for (var i = 0; i < postsContainers.length; i++) {
if (self.parsePostId(postsContainers[i]) === lastPostId) {
numberOfNewPosts = postsContainers.length - 1 - i;
break;
}
}
// When last read post was deleted
if (numberOfNewPosts === 0) {
var lastDetectedPostId = self.parsePostId(postsContainers[postsContainers.length - 1]);
if (lastDetectedPostId !== lastPostId) {
lastPostId = lastDetectedPostId;
forceUpdate = true;
}
}
callback(boardName, threadId, lastPostId, numberOfNewPosts, forceUpdate, 200);
};
request.send();
};
ThreadsWatcher.prototype.getNumberOfNewPostsJSON = function (boardName, threadId, lastPostId, callback) {
var request = new XMLHttpRequest();
request.open('GET', '/' + boardName + '/res/' + threadId + '.json');
request.onload = function () {
var forceUpdate = false;
// On error
if (request.status !== 200) {
callback(boardName, threadId, lastPostId, -1, forceUpdate, request.status);
return;
}
// On success
var posts = JSON.parse(request.responseText).posts;
posts.shift();
// If only op post
if (posts.length === 0) {
callback(boardName, threadId, lastPostId, 0, forceUpdate, request.status);
}
posts.sort(function (a, b) {
return parseInt(a.no) - parseInt(b.no);
});
var numberOfNewPosts = 0;
for (var i = 0; i < posts.length; i++) {
if (parseInt(posts[i].no) === lastPostId) {
numberOfNewPosts = posts.length - 1 - i;
break;
}
}
// When last read post was deleted
if (numberOfNewPosts === 0) {
var lastDetectedPostId = parseInt(posts[posts.length - 1].no);
if (lastDetectedPostId !== lastPostId) {
lastPostId = lastDetectedPostId;
forceUpdate = true;
}
}
callback(boardName, threadId, lastPostId, numberOfNewPosts, forceUpdate, request.status);
};
request.send();
};
/**
* @private
*/
ThreadsWatcher.prototype.parsePostId = function (htmlElement) {
return parseInt(htmlElement.id.substr(2));
};
/**
* @private
*/
ThreadsWatcher.prototype.getCurrentBoardName = function () {
return document.querySelector('meta[property="og:boardname"]').getAttribute('content');
};
/**
* @private
*/
ThreadsWatcher.prototype.getCurrentThreadId = function () {
if (window.location.pathname.split('/')[2] !== 'res') {
return -1;
}
return parseInt(document.querySelector('.thread .opContainer').id.substr(2));
};
ThreadsWatcher.prototype.getTopicOfThread = function (threadId) {
var postMessage = document.querySelector('.thread[id$="' + threadId + '"] .postMessage').cloneNode(true);
var backlinks = postMessage.getElementsByClassName('backlink');
if (backlinks.length > 0) {
postMessage.removeChild(backlinks[0]);
}
var links = postMessage.getElementsByClassName('postlink');
for (var i = 0; i < links.length; i++) {
links[i].parentNode.removeChild(links[i]);
}
var quoteLinks = postMessage.getElementsByClassName('quotelink');
for (var j = 0; j < quoteLinks.length; j++) {
postMessage.removeChild(quoteLinks[i]);
}
var postContent = postMessage.textContent.trim();
if (postContent === '') {
return '(brak treści posta)';
}
return postContent.substr(0, Math.min(postContent.length, 25));
};
return ThreadsWatcher;
})();
// Konfiguracja
var customBBoardTitle = '/b/ - Random';
var enableBetterFonts = true;
var deleteTextUnderPostForm = false;
var biggerOnlineCountFont = false;
var hideThreadsWithNoNewPosts = false;
var enableHighlightPostsButton = true;
// postów danego użytkownika
var enableJumpButtons = true;
// Zaawansowana konfiguracja
var unhighlightedPostOpacity = 0.3;
// użytkownika; 0 - niewidoczny, 1 - nieprzezroczysty
var bbCodes = ['b', 'i', 'u', 'code', 'spoiler'];
var specialCharacters = [{
contentToInsert: '\u2026',
buttonTitle: 'Wielokropek',
buttonLabel: '\u2026'
}, {
contentToInsert: '\u200b',
buttonTitle: 'Spacja o zerowej szerokości',
buttonLabel: 'ZWSP'
}];
var wordfilters = [
['#nowocioty', 'STAROCIOTY PAMIĘTAJĄ'],
['#gimbo', 'xD'],
['#penis', 'pisiorek'],
['#wagina', 'cipuszka'],
['#m__b', 'groźny WYKOPEK wykryty'],
['#Lasoupeauxchoux', 'kapuśniaczek'],
['#homoś', 'pedał'],
['#korwinkrulempolski', 'kongres nowej prawicy'],
['#1%', 'groźny LEWAK wykryty'],
['#mylittlefaggot', 'PRZYJAŹŃ JEST MAGIĄ'],
['hizume', 'Mała Księżniczka'],
['#tetetka', 'ALE ZAPIERDALA'],
['/r/pcmasterrace', '/r/pcmasterrace']
];
var boardsWithId = ['b', 'fz', 'z'];
var colors = [
'#ff8080',
'#ffdd80',
'#80ffb7',
'#80d0ff',
'#c680ff',
'#ffae80',
'#d5ff80',
'#80fffd',
'#8097ff',
'#ff80ca',
'#ff7f7f',
'#779aef',
'#b0de6f',
'#cc66c0',
'#5cb9a9',
'#f3bb79',
'#8d71e2',
'#6dd168',
'#be5f7e',
'#7bc8f6'
];
var allowedFileExtensions = ['gif', 'jpeg', 'jpg', 'png', 'webm'];
/* internal configuration flags */
var roundedIdBackground = true;
var showPostCountNearHighlightPostsButton = true;
var showPostCountNearId = false;
showPostCountNearId = !enableHighlightPostsButton;
///
var main = function () {
window.kurahenPremium = new KurahenPremium();
};
if (navigator.userAgent.toLowerCase().indexOf('chrome/') > -1) {
// Chrome/Chromium/Opera Next
main();
} else {
// Firefox and others
window.addEventListener('DOMContentLoaded', main);
}