Expand collapsed GitHub code blocks

Adds click event and distinct hover style to collapsed code indicator

2020-06-09 기준 버전입니다. 최신 버전을 확인하세요.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name        Expand collapsed GitHub code blocks
// @namespace   http://tampermonkey.net/
// @description Adds click event and distinct hover style to collapsed code indicator
// @match       https://github.com/*
// @version     1.3
// @grant       GM_addStyle
// ==/UserScript==

// Use with violentmonkey
// https://addons.mozilla.org/en-US/firefox/addon/violentmonkey/
// https://chrome.google.com/webstore/detail/violentmonkey/jinjaccalgkegednnccohejagnlnfdag?hl=en

(function () {
  "use strict";

  GM_addStyle(`
      .is-hovered.blob-code.blob-code-inner.blob-code-hunk {
          background-color: #ffedde !important;
      }`);

  makeCollapsedRegionsClickableAfterLoad();
})();

function makeCollapsedRegionsClickableAfterLoad() {
  let isLoading = false;

  const diffContainers = [
    ...document.querySelectorAll(".js-diff-progressive-container"),
  ];
  if (diffContainers.some((c) => showsLoadingIndicator(c))) {
    isLoading = true;
  }

  if (isLoading == true) {
    window.setTimeout(makeCollapsedRegionsClickableAfterLoad, 5);
  } else {
    makeCollapsedRegionsClickable();
  }
}

function makeCollapsedRegionsClickable() {
  const expandables = document.querySelectorAll(".js-expandable-line");

  expandables.forEach((expandable) => {
    let line = expandable.querySelector(
      ".blob-code.blob-code-inner.blob-code-hunk"
    );

    line = recreateNode(line);
    line.style.cursor = "pointer";
    line.addEventListener("click", () => expandCodeBlock(expandable));
  });
}

function expandCodeBlock(line) {
  line.querySelector(".blob-num-expandable").children[0].click();
  window.setTimeout(makeCollapsedRegionsClickableAfterLoad, 800);
}

function showsLoadingIndicator(container) {
  return container.querySelectorAll(".diff-progressive-loader").length > 0;
}

function recreateNode(el, withChildren) {
  if (withChildren) {
    const clone = el.cloneNode(true);
    el.parentNode.replaceChild(clone, el);
    return clone;
  } else {
    var newEl = el.cloneNode(false);
    while (el.hasChildNodes()) newEl.appendChild(el.firstChild);
    el.parentNode.replaceChild(newEl, el);
    return newEl;
  }
}