Skip to content

Commit 1fa99dd

Browse files
committed
Merge branch 'release/1.0.0'
2 parents c34f074 + 42d90fc commit 1fa99dd

39 files changed

+7304
-3
lines changed

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
.vscode
2+
*.crx
3+
*.pem
4+
*.zip
5+
*_original*

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2022 gitd export - Git Download Manager
3+
Copyright (c) 2022 Gitdownloadmanager.com
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

README.md

Lines changed: 78 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,78 @@
1-
# gitd-extension
2-
Browser extension download Github, Gitlab, Bitbucket repository on browser
1+
# Gitd Download Manager Browser Extension
2+
It is a browser extension that allows you to download only the files/folders you want without having to download all of the public repository. Github.com, Bitbucket.org, Gitlab.com provides all of the public repos in git services to download selected files and folders as a zip files with a single click, without the need for any API key or token.
3+
4+
The "Gitd Start" button is ready for use on every screen you see.
5+
6+
> Note: Gitd Download Manager browser extension creates download lists using Gitdownloadmanager.com api service.
7+
8+
![screenshot](screenshots/gitd-manager-github-download.jpeg)
9+
10+
## Features
11+
- Support only Github.com, Bitbucket.org, Gitlab.com public repositories page
12+
- Not neeeded ApiKey/ApiToken
13+
- Support single or multiple files download
14+
- Download selected contents as a zip file with one click
15+
- Support all branches
16+
- Maximum Selection Limit: 5
17+
- Maximum Download Files: 5000
18+
19+
## Next Features
20+
- No limitations for selection and downloading files count
21+
- Support branch names with includes slash
22+
- Support Bitbucket.org commitId url (Maybe)
23+
24+
## Compatibility
25+
- Chrome (Manifestv3)
26+
- Firefox (Manifestv2)
27+
- Microsoft Edge (Manifestv3)
28+
29+
## Installation
30+
### Chrome Store/Firefox Add-Ons
31+
32+
Go to [Gitd Download Manager](https://chrome.google.com/webstore/detail/gitd-download-manager/cbnplpkljokdodpligcaolkmodfondhl) Chrome Store Page
33+
34+
Go to [Gitd Download Manager](https://addons.mozilla.org/en-US/firefox/addon/gitd-download-manager/) Firefox Add-Ons Page
35+
36+
Go to [Gitd Download Manager](https://microsoftedge.microsoft.com/addons/detail/-/-) Microsoft Edge Add-Ons Page
37+
38+
### Local Development
39+
40+
- Run `./build.<env>.sh <NEW_VERSION>` (./build.dev.sh 1.0.0) command after go to "build" folder.
41+
42+
1. Open Chrome and go to: chrome://extensions/ (same as Firefox)
43+
2. Enable: "Developer mode"
44+
3. Click: "Load unpacked extension"
45+
4. Select: "extension" directory
46+
5. Ready to use
47+
6. Go to github.com, gitlab.com or bitbucket.org website
48+
49+
### Usage
50+
- In the right corner of the browser, the "Gitd Start" button notifies you that the plugin is active.
51+
- The plugin is automatically installed on Github.com and adds checkboxes, but on other websites you have to press the "Gitd Start" button.
52+
53+
### Find Open Source Projects: Public Repository
54+
[Github.com](https://github.com/search/advanced) advanced search page.
55+
[Gitlab.com](https://gitlab.com/explore/projects) advanced search page.
56+
[Bitbucket.org](https://bitbucket.org/repo/all) simple search page.
57+
58+
## Licence
59+
See LICENSE for more details.
60+
61+
# Thanks
62+
[Alpinejs](https://alpinejs.dev) for DOM manipulation
63+
64+
[fflate](https://github.com/101arrowz/fflate) for generate zip packages
65+
66+
[Bootstrap Icons](https://icons.getbootstrap.com) for svg icons
67+
68+
[Photopea](https://www.photopea.com) for create logo, icon and favicon
69+
70+
[Liozon/Edge add-on badge.md](https://gist.github.com/Liozon/cf898c47628bfecd9896f79e6c9a8db8) for Microsoft Edge Add-On Badge
71+
72+
## Source
73+
[Firefox Manifest Docs](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json) * perfect docs
74+
75+
[Google Chrome Manifest Docs](https://developer.chrome.com/docs/extensions/mv3/manifest/) * not recomended **sorry**
76+
77+
[Microsoft Edge Manifest Docs](https://learn.microsoft.com/en-us/microsoft-edge/extensions-chromium/getting-started/manifest-format) * firefox alternate
78+

VERSION

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
1.0.0

build.dev.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#!/bin/bash
2+
ARGS=("$@")
3+
BUILD_NUMBER_NEW="${ARGS[0]}"
4+
5+
./sh/build.sh "dev" $BUILD_NUMBER_NEW "https://localhost:3002" "https://localhost"

build.prod.sh

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#!/bin/bash
2+
3+
ARGS=("$@")
4+
BUILD_NUMBER_NEW="${ARGS[0]}"
5+
6+
./sh/build.sh "prod" $BUILD_NUMBER_NEW "https://api.gitdownloadmanager.com" "https://*.gitdownloadmanager.com"

extension/background.js

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
"use strict";
2+
3+
// Manifest json file to object data
4+
let manifestData = chrome.runtime.getManifest()
5+
6+
// console.log("manifestData", manifestData);
7+
// Fired when the extension is first installed, when the extension is updated to a new version, and when the browser is updated to a new version.
8+
chrome.runtime.onInstalled.addListener(
9+
function() {
10+
console.info('%c' + manifestData.name + ' Extension: %cWelcome to my world!', 'color: orange;', 'color: default;')
11+
}
12+
)
13+
14+
// Use APIs that support event filters to restrict listeners to the cases the extension cares about.
15+
// If an extension is listening for the tabs.onUpdated event, try using the webNavigation.onCompleted event with filters instead, as the tabs API does not support filters.
16+
// https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/events/UrlFilter
17+
let urlFilters = {
18+
url: [
19+
{
20+
hostEquals:'github.com',
21+
schemes:["https"]
22+
},
23+
{
24+
hostEquals:'gitlab.com',
25+
schemes:["https"]
26+
},
27+
{
28+
hostEquals:'bitbucket.org',
29+
schemes:["https"]
30+
}
31+
]
32+
}
33+
34+
/*chrome.webNavigation.onDOMContentLoaded.addListener(function (details) {
35+
// send message
36+
chrome.tabs.sendMessage(details.tabId, {
37+
action: 'IM_LOADING'
38+
})
39+
}, urlFilters)*/
40+
41+
chrome.webNavigation.onCompleted.addListener(function (details) {
42+
chrome.tabs.sendMessage(details.tabId, {
43+
action: 'IM_READY'
44+
})
45+
}, urlFilters)
46+
47+
chrome.webNavigation.onHistoryStateUpdated.addListener(function (details) {
48+
chrome.tabs.sendMessage(details.tabId, {
49+
action: 'IM_CHANGED'
50+
})
51+
}, urlFilters)
52+
53+
// gitdmanager api request listener
54+
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
55+
// console.log("bg", request, sender, sendResponse)
56+
57+
if (request.name === "gitd-api") {
58+
// console.log(_findUrlFromManifest(request.url))
59+
fetch(_findUrlFromManifest(request.url), {
60+
method: "POST",
61+
body: JSON.stringify(request.body),
62+
headers: {
63+
"content-type": "application/json",
64+
},
65+
})
66+
.then(resp => resp.json())
67+
.then(response => sendResponse(response))
68+
.catch(e => {
69+
//console.warn("fetch Error", e);
70+
71+
sendResponse({status: false, message: "internal server error. something wrong!"})
72+
})
73+
}
74+
75+
return true // last error fixed
76+
})
77+
78+
function _findUrlFromManifest(request_url) {
79+
let version = manifestData.manifest_version
80+
81+
let url = ""
82+
if (version === 2) {
83+
url = (manifestData.permissions[0]).replace("/*", request_url)
84+
} else if (version === 3) {
85+
url = (manifestData.host_permissions[0]).replace("/*", request_url)
86+
}
87+
88+
return url
89+
}

extension/contentScript.js

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
"use strict";
2+
3+
// declare debug mode var
4+
let gitdDebugMode = false
5+
6+
// listen runtime message from bg
7+
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
8+
switch (request.action) {
9+
case "IM_CHANGED":
10+
// Dom Content Loading but not finish
11+
if (isDebugActive()) console.log("content-script", "im changed")
12+
13+
// inject templates
14+
injectGitdTemplates()
15+
16+
break;
17+
/*case "IM_LOADING":
18+
// Dom Content Loading but not finish
19+
if (isDebugActive()) console.log("content-script", "im loading")
20+
21+
break;*/
22+
case "IM_READY":
23+
// Everything Loading finished. Ready to use.
24+
if (isDebugActive()) console.log("content-script", "im ready")
25+
26+
// inject templates
27+
injectGitdTemplates()
28+
29+
// inject gitdmanager
30+
injectGitdScripts("lib/gitdmanager.js")
31+
/*let gitdmanagerjs = chrome.runtime.getURL("lib/gitdmanager.js")
32+
let s2 = document.createElement('script')
33+
s2.src = gitdmanagerjs;
34+
s2.onload = function() {
35+
s2.parentNode.removeChild(s2);
36+
//this.remove();
37+
};
38+
(document.body || document.documentElement).appendChild(s2)
39+
if (isDebugActive()) console.log(s2);*/
40+
41+
// inject alpine
42+
injectGitdScripts("lib/alpine-scp.min.js")
43+
/*let alpinejs = chrome.runtime.getURL("lib/alpine-scp.min.js")
44+
let s = document.createElement('script')
45+
s.setAttribute("defer", "defer")
46+
s.src = alpinejs;
47+
s.onload = function() {
48+
s.parentNode.removeChild(s);
49+
//this.remove();
50+
};
51+
(document.head || document.documentElement).appendChild(s)
52+
if (isDebugActive()) console.log(s);*/
53+
54+
// inject fflate
55+
injectGitdScripts("lib/fflate.min.js")
56+
/*let afflatejs = chrome.runtime.getURL("lib/fflate.min.js")
57+
let s1 = document.createElement('script')
58+
s1.src = afflatejs;
59+
s1.onload = function() {
60+
s1.parentNode.removeChild(s1);
61+
//this.remove();
62+
};
63+
(document.head || document.documentElement).appendChild(s1)
64+
if (isDebugActive()) console.log(s1);*/
65+
66+
break;
67+
default:
68+
break;
69+
}
70+
});
71+
72+
// listen browser submit event
73+
// Request: gitdmanager (browser) -> contentScript -> background
74+
// Response: background -> contentScript -> gitdmanager (browser)
75+
window.addEventListener("submit-action", function(evt) {
76+
if (isDebugActive()) console.log("content-script","submit-action", evt.detail)
77+
chrome.runtime.sendMessage(JSON.parse(evt.detail), function(response) {
78+
if (isDebugActive()) console.log("bg-response", response);
79+
80+
window.dispatchEvent(new CustomEvent(
81+
'submit-action-response',
82+
{
83+
bubbles: true,
84+
detail: JSON.stringify(response)
85+
}
86+
))
87+
});
88+
}, false);
89+
90+
// via: chrome dev tools: getEventListeners(window) -> return all events
91+
// only for github "turbo:load" event listen
92+
window.addEventListener("turbo:load", function(evt) {
93+
if (isDebugActive()) console.log("content-script", "turbo:load", evt)
94+
95+
setTimeout(function() {
96+
97+
// checkbox add
98+
let navItem = document.querySelectorAll("div.js-navigation-item > div:first-child > svg")
99+
if (navItem.length > 0) {
100+
101+
// inject checkbox
102+
for (const key in navItem) {
103+
if (Object.hasOwnProperty.call(navItem, key)) {
104+
const element = navItem[key];
105+
106+
// type: none: 0 - file: 1 - folder: 2
107+
let itemType = element.getAttribute("aria-label")
108+
if (itemType === "Directory") {
109+
itemType = 2
110+
} else if (itemType === "File") {
111+
itemType = 1
112+
}
113+
114+
let pathElement = element.parentElement.nextElementSibling.querySelector("div > span > a")
115+
if (!!pathElement) {
116+
element.parentElement.insertAdjacentHTML("beforebegin", "<div role=\"gridcell\" class=\"mr-3 flex-shrink-0\"><input class=\"gitd-tree-checkbox\" type=\"checkbox\" data-name=\""+pathElement.innerText+"\" data-type=\""+itemType+"\" @click=\"toggleSelectList\"></div>")
117+
}
118+
}
119+
}
120+
}
121+
122+
}, 1500)
123+
124+
}, false);
125+
126+
/*window.addEventListener("turbo:visit", function(evt) {
127+
if (isDebugActive()) console.log("content-script", "turbo:visit", evt)
128+
}, false);
129+
130+
window.addEventListener("pageshow", function(evt) {
131+
if (isDebugActive()) console.log("content-script", "pageshow", evt)
132+
}, false);
133+
134+
window.addEventListener("turbo:frame-render", function(evt) {
135+
if (isDebugActive()) console.log("content-script", "turbo:frame-render", evt)
136+
}, false);*/
137+
138+
// debug mode listener
139+
window.addEventListener("debug-mode-changed", function(evt) {
140+
if (isDebugActive()) console.log("content-script", "debug-mode-changed", evt)
141+
142+
gitdDebugMode = evt.detail
143+
144+
}, false);
145+
146+
// check debug mode
147+
function isDebugActive() {
148+
return gitdDebugMode
149+
}
150+
151+
// inject templates
152+
function injectGitdTemplates() {
153+
if (!document.body.hasAttribute("x-data")) {
154+
document.body.setAttribute("x-data", "gitdManager")
155+
document.body.insertAdjacentHTML("beforeend", gitdInitTemplate)
156+
}
157+
}
158+
159+
// inject scripts
160+
function injectGitdScripts(scrPath) {
161+
let s = document.createElement('script')
162+
s.src = chrome.runtime.getURL(scrPath);
163+
s.onload = function() {
164+
s.parentNode.removeChild(s);
165+
};
166+
(document.body || document.documentElement).appendChild(s)
167+
if (isDebugActive()) console.log(s);
168+
}

0 commit comments

Comments
 (0)