Skip to content

Commit c9086de

Browse files
committed
big update
soundcloud, twitter, spotify, youtube local
1 parent eaaca9d commit c9086de

22 files changed

+823
-535
lines changed

empty_script.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export default {
77
description: {
88
en: "",
99
vi: "",
10+
img: "",
1011
},
1112
infoLink: "",
1213

popup/index.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,9 @@ function createScriptButton(script, isFavorite = false) {
289289
const tooltip = document.createElement("span");
290290
tooltip.classList.add("tooltiptext");
291291
tooltip.innerHTML = t(script.description);
292+
if (script.description?.img) {
293+
tooltip.innerHTML += `<img src="${script.description.img}" style="width:95%" />`;
294+
}
292295
button.appendChild(tooltip);
293296

294297
buttonContainer.appendChild(button);

popup/tabs.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,9 @@ const tabs = [
6868
s.getLinkLuanxt,
6969
s.vuiz_getLink,
7070
// s.bookmark_exporter,
71+
s.twitter_downloadButton,
7172
createTitle("--- Music ---", "--- Nhạc ---"),
73+
s.spotify_downloadButton,
7274
s.soundcloud_downloadMusic,
7375
s.nhaccuatui_downloader,
7476
s.zingmp3_downloadMusic,

scripts/content-scripts/run_scripts.js

Lines changed: 8 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -75,48 +75,14 @@ function checkWillRun(script) {
7575
);
7676
}
7777

78-
// Source: https://github.com/fregante/webext-patterns/blob/main/index.ts
7978
function matchPatterns(url, patterns) {
80-
const patternValidationRegex =
81-
/^(https?|wss?|file|ftp|\*):\/\/(\*|\*\.[^*/]+|[^*/]+)\/.*$|^file:\/\/\/.*$|^resource:\/\/(\*|\*\.[^*/]+|[^*/]+)\/.*$|^about:/;
82-
const isFirefox =
83-
typeof navigator === "object" && navigator.userAgent.includes("Firefox/");
84-
const allStarsRegex = isFirefox
85-
? /^(https?|wss?):[/][/][^/]+([/].*)?$/
86-
: /^https?:[/][/][^/]+([/].*)?$/;
87-
const allUrlsRegex = /^(https?|file|ftp):[/]+/;
88-
89-
function getRawPatternRegex(pattern) {
90-
if (!patternValidationRegex.test(pattern))
91-
throw new Error(
92-
pattern +
93-
" is an invalid pattern, it must match " +
94-
String(patternValidationRegex)
95-
);
96-
let [, protocol, host, pathname] = pattern.split(/(^[^:]+:[/][/])([^/]+)?/);
97-
protocol = protocol
98-
.replace("*", isFirefox ? "(https?|wss?)" : "https?")
99-
.replace(/[/]/g, "[/]");
100-
host = (host ?? "")
101-
.replace(/^[*][.]/, "([^/]+.)*")
102-
.replace(/^[*]$/, "[^/]+")
103-
.replace(/[.]/g, "[.]")
104-
.replace(/[*]$/g, "[^.]+");
105-
pathname = pathname
106-
.replace(/[/]/g, "[/]")
107-
.replace(/[.]/g, "[.]")
108-
.replace(/[*]/g, ".*");
109-
return "^" + protocol + host + "(" + pathname + ")?$";
110-
}
111-
112-
function patternToRegex(matchPatterns) {
113-
if (matchPatterns.length === 0) return /$./;
114-
if (matchPatterns.includes("<all_urls>")) return allUrlsRegex;
115-
if (matchPatterns.includes("*://*/*")) return allStarsRegex;
116-
return new RegExp(
117-
matchPatterns.map((x) => getRawPatternRegex(x)).join("|")
118-
);
79+
for (let pattern of patterns) {
80+
// Replace wildcard characters * with regex wildcard .*
81+
const regexRule = pattern.replace(/\*/g, ".*");
82+
// Create a regex pattern from the rule
83+
const reg = new RegExp("^" + regexRule + "$");
84+
// Check if the URL matches the pattern
85+
if (!reg.test(url)) return false;
11986
}
120-
121-
return patternToRegex(patterns).test(url);
87+
return true;
12288
}

scripts/content-scripts/scripts/ufs_global_webpage_context.js

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,43 @@ const UsefulScriptGlobalPageContext = {
223223
},
224224
},
225225
Utils: {
226+
// modified by chatgpt based on: https://gist.github.com/jcouyang/632709f30e12a7879a73e9e132c0d56b
227+
promiseAllStepN(n, list) {
228+
const head = list.slice(0, n);
229+
const tail = list.slice(n);
230+
const resolved = [];
231+
232+
return new Promise((resolve) => {
233+
let processed = 0;
234+
235+
function runNext() {
236+
if (processed === tail.length) {
237+
resolve(Promise.all(resolved));
238+
return;
239+
}
240+
241+
const promise = tail[processed]();
242+
resolved.push(
243+
promise.then((result) => {
244+
runNext();
245+
return result;
246+
})
247+
);
248+
processed++;
249+
}
250+
251+
head.forEach((func) => {
252+
const promise = func();
253+
resolved.push(
254+
promise.then((result) => {
255+
runNext();
256+
return result;
257+
})
258+
);
259+
});
260+
});
261+
},
262+
226263
hook(obj, name, callback) {
227264
const fn = obj[name];
228265
obj[name] = function (...args) {

scripts/fireship_vip.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export default {
1515
// ==UserScript==
1616
// @name Freeship
1717
// @namespace lemons
18-
// @version 1.6
18+
// @version 1.7
1919
// @description Unlock all Fireship PRO courses/lessons.
2020
// @author lemons
2121
// @match https://fireship.io/*
@@ -35,7 +35,7 @@ export default {
3535
}
3636

3737
if (document.querySelector("video-player")?.shadowRoot?.querySelector(".vid")?.innerHTML) return; // return if no video player
38-
const vimeoId = Number(atob(document.querySelector("global-data").vimeo)) - Number(document.querySelector("head").getAttribute("data-build")); // get id for vimeo video
38+
const vimeoId = Number(atob(document.querySelector("global-data").vimeo)); // get id for vimeo video
3939
const youtubeId = atob(document.querySelector("global-data").youtube); // get id for vimeo video
4040

4141
if (youtubeId) { // if there is an id,

scripts/getFavicon.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
export default {
2-
icon: `https://s2.googleusercontent.com/s2/favicons?domain=favicon.io`,
2+
icon: `https://s2.googleusercontent.com/s2/favicons?domain_url=https://favicon.io/`,
33
name: {
44
en: "Download favicon from website",
55
vi: "Tải favicon của trang web",

scripts/helpers/utils.js

Lines changed: 19 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -167,55 +167,16 @@ export function checkBlackWhiteList(script, url) {
167167
return willRun;
168168
}
169169

170-
// Source: https://github.com/fregante/webext-patterns/blob/main/index.ts
171170
function matchPatterns(url, patterns) {
172-
const patternValidationRegex =
173-
/^(https?|wss?|file|ftp|\*):\/\/(\*|\*\.[^*/]+|[^*/]+)\/.*$|^file:\/\/\/.*$|^resource:\/\/(\*|\*\.[^*/]+|[^*/]+)\/.*$|^about:/;
174-
const isFirefox =
175-
typeof navigator === "object" && navigator.userAgent.includes("Firefox/");
176-
const allStarsRegex = isFirefox
177-
? /^(https?|wss?):[/][/][^/]+([/].*)?$/
178-
: /^https?:[/][/][^/]+([/].*)?$/;
179-
const allUrlsRegex = /^(https?|file|ftp):[/]+/;
180-
181-
function getRawPatternRegex(pattern) {
182-
if (!patternValidationRegex.test(pattern))
183-
throw new Error(
184-
pattern +
185-
" is an invalid pattern, it must match " +
186-
String(patternValidationRegex)
187-
);
188-
let [, protocol, host, pathname] = pattern.split(/(^[^:]+:[/][/])([^/]+)?/);
189-
protocol = protocol
190-
.replace("*", isFirefox ? "(https?|wss?)" : "https?")
191-
.replace(/[/]/g, "[/]");
192-
host = (host ?? "")
193-
.replace(/^[*][.]/, "([^/]+.)*")
194-
.replace(/^[*]$/, "[^/]+")
195-
.replace(/[.]/g, "[.]")
196-
.replace(/[*]$/g, "[^.]+");
197-
pathname = pathname
198-
.replace(/[/]/g, "[/]")
199-
.replace(/[.]/g, "[.]")
200-
.replace(/[*]/g, ".*");
201-
return "^" + protocol + host + "(" + pathname + ")?$";
202-
}
203-
204-
function patternToRegex(matchPatterns) {
205-
if (matchPatterns.length === 0) return /$./;
206-
if (matchPatterns.includes("<all_urls>")) return allUrlsRegex;
207-
if (matchPatterns.includes("*://*/*")) return allStarsRegex;
208-
return new RegExp(
209-
matchPatterns.map((x) => getRawPatternRegex(x)).join("|")
210-
);
211-
}
212-
213-
try {
214-
return patternToRegex(patterns).test(url);
215-
} catch (e) {
216-
console.log("ERROR matchPatterns", e);
217-
return false;
171+
for (let pattern of patterns) {
172+
// Replace wildcard characters * with regex wildcard .*
173+
const regexRule = pattern.replace(/\*/g, ".*");
174+
// Create a regex pattern from the rule
175+
const reg = new RegExp("^" + regexRule + "$");
176+
// Check if the URL matches the pattern
177+
if (!reg.test(url)) return false;
218178
}
179+
return true;
219180
}
220181

221182
// https://stackoverflow.com/a/68634884/11898496
@@ -272,11 +233,11 @@ export async function captureVisibleTab(options = {}, willDownload = true) {
272233

273234
// https://gist.github.com/bluzky/b8c205c98ff3318907b30c3e0da4bf3f
274235
export function removeAccents(str) {
275-
var from =
236+
let from =
276237
"àáãảạăằắẳẵặâầấẩẫậèéẻẽẹêềếểễệđùúủũụưừứửữựòóỏõọôồốổỗộơờớởỡợìíỉĩịäëïîöüûñçýỳỹỵỷ",
277238
to =
278239
"aaaaaaaaaaaaaaaaaeeeeeeeeeeeduuuuuuuuuuuoooooooooooooooooiiiiiaeiiouuncyyyyy";
279-
for (var i = 0, l = from.length; i < l; i++) {
240+
for (let i = 0, l = from.length; i < l; i++) {
280241
str = str.replace(RegExp(from[i], "gi"), to[i]);
281242
}
282243

@@ -380,8 +341,8 @@ export const JSONUtils = {
380341

381342
// https://stackoverflow.com/a/4068385/11898496
382343
export function popupCenter({ url, title, w, h }) {
383-
var left = screen.width / 2 - w / 2;
384-
var top = screen.height / 2 - h / 2;
344+
let left = screen.width / 2 - w / 2;
345+
let top = screen.height / 2 - h / 2;
385346
const newWindow = window.open(
386347
url,
387348
title,
@@ -476,19 +437,19 @@ export function waitForKeyElements(
476437
actionFunction /* Required: The code to run when elements are found. It is passed a jNode to the matched element.*/,
477438
bWaitOnce /* Optional: If false, will continue to scan for new elements even after the first match is found.*/
478439
) {
479-
var targetNodes, btargetsFound;
440+
let targetNodes, btargetsFound;
480441
targetNodes = document.querySelectorAll(selectorTxt);
481442

482443
if (targetNodes && targetNodes.length > 0) {
483444
btargetsFound = true;
484445
/*--- Found target node(s). Go through each and act if they are new. */
485446
targetNodes.forEach(function (element) {
486-
var alreadyFound =
447+
let alreadyFound =
487448
element.dataset.found == "alreadyFound" ? "alreadyFound" : false;
488449

489450
if (!alreadyFound) {
490451
//--- Call the payload function.
491-
var cancelFound = actionFunction(element);
452+
let cancelFound = actionFunction(element);
492453
if (cancelFound) btargetsFound = false;
493454
else element.dataset.found = "alreadyFound";
494455
}
@@ -497,10 +458,10 @@ export function waitForKeyElements(
497458
btargetsFound = false;
498459
}
499460

500-
//--- Get the timer-control variable for this selector.
501-
var controlObj = waitForKeyElements.controlObj || {};
502-
var controlKey = selectorTxt.replace(/[^\w]/g, "_");
503-
var timeControl = controlObj[controlKey];
461+
//--- Get the timer-control letiable for this selector.
462+
let controlObj = waitForKeyElements.controlObj || {};
463+
let controlKey = selectorTxt.replace(/[^\w]/g, "_");
464+
let timeControl = controlObj[controlKey];
504465

505466
//--- Now set or clear the timer as appropriate.
506467
if (btargetsFound && bWaitOnce && timeControl) {

scripts/index.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,8 @@ import vuiz_getLink from "./vuiz_getLink.js";
184184
import ggdrive_downloadPdf from "./ggdrive_downloadPdf.js";
185185
import ggdrive_downloadPresentation from "./ggdrive_downloadPresentation.js";
186186
import youtube_localDownloader from "./youtube_localDownloader.js";
187+
import twitter_downloadButton from "./twitter_downloadButton.js";
188+
import spotify_downloadButton from "./spotify_downloadButton.js";
187189

188190
// inject badges
189191
const allScripts = {
@@ -392,6 +394,8 @@ const allScripts = {
392394
BADGES.new
393395
),
394396
youtube_localDownloader: addBadge(youtube_localDownloader, BADGES.new),
397+
twitter_downloadButton: addBadge(twitter_downloadButton, BADGES.new),
398+
spotify_downloadButton: addBadge(spotify_downloadButton, BADGES.new),
395399
};
396400

397401
// alert(Object.keys(allScripts).length);

0 commit comments

Comments
 (0)