Pikabu Enhancement Suite

Новый новый дизайн пикабу. Не забудь установить юзерстиль.

目前為 2018-03-17 提交的版本,檢視 最新版本

// ==UserScript==
// @name         Pikabu Enhancement Suite
// @version      1.1.2
// @license      CC-BY-4.0
// @description  Новый новый дизайн пикабу. Не забудь установить юзерстиль.
// @author       NeverLoved
// @match        https://pikabu.ru/*
// @grant        none
// @namespace https://greasyfork.org/users/175168
// ==/UserScript==

(function() {
    'use strict';
    let _c;
    try {
        _c = JSON.parse(window.localStorage.getItem('enhancements'));
    } catch(e) {
        _c = {};
    }
    var config = {
        values:_c || {},
        set:function(param, value) {
            this.values[param] = value;
            window.localStorage.setItem('enhancements', JSON.stringify(this.values));
        },
        get:function(param) {
            if(this.is_empty()) {
                return this.defconfig[param];
            } else {
                return this.values[param];
            }
        },
        is_empty:function() {
            try {
                return !JSON.parse(window.localStorage.getItem('enhancements'));
            } catch(e) {
                return true;
            }
        },
        defconfig: {
            "top_big_searchbar":true,
            "top_no_avatar":true,
            "porn_stealth":true,
            "restore_f":true,
            "great_comment_links":true,
            "post_header_collapse":true,
            "sidebar_icons":true
        }
    };



    if(window.location.pathname == '/settings') {
        var onchange = function(e) {
            let checkbox = e.target;
            config.set(checkbox.id, checkbox.checked);
        };

        var create_config_item = function(caption, id, value) {
            let checkbox = document.createElement('input');
            checkbox.setAttribute('id', id);
            checkbox.setAttribute('type', 'checkbox');
            if(value) {
                checkbox.checked = true;
            }
            checkbox.onchange = onchange;
            let label = document.createElement('label');
            label.innerText = caption;
            label.setAttribute('for', id);

            let tr = document.createElement('tr');
            tr.append(document.createElement('td'));
            tr.append(document.createElement('td'));
            tr.children[0].append(label);
            tr.children[1].append(checkbox);
            return tr;
        };

        var sett_table = document.querySelector('form[name="general"] .page-settings__table tbody');
        [
            create_config_item("Иконки в меню сайдбара", 'sidebar_icons', config.get('sidebar_icons')),
            create_config_item("Скрывать пост нажатием на пустое место в заголовке", 'post_header_collapse', config.get('post_header_collapse')),
            create_config_item("Скрытие просмотренных постов по F", 'restore_f', config.get('restore_f')),
            create_config_item("Добавить нормальные ссылки на комментарии [#]", 'great_comment_links', config.get('great_comment_links')),
            create_config_item("Строка поиска всегда развёрнута", 'top_big_searchbar', config.get('top_big_searchbar')),
            create_config_item("Убрать быстрое меню в шапке", 'top_no_avatar', config.get('top_no_avatar')),
            create_config_item("Скрытная иконка клубнички", 'porn_stealth', config.get('porn_stealth')),
        ].forEach(function(tr) { sett_table.append(tr); });
        document.querySelector('form[name="general"] .page-settings__table tbody').append();
    }

    var sidebar = document.querySelector('div.sidebar aside');
    var profile_info = sidebar.querySelector('.profile-info');
    var answers_link = sidebar.querySelector('div.menu a.menu__item[href="/answers"]');
    var main_menu = answers_link.parentNode;
    var rating_container = profile_info.children[0];
    var subscribers_container = profile_info.children[1];

    var rating_val = 0;
    if((rating_val = rating_container.getAttribute('aria-label')) == null) {
        rating_val = rating_container.children[0].innerText;
    }
    var subscribers_val = 0;
    if((subscribers_val = subscribers_container.getAttribute('aria-label')) == null) {
        subscribers_val = subscribers_container.children[0].innerText;
    }
    subscribers_val = parseInt(subscribers_val.replace(/[^0-9]/g, ''));
    rating_val = parseInt(rating_val.replace(/[^0-9]/g, ''));



    var rating = document.createElement('span');
    rating.innerText = "Рейтинг: "+rating_val;
    rating.style['padding-left'] = getComputedStyle(answers_link)['padding-left'];
    rating.className = "rating";

    var subscribers = document.createElement('span');
    subscribers.innerText = "Подписчиков: "+subscribers_val;
    subscribers.style['padding-left'] = getComputedStyle(answers_link)['padding-left'];
    subscribers.className = "subscribers";

    main_menu.prepend(subscribers);
    main_menu.prepend(rating);

    var edits = sidebar.querySelector('div.menu a.menu__item[href="/edits"]');
    if(edits) {
        var unneeded_menu = edits.parentNode;
        main_menu.append(edits);
        unneeded_menu.remove();
    }
    profile_info.remove();


    if(config.get('sidebar_icons')) {
        var menu_items = [].slice.call(main_menu.children); //Конвертируем HTMLCollection в массив
        menu_items.forEach(function(item) {
            let icon_container = document.createElement('span');

            icon_container.className = "icon_container";
            let i = document.createElement('i');
            let space = document.createTextNode(' ');
            let icon = 'circle-o';
            switch(item.getAttribute('href')) {
                case '/answers':
                    if(item.children.length) {
                        icon = "envelope-o";
                    } else {
                        icon = "envelope-open-o";
                    }
                    break;
                case '/comments':
                    icon = "comments-o";
                    break;
                case '/liked':
                    icon = "thumbs-o-up";
                    break;
                case '/saved-stories':
                    icon = 'floppy-o';
                    break;
                case '/subs-list':
                    icon = 'list';
                    break;
                case '/ignore-list':
                    icon = 'times';
                    break;
                case '/notes':
                    icon = 'sticky-note-o';
                    break;
                case '/edits':
                    icon = 'pencil';
                    break;
                default:
                    if(item.className == "rating") {
                        icon = "bar-chart";
                    } else if(item.className == "subscribers") {
                        icon = "users";
                    }
                    break;
            }
            i.className = 'fa fa-'+icon;
            icon_container.prepend(i);
            item.prepend(space);
            item.prepend(icon_container);
        });
    }
    var top_menu = document.querySelector('header.header');
    var right_menu = top_menu.querySelector('.header-right-menu');
    var search_bar = right_menu.querySelector('.header-right-menu__search');

    if(config.get('top_big_searchbar')) {
        search_bar.style.width = "250px";
        search_bar.style['background-color'] = "#fff";
        search_bar.style['border-radius'] = "2px";
        search_bar.querySelector('button').style.color = "#8ac858";
    }
    if(config.get('top_no_avatar')) {
        right_menu.querySelector('.avatar').remove();
    }
    var notify_btn = right_menu.querySelector('.header-right-menu__notification');
    notify_btn.innerHTML = '<i class="fa fa-bell fa-bigger" style="font-size:1.3em"></i>';
    notify_btn.style['line-height'] = '1px';
    notify_btn.style['margin-right'] = '0px';


    var user_info = sidebar.querySelector('.user');
    var settings = user_info.querySelector('a[href="/settings"]');
    var exit = user_info.querySelector('.user__exit');
    var nick_container = user_info.querySelector('.user__nick_big').parentNode;

    try {
        var straw = sidebar.querySelector('div[data-role="switch-adult"]');
        if(config.get('porn_stealth')) {
            straw.children[0].innerHTML = '<i class="fa fa-bigger fa-user-secret"></i>';
        } else {
            straw.children[0].innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" class="icon icon--ui__strawberry"><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#icon--ui__strawberry"></use></svg>';
        }
        var qs = straw.parentNode.remove();
    } catch(err) {
        console.log('Настройка клубнички выключена.');
        var straw = document.createTextNode('');
    }

    try {
        var displaymode = sidebar.querySelector('div[data-role="display-mode"]');
        displaymode.previousElementSibling.remove();
        var quickset = displaymode.parentNode.parentNode.parentNode;
        displaymode.style.float = "none";
        displaymode.style.display = "inline-block";
        var dtxt = displaymode.children[0];
        if(dtxt.innerText.indexOf('скрыто')+1) {
            dtxt.innerText += ' просмотренных постов';
        } else {
            dtxt.innerText += ' просмотренные посты';
        }
        var panel = document.querySelector('main section:first-child');
        //panel.insertBefore(displaymode, panel.lastChild);
        panel.insertBefore(displaymode, panel.lastElementChild);
        quickset.remove();

    } catch(err) {
        //var straw = document.createTextNode('');
    }

    settings.innerHTML = '<i class="fa fa-cog fa-bigger"></i>';
    settings.style.color = '#757575';

    exit.style.display = "inline-block";
    exit.innerHTML = '<i class="fa fa-sign-out fa-2x"></i>';


    var btn_container = exit.parentNode;
    btn_container.className += " btn_container";

    btn_container.append(settings);
    btn_container.append(document.createTextNode(' '));

    btn_container.append(notify_btn);
    btn_container.append(document.createTextNode(' '));
    btn_container.append(straw);

    user_info.append(exit);
    if(config.get('post_header_collapse')) {
        document.querySelector('main').addEventListener('click', function(e) {
            if(e.target.nodeName == "HEADER") {
                e.target.parentNode.parentNode.querySelector('.collapse-button').click();
            }
        }, false);
    }

    if(config.get('restore_f')) {

        if(document.querySelectorAll('article.story').length > 1) {
            var first_story,prev_story,current_story, next_story;
            /**
             * Для первого поста не срабатывает mutation observer
             * т.к его ещё нет когда пост попадает в поле зрения,
             * потому мы заранее записываем первый пост и удаляем его
            */
            first_story = document.querySelector('main > .stories-feed > .stories-feed__container article:first-child');
            first_story.setAttribute('data-visited', "true");
            current_story = first_story;
            var known_ids = [];
            var o = new MutationObserver(function(records) {
                records.some(function(item) {
                    let post_id = item.target.getAttribute('data-story-id');
                    if(!post_id) return false;
                    if(known_ids.indexOf(post_id)+1 == 0 && item.target.nodeName == "ARTICLE" && item.attributeName != "data-visited") {
                        item.target.setAttribute('data-visited', "true");
                        current_story = item.target;
                        console.log('Пост '+post_id+' прочитан.');
                        known_ids.push(post_id);
                        return true;
                    }
                });
            });
            o.observe(document.querySelector('main > .stories-feed > .stories-feed__container'), {'attributes':true, subtree:true});

            window.addEventListener('keyup', function(e) {
                if(e.key == "f" || e.key == "F" || e.key == "а" || e.key == "А") {
                    /* Нанокостыль */
                    if(prev_story == current_story) {
                        current_story = current_story.nextElementSibling;
                    }

                    next_story = current_story.nextElementSibling;
                    document.querySelectorAll('article.story[data-visited="true"]').forEach(function(item) { item.style.display = "none"; });
                    try {
                        next_story.scrollIntoView({behavior:'smooth', 'block':'start'});
                    } catch(e) {
                        console.log('Не удалось проскроллить к следующему посту.');
                    }
                    prev_story = current_story;
                    current_story = next_story;
                }
            });
        }
    }

    if(config.get('great_comment_links')) {

        var makeCommentGreatAgain = function(element) {
            let comment_tools = element.querySelector('.comment__tools');
            let branch_link = comment_tools.querySelector('[data-role="link"]');
            let branch_link_href = branch_link.getAttribute('href');
            branch_link.setAttribute('aria-label', 'Ссылка на ветку комментариев');

            let comment_link = document.createElement('a');
            comment_link.className = 'comment__tool hint';
            comment_link.setAttribute('data-role', 'comment_link');
            comment_link.setAttribute('aria-label', 'Ссылка на комментарий');
            comment_link.setAttribute('href', branch_link_href.replace('?cid=', '#comment_'));
            comment_link.innerText = '#';
            comment_tools.insertBefore(comment_link, branch_link);
            element.setAttribute('data-great', "true");
        };
        var makeCommentsGreatAgain = function() {
            document.querySelectorAll('.comment:not([data-great])').forEach(function(item) {
                makeCommentGreatAgain(item);
            });
        };
        makeCommentsGreatAgain();
        var jumpto = function() {
            if(window.location.hash.indexOf('comment_')+1) {
                var comment = document.querySelector(window.location.hash);
                if(comment) {
                    comment.scrollIntoView({behavior:'smooth', 'block':'start'});
                } else { //В списке комментариев нет загруженного комментария
                    var more_comments = document.querySelector('button.comments__more-button');
                    if(more_comments) {
                        more_comments.scrollIntoView({behavior:'smooth', 'block':'start'});
                        more_comments.className = more_comments.className += " button_yellow";
                        (function() { setTimeout(function() { console.log('release');more_comments.className = more_comments.className.replace(' button_yellow', ''); }, 2500); })();
                    }
                }
            }
        };


        if(window.location.href.indexOf('/story/')+1) {
            jumpto();

            document.querySelector('button.comments__more-button').addEventListener('click', function() {
                var emitted = false;
                var e = document.createEvent('Event');
                e.initEvent('comments.loaded', true, true);
                var comment_observer = new MutationObserver(function(records) {
                    records.some(function(record) {
                        if(record.target.className.indexOf('comment')+1) {
                            document.dispatchEvent(e);
                            comment_observer.disconnect();
                            return true;
                        } else {
                            return false;
                        }
                    });
                });
                comment_observer.observe(document.querySelector('section.comments'),  {'childList':true, 'subtree':true});
            });

            document.addEventListener('comments.loaded', function() {
                console.log('comments loaded emitted');
                makeCommentsGreatAgain();
                jumpto();
            });
        }
    }

})();