Skip to content

Commit

Permalink
Merge branch 'release/1.0.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
uretgec committed Sep 25, 2022
2 parents c34f074 + 42d90fc commit 1fa99dd
Show file tree
Hide file tree
Showing 39 changed files with 7,304 additions and 3 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.vscode
*.crx
*.pem
*.zip
*_original*
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

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

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
80 changes: 78 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,78 @@
# gitd-extension
Browser extension download Github, Gitlab, Bitbucket repository on browser
# Gitd Download Manager Browser Extension
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.

The "Gitd Start" button is ready for use on every screen you see.

> Note: Gitd Download Manager browser extension creates download lists using Gitdownloadmanager.com api service.
![screenshot](screenshots/gitd-manager-github-download.jpeg)

## Features
- Support only Github.com, Bitbucket.org, Gitlab.com public repositories page
- Not neeeded ApiKey/ApiToken
- Support single or multiple files download
- Download selected contents as a zip file with one click
- Support all branches
- Maximum Selection Limit: 5
- Maximum Download Files: 5000

## Next Features
- No limitations for selection and downloading files count
- Support branch names with includes slash
- Support Bitbucket.org commitId url (Maybe)

## Compatibility
- Chrome (Manifestv3)
- Firefox (Manifestv2)
- Microsoft Edge (Manifestv3)

## Installation
### Chrome Store/Firefox Add-Ons

Go to [Gitd Download Manager](https://chrome.google.com/webstore/detail/gitd-download-manager/cbnplpkljokdodpligcaolkmodfondhl) Chrome Store Page

Go to [Gitd Download Manager](https://addons.mozilla.org/en-US/firefox/addon/gitd-download-manager/) Firefox Add-Ons Page

Go to [Gitd Download Manager](https://microsoftedge.microsoft.com/addons/detail/-/-) Microsoft Edge Add-Ons Page

### Local Development

- Run `./build.<env>.sh <NEW_VERSION>` (./build.dev.sh 1.0.0) command after go to "build" folder.

1. Open Chrome and go to: chrome://extensions/ (same as Firefox)
2. Enable: "Developer mode"
3. Click: "Load unpacked extension"
4. Select: "extension" directory
5. Ready to use
6. Go to github.com, gitlab.com or bitbucket.org website

### Usage
- In the right corner of the browser, the "Gitd Start" button notifies you that the plugin is active.
- The plugin is automatically installed on Github.com and adds checkboxes, but on other websites you have to press the "Gitd Start" button.

### Find Open Source Projects: Public Repository
[Github.com](https://github.com/search/advanced) advanced search page.
[Gitlab.com](https://gitlab.com/explore/projects) advanced search page.
[Bitbucket.org](https://bitbucket.org/repo/all) simple search page.

## Licence
See LICENSE for more details.

# Thanks
[Alpinejs](https://alpinejs.dev) for DOM manipulation

[fflate](https://github.com/101arrowz/fflate) for generate zip packages

[Bootstrap Icons](https://icons.getbootstrap.com) for svg icons

[Photopea](https://www.photopea.com) for create logo, icon and favicon

[Liozon/Edge add-on badge.md](https://gist.github.com/Liozon/cf898c47628bfecd9896f79e6c9a8db8) for Microsoft Edge Add-On Badge

## Source
[Firefox Manifest Docs](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json) * perfect docs

[Google Chrome Manifest Docs](https://developer.chrome.com/docs/extensions/mv3/manifest/) * not recomended **sorry**

[Microsoft Edge Manifest Docs](https://learn.microsoft.com/en-us/microsoft-edge/extensions-chromium/getting-started/manifest-format) * firefox alternate

1 change: 1 addition & 0 deletions VERSION
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1.0.0
5 changes: 5 additions & 0 deletions build.dev.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/bash
ARGS=("$@")
BUILD_NUMBER_NEW="${ARGS[0]}"

./sh/build.sh "dev" $BUILD_NUMBER_NEW "https://localhost:3002" "https://localhost"
6 changes: 6 additions & 0 deletions build.prod.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/bash

ARGS=("$@")
BUILD_NUMBER_NEW="${ARGS[0]}"

./sh/build.sh "prod" $BUILD_NUMBER_NEW "https://api.gitdownloadmanager.com" "https://*.gitdownloadmanager.com"
89 changes: 89 additions & 0 deletions extension/background.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
"use strict";

// Manifest json file to object data
let manifestData = chrome.runtime.getManifest()

// console.log("manifestData", manifestData);
// 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.
chrome.runtime.onInstalled.addListener(
function() {
console.info('%c' + manifestData.name + ' Extension: %cWelcome to my world!', 'color: orange;', 'color: default;')
}
)

// Use APIs that support event filters to restrict listeners to the cases the extension cares about.
// 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.
// https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/events/UrlFilter
let urlFilters = {
url: [
{
hostEquals:'github.com',
schemes:["https"]
},
{
hostEquals:'gitlab.com',
schemes:["https"]
},
{
hostEquals:'bitbucket.org',
schemes:["https"]
}
]
}

/*chrome.webNavigation.onDOMContentLoaded.addListener(function (details) {
// send message
chrome.tabs.sendMessage(details.tabId, {
action: 'IM_LOADING'
})
}, urlFilters)*/

chrome.webNavigation.onCompleted.addListener(function (details) {
chrome.tabs.sendMessage(details.tabId, {
action: 'IM_READY'
})
}, urlFilters)

chrome.webNavigation.onHistoryStateUpdated.addListener(function (details) {
chrome.tabs.sendMessage(details.tabId, {
action: 'IM_CHANGED'
})
}, urlFilters)

// gitdmanager api request listener
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
// console.log("bg", request, sender, sendResponse)

if (request.name === "gitd-api") {
// console.log(_findUrlFromManifest(request.url))
fetch(_findUrlFromManifest(request.url), {
method: "POST",
body: JSON.stringify(request.body),
headers: {
"content-type": "application/json",
},
})
.then(resp => resp.json())
.then(response => sendResponse(response))
.catch(e => {
//console.warn("fetch Error", e);

sendResponse({status: false, message: "internal server error. something wrong!"})
})
}

return true // last error fixed
})

function _findUrlFromManifest(request_url) {
let version = manifestData.manifest_version

let url = ""
if (version === 2) {
url = (manifestData.permissions[0]).replace("/*", request_url)
} else if (version === 3) {
url = (manifestData.host_permissions[0]).replace("/*", request_url)
}

return url
}
168 changes: 168 additions & 0 deletions extension/contentScript.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
"use strict";

// declare debug mode var
let gitdDebugMode = false

// listen runtime message from bg
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) {
switch (request.action) {
case "IM_CHANGED":
// Dom Content Loading but not finish
if (isDebugActive()) console.log("content-script", "im changed")

// inject templates
injectGitdTemplates()

break;
/*case "IM_LOADING":
// Dom Content Loading but not finish
if (isDebugActive()) console.log("content-script", "im loading")
break;*/
case "IM_READY":
// Everything Loading finished. Ready to use.
if (isDebugActive()) console.log("content-script", "im ready")

// inject templates
injectGitdTemplates()

// inject gitdmanager
injectGitdScripts("lib/gitdmanager.js")
/*let gitdmanagerjs = chrome.runtime.getURL("lib/gitdmanager.js")
let s2 = document.createElement('script')
s2.src = gitdmanagerjs;
s2.onload = function() {
s2.parentNode.removeChild(s2);
//this.remove();
};
(document.body || document.documentElement).appendChild(s2)
if (isDebugActive()) console.log(s2);*/

// inject alpine
injectGitdScripts("lib/alpine-scp.min.js")
/*let alpinejs = chrome.runtime.getURL("lib/alpine-scp.min.js")
let s = document.createElement('script')
s.setAttribute("defer", "defer")
s.src = alpinejs;
s.onload = function() {
s.parentNode.removeChild(s);
//this.remove();
};
(document.head || document.documentElement).appendChild(s)
if (isDebugActive()) console.log(s);*/

// inject fflate
injectGitdScripts("lib/fflate.min.js")
/*let afflatejs = chrome.runtime.getURL("lib/fflate.min.js")
let s1 = document.createElement('script')
s1.src = afflatejs;
s1.onload = function() {
s1.parentNode.removeChild(s1);
//this.remove();
};
(document.head || document.documentElement).appendChild(s1)
if (isDebugActive()) console.log(s1);*/

break;
default:
break;
}
});

// listen browser submit event
// Request: gitdmanager (browser) -> contentScript -> background
// Response: background -> contentScript -> gitdmanager (browser)
window.addEventListener("submit-action", function(evt) {
if (isDebugActive()) console.log("content-script","submit-action", evt.detail)
chrome.runtime.sendMessage(JSON.parse(evt.detail), function(response) {
if (isDebugActive()) console.log("bg-response", response);

window.dispatchEvent(new CustomEvent(
'submit-action-response',
{
bubbles: true,
detail: JSON.stringify(response)
}
))
});
}, false);

// via: chrome dev tools: getEventListeners(window) -> return all events
// only for github "turbo:load" event listen
window.addEventListener("turbo:load", function(evt) {
if (isDebugActive()) console.log("content-script", "turbo:load", evt)

setTimeout(function() {

// checkbox add
let navItem = document.querySelectorAll("div.js-navigation-item > div:first-child > svg")
if (navItem.length > 0) {

// inject checkbox
for (const key in navItem) {
if (Object.hasOwnProperty.call(navItem, key)) {
const element = navItem[key];

// type: none: 0 - file: 1 - folder: 2
let itemType = element.getAttribute("aria-label")
if (itemType === "Directory") {
itemType = 2
} else if (itemType === "File") {
itemType = 1
}

let pathElement = element.parentElement.nextElementSibling.querySelector("div > span > a")
if (!!pathElement) {
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>")
}
}
}
}

}, 1500)

}, false);

/*window.addEventListener("turbo:visit", function(evt) {
if (isDebugActive()) console.log("content-script", "turbo:visit", evt)
}, false);
window.addEventListener("pageshow", function(evt) {
if (isDebugActive()) console.log("content-script", "pageshow", evt)
}, false);
window.addEventListener("turbo:frame-render", function(evt) {
if (isDebugActive()) console.log("content-script", "turbo:frame-render", evt)
}, false);*/

// debug mode listener
window.addEventListener("debug-mode-changed", function(evt) {
if (isDebugActive()) console.log("content-script", "debug-mode-changed", evt)

gitdDebugMode = evt.detail

}, false);

// check debug mode
function isDebugActive() {
return gitdDebugMode
}

// inject templates
function injectGitdTemplates() {
if (!document.body.hasAttribute("x-data")) {
document.body.setAttribute("x-data", "gitdManager")
document.body.insertAdjacentHTML("beforeend", gitdInitTemplate)
}
}

// inject scripts
function injectGitdScripts(scrPath) {
let s = document.createElement('script')
s.src = chrome.runtime.getURL(scrPath);
s.onload = function() {
s.parentNode.removeChild(s);
};
(document.body || document.documentElement).appendChild(s)
if (isDebugActive()) console.log(s);
}
Loading

0 comments on commit 1fa99dd

Please sign in to comment.