0
Files
joyreactor-mod/jrh.user.js

282 lines
8.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// ==UserScript==
// @name JRM: JoyReactor Mod
// @description Модификация JoyReactor
// @version 2.4.1
// @author DmitriyMX
// @namespace https://gitlab.com/DmitriyMX/joyreactor-helper
// @downloadURL https://gitlab.com/DmitriyMX/joyreactor-helper/raw/master/jrh.user.js
// @updateURL https://gitlab.com/DmitriyMX/joyreactor-helper/raw/master/jrh.user.js
// @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());
}
})();