280 lines
8.4 KiB
JavaScript
280 lines
8.4 KiB
JavaScript
// ==UserScript==
|
||
// @name JRM: JoyReactor Mod
|
||
// @description Модификация JoyReactor
|
||
// @version 2.4.2
|
||
// @author DmitriyMX
|
||
// @namespace https://gitlab.com/DmitriyMX/joyreactor-mod
|
||
// @downloadURL https://gitlab.com/DmitriyMX/joyreactor-mod/raw/master/jrm.user.js
|
||
// @updateURL https://gitlab.com/DmitriyMX/joyreactor-mod/raw/master/jrm.user.js
|
||
// @match http://joy.reactor.cc/*
|
||
// @grant none
|
||
// @run-at document-end
|
||
// ==/UserScript==
|
||
|
||
class Post {
|
||
/**
|
||
* @param {HTMLElement} elmPost
|
||
*/
|
||
constructor(elmPost) {
|
||
const pc_len = 'postContainer'.length;
|
||
|
||
/** @public {Number} */
|
||
this.id = parseInt(elmPost.id.substring(pc_len));
|
||
|
||
/** @public {String} */
|
||
this.author = elmPost.getElementsByClassName('uhead_nick')[0].getElementsByTagName('a')[0].text;
|
||
|
||
/** @public {String[]} */
|
||
this.tags = [];
|
||
for (const elmChild of elmPost.getElementsByClassName('taglist')[0].children) {
|
||
this.tags.push(elmChild.textContent.trim());
|
||
}
|
||
}
|
||
}
|
||
|
||
class Comment {
|
||
/**
|
||
* @param {HTMLElement} elmComment
|
||
*/
|
||
constructor(elmComment) {
|
||
const cm_len = 'comment'.length;
|
||
|
||
/** @public {HTMLElement} */
|
||
this.element = elmComment;
|
||
|
||
/** @public {Number} */
|
||
this.id = parseInt(elmComment.id.substring(cm_len));
|
||
|
||
const elmsTxt = elmComment.getElementsByClassName('txt');
|
||
|
||
/** @public {String} */
|
||
this.author = null;
|
||
/** @public {String} */
|
||
this.text = null;
|
||
if (elmsTxt.length > 0) {
|
||
let elms = elmsTxt[0].getElementsByClassName('comment_username');
|
||
if (elms.length > 0) {
|
||
this.author = elmsTxt[0].getElementsByClassName('comment_username')[0].textContent;
|
||
this.text = elmsTxt[0].children[0].textContent;
|
||
} else if (elmComment.getElementsByClassName('comment_show').length > 0) {
|
||
this.author = elmComment.getElementsByClassName('comments_bottom')[0].children[1].children[0].textContent;
|
||
this.text = '[HIDDEN COMMENT]';
|
||
}
|
||
}
|
||
|
||
if (this.author === null) {
|
||
throw new Error('author is NULL');
|
||
}
|
||
|
||
/** @public {String} */
|
||
this.image = null;
|
||
if (elmComment.getElementsByClassName('image').length > 0) {
|
||
this.image = elmComment.getElementsByClassName('image')[0].children[0].href;
|
||
}
|
||
|
||
/** @public {Comment[]} */
|
||
this.children = [];
|
||
for (const childComment of document.getElementById('comment_list_comment_' + this.id).children) {
|
||
if (childComment.id.startsWith('comment_list_comment_')) {
|
||
continue;
|
||
}
|
||
|
||
try {
|
||
this.children.push(new Comment(childComment));
|
||
} catch (e) {
|
||
console.error("--- ERROR ---");
|
||
console.error(childComment);
|
||
console.error(e);
|
||
console.error("--- END ---");
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
class JRApi {
|
||
constructor() {
|
||
/** @private {RegExp} */
|
||
this._urlPostRegexp = new RegExp("https?:\/\/.+/post/([0-9]+)");
|
||
/** @private {Comment[]} */
|
||
this._comments = null;
|
||
}
|
||
|
||
/**
|
||
* @return {Boolean}
|
||
*/
|
||
isPostPage() {
|
||
return (document.URL.match(this._urlPostRegexp) !== null);
|
||
}
|
||
|
||
/**
|
||
* @return {Post}
|
||
*/
|
||
post() {
|
||
const postId = document.URL.match(this._urlPostRegexp)[1];
|
||
const elmPostContainer = document.getElementById('postContainer' + postId);
|
||
|
||
return new Post(elmPostContainer);
|
||
}
|
||
|
||
/**
|
||
* @return {Post[]}
|
||
*/
|
||
posts() {
|
||
const elmPostList = document.getElementById('post_list');
|
||
const postList = [];
|
||
for (const elmPostContainer of elmPostList.children) {
|
||
postList.push(new Post(elmPostContainer));
|
||
}
|
||
|
||
return postList;
|
||
}
|
||
|
||
/**
|
||
* @return {Comment[]}
|
||
*/
|
||
comments() {
|
||
if (this._comments == null) {
|
||
const postId = document.URL.match(this._urlPostRegexp)[1];
|
||
|
||
this._comments = [];
|
||
for (const elmComment of document.getElementById('comment_list_post_' + postId).children) {
|
||
if (elmComment.id.startsWith('comment_list_comment_')) {
|
||
continue;
|
||
}
|
||
|
||
this._comments.push(new Comment(elmComment));
|
||
}
|
||
}
|
||
|
||
return this._comments;
|
||
}
|
||
}
|
||
|
||
class JRMod {
|
||
/**
|
||
* @param {JRApi} jrApi
|
||
*/
|
||
constructor(jrApi) {
|
||
this.jrApi = jrApi;
|
||
}
|
||
|
||
/**
|
||
* Добавляем кнопку сворачивания ветки комментариев
|
||
*/
|
||
addCollapseTreeCommentsButton() {
|
||
/**
|
||
* @param {Comment} comment
|
||
* @return {HTMLElement}
|
||
*/
|
||
const createButton = function (comment) {
|
||
const aTag = document.createElement('a');
|
||
aTag.href = "#";
|
||
aTag.innerHTML = '➖';
|
||
|
||
aTag.style.fontWeight = 'bold';
|
||
aTag.style.color = '#656464';
|
||
aTag.style.lineHeight = '31px';
|
||
aTag.style.textDecoration = 'none';
|
||
aTag.style.margin = '0 10px';
|
||
aTag.style.padding = '0 10px'
|
||
aTag.style.borderRadius = '15px';
|
||
aTag.style.background = '#dfdfdf';
|
||
|
||
const elmSubCommentList = document.getElementById('comment_list_comment_' + comment.id);
|
||
aTag.onclick = function () {
|
||
if (elmSubCommentList.style.display === 'none') {
|
||
elmSubCommentList.style.display = '';
|
||
aTag.innerHTML = '➖'; // ➖, -
|
||
} else {
|
||
elmSubCommentList.style.display = 'none';
|
||
aTag.innerHTML = '➕'; // ➕, +
|
||
}
|
||
return false;
|
||
}
|
||
|
||
return aTag;
|
||
}
|
||
|
||
/** @param {Comment} comment */
|
||
const func = function (comment) {
|
||
if (comment.children.length === 0) return;
|
||
comment.element.getElementsByClassName('reply-link')[0].appendChild(createButton(comment));
|
||
comment.children.forEach(comment => func(comment));
|
||
}
|
||
|
||
this.jrApi.comments().forEach(comment => func(comment));
|
||
}
|
||
|
||
/**
|
||
* Удалить пункты меню "Люди" и "О проекте"
|
||
*/
|
||
removeTopMenuItems() {
|
||
//@formatter:off
|
||
Array.from(document.querySelectorAll('#navlist li'))
|
||
.filter(elm => { return elm.querySelector('a').text === "Люди"
|
||
|| elm.querySelector('a').text === "О проекте" })
|
||
.forEach(elm => { elm.remove() });
|
||
//@formatter:on
|
||
}
|
||
|
||
/**
|
||
* Удалить правую колонку
|
||
*/
|
||
removeRightColumn() {
|
||
document.getElementById('sidebar').remove();
|
||
|
||
const width = '930px';
|
||
document.getElementById('header').style.width = width;
|
||
document.getElementById('page').style.width = width;
|
||
document.getElementById('topbar').children[0].style.width = width;
|
||
document.getElementById('container').style.minWidth = '0';
|
||
}
|
||
|
||
/**
|
||
* Удалить переключатель языков
|
||
*/
|
||
removeLangSwitch() {
|
||
Array.from(document.getElementsByClassName('lang_select')).forEach(elm => { elm.remove() });
|
||
}
|
||
|
||
/**
|
||
* Удалить из поста блоки "Тренды" и "Фэндомы"
|
||
*/
|
||
removeTrandsAndFandomsBlock() {
|
||
const elements = document.getElementsByClassName('additional_info');
|
||
if (elements.length > 0) {
|
||
elements[0].remove();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Удалить из поста блок "Похожие посты"
|
||
*/
|
||
removeSimilarPostsBlock() {
|
||
const elements = Array.from(document.getElementsByClassName('mainheader'))
|
||
.filter(elm => { return elm.innerText === "Похожие посты" });
|
||
if (elements.length === 1) {
|
||
elements[0].nextElementSibling.remove();
|
||
elements[0].remove();
|
||
}
|
||
}
|
||
}
|
||
|
||
(function() {
|
||
'use strict';
|
||
const api = new JRApi();
|
||
const mod = new JRMod(api);
|
||
|
||
mod.removeLangSwitch();
|
||
mod.removeTopMenuItems();
|
||
mod.removeRightColumn();
|
||
|
||
if (api.isPostPage()) {
|
||
mod.addCollapseTreeCommentsButton();
|
||
mod.removeTrandsAndFandomsBlock()
|
||
mod.removeSimilarPostsBlock()
|
||
} else {
|
||
console.log(api.posts());
|
||
}
|
||
})();
|