XNXX - Search Filters

Various search filters

Stan na 16-12-2018. Zobacz najnowsza wersja.

Aby zainstalować ten skrypt, wymagana jest instalacje jednego z następujących rozszerzeń: Tampermonkey, Greasemonkey lub Violentmonkey.

Aby zainstalować ten skrypt, wymagana jest instalacje jednego z następujących rozszerzeń: Tampermonkey, Violentmonkey.

Aby zainstalować ten skrypt, wymagana jest instalacje jednego z następujących rozszerzeń: Tampermonkey, Violentmonkey.

Aby zainstalować ten skrypt, wymagana będzie instalacja rozszerzenia Tampermonkey lub Userscripts.

You will need to install an extension such as Tampermonkey to install this script.

Aby zainstalować ten skrypt, musisz zainstalować rozszerzenie menedżera skryptów użytkownika.

(Mam już menedżera skryptów użytkownika, pozwól mi to zainstalować!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

Będziesz musiał zainstalować rozszerzenie menedżera stylów użytkownika, aby zainstalować ten styl.

Będziesz musiał zainstalować rozszerzenie menedżera stylów użytkownika, aby zainstalować ten styl.

Musisz zainstalować rozszerzenie menedżera stylów użytkownika, aby zainstalować ten styl.

(Mam już menedżera stylów użytkownika, pozwól mi to zainstalować!)

// ==UserScript==
// @name          XNXX - Search Filters
// @namespace     brazenvoid
// @version       2.0.0
// @author        brazenvoid
// @license       GPL-3.0-only
// @description   Various search filters
// @include       https://www.xnxx.com/*
// @require       https://greasyfork.org/scripts/375557-brazenvoid-s-base-resource/code/Brazenvoid's%20Base%20Resource.js?version=654020
// @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: [120, 0], // In Seconds
  resolution: '720p', // SD / 480p / 720p / 1080p
  views: [0, 0],
  showUIAlways: false, // Desktop/Tablet
  debugLogging: false
}

// Base Resources Initialization

let logger = new Logger(settings.debugLogging)
let selectorGenerator = new SelectorGenerator('xnxx-sui-')
let statistics = new StatisticsRecorder(logger, selectorGenerator)
let uiGenerator = new UIGenerator(settings.showUIAlways, selectorGenerator)

let filters = new Filters(logger, statistics)
filters.blacklist = settings.blacklist
filters.sanitizationRules = settings.sanitize
filters.init()

// Filters
// -- Duration validation

let validateDuration = function (duration) {

  if (settings.duration[0] > 0 || settings.duration[1] > 0) {

    duration = duration.split(' ')

    if (duration[1] === 'min') {
      duration[0] *= 60
    }
    return filters.validateRange('Duration', duration[0], settings.duration)
  }
  return true
}

// -- Resolution validation

let validateResolution = function (resolution) {

  let validationCheck = true

  if (settings.resolution !== 'SD') {

    switch (settings.resolution) {

      case '480p':
        validationCheck = resolution !== 'SD'
        break

      case '720p':
        validationCheck = resolution !== 'SD' && resolution !== '480p'
        break

      case '1080p':
        validationCheck = resolution !== 'SD' && resolution !== '480p' && resolution !== '720p'
        break
    }
    statistics.record('Resolution', validationCheck)
  }
  return validationCheck
}

// -- Video name sanitation

let sanitizeVideoPage = function () {

  let videoTitle = document.querySelector('.inlineFree')
  if (videoTitle !== null) {

    let sanitizedVideoName = filters.sanitize(videoTitle.textContent)
    videoTitle.textContent = sanitizedVideoName
    document.title = sanitizedVideoName
  }

}
let sanitizeVideoItem = function (videoItem, videoName) {

  videoItem.querySelector('.thumb-under > p:nth-child(1) > a:nth-child(1)').textContent = filters.sanitize(videoName)
}

// -- View count validation

let validateViews = function (views) {

  let validationCheck = true;

  if (settings.views[0] > 0 || settings.views[1] > 0) {
    validationCheck = filters.validateRange('Views', views, settings.views)
  }
  return validationCheck
}

// -- Compliance logic

let complianceCallback = function (target) {

  let videoItems = target.querySelectorAll('.thumb-block')
  let videoDuration, videoComplies, videoMetadata, videoName, videoResolution, videoViews

  for (let videoItem of videoItems) {

    videoMetadata = videoItem.querySelector('.metadata').textContent.split('-')
    videoDuration = videoMetadata[0].trim()

    if (typeof videoMetadata[1] === 'undefined') {
      videoResolution = 'SD'
      videoViews = 0
    } else if (videoMetadata[1].includes('hits')) {
      videoResolution = typeof videoMetadata[2] === 'undefined' ? 'SD' : videoMetadata[2].trim()
      videoViews = videoMetadata[1].trim().replace(' hits', '').replace(',', '')
    } else {
      videoResolution = videoMetadata[1].trim()
    }

    videoName = videoItem.querySelector('.thumb-under > p:nth-child(1) > a:nth-child(1)').textContent
    logger.logVideoCheck(videoName)

    videoComplies =
      validateResolution(videoResolution) &&
      filters.validateBlackList(videoName) &&
      validateDuration(videoDuration) &&
      validateViews(videoViews)

    if (videoComplies) {
      videoItem.style.display = 'inline-block'
      sanitizeVideoItem(videoItem, videoName)
    } else {
      videoItem.style.display = 'none'
    }
    logger.logSeparator()
  }
  statistics.updateUI()
}

// UI Composition
// -- Control Panel

let section = uiGenerator.createSection('settings', '#ffa31a', [
  uiGenerator.createSettingsFormGroup('Min Duration', settings.duration[0].toString()),
  uiGenerator.createSettingsFormGroup('MIn Resolution', settings.resolution.toString()),
  uiGenerator.createSettingsFormGroup('Min Views', settings.views[0].toString()),
  uiGenerator.createFormButton('Apply', function () {

    settings.duration[0] = document.getElementById(selectorGenerator.getSettingsInputSelector('Min Duration')).value
    settings.resolution = document.getElementById(selectorGenerator.getSettingsInputSelector('Min Resolution')).value
    settings.views[0] = document.getElementById(selectorGenerator.getSettingsInputSelector('Min Views')).value

    statistics.reset()
    complianceCallback(document.querySelector('.mozaique'))
  }),
  uiGenerator.createSeparator(),
  uiGenerator.createStatisticsFormGroup('Duration', 'Short'),
  uiGenerator.createStatisticsFormGroup('Resolution', 'Low Resolution'),
  uiGenerator.createStatisticsFormGroup('Views', 'By Views'),
  uiGenerator.createStatisticsFormGroup('Blacklist', 'Blacklisted'),
  uiGenerator.createStatisticsFormGroup('Total', ''),
  uiGenerator.createFormButton('Hide', function () {
    document.getElementById(selectorGenerator.getSelector('settings')).style.display = 'none'
  })
])
section.style.width = '220px'
uiGenerator.appendToBody(section)

let labels = section.getElementsByTagName('label');
for (let label of labels) {
  label.style.margin = '0';
}

// -- Settings Button
// -- -- Composition

let controlButton = document.createElement('button')
controlButton.textContent = 'Show Settings UI'
controlButton.style.margin = '2px 5px'
controlButton.style.padding = '2px 5px'
controlButton.style.backgroundColor = '#ffa31a'
controlButton.style.border = '0'

controlButton.addEventListener('click', function () {

  let settingsUI = document.getElementById(selectorGenerator.getSelector('settings'))
  settingsUI.style.display = settingsUI.style.display === 'none' ? 'block' : 'none'
})

// -- -- Placement

let controlListItem = document.createElement('div')
controlListItem.appendChild(controlButton)

let filtersBar = document.querySelector('#listing-page-filters-block')
filtersBar.appendChild(controlButton)

logger.logTaskCompletion('Building UI')

// Script run
// -- Initial compliance run & observer attachment

let videoItemsObserver = new ChildObserver(complianceCallback)
videoItemsObserver.observe(document.querySelector('.mozaique'), true)

sanitizeVideoPage()

logger.logTaskCompletion('Initial run and observer attachment.')