From 37f46044bff974eff08978e306a388f6dc3cbfa4 Mon Sep 17 00:00:00 2001 From: vinhyan Date: Mon, 9 Dec 2024 23:27:36 -0500 Subject: [PATCH 1/3] fix: commits button not showing consistently --- js/addCommitsButton.js | 123 ++++++++++++++++++++++----------------- js/loadBranchesButton.js | 57 +++++++++--------- js/main.js | 36 +++++++++++- js/openCommitsTab.js | 118 ++++++++++++++++++------------------- js/showCommits.js | 5 +- js/showCommitsLoading.js | 9 ++- 6 files changed, 200 insertions(+), 148 deletions(-) diff --git a/js/addCommitsButton.js b/js/addCommitsButton.js index 7261b57..256e96e 100644 --- a/js/addCommitsButton.js +++ b/js/addCommitsButton.js @@ -1,59 +1,72 @@ var isCommitsTabOpen = false; function addCommitsButton() { - // parentObject is the bar which contains all the - // tab buttons, (code, issues, pull requests,..) - var parentObject = document.querySelector('[data-pjax="#js-repo-pjax-container"]').children[0]; - - // Copies the "Issues" tab button, and edit it to commits - // so that the UI matches even if GitHub choose to change UI - var newButton = parentObject.children[1].cloneNode(true); - var newButtonChild = newButton.children[0]; - newButtonChild.id = "commits-tab"; - newButtonChild.setAttribute("aria-disabled", "true"); - newButtonChild.setAttribute("data-tab-item", "commits-tab"); + // parentObject is the bar which contains all the + // tab buttons, (code, issues, pull requests,..) + var parentObject = document.querySelector('[data-pjax="#js-repo-pjax-container"]').children[0]; + + // Clean up the old Commits button if exists + const oldCommitsButton = document.getElementById("commits-tab"); + if (oldCommitsButton) { + oldCommitsButton.removeEventListener("click", openCommitsTab); + oldCommitsButton.removeAttribute("aria-current"); + oldCommitsButton.removeAttribute("data-selected-links"); + oldCommitsButton.remove(); + // remove old Commits button's
  • from the parent Nav + const oldCommitsLiElement = parentObject.children[1]; + const removedLi = parentObject.removeChild(oldCommitsLiElement); + } + + // Copies the "Issues" tab button, and edit it to commits + // so that the UI matches even if GitHub choose to change UI + var newButton = parentObject.children[1].cloneNode(true); + var newButtonChild = newButton.children[0]; + newButtonChild.id = "commits-tab"; + newButtonChild.setAttribute("aria-disabled", "true"); + newButtonChild.setAttribute("data-tab-item", "commits-tab"); + newButtonChild.removeAttribute("aria-current"); + newButtonChild.classList.remove("selected"); + newButtonChild.setAttribute("data-selected-links", "repo_commits repo_milestones /NirmalScaria/le-git-graph/commits") + + // Remove the href. We wont navigate anywhere. + newButtonChild.removeAttribute("href"); + newButtonChild.addEventListener("click", openCommitsTab); + + Array.from(parentObject.children).forEach((child) => { + thisChild = child.children[0]; + thisChild.addEventListener("click", closeCommitsTab); + }); + + // Set the commits button SVG + newButtonChild.children[0].setAttribute("class", "octicon octicon-issue-opened UnderlineNav-octicon d-none d-sm-inline"); + // newButtonChild.children[0].removeChild(newButtonChild.children[0].children[0]); + newButtonChild.children[0].children[0].setAttribute("d", "M10.5 7.75a2.5 2.5 0 11-5 0 2.5 2.5 0 015 0zm1.43.75a4.002 4.002 0 01-7.86 0H.75a.75.75 0 110-1.5h3.32a4.001 4.001 0 017.86 0h3.32a.75.75 0 110 1.5h-3.32z"); + newButtonChild.children[0].children[0].setAttribute("fill-rule", "evenodd"); + // remove the second child + try { + newButtonChild.children[0].removeChild(newButtonChild.children[0].children[1]); + } catch { + // The repo has no issues tab + } + // Set the label to "Commits" + newButtonChild.children[1].setAttribute("data-content", "Commits"); + newButtonChild.children[1].innerText = "Commits"; + + // Remove the count indicator if exists. + if (newButtonChild.children[2]) { + newButtonChild.removeChild(newButtonChild.children[2]); + } + + // Add the commits button to the UI + parentObject.insertBefore(newButton, parentObject.children[1]); + + function closeCommitsTab() { + // Deselect the commits tab. + // Navigation would be handled automatically by the original GitHub code. + isCommitsTabOpen = false; + var commitsTabButton = document.getElementById("commits-tab"); + commitsTabButton.removeEventListener("click", openCommitsTab); + commitsTabButton.addEventListener("click", openCommitsTab); newButtonChild.removeAttribute("aria-current"); - newButtonChild.classList.remove("selected"); - newButtonChild.setAttribute("data-selected-links", "repo_commits repo_milestones /NirmalScaria/le-git-graph/commits") - - // Remove the href. We wont navigate anywhere. - newButtonChild.removeAttribute("href"); - newButtonChild.addEventListener("click", openCommitsTab); - - Array.from(parentObject.children).forEach((child) => { - thisChild = child.children[0]; - thisChild.addEventListener("click", closeCommitsTab); - }); - - // Set the commits button SVG - newButtonChild.children[0].setAttribute("class", "octicon octicon-issue-opened UnderlineNav-octicon d-none d-sm-inline"); - // newButtonChild.children[0].removeChild(newButtonChild.children[0].children[0]); - newButtonChild.children[0].children[0].setAttribute("d", "M10.5 7.75a2.5 2.5 0 11-5 0 2.5 2.5 0 015 0zm1.43.75a4.002 4.002 0 01-7.86 0H.75a.75.75 0 110-1.5h3.32a4.001 4.001 0 017.86 0h3.32a.75.75 0 110 1.5h-3.32z"); - newButtonChild.children[0].children[0].setAttribute("fill-rule", "evenodd"); - // remove the second child - try { - newButtonChild.children[0].removeChild(newButtonChild.children[0].children[1]); - } catch { - // The repo has no issues tab - } - // Set the label to "Commits" - newButtonChild.children[1].setAttribute("data-content", "Commits"); - newButtonChild.children[1].innerText = "Commits"; - - // Remove the count indicator if exists. - if (newButtonChild.children[2]) { - newButtonChild.removeChild(newButtonChild.children[2]); - } - - // Add the commits button to the UI - parentObject.insertBefore(newButton, parentObject.children[1]); - - function closeCommitsTab() { - // Deselect the commits tab. - // Navigation would be handled automatically by the original GitHub code. - isCommitsTabOpen = false; - var commitsTabButton = document.getElementById("commits-tab"); - commitsTabButton.addEventListener("click", openCommitsTab); - newButtonChild.removeAttribute("aria-current"); - newButtonChild.removeAttribute("data-selected-links"); - } + newButtonChild.removeAttribute("data-selected-links"); + } } \ No newline at end of file diff --git a/js/loadBranchesButton.js b/js/loadBranchesButton.js index 0a30763..1e99ec8 100644 --- a/js/loadBranchesButton.js +++ b/js/loadBranchesButton.js @@ -1,31 +1,34 @@ async function loadBranchesButton() { - var contentView = document.getElementsByClassName("clearfix")[0]; - var branchSelectionHtml = chrome.runtime.getURL('html/branchSelection.html'); - await fetch(branchSelectionHtml).then(response => response.text()).then(branchSelectionHtmlText => { - var tempDiv = document.createElement('div'); - tempDiv.innerHTML = branchSelectionHtmlText; - var newContent = tempDiv.firstChild; - contentView.innerHTML = ""; - contentView.appendChild(newContent); - var token = getLocalToken(); - var userName = getLocalUserName(); - var url = "https://us-central1-github-tree-graph.cloudfunctions.net/prompt?userName=" + userName; - var xhr = new XMLHttpRequest(); - xhr.open("GET", url, true); - xhr.onreadystatechange = function () { - if (xhr.readyState == 4) { - var resp = JSON.parse(xhr.responseText); - var showPrompt = resp.showPrompt; - console.log("showPrompt: " + showPrompt); - if (showPrompt) { - document.getElementById("promptImage").style.display = "inline-block"; - document.getElementById("promptImage").addEventListener("click", function () { - window.open("https://scaria.dev/redirection.html", "_blank"); - }); - } - } + var contentView = + document.getElementsByClassName("clearfix")[0] || + document.getElementsByClassName("PageLayout")[0] || + document.getElementsByClassName("repository-content")[0]; + var branchSelectionHtml = chrome.runtime.getURL('html/branchSelection.html'); + await fetch(branchSelectionHtml).then(response => response.text()).then(branchSelectionHtmlText => { + var tempDiv = document.createElement('div'); + tempDiv.innerHTML = branchSelectionHtmlText; + var newContent = tempDiv.firstChild; + contentView.innerHTML = ""; + contentView.appendChild(newContent); + var token = getLocalToken(); + var userName = getLocalUserName(); + var url = "https://us-central1-github-tree-graph.cloudfunctions.net/prompt?userName=" + userName; + var xhr = new XMLHttpRequest(); + xhr.open("GET", url, true); + xhr.onreadystatechange = function () { + if (xhr.readyState == 4) { + var resp = JSON.parse(xhr.responseText); + var showPrompt = resp.showPrompt; + console.log("showPrompt: " + showPrompt); + if (showPrompt) { + document.getElementById("promptImage").style.display = "inline-block"; + document.getElementById("promptImage").addEventListener("click", function () { + window.open("https://scaria.dev/redirection.html", "_blank"); + }); + } } - xhr.send(); + } + xhr.send(); }); - return; + return; } \ No newline at end of file diff --git a/js/main.js b/js/main.js index bd75515..d2c4498 100644 --- a/js/main.js +++ b/js/main.js @@ -11,6 +11,36 @@ var windowUrlLink = window.location.href; var windowUrl = new URL(windowUrlLink); var windowPath = windowUrl.pathname; var windowPathArray = windowPath.split("/"); -if (pathsToExclude.includes(windowPathArray[1]) == false) { - addCommitsButton(); -} \ No newline at end of file +const mo = new MutationObserver(onMutation); +observer(); + +let prevURL = window.location.href; + +function onMutation() { + const currentURL = window.location.href; + function addCommitsButtonToUI() { + if (isCommitsTabOpen) return; + if ( + pathsToExclude.includes(windowPathArray[1]) == false && + windowPathArray[2] + ) { + mo.disconnect(); + addCommitsButton(); + observer(); + } + } + + addCommitsButtonToUI(); + + if (currentURL !== prevURL) { + prevURL = currentURL; + addCommitsButtonToUI(); + } +} + +function observer() { + mo.observe(document, { + childList: true, + subtree: true, + }); +} diff --git a/js/openCommitsTab.js b/js/openCommitsTab.js index 506af17..ef19eed 100644 --- a/js/openCommitsTab.js +++ b/js/openCommitsTab.js @@ -1,76 +1,76 @@ async function openCommitsTab() { - isCommitsTabOpen = true; - // Get the commits tab button - var commitsTabButton = document.getElementById("commits-tab"); - commitsTabButton.removeEventListener("click", openCommitsTab); + isCommitsTabOpen = true; + // Get the commits tab button + var commitsTabButton = document.getElementById("commits-tab"); + commitsTabButton.removeEventListener("click", openCommitsTab); - showCommitsLoading(); + showCommitsLoading(); + + var parentObject = document.querySelector('[data-pjax="#js-repo-pjax-container"]').children[0]; - var parentObject = document.querySelector('[data-pjax="#js-repo-pjax-container"]').children[0]; + // Contains all the branch objects + var branches = []; - // Contains all the branch objects - var branches = []; + // Keeps the SHAs of only those branches which are + // selected by the user + var selectedBranchNames = []; - // Keeps the SHAs of only those branches which are - // selected by the user - var selectedBranchNames = []; + // Copies the "Issues" tab button, and edit it to commits + // so that the UI matches even if GitHub choose to change UI + var newButton = parentObject.children[1]; + var newButtonChild = newButton.children[0]; - // Copies the "Issues" tab button, and edit it to commits - // so that the UI matches even if GitHub choose to change UI - var newButton = parentObject.children[1]; - var newButtonChild = newButton.children[0]; - - // Select the commits tab. - function setCommitsButtonAsActive() { - if (isCommitsTabOpen == false) { - return; - } - newButtonChild.setAttribute("aria-current", "page"); - - // Deselect all the tabs except commits tab. - Array.from(parentObject.children).forEach((child) => { - if (child.children[0].id != "commits-tab") { - child.children[0].removeAttribute("aria-current"); - child.children[0].classList.remove("selected"); - } - }); + // Select the commits tab. + function setCommitsButtonAsActive() { + if (isCommitsTabOpen == false) { + return; } - setCommitsButtonAsActive(); - var i = 0; - var interval = setInterval(() => { - setCommitsButtonAsActive(); - i++; - if (i == 10) { - clearInterval(interval); - } - }, 1000); + newButtonChild.setAttribute("aria-current", "page"); - // Try to fetch stored authorization token - var authorizationToken = getLocalToken(); - var storedUserName = getLocalUserName(); - if (authorizationToken == null || storedUserName == null) { - // Prompt the user to authorize with GitHub - await addAuthorizationPrompt("GitHub repo access is required to fetch the commits information."); + // Deselect all the tabs except commits tab. + Array.from(parentObject.children).forEach((child) => { + if (child.children[0].id != "commits-tab") { + child.children[0].removeAttribute("aria-current"); + child.children[0].classList.remove("selected"); + } + }); + } + setCommitsButtonAsActive(); + var i = 0; + var interval = setInterval(() => { + setCommitsButtonAsActive(); + i++; + if (i == 10) { + clearInterval(interval); } - else { - console.log("Authorization token found: " + authorizationToken); + }, 1000); - // Load the commits of all branches and show the default view - await fetchCommits(); - } + // Try to fetch stored authorization token + var authorizationToken = getLocalToken(); + var storedUserName = getLocalUserName(); + if (authorizationToken == null || storedUserName == null) { + // Prompt the user to authorize with GitHub + await addAuthorizationPrompt("GitHub repo access is required to fetch the commits information."); + } + else { + console.log("Authorization token found: " + authorizationToken); + + // Load the commits of all branches and show the default view + await fetchCommits(); + } - // TODO : Move all the below code (with necessary modifications) - // to showCommits() function. + // TODO : Move all the below code (with necessary modifications) + // to showCommits() function. - // await loadBranchesButton(); + // await loadBranchesButton(); - // Fetches the branch data from API. - // [branches, selectedBranchNames] = await fetchActiveBranches(); + // Fetches the branch data from API. + // [branches, selectedBranchNames] = await fetchActiveBranches(); - // Set the branches to dropdown - // setBranchOptions(branches, selectedBranchNames); + // Set the branches to dropdown + // setBranchOptions(branches, selectedBranchNames); - // Fetch the commits from API. - // await fetchCommits(branches); + // Fetch the commits from API. + // await fetchCommits(branches); } \ No newline at end of file diff --git a/js/showCommits.js b/js/showCommits.js index 20154fc..9a31948 100644 --- a/js/showCommits.js +++ b/js/showCommits.js @@ -154,7 +154,10 @@ async function showCommits(commits, branchNames, allCommits, heads, pageNo, allB var repoOwner = presentUrl.split('/')[3]; var repoName = presentUrl.split('/')[4]; [commits, allCommits] = await getCommitDetails(repoOwner, repoName, commits, allCommits); - var contentView = document.getElementsByClassName("clearfix")[0]; + var contentView = + document.getElementsByClassName("clearfix")[0] || + document.getElementsByClassName("PageLayout")[0] || + document.getElementsByClassName("repository-content")[0]; var commitsContainerDummy = document.createElement("div"); diff --git a/js/showCommitsLoading.js b/js/showCommitsLoading.js index 35ce056..e74783c 100644 --- a/js/showCommitsLoading.js +++ b/js/showCommitsLoading.js @@ -1,7 +1,10 @@ async function showCommitsLoading() { - var contentView = document.getElementsByClassName("clearfix")[0]; - var commitsLoadingHtml = chrome.runtime.getURL('html/commitsLoading.html'); - await fetch(commitsLoadingHtml).then(response => response.text()).then(commitsLoadingHtmlText => { + var contentView = + document.getElementsByClassName("clearfix")[0] || + document.getElementsByClassName("PageLayout")[0] || + document.getElementsByClassName("repository-content")[0]; + var commitsLoadingHtml = chrome.runtime.getURL('html/commitsLoading.html'); + await fetch(commitsLoadingHtml).then(response => response.text()).then(commitsLoadingHtmlText => { var tempDiv = document.createElement('div'); tempDiv.innerHTML = commitsLoadingHtmlText; var newContent = tempDiv.firstChild; From 060ce5c78679195509f497d85ed486bc9e8e0ff2 Mon Sep 17 00:00:00 2001 From: vinhyan Date: Wed, 29 Jan 2025 00:59:48 -0500 Subject: [PATCH 2/3] fix: FRE popup tooltip not showing up --- js/fre/installFre.js | 21 ++++++++++++++------- js/main.js | 2 +- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/js/fre/installFre.js b/js/fre/installFre.js index d7437af..b5cdcd5 100644 --- a/js/fre/installFre.js +++ b/js/fre/installFre.js @@ -2,13 +2,20 @@ // Make necessary changes to this file to change the FRE. function installFre(resume) { - openCommitsTab(); - if (resume == "true") { - createOverlay(); - installFreStep2(); - } else { - installFreStep1(); - } + const observer = new MutationObserver((mutations, obs) => { + var commitsTabButton = document.getElementById("commits-tab"); + if (commitsTabButton) { + obs.disconnect(); // Stop observing once the button is found + openCommitsTab(); + if (resume == "true") { + createOverlay(); + installFreStep2(); + } else { + installFreStep1(); + } + } + }); + observer.observe(document.body, { childList: true, subtree: true }); } async function installFreStep1() { diff --git a/js/main.js b/js/main.js index d2c4498..ce12ae8 100644 --- a/js/main.js +++ b/js/main.js @@ -19,7 +19,6 @@ let prevURL = window.location.href; function onMutation() { const currentURL = window.location.href; function addCommitsButtonToUI() { - if (isCommitsTabOpen) return; if ( pathsToExclude.includes(windowPathArray[1]) == false && windowPathArray[2] @@ -28,6 +27,7 @@ function onMutation() { addCommitsButton(); observer(); } + if (isCommitsTabOpen) return; } addCommitsButtonToUI(); From 325dca42e9af56921b91120b30be2124f7fe29f9 Mon Sep 17 00:00:00 2001 From: vinhyan Date: Wed, 29 Jan 2025 17:50:23 -0500 Subject: [PATCH 3/3] fix: popup tooltip position commitsButton keeps re-rendering causing popup tooltip not able to locate its position in the DOM --- js/fre/installFre.js | 32 +++++++++++++++++--------------- js/loadBranchesButton.js | 3 ++- js/main.js | 2 +- js/showCommits.js | 3 ++- js/showCommitsLoading.js | 3 ++- 5 files changed, 24 insertions(+), 19 deletions(-) diff --git a/js/fre/installFre.js b/js/fre/installFre.js index b5cdcd5..6f48115 100644 --- a/js/fre/installFre.js +++ b/js/fre/installFre.js @@ -3,9 +3,9 @@ function installFre(resume) { const observer = new MutationObserver((mutations, obs) => { - var commitsTabButton = document.getElementById("commits-tab"); - if (commitsTabButton) { - obs.disconnect(); // Stop observing once the button is found + const commitsButton = document.getElementById("commits-tab"); + if (commitsButton) { + obs.disconnect(); openCommitsTab(); if (resume == "true") { createOverlay(); @@ -21,18 +21,20 @@ function installFre(resume) { async function installFreStep1() { createOverlay(); clearToolTip(); - var commitButton = document.getElementById("commits-tab"); - focusOnItem(commitButton, 10); - showToolTip( - commitButton, - "top-left", - "", - "Notice the new tab added to GitHub?", - "Open this tab from any repository and it will give you this page, where you can find the git graph, and much more!", - ["Continue [1/3]"], - ["btn-primary"], - [installFreStep2] - ); + window.onload = () => { + var commitsButton = document.getElementById("commits-tab"); + focusOnItem(commitsButton, 10); + showToolTip( + commitsButton, + "top-left", + "", + "Notice the new tab added to GitHub?", + "Open this tab from any repository and it will give you this page, where you can find the git graph, and much more!", + ["Continue [1/3]"], + ["btn-primary"], + [installFreStep2] + ); + } } function installFreStep2() { diff --git a/js/loadBranchesButton.js b/js/loadBranchesButton.js index 1e99ec8..8fb9b77 100644 --- a/js/loadBranchesButton.js +++ b/js/loadBranchesButton.js @@ -2,7 +2,8 @@ async function loadBranchesButton() { var contentView = document.getElementsByClassName("clearfix")[0] || document.getElementsByClassName("PageLayout")[0] || - document.getElementsByClassName("repository-content")[0]; + document.getElementsByClassName("repository-content")[0] || + document.getElementsByTagName("react-app")[0]; var branchSelectionHtml = chrome.runtime.getURL('html/branchSelection.html'); await fetch(branchSelectionHtml).then(response => response.text()).then(branchSelectionHtmlText => { var tempDiv = document.createElement('div'); diff --git a/js/main.js b/js/main.js index ce12ae8..5066158 100644 --- a/js/main.js +++ b/js/main.js @@ -23,11 +23,11 @@ function onMutation() { pathsToExclude.includes(windowPathArray[1]) == false && windowPathArray[2] ) { + if (isCommitsTabOpen) return; mo.disconnect(); addCommitsButton(); observer(); } - if (isCommitsTabOpen) return; } addCommitsButtonToUI(); diff --git a/js/showCommits.js b/js/showCommits.js index 9a31948..83e6f51 100644 --- a/js/showCommits.js +++ b/js/showCommits.js @@ -157,7 +157,8 @@ async function showCommits(commits, branchNames, allCommits, heads, pageNo, allB var contentView = document.getElementsByClassName("clearfix")[0] || document.getElementsByClassName("PageLayout")[0] || - document.getElementsByClassName("repository-content")[0]; + document.getElementsByClassName("repository-content")[0] || + document.getElementsByTagName("react-app")[0]; var commitsContainerDummy = document.createElement("div"); diff --git a/js/showCommitsLoading.js b/js/showCommitsLoading.js index e74783c..6f82e27 100644 --- a/js/showCommitsLoading.js +++ b/js/showCommitsLoading.js @@ -2,7 +2,8 @@ async function showCommitsLoading() { var contentView = document.getElementsByClassName("clearfix")[0] || document.getElementsByClassName("PageLayout")[0] || - document.getElementsByClassName("repository-content")[0]; + document.getElementsByClassName("repository-content")[0] || + document.getElementsByTagName("react-app")[0]; var commitsLoadingHtml = chrome.runtime.getURL('html/commitsLoading.html'); await fetch(commitsLoadingHtml).then(response => response.text()).then(commitsLoadingHtmlText => { var tempDiv = document.createElement('div');