GitHub PR review keyboard shortcut

Mark file as "viewed" on GitHub PR UI when hovering and pressing 'Escape' key

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         GitHub PR review keyboard shortcut
// @version      0.3
// @description  Mark file as "viewed" on GitHub PR UI when hovering and pressing 'Escape' key
// @match        https://github.com/*
// @author       dvdvdmt, nbolton
// @source       https://github.com/nbolton/github-review-shortcut
// @namespace    https://github.com/nbolton/github-review-shortcut
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    if (window.disposeMarkAsViewedByEscape) {
        window.disposeMarkAsViewedByEscape();
    }

    window.disposeMarkAsViewedByEscape = start();

    function start() {
        window.addEventListener('keydown', handleKeyDown)
        return () => window.removeEventListener('keydown', handleKeyDown);
    }

    function markFileAsViewed() {
        console.debug("Marking file as viewed");

        const fileElement = document.querySelector(`div[role="region"][id^="diff-"]:hover`);
        if (!fileElement){
            console.warn("No file element under cursor");
            return;
        }

        console.debug("File element found:", fileElement);
        console.debug("Finding buttons")
        const buttons = [...fileElement.querySelectorAll('button')];
        if (buttons.length === 0) {
            console.warn("No buttons found in file element");
            return;
        }

        console.debug("Buttons found:", buttons);

        const checkboxes = buttons.filter(btn => btn.textContent.trim() === 'Viewed');
        console.debug("Checkboxes found:", checkboxes);
        if (checkboxes.length > 1) {
            // Usually happens when the wrong DOM element is selected earlier on.
            throw new Error("More than one checkbox found");
        }
        else if (checkboxes.length === 0) {
            throw new Error("No checkbox found");
        }

        const checkbox = checkboxes[0];
        console.debug("Clicking checkbox:", checkbox);
        checkbox.click();
    }

    function handleKeyDown() {
        if (event.key === 'Escape') {
            markFileAsViewed();
        }
    }

})();