Twitch Clip Link Replacer

Replaces all present Twitch clip links with the better clip link (clips.twitch.tv)

이 스크립트를 설치하려면 Tampermonkey, Greasemonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램을 설치해야 합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Userscripts와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 유저 스크립트 관리자 확장 프로그램이 필요합니다.

(이미 유저 스크립트 관리자가 설치되어 있습니다. 설치를 진행합니다!)

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

(이미 유저 스타일 관리자가 설치되어 있습니다. 설치를 진행합니다!)

// ==UserScript==
// @name            Twitch Clip Link Replacer
// @namespace   twitch.tv
// @include   *://*.twitch.tv/*/clip
// @include		http://clips.twitch.tv/*
// @include		https://clips.twitch.tv/*
// @include		https://*.twitch.tv/*
// @version     1.0.1
// @author       ftn
// @description Replaces all present Twitch clip links with the better clip link (clips.twitch.tv)
// @license GPLv3
// ==/UserScript==
const CLIP_REGEX = /^https?:\/\/(?:www\.)?twitch\.tv\/[^\/]+\/clip\/([^\/?#]+)/i;

function createUrl(url) {
    const m = url.match(CLIP_REGEX);
  // the first returned index is unneeded so the second should be the one to grab
    return m ? `https://clips.twitch.tv/${m[1]}` : null;
}

function replace(nodeList) {
    nodeList.forEach(a => {
        const better = createUrl(a.href);
        if (better) a.href = better;
    });
}

function processDocument() {
    replace(document.querySelectorAll('a[href]'));

    const observer = new MutationObserver(mutations => {
        for (const mut of mutations) {
            mut.addedNodes.forEach(node => {
                if (node.nodeType !== Node.ELEMENT_NODE) return;
                if (node.matches && node.matches('a[href]')) {
                    replace([node]);
                }
                const innerLinks = node.querySelectorAll? node.querySelectorAll('a[href]'): [];
                if (innerLinks.length) replace(innerLinks);
            });
        }
    });
  // this stuff is for sites that navigate pages directly
    observer.observe(document.body, {
        childList: true,
        subtree: true,
    });
}

if (self.navigation) {
  navigation.addEventListener('navigatesuccess', processDocument);
} else {
  let u = location.href;
  new MutationObserver(() => u !== (u = location.href) && processDocument())
    .observe(document, {subtree: true, childList: true});
}
if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', processDocument);
} else {
    processDocument();
}