Nico User Ads Hider

ニコニ広告による動画への装飾を削除

Od 25.12.2015.. Pogledajte najnovija verzija.

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

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

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

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

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

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

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.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name        Nico User Ads Hider
// @namespace   http://userscripts.org/users/121129
// @description ニコニ広告による動画への装飾を削除
// @match       http://www.nicovideo.jp/*
// @match       http://search.nicovideo.jp/*
// @version     5
// @grant       none
// @run-at      document-idle
// ==/UserScript==

;(function() {
  'use strict'
  var handler = function(handleForEachMutation) {
    return function(mutations) {
      for (var m of mutations) handleForEachMutation(m)
    }
  }
  var containsAllClass = function(elem, classTokens) {
    return classTokens.every(function(t) {
      return elem.classList.contains(t)
    })
  }
  var nicovideoObj = function() {
    var isUadLevelClassAdded = function(mutation) {
      return mutation.attributeName === 'class'
          && mutation.target.className.includes('uadlevel')
    }
    var restoreIfUadLevelClassAdded = function(mutation) {
      if (isUadLevelClassAdded(mutation)) {
        mutation.target.className = mutation.oldValue
      }
    }
    var isBalloonShown = function(mutation) {
      var e = mutation.target
      return mutation.attributeName === 'style'
          && e.style.display !== 'none'
          && containsAllClass(e, ['balloon', 'recent', 'active'])
    }
    var hideIfBalloonShown = function(mutation) {
      if (isBalloonShown(mutation)) mutation.target.style.display = 'none'
    }
    var isListRankingPage = function() {
      var p = location.pathname
      return p.startsWith('/ranking/') && p !== '/ranking/'
    }
    var isVideoCommentsShown = function(elem) {
      return elem.hasAttribute('data-video-comments')
          && elem.style.display !== 'none'
    }
    var hideIfVideoCommentsShown = function(mutation) {
      var e = mutation.target
      if (isVideoCommentsShown(e)) e.style.display = 'none'
    }
    var fs = [restoreIfUadLevelClassAdded, hideIfBalloonShown]
    if (isListRankingPage()) fs.push(hideIfVideoCommentsShown)
    return {
      handler: handler(function(mutation) {
        for (var f of fs) f(mutation)
      }),
      options: {
        attributes: true,
        subtree: true,
        attributeOldValue: true,
        attributeFilter: ['class', 'style'],
      },
    }
  }
  var searchObj = function() {
    var isClassMutated = function(mutation) {
      return mutation.type === 'attributes'
          && mutation.attributeName === 'class'
    }
    var removeClassIfContains = function(classToken) {
      return function(elem) {
        var l = elem.classList
        if (l.contains(classToken)) l.remove(classToken)
      }
    }
    var removeGoldAdIfContains = removeClassIfContains('gold-ad')
    var removeSilverAdIfContains = removeClassIfContains('silver-ad')
    var isTooltipShown = function(mutation) {
      return mutation.type === 'childList'
          && mutation.addedNodes.length === 1
          && Boolean(mutation.addedNodes[0].classList)
          && containsAllClass(mutation.addedNodes[0]
                            , ['tooltip', 'fade', 'top', 'in'])
    }
    var hideTooltip = function(mutation) {
      mutation.addedNodes[0].style.display = 'none'
    }
    return {
      handler: handler(function(mutation) {
        if (isClassMutated(mutation)) {
          removeGoldAdIfContains(mutation.target)
          removeSilverAdIfContains(mutation.target)
        } else if (isTooltipShown(mutation)) {
          hideTooltip(mutation)
        }
      }),
      options: {
        attributes: true,
        childList: true,
        subtree: true,
        attributeFilter: ['class'],
      },
    }
  }
  var diffBy = function(location) {
    switch (location.hostname) {
      case 'www.nicovideo.jp': return nicovideoObj()
      case 'search.nicovideo.jp': return searchObj()
      default: throw new Error(location.hostname)
    }
  }
  var observe = function(obj) {
    new MutationObserver(obj.handler).observe(document.body, obj.options)
  }
  observe(diffBy(location))
})()