• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

NikkelM / Random-YouTube-Video / 9236279078

25 May 2024 02:54PM UTC coverage: 93.948%. Remained the same
9236279078

push

github

web-flow
Made the Advanced settings a slideout menu (#290)

290 of 337 branches covered (86.05%)

1366 of 1454 relevant lines covered (93.95%)

510.04 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.36
/src/utils.js
1
// Global utilities
1✔
2

1✔
3
/* c8 ignore start - The console reroutings cannot be tested correctly */
1✔
4
// ---------- Console rerouting ----------
1✔
5
const oldLog = console.log;
1✔
6
console.log = function () {
1✔
7
        // The last argument to console.log is a boolean that determines if the message should be shown in production
1✔
8
        const showInProduction = arguments[arguments.length - 1] === true;
1✔
9
        // If we are either in development or the message should be shown in production, log the message
1✔
10
        if (process.env.NODE_ENV !== 'production' || showInProduction) {
1✔
11
                if (arguments[0] !== "[random-youtube-video]:") {
1✔
12
                        Array.prototype.unshift.call(arguments, '[random-youtube-video]:');
1✔
13
                }
1✔
14
                // Remove the showInProduction flag from the arguments so it doesn't get logged
1✔
15
                if (typeof arguments[arguments.length - 1] === 'boolean') {
1✔
16
                        Array.prototype.pop.call(arguments);
1✔
17
                }
1✔
18
                oldLog.apply(this, arguments);
1✔
19
        }
1✔
20
}
1✔
21
/* c8 ignore stop */
1✔
22

1✔
23
// ---------- Utility functions ----------
1✔
24

1✔
25
// ----- URLs -----
1✔
26
export function isVideoUrl(url) {
1✔
27
        if (!url) return false;
12✔
28

9✔
29
        const urlParts = url.split("/");
9✔
30
        if (!urlParts[2]?.includes("youtube")) return false;
12✔
31
        return urlParts[3]?.startsWith("watch?v=") ?? false;
12✔
32
}
12✔
33

1✔
34
export function getPageTypeFromURL(url) {
1✔
35
        if (!url) return null;
637✔
36

633✔
37
        const urlParts = url.split("/");
633✔
38
        if (!urlParts[2]?.includes("youtube")) return null;
637✔
39
        if (urlParts[3]?.startsWith("watch?v=")) {
637✔
40
                return "video";
624✔
41
        } else if (urlParts[3]?.startsWith("shorts")) {
637✔
42
                return "short";
1✔
43
        } else {
5✔
44
                return "channel";
4✔
45
        }
4✔
46
}
637✔
47

1✔
48
// ----- DOM -----
1✔
49
export function setDOMTextWithDelay(textElement, newText, delayMS, predicate = () => { return true; }) {
1✔
50
        // Sets the innerHTML of a (text) DOM element after a delay, if a predicate evaluates to true
3✔
51
        // If no predicate is passed, this function will always set the text after the delay
3✔
52
        delay(delayMS).then(() => {
3✔
53
                if (predicate()) {
3✔
54
                        textElement.innerText = newText;
2✔
55
                }
2✔
56
        });
3✔
57
}
3✔
58

1✔
59
export function updateSmallButtonStyleForText(textElement, isTextStyle) {
1✔
60
        textElement.style.fontSize = isTextStyle ? "12px" : "";
463!
61
        textElement.style.position = isTextStyle ? "absolute" : "";
463!
62
        textElement.style.top = isTextStyle ? "50%" : "";
463!
63
        textElement.style.left = isTextStyle ? "50%" : "";
463!
64
        textElement.style.transform = isTextStyle ? "translate(-50%, -50%)" : "";
463!
65
        textElement.style.alignItems = isTextStyle ? "center" : "";
463!
66
        textElement.style.justifyContent = isTextStyle ? "center" : "";
463!
67
        textElement.style.display = isTextStyle ? "flex" : "";
463!
68

463✔
69
        if (isTextStyle) {
463✔
70
                textElement.classList.remove("material-symbols-outlined");
463✔
71
        } else {
463!
72
                textElement.classList.add("material-symbols-outlined");
×
73
        }
×
74
}
463✔
75

1✔
76
// ----- Small utilities -----
1✔
77
// Waits for a certain amount of milliseconds
1✔
78
export function delay(ms) {
1✔
79
        return new Promise(resolve => setTimeout(resolve, ms));
4✔
80
}
4✔
81

1✔
82
// Determines if an object is empty
1✔
83
export function isEmpty(obj) {
1✔
84
        return Object.keys(obj).length === 0;
1,693✔
85
}
1,693✔
86

1✔
87
// Gets the length of an object
1✔
88
export function getLength(obj) {
1✔
89
        return Object.keys(obj ?? {}).length;
1,365✔
90
}
1,365✔
91

1✔
92
// Adds a number of hours to a date
1✔
93
export function addHours(date, hours) {
1✔
94
        return new Date(date.getTime() + hours * 3600000);
1,401✔
95
}
1,401✔
96

1✔
97
// ----- Errors -----
1✔
98
export class RandomYoutubeVideoError extends Error {
1✔
99
        constructor({ code = "RYV-0", message = "", solveHint = "", showTrace = true, canSavePlaylist = false }) {
1✔
100
                super(message);
282✔
101
                this.code = code;
282✔
102
                this.message = message;
282✔
103
                this.solveHint = solveHint;
282✔
104
                this.showTrace = showTrace;
282✔
105
                // This should be set to true for 'non-fatal' errors, where the playlist is in a safe state
282✔
106
                this.canSavePlaylist = canSavePlaylist;
282✔
107
                this.name = "RandomYoutubeVideoError";
282✔
108
        }
282✔
109
}
1✔
110

1✔
111
export class YoutubeAPIError extends RandomYoutubeVideoError {
1✔
112
        constructor(code = "YAPI-0", message = "", reason = "", solveHint = "", showTrace = true, canSavePlaylist = false) {
1✔
113
                super(message);
9✔
114
                this.code = code;
9✔
115
                this.message = message;
9✔
116
                this.reason = reason;
9✔
117
                this.solveHint = solveHint;
9✔
118
                this.showTrace = showTrace;
9✔
119
                this.canSavePlaylist = canSavePlaylist;
9✔
120
                this.name = "YoutubeAPIError";
9✔
121
        }
9✔
122
}
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc