您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Various search filters
当前为
// ==UserScript== // @name XHamster - Search Filters // @namespace brazenvoid // @version 1.0.2 // @author brazenvoid // @license GPL-3.0-only // @description Various search filters // @include https://xhamster.com/* // @require https://greasyfork.org/scripts/375557-brazenvoid-s-base-resource/code/Brazenvoid's%20Base%20Resource.js?version=673754 // @run-at document-idle // ==/UserScript== // Settings & Defaults let settings = { blacklist: [ // case-insensitive 'urin', 'arab', 'muslim', 'desi', 'squirt', 'fake', 'pregnant', 'pee', ], sanitize: { // Substitutes values with key (case-insensitive) ' ': ['neighbor', 'step'], Boyfriend: ['brother', 'bro', 'daddy', 'dad'], Girlfriend: ['daughter', 'mom', 'mother', 'sister', 'sis'] }, duration: { // In Seconds minimum: 120, maximum: 0 }, rating: { minimum: 80, maximum: 0 }, views: { minimum: 0, maximum: 0 }, hideSDVideos: true, showUIAlways: false, // Desktop debugLogging: false } // Base Resources Initialization const scriptPrefix = 'xh-sui-' let storage = new LocalStore(scriptPrefix + 'settings', settings) settings = storage.retrieve().get() let logger = new Logger(settings.debugLogging) let selectorGenerator = new SelectorGenerator(scriptPrefix) let statistics = new StatisticsRecorder(logger, selectorGenerator) let uiGenerator = new UIGenerator(settings.showUIAlways, selectorGenerator) uiGenerator.buttonBackroundColor = 'rgb(218, 218, 218)' let validator = new Validator(statistics) validator.addBlacklistFilter(settings.blacklist).addSanitizationFilter(settings.sanitize).optimize() function getVideoLists () { return document.querySelectorAll('div.thumb-list') } // Local Store Events let refreshUI = function () { let store = this.get() uiGenerator.setSettingsInputValue('Min Duration', store.duration.minimum) uiGenerator.setSettingsInputValue('Min Rating', store.rating.minimum) uiGenerator.setSettingsInputValue('Min Views', store.views.minimum) } storage.onDefaultsLoaded = refreshUI storage.onRetrieval = refreshUI storage.onUpdated = refreshUI // Validators // -- Duration validation let validateDuration = function (videoItem) { if (settings.duration.minimum > 0 || settings.duration.maximum > 0) { let duration = videoItem.querySelector('div.thumb-image-container__duration') if (duration !== null) { duration = duration.textContent.split(':') duration = (parseInt(duration[0]) * 60) + parseInt(duration[1]) return validator.validateRange('Duration', duration, [settings.duration.minimum, settings.duration.maximum]) } } return true } // -- High definition validation let validateHD = function (videoItem) { let validationCheck = true if (settings.hideSDVideos) { validationCheck = videoItem.querySelector('i.thumb-image-container__icon--hd') !== null logger.logValidation('HD', validationCheck) } return validationCheck } // -- Rating validation let validateRating = function (videoItem) { let validationCheck = true if (settings.rating.minimum > 0 || settings.rating.maximum > 0) { let rating = videoItem.querySelector('i.video-thumb-info__rating') if (rating !== null) { rating = parseInt(rating.textContent.replace('%', '')) validationCheck = validator.validateRange('Rating', rating, [settings.rating.minimum, settings.rating.maximum]) } } return validationCheck } // -- View count validation let validateViews = function (videoItem) { if (settings.views.minimum > 0 || settings.views.maximum > 0) { let views = videoItem.querySelector('i.video-thumb-info__views') if (views !== null) { views = parseInt(views.textContent.replace(',', '')); if (isNaN(views)) { views = 0 } return validator.validateRange('Views', views, [settings.views.minimum, settings.views.maximum]) } } return true } // -- Compliance logic let complianceCallback = function (target) { let videoItems = target.querySelectorAll('div.thumb-list__item') let videoName, videoComplies for (let videoItem of videoItems) { videoName = videoItem.querySelector('a.video-thumb-info__name') logger.logVideoCheck(videoName.textContent) videoComplies = validateHD(videoItem) && validateRating(videoItem) && validator.validateBlackList(videoName.textContent) && validateDuration(videoItem) && validateViews(videoItem) if (videoComplies) { videoItem.style.display = 'inline-block' validator.sanitizeVideoItem(videoName) } else { videoItem.style.display = 'none' } logger.logSeparator() } statistics.updateUI() } // UI Composition // -- Control Panel let section = uiGenerator.createSection('settings', '#ffa31a', '150px', '220px', [ uiGenerator.createSettingsFormGroup('Min Duration', 'number', settings.duration.minimum), uiGenerator.createSettingsFormGroup('Min Rating', 'number', settings.rating.minimum), uiGenerator.createSettingsFormGroup('Min Views', 'number', settings.views.minimum), uiGenerator.createSettingsFormActions(storage, function () { settings.duration.minimum = uiGenerator.getSettingsInputValue('Min Duration') settings.rating.minimum = uiGenerator.getSettingsInputValue('Min Rating') settings.views.minimum = uiGenerator.getSettingsInputValue('Min Views') statistics.reset() for (let videoList of getVideoLists()) { complianceCallback(videoList) } }, true), uiGenerator.createSeparator(), uiGenerator.createStoreControlPanel(storage), uiGenerator.createSeparator(), uiGenerator.createStatisticsFormGroup('Duration', 'Short'), uiGenerator.createStatisticsFormGroup('Rating', 'Low Rated'), uiGenerator.createStatisticsFormGroup('Views', 'By Views'), uiGenerator.createStatisticsFormGroup('Blacklist', 'Blacklisted'), uiGenerator.createStatisticsFormGroup('Total'), uiGenerator.createSettingsHideButton('settings'), ]) uiGenerator.appendToBody(section) uiGenerator.appendToBody(uiGenerator.createSettingsShowButton('Search & Tweaks', section)) logger.logTaskCompletion('Building UI') // Script run // -- Initial compliance run & observer attachment ChildObserver.observe(getVideoLists(), complianceCallback, true) validator.sanitizeVideoPage('h1.entity-info-container__title') logger.logTaskCompletion('Initial run and observer attachment.')