您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Скрывает на сайте элементы, которые чем-то не угодили. Например фанфики, со слэшем, фэмслэшем, с нелюбимыми жанрами... Или рекламу. Возвращает старые отметки обновлений на страницы избранных авторов и новых частей в текстах, а также помечает изменённые сборники и новые тексты в них. Убирает промежуточную страницу при переходе по ссылкам. Добавляет прямое скачивание FB2-файла в шапку произведения. Сделано на основе скрипта Wilat Collany - https://github.com/ShadowOfKing/JSScripts/
当前为
// ==UserScript== // @name ficbook.notifications.improvement // @namespace https://siwatcher.ru // @version 1.0.2 beta // @description Скрывает на сайте элементы, которые чем-то не угодили. Например фанфики, со слэшем, фэмслэшем, с нелюбимыми жанрами... Или рекламу. Возвращает старые отметки обновлений на страницы избранных авторов и новых частей в текстах, а также помечает изменённые сборники и новые тексты в них. Убирает промежуточную страницу при переходе по ссылкам. Добавляет прямое скачивание FB2-файла в шапку произведения. Сделано на основе скрипта Wilat Collany - https://github.com/ShadowOfKing/JSScripts/ // @author El'Drako, Wilat Collany // @match https://ficbook.net/* // @license MIT // @grant none // ==/UserScript== var cntAllNotification = ''; //Условия блокировки var blocks = { slash: { constraints: [ { selector: ".icon-slash, .ic_slash", parent: "article, .festival-thumb", }, { selector: ".direction-slash", parent: "main, #main", }, { selector: ".slash", parent: "arvicle, .fanfic-inline.mbt-2", }, ], message: "Тут был слэш", block: true, }, femslash: { constraints: [ { selector: ".icon-femslash, ic-femslash", parent: "article, .festival-thumb", }, { selector: ".direction-femslash", parent: "main, #main", }, { selector: ".femslash", parent: "arvicle, .fanfic-inline.mbt-2", }, ], message: "Тут был фемслэш", block: false, saveContent: true, }, ads: { constraints: [ { selector: "yatag, .rkl-banner > a", parent: "div, main, #main, body", }, { selector: ".adsbygoogle > *", parent: ".adsbygoogle", }, ], message: "Тут была реклама", block: true, delay: 0, repeats: 10, step: 500, css: { "background-color": "#4d2917", color: "#f6ecda", }, saveContent: true, }, genres: { constraints: [ { selector: "a.tag.disliked-parameter-link", parent: "article.fanfic-block-disliked", }, { selector: "a.tag.disliked-parameter-link", parent: "article.fanfic-inline.mbt-2", }, ], message: "Тут был нелюбимый жанр", block: true, css: { "background-color": "#2c1a14", color: "#dd3131", }, saveContent: true, }, authors: { constraints: [ { selector: "article.block .description ul li a", parent: "article.block", text: [ "test", ] } ], message: "Здесь был нелюбимый автор", block: true, css: { "background-color": "black", color: "white;" }, saveContent: true } }; //Блок кнопок для отметок прочитанными и удаления оповещений в категории var btnNotifBlock = '<div class="notification-action-buttons" style="float:right">'+ '<form class="d-inline-block mr-5 jsAjaxSubmitForm" action="/user_notifications/mark_old_all" method="post">'+ '<input type="hidden" name="type" value="__TYPE">'+ '<button type="submit" class="btn btn-default" onclick="return confirm(\'Отметить все оповещения в выбранной категории как прочитанные?\')">'+ '<svg class="ic_ok2 icon mr-5"><use href="/assets/icons/icons-sprite8.svg#ic_ok2"></use></svg>'+ 'Всё прочитано'+ '</button>'+ '</form>'+ '<form class="d-inline-block" action="/user_notifications/delete_all" method="post">'+ '<input type="hidden" name="type" value="__TYPE">'+ '<button type="submit" class="btn btn-default" onclick="return confirm(\'Удалить все оповещения в выбранной категории?\')">'+ '<svg class="ic_bin icon mr-5"><use href="/assets/icons/icons-sprite8.svg#ic_bin"></use></svg>'+ 'Удалить оповещения'+ '</button>'+ '</form>'+ '</div>'; //Функция блокировки function blockElement(el) { var message = el.message; var delay = el.delay == null ? 1 : el.delay; var count = el.repeats == null ? 1 : el.repeats; var step = el.step == null ? delay : el.step; var saveContent = el.saveContent; var changeContent = el.changeContent; var content = el.content; for (var iter = 0; iter < count; iter++) { setTimeout(function() { for (var i = 0; i < el.constraints.length; i++) { var con = el.constraints[i]; var $selector = $(con.selector); var count = con.text ? con.text.length : 1; $selector.each(function() { if ($(this).parents('.blockedContent').length > 0) { return; } for (var ii = 0; ii < count; ii++) { var text = con.text && con.text.length > 0 ? con.text[ii].trim().toLowerCase() : ""; if (text == "" || text == $(this).text().trim().toLowerCase()) { var $parent = $(this).parents(con.parent).first(); if (el.hide == true) { $parent.remove(); return; } $parent.wrap("<div></div>"); $parent = $parent.parent(); var css = ""; if (el.css != null) { css = 'style="'; for (var j in el.css) { css += j + ': ' + el.css[j] + ';'; } css += '"'; } if (saveContent) { $parent.html("<div style='display: none;' class='blockedContent'>" + $parent.html() + "</div>"); $parent.append('<div class="openBlockedContent">Показать скрытый контент</div>'); $parent.css('position', 'relative'); $parent.children('.openBlockedContent').click(function(e) { $(this).hide(); var $el = $(this).parent().slideUp(500); setTimeout(function() { $el.children('.BlockContent').hide(); $el.children('.blockedContent').show(); $el.slideDown(500); }, 500); }); } else { $parent.html("<span></span>"); } $parent.children().last().before("<div class='BlockContent'" + css + ">" + message + "</div>"); $parent.children('.BlockContent').click(function(e) { $(this).addClass('closed'); var $par = $(this).parent(); $par.slideUp(500); setTimeout(function() { $par.remove(); }, 600); }); } } }); } }, delay); delay += step; } } //Удаляем переходную страницу на ссылках function remoteAwayPage() { var awayString = '/away?url='; $('a[href^="' + awayString + '"]').each(function(){ // Update the 'rules[0]' part of the name attribute to contain the latest count $(this).attr('href', $(this).attr('href').replace(awayString,'')); // Add attribute target="_blank" $(this).attr('target', '_blank' ); $(this).attr('href', decodeURIComponent($(this).attr('href'))); }); } //Добавление стилей для заблокированного элемента function addStyles() { var styleEl = document.createElement('style'); document.head.appendChild(styleEl); var styleSheet = styleEl.sheet; styleSheet.insertRule(".BlockContent {text-align: center;font-size: 1.5em;background-color: rgb(146, 32, 32); opacity: 0.46; color: black;padding: 5px 0px;margin-bottom: 15px;border: 1px solid red;cursor: pointer; transition: 0.3s linear all;}", styleSheet.cssRules.length); styleSheet.insertRule(".BlockContent:hover:not(.closed) { opacity: 0.76;}", styleSheet.cssRules.length); styleSheet.insertRule(".BlockContent.closed {cursor: default;}", styleSheet.cssRules.length); styleSheet.insertRule(".openBlockedContent {transition: 0.5s ease-in-out all; position: absolute;color: #fafafa;right: 5px;bottom: 5px;background-color: #121517;padding: 5px;border-radius: 15px;border: 1px solid red; opacity: 0.7; cursor: pointer;}", styleSheet.cssRules.length); styleSheet.insertRule(".openBlockedContent:hover {opacity: 1.7; background-color: #fafafa; color: #121517;}", styleSheet.cssRules.length); //стили плашек панели обновлений styleSheet.insertRule(".iconblock-5 { color: #8b724d;position: relative; margin:30px 10px 5px; border: 2px solid #cdbea2; border-radius:4px;background-color: #f6ecda; transition: transform 300ms ease, box-shadow 300ms ease;text-align:center;width:130px;}", styleSheet.cssRules.length); styleSheet.insertRule(".iconblock-5 .np-icon { display: block; position: absolute; left: 50%; width: 60px; transform: translate(-50%, -50%); }", styleSheet.cssRules.length); styleSheet.insertRule(".iconblock-5 .np-icon svg.np-i {transition: all 0.7s ease 0s;position: absolute;top: 40%;left: 50%;font-size: 32px; transform: translate(-50%, -50%); fill: #8b724d;width: 32px;height: 32px;}", styleSheet.cssRules.length); styleSheet.insertRule(".iconblock-5 .np-icon img{position: absolute; top: 40%; left: 50%; font-size: 32px; transform: translate(-50%, -50%);color: #cdbea2;width: 32px;height: 32px;}", styleSheet.cssRules.length); styleSheet.insertRule(".iconblock-5 .np-icon svg path {stroke-width: 8px;stroke: #cdbea2;transition: stroke 300ms ease;}", styleSheet.cssRules.length); styleSheet.insertRule(".iconblock-5 .np-icon svg polygon {fill: #f6ecda; }", styleSheet.cssRules.length); styleSheet.insertRule(".iconblock-5 h3 {transition: all 0.7s ease 0s; margin:32px 0 1px 0;}", styleSheet.cssRules.length); styleSheet.insertRule(".iconblock-5 p {transition: all 0.7s ease 0s; margin:5px 0 5px 0;line-height: 1.2em; font-size:0.9em;}", styleSheet.cssRules.length); styleSheet.insertRule(".iconblock-5:hover h3 {color: #000;}", styleSheet.cssRules.length); styleSheet.insertRule(".iconblock-5:hover p {color: #000;}", styleSheet.cssRules.length); styleSheet.insertRule(".iconblock-5:hover {transform: translateY(-10px);box-shadow: 0px 7px 10px 1px rgba(84, 84, 84, 0.5); border-color: #8b724d;}", styleSheet.cssRules.length); styleSheet.insertRule(".iconblock-5:hover .np-icon svg path {stroke: #8b724d;}", styleSheet.cssRules.length); styleSheet.insertRule(".iconblock-5:hover .np-icon svg.np-i {transition: all 1.7s ease 0s;fill: #000;}", styleSheet.cssRules.length); styleSheet.insertRule("section.np-info {display: flex;flex-direction: row;justify-content: flex-start;flex-wrap: wrap;align-items: baseline;}", styleSheet.cssRules.length); //стили всплывающего окна styleSheet.insertRule("#myModal-fav {flex-direction: column;width: 90%; height: fit-content; max-height: 90%;margin: 0 auto; border-radius: 4px; background: #f6ecda; position: fixed; top: 0; left: 0; right: 0; bottom: 0; margin: auto; display: none; opacity: 0; z-index: 55;overflow: none}", styleSheet.cssRules.length); styleSheet.insertRule("#myModal-fav #myModal__close-fav { width: 21px; height: 21px; position: absolute; top: 1px; right: 11px; cursor: pointer; display: block; font-size: 29px;}", styleSheet.cssRules.length); styleSheet.insertRule("#myOverlay-fav { z-index: 37; position: fixed; background-color: rgba(0,0,0,.7); width: 100%; height: 100%; top: 0; left: 0; cursor :pointer; display :none;}", styleSheet.cssRules.length); styleSheet.insertRule("#myModal-fav > h3{box-shadow: 0 4px 8px rgba(0,0,0,0.25), 0 2px 2px rgba(0,0,0,0.22);text-align: left;background-color: #ddc9af;margin: 0 0 10px!important;border-radius: 4px 4px 0 0;height: 2em;line-height: 2em;padding: 0 10px;}", styleSheet.cssRules.length); styleSheet.insertRule("#myModal-upd {flex-direction: column;width: 90%; height: fit-content; max-height: 90%;margin: 0 auto; border-radius: 4px; background: #f6ecda; position: fixed; top: 0; left: 0; right: 0; bottom: 0; margin: auto; display: none; opacity: 0; z-index: 55;overflow: none}", styleSheet.cssRules.length); styleSheet.insertRule("#myModal-upd #myModal__close-upd { width: 21px; height: 21px; position: absolute; top: 1px; right: 11px; cursor: pointer; display: block; font-size: 29px;}", styleSheet.cssRules.length); styleSheet.insertRule("#myOverlay-upd { z-index: 37; position: fixed; background-color: rgba(0,0,0,.7); width: 100%; height: 100%; top: 0; left: 0; cursor :pointer; display :none;}", styleSheet.cssRules.length); styleSheet.insertRule("#myModal-upd > h3{box-shadow: 0 4px 8px rgba(0,0,0,0.25), 0 2px 2px rgba(0,0,0,0.22);text-align: left;background-color: #ddc9af;margin: 0 0 10px!important;border-radius: 4px 4px 0 0;height: 2em;line-height: 2em;padding: 0 10px;}", styleSheet.cssRules.length); styleSheet.insertRule(".overfl{overflow: auto;display: flex;flex-flow: column nowrap;justify-content: flex-start;align-items: stretch;flex-direction: column;flex-wrap: nowrap;align-content: stretch;}", styleSheet.cssRules.length); styleSheet.insertRule(".margin-5{margin:5px;overflow: auto;}", styleSheet.cssRules.length); styleSheet.insertRule(".mp-1{margin:1px;padding:1px;}", styleSheet.cssRules.length); styleSheet.insertRule(".mp-0-1{margin:0px 1px;padding:0 1px;}", styleSheet.cssRules.length); styleSheet.insertRule(".m-0-5{margin:0px 5px;}", styleSheet.cssRules.length); styleSheet.insertRule(".mbt-2{margin-bottom:2px;margin-top:2px;}", styleSheet.cssRules.length); styleSheet.insertRule(".p-0-10-10{padding:0 10px 10px;}", styleSheet.cssRules.length); styleSheet.insertRule(".p-5-10-10{padding:5px 10px 10px;}", styleSheet.cssRules.length); styleSheet.insertRule(".p-5-10-5-5{padding: 5px 10px 5px 5px;}", styleSheet.cssRules.length); styleSheet.insertRule(".myshadow{box-shadow: 0 4px 8px rgba(0,0,0,0.25), 0 2px 2px rgba(0,0,0,0.22);border-radius: 4px;}", styleSheet.cssRules.length); styleSheet.insertRule(".mp-0{margin:0;padding:0;}", styleSheet.cssRules.length); styleSheet.insertRule(".custom-scroll::-webkit-scrollbar {width: 10px;}", styleSheet.cssRules.length); styleSheet.insertRule(".custom-scroll::-webkit-scrollbar-track {-webkit-box-shadow: #503e2299 5px 5px 5px -5px inset;background-color: #dfc79c; border-radius: 4px;}", styleSheet.cssRules.length); styleSheet.insertRule(".custom-scroll::-webkit-scrollbar-thumb {border-radius: 5px;background: linear-gradient(#c3aa7e, #b68752);}", styleSheet.cssRules.length); } //Для генерации хешей контрольных сумм для подтверждения, что нажали скачать на странице выбора формата файла function p(t) { return ( (function (t) { if (Array.isArray(t)) return m(t); })(t) || (function (t) { if ("undefined" != typeof Symbol && Symbol.iterator in Object(t)) return Array.from(t); })(t) || (function (t, e) { if (!t) return; if ("string" == typeof t) return m(t, e); var n = Object.prototype.toString.call(t).slice(8, -1); "Object" === n && t.constructor && (n = t.constructor.name); if ("Map" === n || "Set" === n) return Array.from(t); if ("Arguments" === n || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return m(t, e); })(t) || (function () { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); })() ); } function m(t, e) { (null == e || e > t.length) && (e = t.length); for (var n = 0, r = new Array(e); n < e; n++) r[n] = t[n]; return r; } function fanficDownload(fanfic_id, token) { var e = parseInt(fanfic_id, 10), n = p(token).map(function (t) {return parseInt(t, 8);}).filter(function (t) {return !isNaN(t) && t > 0;}).reduce(function (t, e) {return t + e;}), r = document.createElement("input"); r.type = "hidden"; r.name = e + n; r.value = String(e^n+1); $(".js-download-form").last().append(r); }; function markNotifOld(events, cur){ $.post("/user_notifications/mark_old",{notification_ids:[events['id'][cur]]}, function(){ //window.location.href='https://ficbook.net' + events['url'][cur]; }); } function getNotifications(url,cnt) { var dfrs = []; var uri = " div.notifications-content a.notification-item"; var items = 0; $("body").append('<div id="notification-selector" style="display:none"></div>'); var p = 1+(cnt - cnt % 30) / 30; var i =1; //загружаем все события со страниц пагинации оповещений for (; i <= p; i++) { dfrs.push( $.Deferred(function( promise ) { $("#notification-selector").append('<span id="page'+i+'">'+i+'</span>'); $("#notification-selector span#page"+i).load(url+"?p="+i+uri, function() { promise.resolve(); }); }).promise() ); } return dfrs; } function parseNotifications(url, cnt){ let result = {count: 0, notifications: []}; //загружаем все события со страниц пагинации оповещений $.when.apply(null,getNotifications(url,cnt)).done(function() { //формируем строку json $("#notification-selector span").find("a.notification-item").each(function() { let item = { date: 0, id: "", is_new: true, message: "", type: 0, url: "", }; item.id = $(this).attr("data-notification-id"); item.url = $(this).attr("href"); item.message = $(this).find('div.notification-info div').last().text(); item.date = $(this).find('div.date').text().trim(); item.is_new = $(this).find('div.dot').html() === "" ? true: false; item.type = 0; $(this).find('div.notification-title').text().trim() == "Обновления в работе избранных авторов" ? item.type = 17 : item.type=item.type; item.type == 0 && $(this).find('div.notification-title').text().trim() == "Новые работы в сборниках" ? item.type = 18 : item.type=item.type; item.type == 0 && $(this).find('div.notification-title').text().trim() == "Новые части в работе" ? item.type = 19 : item.type=item.type; result.notifications.push(item); item.length = 0; result.count++; }); let curURL = document.location.href; let pathURL = document.location.pathname; let searchURL = document.location.search; let data=groupNotifications(result.notifications); //выделяем второй массив только с непрочитанными оповещениями let notif_new = []; result.notifications.forEach(function(it, pos) { //если это уже прочитанное оповещение, то сохраняем его if (it.is_new == true) notif_new.push(it); }); console.info(notif_new); var favData = data.filter(data => data.type == 17); //избранные авторы //добавляем количество обновлений в шапку if (favData.length > 0 ) var favCount = favData[0]['is_new'].reduce(function(acc, el) {el ? acc++ : el=el; return acc;}, 0); if (favCount > 0) { var starHtml = '<li><a class="important-link" style="color:#caaa6a;" href="/home/favourites"><svg class="icon ic_star-empty"><use href="/assets/icons/icons-sprite8.svg#ic_star-empty"></use></svg> <span class="notification-cnt">'+favCount+'</span></a></li>'; $('ul.top-notifications').append(starHtml); } var updData = data.filter(data => data.type == 19); //сборники по датам if (updData.length > 0 ) var updCount = updData[0]['is_new'].reduce(function(acc, el) {el ? acc++ : el=el; return acc;}, 0); if (updCount > 0) { starHtml = '<li><a href="/home/collections?type=update" class="important-link" style="color:#caaa6a;"><svg class="icon ic_stack-star"><use href="/assets/icons/icons-sprite8.svg#ic_stack-star"></use></svg> <span class="notification-cnt">'+updCount+'</span></a></li>'; $('ul.top-notifications').append(starHtml); } var collData = data.filter(data => data.type == 18); //чужие сборники if (collData.length > 0 ) var collCount = collData[0]['is_new'].reduce(function(acc, el) {el ? acc++ : el=el; return acc;}, 0); if (collCount > 0) { starHtml = '<li><a href="https://ficbook.net/home/collections?type=other" class="important-link" style="color:#eaca9a;"><svg class="icon ic_stack-star"><use href="/assets/icons/icons-sprite8.svg#ic_stack-star"></use></svg> <span class="notification-cnt">'+collCount+'</span></a></li>'; $('ul.top-notifications').append(starHtml); } if (cntAllNotification > 0) { //Добавляем для страницы новостей пользователя блок оповещений if (document.location.href == 'https://ficbook.net/home/news') { $("section.content-section > div.news-area").prepend('<div class="news-container"><h2>Панель оповещений</h2><ul class="list-unstyled"><li class="notif-panel"></li></ul></div>'); let newdata=groupNotifications(notif_new); updNotificationPanel(newdata); } } //проверяем адрес страницы и если это избранные авторы, то выбираем из type = 17 var show_dot = ''; //if (curURL == 'https://ficbook.net/home/favourites') { if (pathURL == '/home/favourites') { //console.info(favData); setCookie('ficbook_lasturl',17); //Добавляем кнопки $('section.content-section h1').before(btnNotifBlock.replace(/__TYPE/g, '17')); favData[0]['url'].forEach(function(url, cur){ var dt = favData[0]['date'][cur]; if (favData[0]['is_new'][cur] === true) {show_dot = '<div class="dot" style="color: darkred;"> ★ </div>';} $('a[href="'+url+'"]') .parents('h3') .next() .prepend('<div><div class="badge-with-icon direction direction-before-het small-direction-het">'+show_dot+' Обновлено '+dt+' </div></div>') ; $('a[href="'+url+'"]').on('click', function(){markNotifOld(favData[0], cur)}).attr('target', '_blank'); show_dot = ''; }); } //проверяем адрес страницы и если это фанфики по дате обновления, то выбираем из type = 19 if (pathURL == '/home/collections' && searchURL.indexOf('type=update') == 1) { $('section.content-section h1').before(btnNotifBlock.replace(/__TYPE/g, '19')); setCookie('ficbook_lasturl',19); updData[0]['url'].forEach(function(url, cur){ var dt = updData[0]['date'][cur]; if (updData[0]['is_new'][cur] == true) {show_dot = '<div class="dot" style="color: darkred;"> ★ </div>';} var uri = /readfic\/(\d+)/m; var fid = url.match(uri); $('a[href="/readfic/'+fid[1]+'"]').parents('h3').next().prepend('<a href="'+url+'" target="_blank" style="text-decoration: none;"><div><div class="badge-with-icon direction direction-before-het small-direction-het">'+show_dot+' Обновлено '+dt+' </div></div></a>'); $('a[href="/readfic/'+fid[1]+'"]').on('click', function(){markNotifOld(updData[0], cur)}).attr('target', '_blank'); show_dot = ''; }); } //проверяем адрес страницы и если это сборники, то выбираем из type = 18 if (pathURL == '/home/collections' && searchURL.indexOf('type=other') == 1) { $('section.content-section h1').before(btnNotifBlock.replace(/__TYPE/g, '18')); setCookie('ficbook_lasturl', 18); if (collData.length > 0 ) { var regex = /^Сборник "(.+)", работа: (.+), фэндом.*: "(.+)", автор сборника (.+)/; var newFandomsInColl = []; collData[0]['message'].forEach(function(coll, cur){ if (collData[0]['is_new'][cur] == true) { var collection = coll.match(regex); $('div.collection-thumb').each(function(){ if ($(this).find('div.collection-thumb-info > a').text() == collection[1] && $(this).find('div.collection-thumb-author > a').text() == collection[4]) { $(this).attr('style','background-color: beige'); let colHref = $(this).find('div.collection-thumb-info > a').attr('href'); let colUri = /collections\/(\d+)/m; var colFid = colHref.match(colUri); if (newFandomsInColl[colFid[1]] === undefined) { newFandomsInColl[colFid[1]] = []; newFandomsInColl[colFid[1]]['fandoms'] = ''; newFandomsInColl[colFid[1]]['count'] = 0; } newFandomsInColl[colFid[1]]['fandoms'] = newFandomsInColl[colFid[1]]['fandoms'] + collection[3].replace(/"/g,'') + ', '; //создаём список фандомов каждого текста в массиве по номеру коллекции newFandomsInColl[colFid[1]]['count']++; $(this).find('div.collection-thumb-info > a').attr('href', '/collections/' + colFid[1] + '?sort=7').attr('target', '_blank'); $(this).find('div.collection-thumb-info').append('<div id="collID-'+colFid[1]+'" style="font-size:0.8em"></div>'); } }); //второй обход для вывода списка фендомов новых текстов $('div.collection-thumb').each(function(){ if ($(this).find('div.collection-thumb-info > a').text() == collection[1] && $(this).find('div.collection-thumb-author > a').text() == collection[4]) { $(this).attr('style','background-color: beige'); let colHref = $(this).find('div.collection-thumb-info > a').attr('href'); let colUri = /collections\/(\d+)/m; var colFid = colHref.match(colUri); //убираем повторы фендомов let fanNames = clearDuples(newFandomsInColl[colFid[1]]['fandoms']).trim().slice(0, -1); let fanCount = fanNames.split(",").length; //выводим $(this).find('#collID-'+colFid[1]).text(newFandomsInColl[colFid[1]]['count']+' '+ declOfNum(newFandomsInColl[colFid[1]]['count'], ['работа', 'работы', 'работ'])+ ' по '+ declOfNum(fanCount, ['фэндому', 'фэндомам', 'фэндомам'])+' '+ fanNames); } }); } }); } } var collUri = curURL.match(/^https:\/\/ficbook.net\/(.+)\/\d+/); if (collUri != null && collUri[1] == 'collections') { collData[0]['url'].forEach(function(url, cur){ var dt = collData[0]['date'][cur]; if (collData[0]['is_new'][cur] === true) {show_dot = '<div class="dot" style="color: darkred;"> ★ </div>';} var uri = /readfic\/(\d+)/m; var fid = url.match(uri); $('a[href="/readfic/'+fid[1]+'"]').parents('h3').next().prepend('<a href="'+url+'" target="_blank" style="text-decoration: none;"><div><div class="badge-with-icon direction direction-before-het small-direction-het">'+show_dot+' Добавлено '+dt+' </div></div></a>'); $('a[href="/readfic/'+fid[1]+'"]').on('click', function(){markNotifOld(collData[0], cur)}).attr('target', '_blank'); show_dot = ''; }); } }) } //склонение числительных // from https://gist.github.com/realmyst/1262561 //use: declOfNum(count, ['найдена', 'найдено', 'найдены']); function declOfNum(number, titles) { let cases = [2, 0, 1, 1, 1, 2]; return titles[ (number%100>4 && number%100<20)? 2 : cases[(number%10<5)?number%10:5] ]; } function clearDuples(str) { return str.split(' ') .filter(function(word, i, arr){ return i === arr.lastIndexOf(word); }) .join(" "); } function showUserNotifications() { // Получение списка обновлений $.post("https://ficbook.net/user_notifications/get_new", function(e) { parseNotifications('https://ficbook.net/notifications', 3 * e.data.count); cntAllNotification = e.data.count; }); } //загружаем по ссылкам из массива непрочитанных оповещений карточки текстов и заливаем в блок всплывающего окна function loadFicUpdDetails (data) { $("body").append('<div id="notification-fic-upd-details" style="display:none"></div>'); //загружаем все данные о тексте со страниц произведений $.when.apply(null,getFicUpdDetails(data)).done(function() { //заполняем ленту обновлений новых глав updNotifOfParts(data); }); } function loadFavAuthorsFicDetails (data) { $("body").append('<div id="notification-fic-fav-details" style="display:none"></div>'); //загружаем все данные о тексте со страниц произведений $.when.apply(null,getFavAuthorsFicDetails(data)).done(function() { //заполняем ленту обновлений новых глав updNotifOfFav(data); }); } function getFicUpdDetails(data) { var dfrs = []; var uri = " section.chapter-info"; var items = 0; console.info('getFicUpdDetails(data):'); console.info(data); console.info('url-upd:'); var i =1; //загружаем все события со страниц пагинации оповещений for (; i <= data[0]['url'].length; i++) { dfrs.push( $.Deferred(function( promise ) { var rgx = /readfic\/(\d+)/m; var fid = data[0]['url'][i-1].match(rgx); $("#notification-fic-upd-details").append('<span id="updDetails'+i+'">'+i+'</span>'); sleep(280); $("#notification-fic-upd-details span#updDetails"+i).load('/readfic/'+fid[1]+uri, function() { sleep(150); promise.resolve(); }); console.info(data[0]['url'][i-1]); }).promise() ); } return dfrs; } function getFavAuthorsFicDetails(data) { var dfrs = []; var uri = " section.chapter-info > header.head"; var items = 0; console.info('getFavAuthorsFicDetails(data):'); console.info(data); console.info('url-fav:'); var i =1; //загружаем все события со страниц пагинации оповещений for (; i <= data[0]['url'].length; i++) { dfrs.push( $.Deferred(function( promise ) { $("#notification-fic-fav-details").append('<span id="favDetails'+i+'">'+i+'</span>'); sleep(280); $("#notification-fic-fav-details span#favDetails"+i).load(data[0]['url'][i-1]+uri, function() { sleep(150); promise.resolve(); }); console.info(data[0]['url'][i-1]); }).promise() ); } return dfrs; } function groupNotifications(t) { var map = t.reduce((acc, cur)=>{ acc[cur.type] = acc[cur.type] || { type: cur.type, id: [], url: [], date: [], is_new: [], message: [], }; acc[cur.type].id.push(cur.id); acc[cur.type].url.push(cur.url); acc[cur.type].date.push(cur.date); acc[cur.type].is_new.push(cur.is_new); acc[cur.type].message.push(cur.message); return acc; },{}); return Object.values(map); } function updNotificationPanel(data) { //функция парсит массив группированных оповещений и выводит результат в панель оповещений на странице новостей var starHtml = '<div style="margin: 0px 10px 0">Всего <span style="font-size: 1.4em;font-weight:bold;">' + cntAllNotification + '</span> ' + declOfNum(cntAllNotification, ['оповещение', 'оповещения', 'оповещений'])+': </div><div class="np-main-info"><section class="np-info" style="font-size:1.1em;"></section></div>'; $('li.notif-panel').append(starHtml); starHtml = ''; var favData = data.filter(data => data.type == 17); //избранные авторы //добавляем количество обновлений избранных авторов if (favData.length > 0 ) var favCount = favData[0]['is_new'].length; if (favCount > 0) { starHtml = '<a class="important-link myLinkModal-fav" style="text-decoration:none" href="#"><div class="iconblock-5"><div class="np-icon"><svg version="1.1" id="Layer_0" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0" y="0" viewBox="0 -10 300 320" xml:space="preserve" class="np-i"><use href="/assets/icons/icons-sprite8.svg#ic_star-empty"></use></svg><svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0" y="0" viewBox="0 -10 300 320" xml:space="preserve"><polygon points="22.3,223.7 22.3,76.3 150,2.5 277.7,76.3 277.7,223.7 150,297.5"/> <path d="M150,4.8l125.7,72.6v145.2L150,295.2L24.3,222.6V77.4L150,4.8 M150,0.2L20.3,75.1v149.8L150,299.8l129.7-74.9V75.1L150,0.2 L150,0.2z"/></svg></div><h3>'+favCount+'</h3> <p>Избранные<br/>авторы</p></div></a>'; } var updData = data.filter(data => data.type == 19); //сборники по датам if (updData.length > 0 ) var updCount = updData[0]['is_new'].length; if (updCount > 0) { //starHtml += '<a class="important-link" style="text-decoration:none" href="/home/collections?type=update"><div class="iconblock-5"><div class="np-icon"><svg version="1.1" id="Layer_0" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0" y="0" viewBox="0 -10 300 320" xml:space="preserve" class="np-i"><use href="/assets/icons/icons-sprite8.svg#ic_stack-star"></use></svg><svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0" y="0" viewBox="0 -10 300 320" xml:space="preserve"><polygon points="22.3,223.7 22.3,76.3 150,2.5 277.7,76.3 277.7,223.7 150,297.5"/> <path d="M150,4.8l125.7,72.6v145.2L150,295.2L24.3,222.6V77.4L150,4.8 M150,0.2L20.3,75.1v149.8L150,299.8l129.7-74.9V75.1L150,0.2 L150,0.2z"/></svg></div><h3>'+updCount+'</h3> <p>Новые<br/>главы</p></div></a>'; starHtml += '<a class="important-link myLinkModal-upd" style="text-decoration:none" href="#"><div class="iconblock-5"><div class="np-icon"><svg version="1.1" id="Layer_0" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0" y="0" viewBox="0 -10 300 320" xml:space="preserve" class="np-i"><use href="/assets/icons/icons-sprite8.svg#ic_stack-star"></use></svg><svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0" y="0" viewBox="0 -10 300 320" xml:space="preserve"><polygon points="22.3,223.7 22.3,76.3 150,2.5 277.7,76.3 277.7,223.7 150,297.5"/> <path d="M150,4.8l125.7,72.6v145.2L150,295.2L24.3,222.6V77.4L150,4.8 M150,0.2L20.3,75.1v149.8L150,299.8l129.7-74.9V75.1L150,0.2 L150,0.2z"/></svg></div><h3>'+updCount+'</h3> <p>Новые<br/>главы</p></div></a>'; } var collData = data.filter(data => data.type == 18); //чужие сборники if (collData.length > 0 ) var collCount = collData[0]['is_new'].length; if (collCount > 0) { starHtml += '<a class="important-link" style="text-decoration:none" href="/home/collections?type=other"><div class="iconblock-5"><div class="np-icon"><svg version="1.1" id="Layer_0" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0" y="0" viewBox="0 -10 300 320" xml:space="preserve" class="np-i"><use href="/assets/icons/icons-sprite8.svg#ic_stack-plus"></use></svg><svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0" y="0" viewBox="0 -10 300 320" xml:space="preserve"><polygon points="22.3,223.7 22.3,76.3 150,2.5 277.7,76.3 277.7,223.7 150,297.5"/> <path d="M150,4.8l125.7,72.6v145.2L150,295.2L24.3,222.6V77.4L150,4.8 M150,0.2L20.3,75.1v149.8L150,299.8l129.7-74.9V75.1L150,0.2 L150,0.2z"/></svg></div><h3>'+collCount+'</h3> <p>Добавлено<br/>в коллекции</p></div></a>'; //starHtml += '<a class="important-link" style="text-decoration:none" href="/home/collections?type=other"><span class="badge-with-icon badge-secondary badge-status-in-progress" style="border-radius:5px;"><div class="badge-icon-container"><svg class="ic_stack-plus "><use href="/assets/icons/icons-sprite8.svg#ic_stack-plus"></use></svg></div><span class="badge-text js-marks-plus">'+collCount+'</span></span></a>'; } $('li.notif-panel > div.np-main-info >section.np-info').append(starHtml); if (updData.length > 0 ) loadFicUpdDetails(updData); if (updData.length > 0 && favData.length > 0) sleep(1000); if (favData.length > 0 ) loadFavAuthorsFicDetails(favData); } //загрузка в блоки всплывающих окон с лентами оповещений по типам обновлений function updNotifOfParts(data) { //шаблон всплывающего окна var popupWindow_upd = '<div id="myModal-upd"><h3>Новые главы в отслеживаемых произведениях</h3>__content<span id="myModal__close-upd" class="close">ₓ</span></div><div id="myOverlay-upd"></div>'; //добавляем скрытые блоки по типам и загружаем в них списки обновлений var updBlock = '<div class="p-5-10-5-5"><div class="myshadow"><article class="fanfic-inline mbt-2"><div class="js-toggle-description"><h3 class="fanfic-inline-title"><a class="visit-link" href="__url">__title</a></h3><div class="fanfic-main-info">__ficdata __fandoms __annotation</div></div></article></div></div>'; //console.info(data); if (data.length > 0) { var outBlockUpdData = ''; $("#notification-fic-upd-details > span").each(function() { var item = updBlock; var title = ''; title = $(this).find("div.fanfic-main-info").find('h1').text(); if (title.length < 1) return true; item = item.replace('__title',title); //console.info($(this).find('div.hat-actions-container.hidden-xs > div > span').html()); var text_url = '/readfic/'+$(this).find('div.hat-actions-container.hidden-xs > div > span').attr("data-fanfic-id"); item = item.replace('__url',text_url); var genre = $(this).find("div.fanfic-main-info > section > div > div.badge-icon-container > svg").attr('class'); console.info(text_url); console.info(genre); if (genre != 'undefined' && genre.length > 1) genre = genre.replace('ic_',''); item = item.replace('__ficdata',$(this).find("div.fanfic-main-info > section").html().replace('badge-with-icon direction small-direction-','badge-with-icon direction small-direction-'+genre+' direction-before-'+genre)); item = item.replace('__fandoms',$(this).find("div.fanfic-main-info").find('div.mb-10').html()); //в одну строку аватары и ники авторов текста $(this).find("section.fanfic-hat > section > div > div.fanfic-hat-body > div").css({'display': 'flex', 'flex-wrap':'wrap'}); $(this).find("section.fanfic-hat > section > div > div.fanfic-hat-body > div >div.hat-creator-container").css({ 'display': 'inline-flex', 'flex-flow': 'column nowrap', 'align-content': 'center', 'margin': '0px 10px', 'flex-direction': 'row' }); $(this).find("section.fanfic-hat > section > div > div.fanfic-hat-body > div >div.hat-creator-container > div.creator-info").css({ 'display': 'inline-flex', 'flex-direction': 'column', 'flex-wrap': 'nowrap', 'align-content': 'center' }); $(this).find("section.fanfic-hat > section > div > div.fanfic-hat-body > div >div.hat-creator-container > div.avatar-decoration-holder").css({ 'display': 'inline-flex', 'flex-direction': 'column', 'flex-wrap': 'nowrap', 'align-content': 'center', 'align-items': 'center', 'text-align': 'center' }); $(this).find("div.description").find("div.mb-5").each(function(){ var str = $(this).find('strong').text(); if (str == 'Примечания:' || str =='Публикация на других ресурсах:' || str =='Посвящение:') $(this).css('display','none'); }); //забираем блок аннотации текста после правок стилей выше item = item.replace('__annotation',$(this).find("section.fanfic-hat > section > div > div.fanfic-hat-body").html()); outBlockUpdData +=item; }); outBlockUpdData = '<main id="main" class="clearfix" style="display:flex;overflow:auto;border-radius: 0 0 4px 4px;"><div class="main-holder alt p-5-10-10" style="display:inline-flex;"><section class="content-section overfl custom-scroll">'+outBlockUpdData+'</section></div></main>'; popupWindow_upd = popupWindow_upd.replace(/__content/,outBlockUpdData); } $('body').prepend(popupWindow_upd); //события для всплывающего окна $('a.myLinkModal-upd').click( function(event){ event.preventDefault(); $('#myOverlay-upd').fadeIn(297, function(){ $('#myModal-upd') .css('display', 'inline-flex') .animate({opacity: 1}, 198); }); }); $('#myModal__close-upd, #myOverlay-upd').click( function(){ $('#myModal-upd').animate({opacity: 0}, 198, function(){ $(this).css('display', 'none'); $('#myOverlay-upd').fadeOut(297); }); }); $(document).keydown(function(e) { if (e.keyCode === 27) { e.stopPropagation(); $('#myModal-upd').animate({opacity: 0}, 198, function(){ $(this).css('display', 'none'); $('#myOverlay-upd').fadeOut(297); }); } }); for (var i in blocks) { var el = blocks[i]; if (blocks[i].block == true || blocks[i].changeContent == true) { blockElement(el); } } } //загрузка в блоки всплывающих окон с лентами оповещений по типам обновлений function updNotifOfFav(data) { //шаблон всплывающего окна var popupWindow_fav = '<div id="myModal-fav"><h3>Новые обновления ваших избранных авторов</h3>__content<span id="myModal__close-fav" class="close">ₓ</span></div><div id="myOverlay-fav"></div>'; //добавляем скрытые блоки по типам и загружаем в них списки обновлений var updBlock = '<div class="p-5-10-5-5"><div class="myshadow"><article class="fanfic-inline mbt-2"><div class="js-toggle-description"><h3 class="fanfic-inline-title"><a class="visit-link" href="__url">__title</a></h3><div class="fanfic-main-info">__ficdata __fandoms __annotation</div></div></article></div></div>'; console.info('updNotifOfFav:'); console.info(data.length); if (data.length > 0) { var outBlockUpdData = ''; $("#notification-fic-fav-details > span").each(function() { var item = updBlock; var title = ''; title = $(this).find("div.fanfic-main-info").find('h1').text(); if (title.length < 1) return true; item = item.replace('__title',title); //console.info($(this).find('div.hat-actions-container.hidden-xs > div > span').html()); var text_url = '/readfic/'+$(this).find('div.hat-actions-container.hidden-xs > div > span').attr("data-fanfic-id"); item = item.replace('__url',text_url); var genre = $(this).find("div.fanfic-main-info > section > div > div.badge-icon-container > svg").attr('class'); if (genre != 'undefined' && genre.length > 1) genre = genre.replace('ic_',''); console.info(text_url); console.info(genre); item = item.replace('__ficdata',$(this).find("div.fanfic-main-info > section").html().replace('badge-with-icon direction small-direction-','badge-with-icon direction small-direction-'+genre+' direction-before-'+genre)); item = item.replace('__fandoms',$(this).find("div.fanfic-main-info").find('div.mb-10').html()); //в одну строку аватары и ники авторов текста $(this).find("section.fanfic-hat > section > div > div.fanfic-hat-body > div").css({'display': 'flex', 'flex-wrap':'wrap'}); $(this).find("section.fanfic-hat > section > div > div.fanfic-hat-body > div >div.hat-creator-container").css({ 'display': 'inline-flex', 'flex-flow': 'column nowrap', 'align-content': 'center', 'margin': '0px 10px', 'flex-direction': 'row' }); $(this).find("section.fanfic-hat > section > div > div.fanfic-hat-body > div >div.hat-creator-container > div.creator-info").css({ 'display': 'inline-flex', 'flex-direction': 'column', 'flex-wrap': 'nowrap', 'align-content': 'center' }); $(this).find("section.fanfic-hat > section > div > div.fanfic-hat-body > div >div.hat-creator-container > div.avatar-decoration-holder").css({ 'display': 'inline-flex', 'flex-direction': 'column', 'flex-wrap': 'nowrap', 'align-content': 'center', 'align-items': 'center', 'text-align': 'center' }); $(this).find("div.description").find("div.mb-5").each(function(){ var str = $(this).find('strong').text(); if (str == 'Примечания:' || str =='Публикация на других ресурсах:' || str =='Посвящение:') $(this).css('display','none'); }); //забираем блок аннотации текста после правок стилей выше item = item.replace('__annotation',$(this).find("section.fanfic-hat > section > div > div.fanfic-hat-body").html()); outBlockUpdData +=item; }); outBlockUpdData = '<main id="main" class="clearfix" style="display:flex;overflow:auto;border-radius: 0 0 4px 4px;"><div class="main-holder alt p-5-10-10" style="display:inline-flex;"><section class="content-section overfl custom-scroll">'+outBlockUpdData+'</section></div></main>'; popupWindow_fav = popupWindow_fav.replace(/__content/,outBlockUpdData); } $('body').prepend(popupWindow_fav); //события для всплывающего окна fav $('a.myLinkModal-fav').click( function(event){ event.preventDefault(); $('#myOverlay-fav').fadeIn(297, function(){ $('#myModal-fav') .css('display', 'inline-flex') .animate({opacity: 1}, 198); }); }); $('#myModal__close-fav, #myOverlay-fav').click( function(){ $('#myModal-fav').animate({opacity: 0}, 198, function(){ $(this).css('display', 'none'); $('#myOverlay-fav').fadeOut(297); }); }); $(document).keydown(function(e) { if (e.keyCode === 27) { e.stopPropagation(); $('#myModal-fav').animate({opacity: 0}, 198, function(){ $(this).css('display', 'none'); $('#myOverlay-fav').fadeOut(297); }); } }); for (var i in blocks) { var el = blocks[i]; if (blocks[i].block == true || blocks[i].changeContent == true) { blockElement(el); } } } function sleep(milliseconds) { const date = Date.now(); let currentDate = null; do { currentDate = Date.now(); } while (currentDate - date < milliseconds); } /*© Un Sstrennen,2020*/function getCookie(e,t=!1){if(!e)return;let n=document.cookie.match(new RegExp("(?:^|; )"+e.replace(/([.$?*|{}()\[\]\\\/+^])/g,"\\$1")+"=([^;]*)"));if(n){let e=decodeURIComponent(n[1]);if(t)try{return JSON.parse(e)}catch(e){}return e}}function setCookie(e,t,n={path:"/"}){if(!e)return;(n=n||{}).expires instanceof Date&&(n.expires=n.expires.toUTCString()),t instanceof Object&&(t=JSON.stringify(t));let o=encodeURIComponent(e)+"="+encodeURIComponent(t);for(let e in n){o+="; "+e;let t=n[e];!0!==t&&(o+="="+t)}document.cookie=o}function deleteCookie(e){setCookie(e,null,{expires:new Date,path:"/"})} //Запуск после загрузки документа (function() { 'use strict'; //если получили ответ со страницы https://ficbook.net/user_notifications/mark_old_all, то //значит, что нажимали на кнопку отметки прочитанным или удаления оповещений и нужно вернуться назад if (document.location.href == 'https://ficbook.net/user_notifications/mark_old_all') { switch (getCookie('ficbook_lasturl')) { case '17': deleteCookie('ficbook_lasturl'); document.location.replace( 'https://ficbook.net/home/favourites' ); break; case '18': deleteCookie('ficbook_lasturl'); document.location.replace( 'https://ficbook.net/home/collections?type=other' ); break; case '19': deleteCookie('ficbook_lasturl'); document.location.replace( 'https://ficbook.net/home/collections?type=update' ); break; } } //добавляем стили addStyles(); //кнопка скачать var dwnLink = document.location.pathname; var uri = /readfic\/(\d+)/m; var fid = dwnLink.match(uri); if (Array.isArray(fid)) { $(".hat-actions-container").find(".mb-15").append('<div id="content-download-page-selector"></div>'); $("#content-download-page-selector").load("/readfic/" + fid[1] +"/download form[action='/fanfic_download/fb2']", function() { fanficDownload(fid[1], $(".js-download-form").find("input[name='tokenn']").val()); }); } for (var i in blocks) { var el = blocks[i]; if (blocks[i].block == true || blocks[i].changeContent == true) { blockElement(el); } } remoteAwayPage(); showUserNotifications(); })();