diff --git a/js/main.js b/js/main.js
index 9a8b64f..c476897 100644
--- a/js/main.js
+++ b/js/main.js
@@ -1,20 +1,20 @@
"use strict";
-const ForksDiff = (() => {
- // Icons
- const starIcon =
- '';
- const forkIcon =
- '';
- const loadingIcon =
- '';
+window._forksdiffconstants = {
+ icons: {
+ loading:
+ '',
- // Regex
- const diffRegex =
- /
[\S\s]*?This branch is[\S\s]*?((?
[0-9]*) commits? ahead[\S\s]*?(?[0-9]*) commits? behind|(?[0-9]*) commits? behind|(?[0-9]*) commits? ahead)/;
- const starsRegex = /([0-9]+) users? starred this repository/;
- const githubUrlRegex = /https?:\/\/github\.com\/.*\/network\/members/;
+ star: '',
+ fork: '',
+ },
+ regex: {
+ diff: /[\S\s]*?This branch is[\S\s]*?((?
[0-9]*) commits? ahead[\S\s]*?(?[0-9]*) commits? behind|(?[0-9]*) commits? behind|(?[0-9]*) commits? ahead)/,
+ stars: /([0-9]+) users? starred this repository/,
+ },
+};
+const LegacyLoadDiffButton = (() => {
const queue = [];
const parallelNum = 3;
@@ -30,7 +30,7 @@ const ForksDiff = (() => {
// Add spinner
const spinner = document.createElement("span");
- spinner.innerHTML = loadingIcon;
+ spinner.innerHTML = window._forksdiffconstants.icons.loading;
currentRepo.appendChild(spinner);
const request = new XMLHttpRequest();
@@ -45,7 +45,7 @@ const ForksDiff = (() => {
currentRepo.removeChild(spinner);
// Read diff
- const diffRegexResult = diffRegex.exec(body);
+ const diffRegexResult = window._forksdiffconstants.regex.diff.exec(body);
if (!diffRegexResult) {
_addSpan(currentRepo, "is even", "text-gray");
} else {
@@ -66,9 +66,10 @@ const ForksDiff = (() => {
// Read stars
_addSpan(currentRepo, " ");
- const stars = body.match(starsRegex);
+ const stars = body.match(window._forksdiffconstants.regex.stars);
const starIndicator = document.createElement("span");
- starIndicator.innerHTML = starIcon + " " + stars[1];
+ starIndicator.innerHTML =
+ window._forksdiffconstants.icons.star + " " + stars[1];
currentRepo.appendChild(starIndicator);
// Process next repo
@@ -88,7 +89,9 @@ const ForksDiff = (() => {
e.target.removeEventListener("click", _buttonAction);
// Iterate through repos
- const repos = document.getElementById("network").querySelector("div").children;
+ const repos = document
+ .getElementById("network")
+ .querySelector("div").children;
for (let i = 0; i < repos.length; i++) {
// Skip root fork
if (repos[i].getElementsByClassName("network-tree").length === 0) {
@@ -106,7 +109,7 @@ const ForksDiff = (() => {
}
};
- const init = () => {
+ const addButton = () => {
const network = document.getElementById("network");
// Check if we have at least one div.repo, if not we are on Network page and not Forks page
@@ -114,7 +117,7 @@ const ForksDiff = (() => {
const mainButton = document.createElement("button");
mainButton.className = "btn float-right";
- mainButton.innerHTML = forkIcon + " Load diff";
+ mainButton.innerHTML = window._forksdiffconstants.icons.fork + " Load diff";
mainButton.addEventListener("click", _buttonAction);
network.insertBefore(mainButton, network.childNodes[0]);
@@ -130,6 +133,157 @@ const ForksDiff = (() => {
}
};
+ return {
+ addButton: addButton,
+ };
+})();
+
+const LoadDiffButton = (() => {
+ const queue = [];
+ const parallelNum = 3;
+
+ const addSpan = (parent, text, className) => {
+ const span = document.createElement("span");
+ span.className = className;
+ span.appendChild(document.createTextNode(text));
+ parent.appendChild(span);
+ };
+
+ const createInfoBox = () => {
+ const box = document.createElement("div");
+ box.className = "mr-4 f6";
+ return box;
+ };
+
+ const processRepo = () => {
+ const currentRepo = queue.shift();
+
+ // Get info box
+ const infoBoxContainer = currentRepo
+ .querySelector("div")
+ .querySelector("div");
+
+ // Create info box
+ const infoBox = createInfoBox();
+ infoBoxContainer.insertBefore(infoBox, infoBoxContainer.children[4]);
+
+ // Add spinner
+ const spinner = document.createElement("span");
+ spinner.innerHTML = window._forksdiffconstants.icons.loading;
+ infoBox.appendChild(spinner);
+
+ // TODO: Maybe switch to fetch
+ const request = new XMLHttpRequest();
+ request.addEventListener("load", function () {
+ // Remove spinner
+ infoBox.removeChild(spinner);
+
+ if (this.status == 429) {
+ // Rate limited :(
+ console.log(this.getResponseHeader("Retry-After"));
+ return;
+ }
+
+ const body = this.responseText;
+
+ // Read diff
+ const diffRegexResult = window._forksdiffconstants.regex.diff.exec(body);
+ if (!diffRegexResult) {
+ addSpan(infoBox, "is even", "text-gray");
+ } else {
+ const {
+ groups: { a1, a2, b, c },
+ } = diffRegexResult;
+
+ if (a1 && a2) {
+ addSpan(infoBox, "+" + a1, "cadd");
+ addSpan(infoBox, " ");
+ addSpan(infoBox, "-" + a2, "cdel");
+ } else if (b) {
+ addSpan(infoBox, "-" + b, "cdel");
+ } else if (c) {
+ addSpan(infoBox, "+" + c, "cadd");
+ }
+ }
+
+ // Process next repo
+ if (queue.length > 0) {
+ processRepo();
+ }
+ });
+
+ // Send request
+ request.open("GET", currentRepo.querySelectorAll("a")[1].href);
+ request.send();
+ };
+
+ const buttonAction = (e) => {
+ console.log(e);
+
+ // Disable button
+ e.target.setAttribute("disabled", "disabled");
+ e.target.removeEventListener("click", buttonAction);
+
+ // Extract forks links
+ const forks = document
+ .querySelector(".Layout-main")
+ .querySelector("ul")
+ .querySelectorAll("li");
+ console.log(forks);
+ queue.push.apply(queue, forks);
+ console.log(queue);
+
+ // Start
+ for (let i = 0; i < parallelNum; i++) {
+ if (queue.length > 0) {
+ processRepo();
+ }
+ }
+ };
+
+ const addButton = () => {
+ const buttons = document
+ .querySelector("search-control-menu")
+ .querySelector("div");
+
+ const mainButton = document.createElement("button");
+ mainButton.className =
+ "Button--secondary Button--small Button text-normal mt-2 ml-lg-2 mt-lg-0";
+ mainButton.addEventListener("click", buttonAction);
+
+ // Add text
+ // const span1 = document.createElement("span");
+ // span1.className = "Button-content";
+ // const span2 = document.createElement("span");
+ // span2.className = "Button-label";
+ // span2.appendChild(document.createTextNode("Load diff"));
+ // span1.appendChild(span2);
+ // mainButton.appendChild(span1);
+ mainButton.appendChild(document.createTextNode("Load diff"));
+
+ buttons.appendChild(mainButton);
+ };
+
+ return {
+ addButton: addButton,
+ };
+})();
+
+const ForksDiff = (() => {
+ // Regex
+ const legacyNetworkRegex =
+ /https?:\/\/github.com\/[\w\.\-]+\/[\w\.\-]+\/network\/members/;
+ const forksUrlRegex = /https?:\/\/github.com\/[\w\.\-]+\/[\w\.\-]+\/forks/;
+
+ const init = () => {
+ // Check page
+ if (forksUrlRegex.test(location.href)) {
+ LoadDiffButton.addButton();
+ } else if (legacyNetworkRegex.test(location.href)) {
+ LegacyLoadDiffButton.addButton();
+ }
+ };
+
return {
init: init,
};
diff --git a/manifest.json b/manifest.json
index 8e145b5..2b6d0a9 100644
--- a/manifest.json
+++ b/manifest.json
@@ -1,7 +1,7 @@
{
"manifest_version": 3,
"name": "__MSG_appName__",
- "version": "1.2.3",
+ "version": "1.2.4",
"description": "__MSG_appDescription__",
"default_locale": "en",
diff --git a/pack.sh b/pack.sh
index 545c953..b7e076f 100755
--- a/pack.sh
+++ b/pack.sh
@@ -1,15 +1,15 @@
#!/usr/bin/env bash
-VERSION="1.2.3-chrome"
+VERSION="1.2.4-chrome"
ICONS_SIZES="16 32 48 64 128"
OUTPUT_FOLDER=".build"
# Prepare icons
for size in ${ICONS_SIZES}; do
- (
- cd icons || exit 1
- inkscape -w "${size}" -h "${size}" source.svg --export-filename "icon.${size}.png"
- )
+ (
+ cd icons || exit 1
+ inkscape -w "${size}" -h "${size}" source.svg --export-filename "icon.${size}.png"
+ )
done
# Pack to zip