您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Video filters and UI manipulations
当前为
// ==UserScript== // @name Video Celebs Search And UI Tweaks // @version 1.1.1 // @namespace brazenvoid // @author brazenvoid // @license GPL-3.0-only // @description Video filters and UI manipulations // @include https://videocelebs.net/* // @require https://greasyfork.org/scripts/375557-base-resource/code/Base%20Resource.js?version=869002 // @grant GM_addStyle // @run-at document-end // ==/UserScript== GM_addStyle( `.form-group{display:flex;align-items:center}label.form-label{flex-grow:1}input.form-input{height:auto}input.form-input.check-radio-input{width:auto;margin:0 5px 1px 0}label.form-label{padding: 0}label.title{margin: 0}div.form-group.form-range-input-group>input+input{margin-left: 5px;margin-right:0}`) const PAGE_PATH_NAME = window.location.pathname const IS_VIDEO_PAGE = PAGE_PATH_NAME.endsWith('.html') const FILTER_RATING_VIDEOS_KEY = 'Rating' const FILTER_VIDEOS_YEAR_KEY = 'Year' const OPTION_ALWAYS_SHOW_UI = 'Always Show This Settings Pane' const OPTION_DISABLE_VIDEO_FILTERS = 'Disable All Video Filters' const OPTION_MOVE_VIDEO_ATTRIBUTES_SECTION_KEY = 'Reposition Attributes Section' const OPTION_REMOVE_COMMENTS_SECTION_KEY = 'Remove Comments Section' const OPTION_REMOVE_IFRAME_SECTION_KEY = 'Remove Iframe Share Section' const OPTION_REMOVE_RELATED_VIDEOS_SECTION_KEY = 'Remove Related Videos Section' const PAGINATOR_THRESHOLD = 'Pagination Threshold' class VideoCelebsSearchAndUITweaks extends BaseHandler { /** * @typedef {{disableItemComplianceValidation: boolean, rating: {maximum: number, minimum: number}, year: {maximum: number, minimum: number}, * moveVideoAttributesBelowDescription: boolean, removeCommentsSection: boolean, removeIFrameSection: boolean, removeRelatedVideosSection: boolean, showUIAlways: boolean * paginationThreshold: number}} VideoCelebsSearchAndUITweaksSettings */ static initialize () { return (new VideoCelebsSearchAndUITweaks).init() } constructor () { super({ scriptPrefix: 'vc-sui-', itemClasses: 'item.big', paginator: { enable: !IS_VIDEO_PAGE, listSelector: '.midle_div', lastPageUrl: $('a.last').attr('href'), getPageNo: (url) => url.includes('/page/') ? parseInt(url.split('/').pop()) : 1, getPageUrl: (newPageNo) => { let currentUrl = window.location.href if (currentUrl.includes('/page/')) { let currentUrlFragments = currentUrl.split('/') currentUrlFragments.pop() currentUrl = currentUrlFragments.join('/') } else { currentUrl += '/page' } return currentUrl + '/' + newPageNo }, afterPagination: (paginator) => { let currentPaginationElement = $('.wp-pagenavi span.current') currentPaginationElement.text(paginator.currentPageNo + '-' + paginator.paginatedPageNo) let paginatorLinksAfterCurrent = $('.wp-pagenavi span.current ~ a') if (paginator.paginatedPageNo === paginator.lastPageNo) { paginatorLinksAfterCurrent.remove() } else { paginatorLinksAfterCurrent.each((index, element) => { let paginationLink = $(element) if (paginator.getPageNo($(element).attr('href')) <= paginator.paginatedPageNo) { paginationLink.remove() } }) let nextPageUrl = paginator.getPageUrl(paginator.paginatedPageNo + 1) let nextPageLink = $('.wp-pagenavi a[href="'+ nextPageUrl +'"]') if (nextPageLink.length === 0) { let lastPageLink = $('.wp-pagenavi a.last') lastPageLink.clone().insertAfter(currentPaginationElement). text(paginator.paginatedPageNo + 1).removeClass('last').attr('href', nextPageUrl) } } } }, configDefaults: { rating: { minimum: 0, maximum: 0, }, year: { minimum: 0, maximum: 0, }, moveVideoAttributesBelowDescription: false, removeCommentsSection: false, removeIFrameSection: false, removeRelatedVideosSection: false, }, }) // UI Events this._onBeforeUIBuild = () => { if (IS_VIDEO_PAGE) { this._moveVideoAttributesBelowDescription() this._removeCommentsSection() this._removeIFrameSection() this._removeRelatedVideosSection() } } this._onUIBuild = () => this._uiGen.createSection('settings', '#ffa31a', '15vh', '250px').addSectionChildren([ this._uiGen.createTabsSection(['Filters', 'UI', 'Stats'], [ this._uiGen.createTabPanel('Filters', [ this._createFormRangeInputGroup(FILTER_RATING_VIDEOS_KEY, 'number'), this._createFormRangeInputGroup(FILTER_VIDEOS_YEAR_KEY, 'number'), this._uiGen.createSeparator(), this._uiGen.createFormInputGroup(OPTION_DISABLE_VIDEO_FILTERS, 'checkbox', 'Disables all video filters.'), this._uiGen.createSeparator(), this._createSettingsFormActions(), this._uiGen.createSeparator(), this._uiGen.createStoreFormSection(this._settingsStore), ]), this._uiGen.createTabPanel('UI', [ this._uiGen.createFormInputGroup(OPTION_MOVE_VIDEO_ATTRIBUTES_SECTION_KEY, 'checkbox', 'Move the video attributes section from below the screenshot area to under the description.'), this._uiGen.createFormInputGroup(OPTION_REMOVE_COMMENTS_SECTION_KEY, 'checkbox', 'Remove comments area on video pages.'), this._uiGen.createFormInputGroup(OPTION_REMOVE_IFRAME_SECTION_KEY, 'checkbox', 'Remove iframe share section under video player.'), this._uiGen.createFormInputGroup(OPTION_REMOVE_RELATED_VIDEOS_SECTION_KEY, 'checkbox', 'Remove related videos section on video pages.'), this._uiGen.createSeparator(), this._uiGen.createFormInputGroup(PAGINATOR_THRESHOLD, 'number', 'Merges results from later pages to satisfy the defined minimum.'), this._uiGen.createFormInputGroup(OPTION_ALWAYS_SHOW_UI, 'checkbox', 'Always show this interface.'), this._uiGen.createSeparator(), this._createSettingsFormActions(), this._uiGen.createSeparator(), this._uiGen.createStoreFormSection(this._settingsStore), ]), this._uiGen.createTabPanel('Stats', [ this._uiGen.createStatisticsFormGroup(FILTER_RATING_VIDEOS_KEY), this._uiGen.createStatisticsFormGroup(FILTER_VIDEOS_YEAR_KEY), this._uiGen.createSeparator(), this._uiGen.createStatisticsTotalsGroup(), ]), ]), this._uiGen.createStatusSection(), ]) // Compliance Events this._onGetItemLists = () => document.querySelectorAll('.midle_div,.list_videos') this._complianceFilters = [ (videoItem) => this._validateRating(videoItem), (videoItem) => this._validateYear(videoItem), ] // Store Events this._onSettingsStoreUpdate = () => { /** @type {VideoCelebsSearchAndUITweaksSettings} */ let store = this._settingsStore.get() this._uiGen.setSettingsInputCheckedStatus(OPTION_ALWAYS_SHOW_UI, store.showUIAlways) this._uiGen.setSettingsInputCheckedStatus(OPTION_DISABLE_VIDEO_FILTERS, store.disableItemComplianceValidation) this._uiGen.setSettingsInputCheckedStatus(OPTION_MOVE_VIDEO_ATTRIBUTES_SECTION_KEY, store.moveVideoAttributesBelowDescription) this._uiGen.setSettingsInputCheckedStatus(OPTION_REMOVE_COMMENTS_SECTION_KEY, store.removeCommentsSection) this._uiGen.setSettingsInputCheckedStatus(OPTION_REMOVE_IFRAME_SECTION_KEY, store.removeIFrameSection) this._uiGen.setSettingsInputCheckedStatus(OPTION_REMOVE_RELATED_VIDEOS_SECTION_KEY, store.removeRelatedVideosSection) this._uiGen.setSettingsInputValue(PAGINATOR_THRESHOLD, store.paginationThreshold) this._uiGen.setSettingsRangeInputValue(FILTER_RATING_VIDEOS_KEY, store.rating.minimum, store.rating.maximum) this._uiGen.setSettingsRangeInputValue(FILTER_VIDEOS_YEAR_KEY, store.year.minimum, store.year.maximum) } this._onSettingsApply = () => { /** @type {VideoCelebsSearchAndUITweaksSettings} */ let settings = this._settings settings.disableItemComplianceValidation = this._uiGen.getSettingsInputCheckedStatus(OPTION_DISABLE_VIDEO_FILTERS) settings.moveVideoAttributesBelowDescription = this._uiGen.getSettingsInputCheckedStatus(OPTION_MOVE_VIDEO_ATTRIBUTES_SECTION_KEY) settings.paginationThreshold = this._uiGen.getSettingsInputValue(PAGINATOR_THRESHOLD) settings.rating.minimum = this._uiGen.getSettingsRangeInputValue(FILTER_RATING_VIDEOS_KEY, true) settings.rating.maximum = this._uiGen.getSettingsRangeInputValue(FILTER_RATING_VIDEOS_KEY, false) settings.removeCommentsSection = this._uiGen.getSettingsInputCheckedStatus(OPTION_REMOVE_COMMENTS_SECTION_KEY) settings.removeIFrameSection = this._uiGen.getSettingsInputCheckedStatus(OPTION_REMOVE_IFRAME_SECTION_KEY) settings.removeRelatedVideosSection = this._uiGen.getSettingsInputCheckedStatus(OPTION_REMOVE_RELATED_VIDEOS_SECTION_KEY) settings.showUIAlways = this._uiGen.getSettingsInputCheckedStatus(OPTION_ALWAYS_SHOW_UI) settings.year.minimum = this._uiGen.getSettingsRangeInputValue(FILTER_VIDEOS_YEAR_KEY, true) settings.year.maximum = this._uiGen.getSettingsRangeInputValue(FILTER_VIDEOS_YEAR_KEY, false) } } _moveVideoAttributesBelowDescription () { if (this._settings.moveVideoAttributesBelowDescription) { let videoInfoBlock = document.querySelector('.entry-utility') videoInfoBlock.parentNode.insertBefore(videoInfoBlock, videoInfoBlock.previousSibling.previousSibling) } } _removeCommentsSection () { if (this._settings.removeCommentsSection) { $('.comments-area').remove() } } _removeIFrameSection () { if (this._settings.removeIFrameSection) { $('#tab_share').remove() } } _removeRelatedVideosSection () { if (this._settings.removeRelatedVideosSection) { $('.related').remove() } } /** * Validate video source release year * @param {Node|HTMLElement} videoItem * @return {boolean} * @private */ _validateRating (videoItem) { if (this._settings.rating.minimum > 0 || this._settings.rating.maximum > 0) { let rating = parseInt(videoItem.querySelector('.rating').textContent.trim().replace('%', '')) return this._validator.validateRange(FILTER_RATING_VIDEOS_KEY, rating, [this._settings.rating.minimum, this._settings.rating.maximum]) } return true } /** * Validate video view count * @param {Node|HTMLElement} videoItem * @return {boolean} * @private */ _validateYear (videoItem) { if (this._settings.year.minimum > 0 || this._settings.year.maximum > 0) { let yearFragments = videoItem.querySelector('.title a').textContent.trim().split('(') let year = parseInt(yearFragments[yearFragments.length - 1].replace(')', '')) return this._validator.validateRange(FILTER_RATING_VIDEOS_KEY, year, [this._settings.year.minimum, this._settings.year.maximum]) } return true } /** * @param {string} label * @param {string} inputsType * * @return {HTMLElement} * @private */ _createFormRangeInputGroup (label, inputsType = 'text') { let maxInputSelector = this._uiGen._selectorGenerator.getSettingsRangeInputSelector(label, false) let minInputSelector = this._uiGen._selectorGenerator.getSettingsRangeInputSelector(label, true) let divFormInputGroup = this._uiGen.createFormGroup([ this._uiGen.createFormGroupLabel(label, '', inputsType), this._uiGen.createFormGroupInput(minInputSelector, inputsType), this._uiGen.createFormGroupInput(maxInputSelector, inputsType), ]) divFormInputGroup.classList.add('form-range-input-group') return divFormInputGroup } } VideoCelebsSearchAndUITweaks.initialize()