aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/utils.ts
diff options
context:
space:
mode:
authorAjay Ramachandran <[email protected]>2021-07-31 01:02:41 -0400
committerAjay Ramachandran <[email protected]>2021-07-31 01:02:41 -0400
commit9c54d141e9e8d50c5c9f67d537e132ef1159ee24 (patch)
tree7ba4a628f828905b1e7adfea666e17ba9d7caf94 /src/utils.ts
parent8c9424b6c5177b678bfb3cd65f03e4fa79d3d266 (diff)
parent2a3a04a504029be0f544d4c4523c4dd6e37ad2b1 (diff)
downloadSponsorBlock-9c54d141e9e8d50c5c9f67d537e132ef1159ee24.tar.gz
SponsorBlock-9c54d141e9e8d50c5c9f67d537e132ef1159ee24.zip
Merge branch 'master' of https://github.com/ajayyy/SponsorBlock into improvements
Diffstat (limited to 'src/utils.ts')
-rw-r--r--src/utils.ts52
1 files changed, 45 insertions, 7 deletions
diff --git a/src/utils.ts b/src/utils.ts
index af685a18..6d7e6e89 100644
--- a/src/utils.ts
+++ b/src/utils.ts
@@ -168,6 +168,31 @@ export default class Utils {
}
/**
+ * Starts a spinning animation and returns a function to be called when it should be stopped
+ * The callback will be called when the animation is finished
+ * It waits until a full rotation is complete
+ */
+ applyLoadingAnimation(element: HTMLElement, time: number, callback?: () => void): () => void {
+ element.style.animation = `rotate ${time}s 0s infinite`;
+
+ return () => {
+ // Make the animation finite
+ element.style.animation = `rotate ${time}s`;
+
+ // When the animation is over, hide the button
+ const animationEndListener = () => {
+ if (callback) callback();
+
+ element.style.animation = "none";
+
+ element.removeEventListener("animationend", animationEndListener);
+ };
+
+ element.addEventListener("animationend", animationEndListener);
+ }
+ }
+
+ /**
* Merges any overlapping timestamp ranges into single segments and returns them as a new array.
*/
getMergedTimestamps(timestamps: number[][]): [number, number][] {
@@ -253,7 +278,8 @@ export default class Utils {
getLocalizedMessage(text: string): string | false {
const valNewH = text.replace(/__MSG_(\w+)__/g, function(match, v1) {
- return v1 ? chrome.i18n.getMessage(v1).replace("\n", "<br/>") : "";
+ return v1 ? chrome.i18n.getMessage(v1).replace(/</g, "&#60;")
+ .replace(/"/g, "&quot;").replace(/\n/g, "<br/>") : "";
});
if(valNewH != text) {
@@ -398,6 +424,19 @@ export default class Utils {
return referenceNode;
}
+ objectToURI<T>(url: string, data: T, includeQuestionMark: boolean): string {
+ let counter = 0;
+ for (const key in data) {
+ const seperator = (url.includes("?") || counter > 0) ? "&" : (includeQuestionMark ? "?" : "");
+ const value = (typeof(data[key]) === "string") ? data[key] as unknown as string : JSON.stringify(data[key]);
+ url += seperator + encodeURIComponent(key) + "=" + encodeURIComponent(value);
+
+ counter++;
+ }
+
+ return url;
+ }
+
getFormattedTime(seconds: number, precise?: boolean): string {
const hours = Math.floor(seconds / 60 / 60);
const minutes = Math.floor(seconds / 60) % 60;
@@ -462,14 +501,13 @@ export default class Utils {
async getHash(value: string, times = 5000): Promise<string> {
if (times <= 0) return "";
- let hashBuffer = new TextEncoder().encode(value).buffer;
-
+ let hashHex = value;
for (let i = 0; i < times; i++) {
- hashBuffer = await crypto.subtle.digest('SHA-256', hashBuffer);
- }
+ const hashBuffer = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(hashHex).buffer);
- const hashArray = Array.from(new Uint8Array(hashBuffer));
- const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
+ const hashArray = Array.from(new Uint8Array(hashBuffer));
+ hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');
+ }
return hashHex;
}