diff --git a/jrh.user.js b/jrh.user.js index de50923..e3c2615 100644 --- a/jrh.user.js +++ b/jrh.user.js @@ -1,156 +1,279 @@ // ==UserScript== // @name JRH: JoyReactor Helper -// @description Улучшаем JoyReactor -// @version 2.3.1 +// @description Вспомогательные инструменты для JoyReactor +// @version 2.4 // @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 // @match http://joy.reactor.cc/* -// @match http://pornreactor.cc/* // @grant none // @run-at document-end // ==/UserScript== -const domainAliaces = { - "joy.reactor.cc": ['reactor.cc', 'joyreactor.cc'], - "pornreactor.cc": [], -}; +class Post { + /** + * @param {HTMLElement} elmPost + */ + constructor(elmPost) { + const pc_len = 'postContainer'.length; -/** - * Исправляет внутренние ссылки "реактора" - */ -function fixReactorLinks() { - domainAliaces[document.domain].forEach(domain => { - document.querySelectorAll('a[href^="http://' + domain + '/"]').forEach(elm => { - elm.href = elm.href.replace('http://' + domain + '/', 'http://' + document.domain + '/'); - }); + /** @public {Number} */ + this.id = parseInt(elmPost.id.substring(pc_len)); - document.querySelectorAll('a[href^="//' + domain + '/"]').forEach(elm => { - elm.href = elm.href.replace('//' + domain + '/', '//' + document.domain + '/'); - }); - }); + /** @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()); + } + } } -function createTreeButton(listId) { - var aTag = document.createElement('a'); - aTag.href = "#"; - aTag.classList.toggle('collapse-comments'); - aTag.text = '[-]'; - aTag.dataset.listid = listId; +class Comment { + /** + * @param {HTMLElement} elmComment + */ + constructor(elmComment) { + const cm_len = 'comment'.length; - 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'; + /** @public {HTMLElement} */ + this.element = elmComment; - aTag.onclick = function() { - var listId = this.dataset.listid; - var commentListElement = document.getElementById(listId); + /** @public {Number} */ + this.id = parseInt(elmComment.id.substring(cm_len)); - if (commentListElement.style.display === 'none') { - commentListElement.style.display = ''; - this.text = '[-]'; - } else { - commentListElement.style.display = 'none'; - this.text = '[+]'; + 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]'; + } } - return false; - }; + if (this.author === null) { + throw new Error('author is NULL'); + } - return aTag; + /** @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 ---"); + } + } + } } -/** - * Добавляем кнопку сворачивания комментариев - */ -function collapseTreeComments() { - var blocks = document.getElementsByClassName('post_comment_list'); - var commentBlock = blocks.length === 2 ? blocks[1] : blocks[0]; +class JRApi { + constructor() { + /** @private {RegExp} */ + this._urlPostRegexp = new RegExp("https?:\/\/.+/post/([0-9]+)"); + /** @private {Comment[]} */ + this._comments = null; + } - Array.from(commentBlock.querySelectorAll('div.comment')) - .filter(elm => { return elm.nextElementSibling !== null; }) - .filter(elm => { return elm.nextElementSibling.children.length > 0; }) - .forEach(elm => { - var listId = elm.nextElementSibling.id; - elm.querySelector('span.reply-link').appendChild(createTreeButton(listId)); - }); + /** + * @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; + } } -function isPostPage() { - for (var domain of Object.keys(domainAliaces)) { - let regexp = new RegExp("http?:\/\/" + domain.replace(/\./g, '\\.') + "\/post"); - if (document.URL.match(regexp) !== null) { - return true; +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(); } } - return false; -} - -/** - * Удаляем лишние элементы с сайта - */ -function removeExcessElements() { - // Удаляем пункты меню "Люди" и "О проекте" - Array.from(document.querySelectorAll('#navlist li')) - .filter(elm => { return elm.querySelector('a').text === "Люди" - || elm.querySelector('a').text === "О проекте" }) - .forEach(elm => { elm.remove() }); - - // Удаляем правую колонку - document.getElementById('sidebar').remove(); - - // Косметические исправления - var 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'; - - // Переключатель языков - Array.from(document.getElementsByClassName('lang_select')).forEach(elm => { elm.remove() }); -} - -/** - * Удаляем лишние элементы из поста - */ -function removeExcessElementsInPost() { - // Удаляем "Тренды" и "Фэндомы" - var elements = document.getElementsByClassName('additional_info'); - if (elements.length === 1) { - 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(); + } } - - // Удаляем "Похожие посты" - elements = Array.from(document.getElementsByClassName('mainheader')) - .filter(elm => { return elm.innerText === "Похожие посты" }); - if (elements.length === 1) { - elements[0].nextElementSibling.remove(); - elements[0].remove(); - } -} - -/** - * Все "новые комментарии" перестают подсвечиваться - */ -function unNewComments() { - document.querySelectorAll('.new').forEach(elm => { elm.classList.toggle('new') }); } (function() { 'use strict'; + const api = new JRApi(); + const mod = new JRMod(api); - removeExcessElements(); - fixReactorLinks(); - if (isPostPage()) { - removeExcessElementsInPost(); - collapseTreeComments(); - unNewComments(); + mod.removeLangSwitch(); + mod.removeTopMenuItems(); + mod.removeRightColumn(); + + if (api.isPostPage()) { + mod.addCollapseTreeCommentsButton(); + mod.removeTrandsAndFandomsBlock() + mod.removeSimilarPostsBlock() + } else { + console.log(api.posts()); } })();