Compare commits
No commits in common. "a8fcb3ad6d459399674ff805db8d2c41c83193ab" and "1fb586608c819e4cb16e85cda723c1874162261c" have entirely different histories.
a8fcb3ad6d
...
1fb586608c
@ -1,9 +0,0 @@
|
|||||||
root = true
|
|
||||||
|
|
||||||
[*]
|
|
||||||
indent_style = space
|
|
||||||
indent_size = 2
|
|
||||||
|
|
||||||
[*.json]
|
|
||||||
indent_style = space
|
|
||||||
indent_size = 4
|
|
172
background.js
@ -1,31 +1,29 @@
|
|||||||
let JD2_API_URL = window.localStorage.getItem("jd2_api_url") ?? 'http://localhost:9666/flashgot?';
|
var JD2_API_URL = 'http://localhost:9666/flashgot?';
|
||||||
let JD2_REFERER = window.localStorage.getItem("jd2_referer") ?? 'localhost';
|
var JD2_REFERER = 'localhost';
|
||||||
let JD2_MATCH_URL = window.localStorage.getItem("jd2_match_url") ?? "*://*/flashgot?*";
|
var JD2_MATCH_URL = "*://*/flashgot?*";
|
||||||
|
|
||||||
// menu
|
|
||||||
const mnDlId = "JD2Dl";
|
|
||||||
const mnGrabberId = "JD2Grabber"
|
|
||||||
|
|
||||||
|
|
||||||
function onError(error) {
|
function onError(error) {
|
||||||
console.log('UrlToJD2 background error: ' + error);
|
console.log('UrlToJD2_error: ' + error);
|
||||||
}
|
}
|
||||||
|
|
||||||
function onCreated() {
|
// On startup, check autostart option stored setting or default value
|
||||||
if (browser.runtime.lastError) {
|
const gettingStoredSettings = browser.storage.local.get();
|
||||||
onError(browser.runtime.lastError);
|
gettingStoredSettings.then((item) => {
|
||||||
|
if (!item.autostart) {
|
||||||
|
browser.storage.local.set({ autostart: true })
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
onError);
|
||||||
|
|
||||||
|
|
||||||
function makeRequest(url) {
|
function makeRequest(url) {
|
||||||
var req = new XMLHttpRequest();
|
var req = new XMLHttpRequest();
|
||||||
req.open('GET', url, true);
|
req.open('GET', url, true);
|
||||||
req.send(null);
|
req.send(null);
|
||||||
req.onerror = function () {
|
|
||||||
onError('Is JD2 on and ready ?');
|
|
||||||
}
|
|
||||||
req.onload = function () {
|
req.onload = function () {
|
||||||
if (req.readyState === XMLHttpRequest.DONE && req.status === 200) {
|
// console.log(req.status);
|
||||||
|
if (req.readyState === 4 && req.status === 200) {
|
||||||
// console.log(req.responseText);
|
// console.log(req.responseText);
|
||||||
// notify...
|
// notify...
|
||||||
} else {
|
} else {
|
||||||
@ -35,115 +33,73 @@ function makeRequest(url) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function urlConstruct(url, autostart) {
|
function urlConstruct(url, autostart) {
|
||||||
return JD2_API_URL + "autostart=" + autostart + "&urls=" + encodeURIComponent(url);
|
return JD2_API_URL + "autostart=" + autostart + "&urls=" + url;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return an url from a text, good enought :-)
|
|
||||||
function linkify(text) {
|
function bool_to_int(bool) {
|
||||||
let urlRegex =/(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig;
|
return (bool == true) ? 1 : 0;
|
||||||
let url = text.match(urlRegex);
|
|
||||||
return (url === null) ? '' : url[0];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MENU
|
// main
|
||||||
browser.menus.create({
|
function loadTabUrlToJD2Crawl(storedSettings) {
|
||||||
id: mnGrabberId,
|
var gettingActiveTab = browser.tabs.query({ active: true, currentWindow: true });
|
||||||
title: "Linkgrabbler",
|
gettingActiveTab.then((tabs) => {
|
||||||
contexts: ["link", "selection"],
|
if (tabs[0]) {
|
||||||
icons: {
|
currentTabUrl = tabs[0].url;
|
||||||
"16": "icons/jd2linkgrabber-16.png",
|
url_for_JD2 = urlConstruct(currentTabUrl, bool_to_int(storedSettings.autostart));
|
||||||
"32": "icons/jd2linkgrabber-32.png"
|
|
||||||
}
|
|
||||||
}, onCreated);
|
|
||||||
|
|
||||||
browser.menus.create({
|
|
||||||
id: mnDlId,
|
|
||||||
title: "send to Download",
|
|
||||||
contexts: ["link", "selection"],
|
|
||||||
icons: {
|
|
||||||
"16": "icons/jd2download-16.png",
|
|
||||||
"32": "icons/jd2download-32.png"
|
|
||||||
}
|
|
||||||
}, onCreated);
|
|
||||||
|
|
||||||
// Choose from info (object menus.OnClickData)
|
|
||||||
// linkUrl over selectionText
|
|
||||||
// return link or ''
|
|
||||||
function infoToUrl(info){
|
|
||||||
var url = '';
|
|
||||||
if (typeof info.linkUrl !== 'undefined'){
|
|
||||||
url = info.linkUrl;
|
|
||||||
} else {
|
|
||||||
if (typeof info.selectionText !== 'undefined'){
|
|
||||||
url = linkify(info.selectionText);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return url;
|
|
||||||
}
|
|
||||||
|
|
||||||
browser.menus.onClicked.addListener((info, tab) => {
|
|
||||||
var url = infoToUrl(info);
|
|
||||||
if (url !== ''){
|
|
||||||
switch (info.menuItemId){
|
|
||||||
case mnGrabberId:
|
|
||||||
url_for_JD2 = urlConstruct(url, 0);
|
|
||||||
break;
|
|
||||||
case mnDlId:
|
|
||||||
url_for_JD2 = urlConstruct(url, 1);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// console.log(url);
|
|
||||||
// console.log(url_for_JD2);
|
// console.log(url_for_JD2);
|
||||||
makeRequest(url_for_JD2);
|
makeRequest(url_for_JD2);
|
||||||
}
|
}
|
||||||
});
|
}, onError);
|
||||||
|
|
||||||
function updateMenuItem(url) {
|
|
||||||
browser.menus.update(mnDlId, {
|
|
||||||
title: 'Download: ' + url
|
|
||||||
});
|
|
||||||
browser.menus.update(mnGrabberId, {
|
|
||||||
title: 'Linkgrabber: ' + url
|
|
||||||
});
|
|
||||||
browser.menus.refresh();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function allMenusVisible(visible){
|
|
||||||
browser.menus.update(mnGrabberId, {
|
browser.pageAction.onClicked.addListener(() => {
|
||||||
visible: visible
|
const gettingStoredSettings = browser.storage.local.get();
|
||||||
});
|
gettingStoredSettings.then(loadTabUrlToJD2Crawl, onError);
|
||||||
browser.menus.update(mnDlId, {
|
});
|
||||||
visible: visible
|
|
||||||
|
|
||||||
|
// menu
|
||||||
|
const sendToJD2Id = "send-to-JD2";
|
||||||
|
function onCreated() {
|
||||||
|
if (browser.runtime.lastError) {
|
||||||
|
onError(browser.runtime.lastError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
browser.menus.create({
|
||||||
|
id: sendToJD2Id,
|
||||||
|
title: "send to JD2",
|
||||||
|
contexts: ["link"]
|
||||||
|
}, onCreated);
|
||||||
|
|
||||||
|
|
||||||
|
browser.menus.onClicked.addListener((info, tab) => {
|
||||||
|
if (info.menuItemId === sendToJD2Id) {
|
||||||
|
const gettingStoredSettings = browser.storage.local.get();
|
||||||
|
gettingStoredSettings.then((storedSettings) => {
|
||||||
|
url_for_JD2 = urlConstruct(info.linkUrl, bool_to_int(storedSettings.autostart));
|
||||||
|
makeRequest(url_for_JD2);
|
||||||
|
}, onError);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function updateMenuItem(link) {
|
||||||
|
browser.menus.update(sendToJD2Id, {
|
||||||
|
title: `Send to JD2: "${link}"`
|
||||||
});
|
});
|
||||||
|
browser.menus.refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
browser.menus.onShown.addListener(info => {
|
browser.menus.onShown.addListener(info => {
|
||||||
var url = infoToUrl(info);
|
if (!info.linkUrl) {
|
||||||
// console.log(url);
|
|
||||||
if (url !== ''){
|
|
||||||
allMenusVisible(true);
|
|
||||||
updateMenuItem(url);
|
|
||||||
return;
|
return;
|
||||||
} else {
|
|
||||||
allMenusVisible(false);
|
|
||||||
browser.menus.refresh();
|
|
||||||
}
|
}
|
||||||
|
updateMenuItem(info.linkUrl);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Handle message from 'popup'
|
|
||||||
function handleMessageFromPopup(request, sender, sendResponse) {
|
|
||||||
if (request.message == "refresh") {
|
|
||||||
JD2_API_URL = window.localStorage.getItem("jd2_api_url");
|
|
||||||
JD2_REFERER = window.localStorage.getItem("jd2_referer");
|
|
||||||
JD2_MATCH_URL = window.localStorage.getItem("jd2_match_url");
|
|
||||||
} else {
|
|
||||||
let forJD2link = urlConstruct(request.jd2url, request.jd2action);
|
|
||||||
makeRequest(forJD2link);
|
|
||||||
return Promise.resolve({response: "done"});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
browser.runtime.onMessage.addListener(handleMessageFromPopup);
|
|
||||||
|
|
||||||
|
|
||||||
// Some functions for a good referer !
|
// Some functions for a good referer !
|
||||||
|
|
||||||
|
Before Width: | Height: | Size: 573 B |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 790 B |
Before Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 483 B |
Before Width: | Height: | Size: 898 B |
Before Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 5.1 KiB |
@ -1,8 +1,8 @@
|
|||||||
{
|
{
|
||||||
"manifest_version": 2,
|
"manifest_version": 2,
|
||||||
"name": "UrlToJD2",
|
"name": "UrlToJD2",
|
||||||
"version": "2.1",
|
"version": "1.0",
|
||||||
"description": "Push an url to JDownloader 2 GrabberLink or Download",
|
"description": "Push the current url navigator to JDownloader 2",
|
||||||
|
|
||||||
"developer": {
|
"developer": {
|
||||||
"name": "GTeam",
|
"name": "GTeam",
|
||||||
@ -12,13 +12,11 @@
|
|||||||
"browser_specific_settings": {
|
"browser_specific_settings": {
|
||||||
"gecko": {
|
"gecko": {
|
||||||
"id": "urltojd2@gteam.fr",
|
"id": "urltojd2@gteam.fr",
|
||||||
"strict_min_version": "60.0"
|
"strict_min_version": "55.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
"icons": {
|
"icons": {
|
||||||
"16": "icons/urltojd2-16.png",
|
|
||||||
"32": "icons/urltojd2-32.png",
|
|
||||||
"48": "icons/urltojd2-48.png",
|
"48": "icons/urltojd2-48.png",
|
||||||
"96": "icons/urltojd2-96.png"
|
"96": "icons/urltojd2-96.png"
|
||||||
},
|
},
|
||||||
@ -33,10 +31,7 @@
|
|||||||
"38": "icons/urltojd2-38.png"
|
"38": "icons/urltojd2-38.png"
|
||||||
},
|
},
|
||||||
"show_matches": ["<all_urls>"],
|
"show_matches": ["<all_urls>"],
|
||||||
"default_title": "Send current url to JD2",
|
"default_title": "Send current url to JD2"
|
||||||
"browser_style": true,
|
|
||||||
"default_popup": "popup/popup.html"
|
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
"permissions": [
|
"permissions": [
|
||||||
@ -44,11 +39,13 @@
|
|||||||
"*://*/flashgot?*",
|
"*://*/flashgot?*",
|
||||||
"webRequest",
|
"webRequest",
|
||||||
"webRequestBlocking",
|
"webRequestBlocking",
|
||||||
|
"storage",
|
||||||
"menus"
|
"menus"
|
||||||
],
|
],
|
||||||
|
|
||||||
"options_ui": {
|
"options_ui": {
|
||||||
"page": "options.html",
|
"page": "options/options.html",
|
||||||
"browser_style": true
|
"browser_style": true
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
21
options.html
@ -1,21 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8" />
|
|
||||||
<script src="options.js"></script>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<label for="jd2_api_url">JD2 API URL: </label>
|
|
||||||
<input type="text" id="jd2_api_url" name="jd2_api_url" />
|
|
||||||
<br>
|
|
||||||
<label for="jd2_referer">JD2 Referer: </label>
|
|
||||||
<input type="text" id="jd2_referer" name="jd2_referer" />
|
|
||||||
<br>
|
|
||||||
<label for="jd2_match_url">JD2 API URL: </label>
|
|
||||||
<input type="text" id="jd2_match_url" name="jd2_match_url" />
|
|
||||||
<br>
|
|
||||||
<button id="save">Save</button>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
15
options.js
@ -1,15 +0,0 @@
|
|||||||
document.addEventListener("DOMContentLoaded", () => {
|
|
||||||
document.getElementById("save").onclick = save;
|
|
||||||
|
|
||||||
document.getElementById("jd2_api_url").value = window.localStorage.getItem("jd2_api_url") ?? 'http://localhost:9666/flashgot?';
|
|
||||||
document.getElementById("jd2_referer").value = window.localStorage.getItem("jd2_referer") ?? 'localhost';
|
|
||||||
document.getElementById("jd2_match_url").value = window.localStorage.getItem("jd2_match_url") ?? "*://*/flashgot?*";
|
|
||||||
})
|
|
||||||
|
|
||||||
function save() {
|
|
||||||
window.localStorage.setItem("jd2_api_url", document.getElementById("jd2_api_url").value);
|
|
||||||
window.localStorage.setItem("jd2_referer", document.getElementById("jd2_referer").value);
|
|
||||||
window.localStorage.setItem("jd2_match_url", document.getElementById("jd2_match_url").value);
|
|
||||||
|
|
||||||
browser.runtime.sendMessage({message: "refresh"})
|
|
||||||
}
|
|
19
options/options.html
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="browser-style">
|
||||||
|
<h2>Autostart</h2>
|
||||||
|
<input type="checkbox" id="autostart" checked name="autostart">
|
||||||
|
<label for="autostart">pass directly from JD2 Linkgrabbler to download list</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="options.js"></script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
29
options/options.js
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
function onError(error) {
|
||||||
|
console.log('UrlToJD2_options_error: ' + error);
|
||||||
|
}
|
||||||
|
|
||||||
|
// autostart
|
||||||
|
var chck_autostart = document.getElementById("autostart");
|
||||||
|
|
||||||
|
|
||||||
|
chck_autostart.onchange = function () {
|
||||||
|
if (chck_autostart.checked) {
|
||||||
|
browser.storage.local.set({ autostart: true });
|
||||||
|
} else {
|
||||||
|
browser.storage.local.set({ autostart: false });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Update the options UI or default setting
|
||||||
|
function updateUI(restoredSettings) {
|
||||||
|
if (restoredSettings.autostart == undefined) {
|
||||||
|
chck_autostart.checked = true; //default
|
||||||
|
} else {
|
||||||
|
chck_autostart.checked = restoredSettings.autostart;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// On opening the options page
|
||||||
|
const gettingStoredSettings = browser.storage.local.get();
|
||||||
|
gettingStoredSettings.then(updateUI, onError);
|
@ -1,21 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<style>
|
|
||||||
img {
|
|
||||||
margin: 0px 4px 0px 0px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
|
|
||||||
<div class="panel">
|
|
||||||
<div class="panel-section panel-section-list" id="jd2urlList">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script src="popup.js"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,61 +0,0 @@
|
|||||||
document.addEventListener("DOMContentLoaded", function(event) {
|
|
||||||
|
|
||||||
function onError(error) {
|
|
||||||
console.log(`jd2 popup error: ${error}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const jd2UrlList = document.getElementById('jd2urlList');
|
|
||||||
|
|
||||||
var gettingActiveTab = browser.tabs.query({ active: true, currentWindow: true });
|
|
||||||
gettingActiveTab.then((tabs) => {
|
|
||||||
if (tabs[0]) {
|
|
||||||
var currentTabUrl = tabs[0].url;
|
|
||||||
|
|
||||||
let li = document.createElement("div");
|
|
||||||
li.classList.add("panel-list-item");
|
|
||||||
li.setAttribute("data-href", currentTabUrl);
|
|
||||||
li.setAttribute("jd2", "0");
|
|
||||||
let img = document.createElement("img");
|
|
||||||
img.src = "../icons/jd2linkgrabber-16.png";
|
|
||||||
li.appendChild(img);
|
|
||||||
let txt = document.createElement("div");
|
|
||||||
txt.innerText = 'GrabberLink';
|
|
||||||
li.appendChild(txt);
|
|
||||||
jd2UrlList.appendChild(li);
|
|
||||||
|
|
||||||
let li2 = document.createElement("div");
|
|
||||||
li2.classList.add("panel-list-item");
|
|
||||||
li2.setAttribute("data-href", currentTabUrl);
|
|
||||||
li2.setAttribute("jd2", "1");
|
|
||||||
let img2 = document.createElement("img");
|
|
||||||
img2.src = "../icons/jd2download-16.png";
|
|
||||||
li2.appendChild(img2);
|
|
||||||
let txt2 = document.createElement("div");
|
|
||||||
txt2.innerText = 'Download';
|
|
||||||
li2.appendChild(txt2);
|
|
||||||
jd2UrlList.appendChild(li2);
|
|
||||||
}
|
|
||||||
|
|
||||||
var jd2SelectedAction;
|
|
||||||
document.querySelectorAll(".panel-list-item").forEach( (elem) => {
|
|
||||||
elem.addEventListener('click', (event) => {
|
|
||||||
jd2SelectedAction = elem.getAttribute("jd2");
|
|
||||||
notifyBackgroundPage(event);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
function handleResponse(message) {
|
|
||||||
// console.log(`Message from the background script: ${message.response}`);
|
|
||||||
window.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
function notifyBackgroundPage(e) {
|
|
||||||
var sending = browser.runtime.sendMessage({
|
|
||||||
jd2url: currentTabUrl,
|
|
||||||
jd2action : jd2SelectedAction
|
|
||||||
});
|
|
||||||
sending.then(handleResponse, onError);
|
|
||||||
}
|
|
||||||
|
|
||||||
}, onError);
|
|
||||||
});
|
|
23
readme.md
@ -1,7 +1,8 @@
|
|||||||
# UrlToJD2 - A Firefox extension
|
# UrlToJD2
|
||||||
Push an url from the browser or a link (right-click) to the download manager JDownloader 2.
|
Push the current url navigator or an url in a link (right-click) to the download manager JDownloader 2.
|
||||||
|
|
||||||
This addons use the remote control API (externInterface: Flashgot) from JDownloader2.
|
# Getting Started
|
||||||
|
This addons use the remote control API (externInterface: Flashgot) to send the url to JDownloader2.
|
||||||
|
|
||||||
## Prerequisites
|
## Prerequisites
|
||||||
Install [JDownloader2](http://beta.jdownloader.org/).
|
Install [JDownloader2](http://beta.jdownloader.org/).
|
||||||
@ -9,12 +10,8 @@ In "advanced parameters" search "RemoteAPI".
|
|||||||
The value of "Authorized Website" must look like: ["127.0.0.1", "localhost"]
|
The value of "Authorized Website" must look like: ["127.0.0.1", "localhost"]
|
||||||
JD2 is now ready to listen !
|
JD2 is now ready to listen !
|
||||||
|
|
||||||
## Usage
|
## Option
|
||||||
This extension add two things:
|
"autostart" checked by default: pass directly from JD2 Linkgrabbler to download list.
|
||||||
- A "pageAction" (a clickable icon inside the browser's address bar).
|
|
||||||
- An item in the context menu
|
|
||||||
|
|
||||||
With url or link (or link/url in selection), choose to send to the Linkgrabber or to the Download list.
|
|
||||||
|
|
||||||
## Note
|
## Note
|
||||||
If you want a more complete addons with JD2, try [the official one:](https://my.jdownloader.org/apps/)
|
If you want a more complete addons with JD2, try [the official one:](https://my.jdownloader.org/apps/)
|
||||||
@ -22,10 +19,8 @@ If you want a more complete addons with JD2, try [the official one:](https://my.
|
|||||||
## Code Source
|
## Code Source
|
||||||
[UrlToJD2](https://framagit.org/GTeam/urltojd2)
|
[UrlToJD2](https://framagit.org/GTeam/urltojd2)
|
||||||
|
|
||||||
## Acknowledgments
|
# License
|
||||||
- Extension icon: [primofenax](https://www.deviantart.com/primofenax/art/icon-Minimal-JDownloader-Icon-313625363)
|
|
||||||
- Context icons from JDownloader2
|
|
||||||
|
|
||||||
## Licence
|
|
||||||
This project is licensed under the Mozilla Public License, version 2.0
|
This project is licensed under the Mozilla Public License, version 2.0
|
||||||
|
|
||||||
|
##Acknowledgments
|
||||||
|
icon: [primofenax](https://www.deviantart.com/primofenax/art/icon-Minimal-JDownloader-Icon-313625363)
|
||||||
|
15
versions.md
@ -1,15 +0,0 @@
|
|||||||
# Versions
|
|
||||||
|
|
||||||
## 2.1 (2021-12-30)
|
|
||||||
- fix the (undefined) url send to JD2 when text selection
|
|
||||||
|
|
||||||
## 2.0 (2021-12-20)
|
|
||||||
- Large Refactoring
|
|
||||||
- context menu and pageAction can send to Linkgrabber or Download JD2 list.
|
|
||||||
- remove "options" page
|
|
||||||
|
|
||||||
## 1.1 (2019-08-26)
|
|
||||||
- change (be better) the urlConstruct function for URL encode.
|
|
||||||
|
|
||||||
## 1.0 (2019-08-16)
|
|
||||||
- first release
|
|