Greasy Fork

Brazenvoid's Base Resource

Base library for my scripts

目前为 2018-12-16 提交的版本。查看 最新版本

此脚本不应直接安装,它是一个供其他脚本使用的外部库。如果您需要使用该库,请在脚本元属性加入:// @require https://update.greasyfork.icu/scripts/375557/654020/Brazenvoid%27s%20Base%20Resource.js

// ==UserScript==
// @name          Brazenvoid's Base Resource
// @namespace     brazenvoid
// @version       1.1.1
// @author        brazenvoid
// @license       GPL-3.0-only
// @description   Base library for my scripts
// @run-at	      document-end
// ==/UserScript==

const sleep = (milliseconds) => {
  return new Promise(resolve => setTimeout(resolve, milliseconds))
}

class CaseConverters {

  toCamel (text) {
    return text.replace(/(?:^\w|[A-Z]|\b\w)/g, function (letter, index) {
      return index === 0 ? letter.toLowerCase() : letter.toUpperCase()
    }).replace(/\s+/g, '')
  }

  toKebab (text) {
    return text.toLowerCase().replace(' ', '-')
  }

  toKebabFromSnake (text) {
    return text.replace('_', '-')
  }

  toNormalFromKebab (text) {
    return text.replace('-', ' ')
  }

  toNormalFromSnake (text) {
    return text.replace('_', ' ')
  }

  toSnake (text) {
    return text.toLowerCase().replace(' ', '_')
  }
}

class ChildObserver {

  constructor (handler) {
    this.config = {
      attributes: false,
      childList: true,
      subtree: false
    }
    this.handler = handler
    this.observer = new MutationObserver(function (mutations) {
      for (let mutation of mutations) {
        this.handler(mutation.target)
      }
    })
  }

  observe (node, doInitialRun = false) {

    if (doInitialRun) {
      this.handler(node)
    }
    this.observer.observe(node, this.config)
    return this
  }
}

class Filters {

  constructor (logger, statisticsRecorder) {
    this.blacklist = []
    this.logger = logger
    this.sanitizationRules = []
    this.statisticsRecorder = statisticsRecorder
  }

  init () {

    for (let i = 0; i < this.blacklist.length; i++) {
      this.blacklist[i] = new RegExp(this.blacklist[i], 'ig')
    }

    for (const substitute in this.sanitizationRules) {
      for (let i = 0; i < this.sanitizationRules[substitute].length; i++) {
        this.sanitizationRules[substitute][i] = new RegExp(this.sanitizationRules[substitute][i], 'ig')
      }
    }
  }

  iFramesRemover () {

    GM_addStyle(`
      iframe {
          display: none !important;
      }
   `)
  }

  sanitize (text) {

    for (const substitute in this.sanitizationRules) {
      for (const subject of this.sanitizationRules[substitute]) {
        text = text.replace(subject, substitute)
      }
    }
    return text
  }

  validateBlackList (text) {

    let validationCheck = true

    if (this.blacklist.length > 0) {

      for (const blacklistedWord of this.blacklist) {

        validationCheck = text.match(blacklistedWord) === null
        if (!validationCheck) {
          break
        }
      }
      this.statisticsRecorder.record('Blacklist', validationCheck)
    }
    return validationCheck
  }

  validateRange (type, value, bounds) {

    let validationCheck = true

    if (bounds[0] > 0) {
      validationCheck = value >= bounds[0]
    }
    if (bounds[1] > 0) {
      validationCheck = value <= bounds[1]
    }
    this.statisticsRecorder.record(type, validationCheck)

    return validationCheck
  }
}

class Logger {

  constructor (enableDebugging) {
    this.enableDebugging = enableDebugging
  }

  _log (message) {
    if (this.enableDebugging) {
      console.log(message)
    }
  }

  logTaskCompletion (task) {
    this._log('Completed: ' + task)
    this.logSeparator()
  }

  logSeparator () {
    this._log('------------------------------------------------------------------------------------')
  }

  logValidation (filterName, validationResult = null) {
    this._log('Satisfies ' + filterName + ' Filter: ' + (validationResult ? 'true' : 'false'))
  }

  logVideoCheck (videoName) {
    this._log('Checking Video: ' + videoName)
  }
}

class SelectorGenerator {

  constructor (selectorPrefix) {
    this.prefix = selectorPrefix
  }

  getSelector (selector) {
    return this.prefix + selector
  };

  getSelectorFromName (name) {
    return CaseConverters.prototype.toKebab(name)
  }

  getSettingsInputSelector (settingName) {
    return this.getSelector(this.getSelectorFromName(settingName) + '-setting')
  }

  getStatLabelSelector (statisticType) {
    return this.getSelector(this.getSelectorFromName(statisticType) + '-stat')
  };
}

class StatisticsRecorder {

  constructor (logger, selectorGenerator) {
    this.logger = logger
    this.selectorGenerator = selectorGenerator
    this.statistics = {Total: 0}
  }

  record (statisticType, validationResult, value = 1, log = true) {

    if (!validationResult) {
      if (typeof this.statistics[statisticType] !== 'undefined') {
        this.statistics[statisticType] += value
      } else {
        this.statistics[statisticType] = value
      }
      this.statistics.Total += value
    }
    if (log) {
      this.logger.logValidation(statisticType, validationResult)
    }
  }

  reset () {
    for (const statisticType in this.statistics) {
      this.statistics[statisticType] = 0
    }
  }

  updateUI () {

    let label, labelSelector

    for (const statisticType in this.statistics) {
      labelSelector = this.selectorGenerator.getStatLabelSelector(statisticType)
      label = document.getElementById(labelSelector)
      if (label !== null) {
        label.textContent = this.statistics[statisticType]
      }
    }
  }
}

class UIGenerator {

  constructor (showUI, selectorGenerator) {
    this.selectorGenerator = selectorGenerator
    this.showUI = showUI
  }

  appendToBody (node) {

    let bodyTag = document.getElementsByTagName('body')[0]
    bodyTag.appendChild(node)
  }

  createFormButton (caption, onClick) {

    let button = document.createElement('button')
    button.textContent = caption
    button.style.height = '30px'
    button.style.width = '100%'
    button.addEventListener('click', onClick)

    return button
  }

  createFormGroup () {

    let divFormGroup = document.createElement('div')
    divFormGroup.style.display = 'block'
    divFormGroup.style.height = '18px'
    divFormGroup.style.marginBottom = '2px'
    divFormGroup.style.padding = '5px 0'

    return divFormGroup
  }

  createFormGroupLabel (label, inputID = null) {

    let labelFormGroup = document.createElement('label')
    labelFormGroup.style.float = 'left'
    labelFormGroup.style.padding = '2px 0'
    labelFormGroup.textContent = label + ': '

    if (inputID !== null) {
      labelFormGroup.setAttribute('for', inputID)
    }
    return labelFormGroup
  }

  createFormGroupStatLabel (statisticType) {

    let labelFormGroup = document.createElement('label')
    labelFormGroup.id = this.selectorGenerator.getStatLabelSelector(statisticType)
    labelFormGroup.style.float = 'right'
    labelFormGroup.style.padding = '2px 0'
    labelFormGroup.textContent = '0'

    return labelFormGroup
  }

  createFormGroupInput (id, defaultValue) {

    let inputFormGroup = document.createElement('input')
    inputFormGroup.id = id
    inputFormGroup.style.float = 'right'
    inputFormGroup.style.width = '100px'
    inputFormGroup.style.textAlign = 'center'
    inputFormGroup.value = defaultValue

    return inputFormGroup
  }

  createSection (id, backgroundColor, children) {

    let section = document.createElement('section')
    section.id = this.selectorGenerator.getSelector(id)
    section.style.color = 'black'
    section.style.display = this.showUI ? 'block' : 'none'
    section.style.fontWeight = 'bold'
    section.style.position = 'fixed'
    section.style.top = '250px'
    section.style.left = '0'
    section.style.width = '200px'
    section.style.padding = '5px 10px'
    section.style.backgroundColor = backgroundColor
    section.style.zIndex = '1000'

    for (let child of children) {
      section.appendChild(child)
    }
    return section
  }

  createSeparator () {

    let separator = document.createElement('hr')
    separator.style.margin = '5px 5px 0 5px'

    return separator
  }

  createSettingsFormGroup (label, defaultValue) {

    let divFormGroup = this.createFormGroup()
    let inputID = this.selectorGenerator.getSettingsInputSelector(label)
    let labelFormGroup = this.createFormGroupLabel(label, inputID)
    let inputFormGroup = this.createFormGroupInput(inputID, defaultValue)

    divFormGroup.appendChild(labelFormGroup)
    divFormGroup.appendChild(inputFormGroup)

    return divFormGroup
  }

  createStatisticsFormGroup (statisticsType, label) {

    let divFormGroup = this.createFormGroup()
    let labelFormGroup = this.createFormGroupLabel('Filtered ' + label + ' Videos')
    let statLabelFormGroup = this.createFormGroupStatLabel(statisticsType)

    divFormGroup.appendChild(labelFormGroup)
    divFormGroup.appendChild(statLabelFormGroup)

    return divFormGroup
  }
}