URLActions

URL-based actions (eg. redirects)

当前为 2020-06-19 提交的版本,查看 最新版本

/* jshint esversion: 6 */
// ==UserScript==
// @name         URLActions
// @description  URL-based actions (eg. redirects)
// @version      1
// @include      www.youtube.com
// @grant        none
// @namespace https://greasyfork.org/users/608407
// ==/UserScript==

/**
 * Upon each 'yt-navigate-finish' event encountered on www.youtube.com
 * (which could any of:
 *  - a direct load via link -- new page opened in browser
 *  - clicking on a video in search results -- same page* (YT is de-facto single-page)
 *  - video changed by autoplay -- same page* (YT is de-facto single-page)
 * ),
 * do the following:
 * - look if the current video ID is on the blacklist (`skipVideoIDs`):
 *   -> if not, don't do anything -- everything's ok
 *   -> if yes, look if there is a "Next Video" button:
 *      -> if not, don't do anything -- we're not on a video (this _could_ happen, snice
 *         when checking if video is on the blacklist, we only check the query param `v`, nothing else)
 *      -> if yes:
 *         - register a mutation observer on the Next Video button (`a` element), because the button
 *           doesn't contain the `href` URL immediately after the 'yt-navigate-finish' event:
 *           -> in this observer, upon mutation of the Next Video button, check if the `href` URL is present
 *              -> if not, it means the URL is not loaded yet; the observer returns and will be invoked again
 *              -> if yes:
 *                 - disconnect the observer so it won't get invoked again
 *                   (empiric observation: the button is mutated multiple times, always with the same URL)
 *                 - check whether the Next Video URL is not the same as the current URL:
 *                   -> if yes, the observer is probably being invoked for the second time, having
 *                      aleady redirected on the first invocation (this shouldn't happen since the observer
 *                      disconnects itself upon finding URL; but there _may_ be a race condition)
 *                   -> if not, it means we are on a blacklisted video and we have a valid next video, so let's
 *                      get the FUCK OUT OF THIS ANNOYING BULLSHIT VIDEO THAT STUPID RETARDED YT KEEPS RECOMMENDING
 *
 *  (*) Staying on the same browser page means that this GreaseMonkey script will be invoked only *once*,
 *      when the page is opened in the browser. All subsequent navigation within the same page
 *     (clicking on search results / suggested videos, autoplay, etc.) will *not* invoke this script again.
 */


const skipVideoIDs = ['l0U7SxXHkPY'];

function shouldSkip() {
  const currURL = new URL(document.location);
  const currVideoID = currURL.searchParams.get('v');
  return skipVideoIDs.includes(currVideoID);
}


function installNextButtonObserver() {

  if (!shouldSkip()) {
    return;
  }

  const nextButtonA = document.getElementsByClassName('ytp-next-button')[0];
  if (!nextButtonA) {
    console.log('Next Video button not found');
    return;
  }

  const observer = new MutationObserver((mutations) => {
    // nextButtonA === mutations[0].target

    const nextVideoHref = nextButtonA.href;
    if (!nextVideoHref) {
      console.log('Next Video URL not present');
      return;
    }
    console.log('Next Video URL found, disconnecting observer');
    observer.disconnect();

    if (nextVideoHref !== document.location.href) {
      document.location.replace(nextVideoHref);
    }
  });

  observer.observe(nextButtonA, {
    attributeFilter: ['href'],
    attributeOldValue: false,
    subtree: false,
  });
}

//window.addEventListener('yt-page-data-updated', installNextButtonObserver);
window.addEventListener('yt-navigate-finish', installNextButtonObserver);