Skip to content

Instantly share code, notes, and snippets.

@elazar
Last active October 20, 2021 23:44
Show Gist options
  • Select an option

  • Save elazar/c0e1c7d18aa0c23848c41ac632e5bd6e to your computer and use it in GitHub Desktop.

Select an option

Save elazar/c0e1c7d18aa0c23848c41ac632e5bd6e to your computer and use it in GitHub Desktop.

Revisions

  1. elazar revised this gist Oct 20, 2021. 1 changed file with 11 additions and 6 deletions.
    17 changes: 11 additions & 6 deletions userscript.js
    Original file line number Diff line number Diff line change
    @@ -1,8 +1,11 @@
    const getVideoList = () => $("#contents");
    const getVideoList = () => document.getElementById("contents");

    const getVideoCount = () => {
    return Number(
    $("#stats").getElementsByClassName("yt-formatted-string")[0].textContent
    document
    .getElementById("stats")
    .getElementsByClassName("yt-formatted-string")[0]
    .textContent
    );
    }

    @@ -73,9 +76,11 @@ const getChannelName = (video) => {
    return text;
    };

    (async () => {
    await scroll();
    const menu = $("tp-yt-paper-listbox#menu");
    scroll().then(() => {
    const menu = Array.from(
    document.getElementsByTagName("tp-yt-paper-listbox")
    )
    .find(el => el.id === "menu");
    menu.prepend(
    getOption("Length (shortest)", () => {
    sortVideos((a, b) => getTime(a) - getTime(b));
    @@ -96,4 +101,4 @@ const getChannelName = (video) => {
    sortVideos((a, b) => getChannelName(b) < getChannelName(a) ? -1 : 1);
    })
    );
    })();
    });
  2. elazar revised this gist Oct 10, 2021. 1 changed file with 17 additions and 2 deletions.
    19 changes: 17 additions & 2 deletions userscript.js
    Original file line number Diff line number Diff line change
    @@ -66,19 +66,34 @@ const getTime = (video) => {
    return time;
    };

    const getChannelName = (video) => {
    const name = video.getElementsByTagName("ytd-channel-name")[0];
    const a = name.getElementsByTagName("a")[0];
    const text = a.textContent.trim();
    return text;
    };

    (async () => {
    await scroll();
    const menu = $("tp-yt-paper-listbox#menu");
    menu.prepend(
    getOption("Length (shortest)", () => {
    menu.style.display = "none";
    sortVideos((a, b) => getTime(a) - getTime(b));
    })
    );
    menu.prepend(
    getOption("Length (longest)", () => {
    menu.style.display = "none";
    sortVideos((a, b) => getTime(b) - getTime(a))
    })
    );
    menu.prepend(
    getOption("Channel (A-Z)", () => {
    sortVideos((a, b) => getChannelName(a) < getChannelName(b) ? -1 : 1);
    })
    );
    menu.prepend(
    getOption("Channel (Z-A)", () => {
    sortVideos((a, b) => getChannelName(b) < getChannelName(a) ? -1 : 1);
    })
    );
    })();
  3. elazar created this gist Oct 10, 2021.
    84 changes: 84 additions & 0 deletions userscript.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,84 @@
    const getVideoList = () => $("#contents");

    const getVideoCount = () => {
    return Number(
    $("#stats").getElementsByClassName("yt-formatted-string")[0].textContent
    );
    }

    const getVideos = () => {
    const list = getVideoList();
    const videos = Array.from(
    list.getElementsByTagName("ytd-playlist-video-renderer")
    );
    return videos;
    }

    const scroll = async () => {
    const videoCount = getVideoCount();
    const videoList = getVideoList();
    do {
    window.scrollTo(0, videoList.scrollHeight);
    await new Promise(resolve => setTimeout(resolve, 500));
    } while (getVideos().length < videoCount);
    window.scrollTo(0, 0);
    };

    const getOption = (text, callback) => {
    const html = `
    <a class="yt-simple-endpoint style-scope yt-dropdown-menu" tabindex="-1" aria-selected="false">
    <tp-yt-paper-item class="style-scope yt-dropdown-menu" role="option" tabindex="0" aria-disabled="false">
    <!--css-build:shady-->
    <tp-yt-paper-item-body class="style-scope yt-dropdown-menu">
    <!--css-build:shady-->
    <div class="item style-scope yt-dropdown-menu">${text}</div>
    <div secondary="" id="subtitle" class="style-scope yt-dropdown-menu" hidden="">
    </div>
    </tp-yt-paper-item-body>
    <yt-reload-continuation class="style-scope yt-dropdown-menu">
    </yt-reload-continuation>
    </tp-yt-paper-item>
    </a>
    `;
    const document = new DOMParser().parseFromString(html, "text/html");
    const element = document.activeElement.firstChild;
    element.onclick = callback;
    return element;
    };

    const sortVideos = (callback) => {
    const list = getVideoList();
    const videos = getVideos();
    videos.forEach((video) => video.parentNode.removeChild(video));
    videos.sort(callback);
    videos.forEach((video) => list.appendChild(video));
    };

    const getTime = (video) => {
    const text = video.getElementsByTagName("span")[0].textContent.trim();
    const numbers = text.split(":").map(Number);
    numbers.reverse();
    numbers[1] *= 60;
    if (numbers[2]) {
    numbers[2] *= 3600;
    }
    const time = numbers.reduce((previous, current) => previous + current, 0);
    return time;
    };

    (async () => {
    await scroll();
    const menu = $("tp-yt-paper-listbox#menu");
    menu.prepend(
    getOption("Length (shortest)", () => {
    menu.style.display = "none";
    sortVideos((a, b) => getTime(a) - getTime(b));
    })
    );
    menu.prepend(
    getOption("Length (longest)", () => {
    menu.style.display = "none";
    sortVideos((a, b) => getTime(b) - getTime(a))
    })
    );
    })();