您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
f95zone exclude tags and min like filter.
当前为
// ==UserScript== // @name f95zone tweaks // @namespace f95zone tweaks // @description f95zone exclude tags and min like filter. // @match https://f95zone.to/latest/ // @version 1.3.8 // @author 3xd_Tango // @require https://cdn.jsdelivr.net/combine/npm/@violentmonkey/dom@1,npm/@violentmonkey/[email protected] // @require https://cdn.jsdelivr.net/npm/lodash@4/lodash.min.js // @grant GM_addStyle // @grant GM_getValue // @grant GM_setValue // ==/UserScript== (function () { 'use strict'; var css_248z = ".customTags{border-radius:2px;box-shadow:0 0 0 0 transparent,0 1px 1px 0 rgba(0,0,0,.15),0 1px 2px 0 rgba(0,0,0,.15);display:inline-block;font-size:.8em;line-height:1.8em;margin:4px 4px 0 0;padding:0 6px;text-shadow:1px 1px 2px rgba(0,0,0,.75)}.selected-tags-wrap span:hover{background-color:#ba4545}.selected-tags-wrap span{background-color:#181a1d;border-radius:3px;cursor:pointer;display:inline-block;font-size:.9em;line-height:24px;margin:4px 4px 0 0;padding:0 7px;transition:.2s}.input-tag{width:127px;opacity:1;position:relative;left:0}.border-gradient{border:3px solid;border-image-slice:1}.flxgrow{flex-grow:1}"; const likes = GM_getValue('likes', [['incest', '#ff0000'], ['harem', '#0011ff'], ['futa/trans', '#EE82EE'], ['loli', '#00f5ffff'], ['futa/trans protagonist', '#EE82EE']]); const dislikes = GM_getValue('dislikes', ['female protagonist', 'text based', 'mind control']); const totalTags = GM_getValue('tags', []); function likeFilter() { const element = document.querySelectorAll('.resource-tile'); document.querySelectorAll('.customTags').forEach(e => e.parentNode.remove()); for (let i = 0; i < element.length; i += 1) { element[i].style = ''; element[i].classList.remove('border-gradient'); element[i].setAttribute('isDisplay', 'false'); const colors = []; const node = document.createElement('DIV'); const dataTags = element[i].dataset.tags.split(','); node.style.padding = '.5rem 0'; for (let j = likes.length - 1; j >= 0; j -= 1) { if (dataTags.includes(likes[j][0])) { if (!element[i].classList.contains('border-gradient')) { element[i].classList.add('border-gradient'); } const node1 = document.createElement('SPAN'); colors.push(likes[j][1]); node1.classList.add('customTags'); node1.style.borderLeft = `${likes[j][1]} solid`; node1.appendChild(document.createTextNode(likes[j][0])); node.appendChild(node1); element[i].setAttribute('isDisplay', 'true'); } else if (element[i].getAttribute('isDisplay') === null) { element[i].setAttribute('isDisplay', 'false'); } } if (colors.length > 1) { element[i].style.borderImageSource = `linear-gradient(to bottom right, ${colors.toString()})`; } else { element[i].style.color = colors[0]; } if (element[i].getAttribute('isDisplay') === 'true') { try { element[i].childNodes[0].childNodes[1].childNodes[1].appendChild(node); } catch (e) { console.error(e); setTimeout(likeFilter, 200); } } } } function likeLimit() { const element = document.querySelectorAll('.resource-tile_info'); // if (likesLimit === '') { // likesLimit = -1; // } for (let i = 0; i < element.length; i++) { const elementLikes = element[i].childNodes[1].childNodes[1].innerText; const elementName = element[i].childNodes[0].childNodes[0].childNodes[0].innerText; const checkFilter = Number(elementLikes) <= Number(GM_getValue('like_limit', 200)); console.debug(`we get Like limit of ${elementName} is ${elementLikes} with check ${checkFilter} with display attribute of ${element[i].parentNode.parentNode.parentNode.getAttribute('isDisplay').toLowerCase() === 'false'}`); if (checkFilter) { if (element[i].parentNode.parentNode.parentNode.getAttribute('isDisplay') === 'false') { element[i].parentNode.parentNode.parentNode.setAttribute('isLikeLimit', 'true'); continue; } if (GM_getValue('favLikeFilter', false)) { element[i].parentNode.parentNode.parentNode.setAttribute('isLikeLimit', 'true'); continue; } } element[i].parentNode.parentNode.parentNode.setAttribute('isLikeLimit', 'false'); } } function filterOut() { const element = document.querySelectorAll('.resource-tile'); for (let i = 0; i < element.length; i++) { if (element[i].getAttribute('isDislike') === 'true' || element[i].getAttribute('isLikeLimit') === 'true') { element[i].style.setProperty('display', 'none', 'important'); element[i].style.setProperty('height', '0px', 'important'); element[i].style.setProperty('margin', '0px', 'important'); } else { element[i].style.setProperty('display', 'block', 'important'); element[i].style.setProperty('height', 'unset', 'important'); element[i].style.setProperty('margin', 'unset', 'important'); } } } function checkTags(element, dataTags) { let tagProt = ['female protagonist', 'male protagonist', 'futa/trans protagonist']; const tagProtNames = dislikes.filter(e => e.includes('protagonist')); const b = []; let c = 0; dataTags.forEach(e => { if (tagProtNames.length >= 1) { if (tagProtNames.includes(e)) { return b.push(e); } } if (dislikes.includes(e)) { c += 1; } }); // console.debug(`b = ${b}`, c, element); if (c > 0) { return true; } if (b.length > 0) { b.forEach(e => { tagProt = tagProt.filter(r => r !== e); }); for (let i = 0; i <= tagProt.length - 1; i++) { console.debug(`datatags includes? = ${dataTags.includes(tagProt[i])} for ${tagProt[i]} `); if (dataTags.includes(tagProt[i])) { return false; } if (i === tagProt.length - 1) { return true; } } } console.debug(`tagProt = ${tagProt}`); return false; } function dislikeFilter() { const element = document.querySelectorAll('.resource-tile'); for (let i = 0; i < element.length; i++) { const dataTags = element[i].dataset.tags.split(','); const isFP = checkTags(element[i], dataTags); if (isFP) { element[i].setAttribute('isDislike', 'true'); } else { element[i].setAttribute('isDislike', 'false'); } } } function tagRemoveHandler(event, isLikes) { let filtered = []; if (isLikes) { filtered = likes.filter(r => r[0] !== event.target.textContent); console.debug(`You have clicked the Like Tag to Remove it and the filtered is: ${filtered} within ${likes}`); const removed = _.remove(likes, n => { return n[0] === event.target.textContent; }); console.debug(`after filtred you got likes tags: ${likes} and you removed ${removed}`); likeFilter(); likeLimit(); } else { filtered = dislikes.filter(r => r !== event.target.textContent); console.debug(`You have clicked the dislike Tag to Remove it and the filtered is: ${filtered} within ${dislikes}`); const removed = _.remove(dislikes, n => { return n === event.target.textContent; }); console.debug(`after filtred you got dislike tags: ${dislikes} and you removed ${removed}`); dislikeFilter(); } event.target.remove(); GM_setValue(isLikes ? 'likes' : 'dislikes', filtered); filterOut(); } // function tagRemoveHandler1(event) { // likes = likes.filter(r => r[0] !== event.target.textContent); // event.target.remove(); // GM_setValue('likes', likes); // likeFilter(); // likeLimit(); // filterOut(); // } function likeHandler(event) { const tagName = event.target.value; event.target.value = ''; let x; do { x = prompt('Please Enter the Color in Hex like \'#FFFFFF\''); } while (!x.includes('#') && x === '' && x.length <= 1); console.debug(`you have entered color in hex: ${x} with tagName: ${tagName} and the condition ${x !== null}`); if (x !== null) { const tag = [tagName, x]; likes.push(tag); console.debug(`the likes after pushing the ${tag} is ${likes}`); GM_setValue('likes', _.sortBy(likes, item => item[0])); const node = document.createElement('SPAN'); node.onclick = e => tagRemoveHandler(e, true); node.style.borderLeft = `${x} solid`; node.appendChild(document.createTextNode(tagName)); event.target.parentNode.parentNode.childNodes[2].append(node); likeFilter(); likeLimit(); filterOut(); } } function dislikeHandler(event) { const tagName = event.target.value; dislikes.push(tagName); GM_setValue('dislikes', _.sortBy(dislikes)); event.target.value = ''; const node = document.createElement('SPAN'); node.onclick = e => tagRemoveHandler(e, false); node.appendChild(document.createTextNode(tagName)); event.target.parentNode.parentNode.childNodes[2].append(node); dislikeFilter(); filterOut(); } function limitHandler(event) { GM_setValue('like_limit', event.target.value); likeLimit(); filterOut(); } function clickTotalTags() { const y = document.querySelector('.selectize-control'); if (y !== null) { y.addEventListener('click', e => { const x = document.querySelectorAll('div.option'); console.log('clicked', x); if (x !== []) { const totalTags = []; x.forEach(e => totalTags.push(e.innerHTML)); GM_setValue('tags', totalTags); } }); } } function init() { const element = document.querySelectorAll('.resource-tile'); const elementLength = element.length; if (element[0]) { likeFilter(); clickTotalTags(); for (let i = 0; i < 3; i++) { dislikeFilter(); likeLimit(); filterOut(); // if(document.querySelectorAll('.resource-tile')) const filtered = _.filter(document.querySelectorAll('.resource-tile'), e => { return e.style.getPropertyValue('display') === 'block'; }); console.debug('Filtered', filtered); if (filtered.length < elementLength) { break; } } } else { setTimeout(init, 100); } } function waitForElementToDisplayAndAppend(selector, callback, checkFrequencyInMs, timeoutInMs) { const startTimeInMs = Date.now(); (function loopSearch() { if (document.querySelector(selector).childNodes.length > 0) { document.querySelector(selector).appendChild(callback()); } else { setTimeout(() => { if (timeoutInMs && Date.now() - startTimeInMs > timeoutInMs) return; loopSearch(); }, checkFrequencyInMs); } })(); } function LikesTagFilter() { // filter-block accordion-block filter-block_prefix-group return VM.createElement("div", { className: "filter-block accordion-block filter-block_prefix-group" }, VM.createElement("h4", { className: "filter-block_title accordion-toggle" }, "Like Tags"), VM.createElement("div", { className: "filter-block_content filter-block_v accordion-content" }, VM.createElement("div", { className: "selectize-input" }, VM.createElement("input", { autoComplete: "on", placeholder: "Enter a tag to filter...", className: "input-tag", onChange: likeHandler, list: "totalTagName" })), VM.createElement("datalist", { id: "totalTagName" }, totalTags.map(item => { return VM.createElement("option", { value: item }); })), VM.createElement("div", { className: "selected-tags-wrap" }, likes.map(dl => VM.createElement("span", { onClick: e => tagRemoveHandler(e, true), style: { borderLeft: `${dl[1]} solid` } }, dl[0]))))); } function DislikeTagFilter() { return VM.createElement("div", { className: "filter-block accordion-block filter-block_prefix-group" }, VM.createElement("h4", { className: "filter-block_title accordion-toggle" }, "Dislike Tags"), VM.createElement("div", { className: "filter-block_content filter-block_v accordion-content" }, VM.createElement("div", { className: "selectize-input" }, VM.createElement("input", { autoComplete: "off", placeholder: "Enter a tag to filter...", className: "input-tag", onChange: dislikeHandler, list: "totalTagName1" })), VM.createElement("datalist", { id: "totalTagName1" }, totalTags.map(item => { return VM.createElement("option", { value: item }); })), VM.createElement("div", { className: "selected-tags-wrap" }, dislikes.map(dl => VM.createElement("span", { onClick: e => tagRemoveHandler(e, false) }, dl))))); } function LikeLimitDisplay() { return VM.createElement("div", { className: "filter-block" }, VM.createElement("h4", { className: "filter-block_title" }, "Tags Like Limits"), VM.createElement("div", { className: "selectize-input" }, VM.createElement("input", { value: GM_getValue('like_limit', 200), autoComplete: "off", style: "width: 127px;", onChange: limitHandler }))); } function FilterFavLikeHandler(event) { GM_setValue('favLikeFilter', event.target.checked); likeLimit(); filterOut(); } function mainFilter() { init(); return VM.createElement(VM.Fragment, null, LikeLimitDisplay(), VM.createElement("div", { className: "filter-block" }, VM.createElement("div", { className: "filter-block_button-wrap", style: { display: 'flex' } }, VM.createElement("span", { className: "filter-block_title flxgrow" }, "Filter Fav likes:"), VM.createElement("input", { type: "checkbox", id: "filter-fav-likes", onChange: FilterFavLikeHandler, checked: GM_getValue('favLikeFilter', false) }))), VM.createElement("style", null, css_248z)); } document.querySelector('.content-block_filter').appendChild(mainFilter()); waitForElementToDisplayAndAppend('#filter-block_prefixes', LikesTagFilter, 1000, 10000); waitForElementToDisplayAndAppend('#filter-block_prefixes', DislikeTagFilter, 1000, 10000); history.onpushstate = function (state) { setTimeout(init, 200); }; (function (history) { const pushState = history.pushState; history.pushState = function (state) { if (typeof history.onpushstate === 'function') { history.onpushstate({ state }); } return pushState.apply(history); }; })(window.history); }());