From 5fbe9cd19b214fce0b8d338dcde12b8043ceaa6c Mon Sep 17 00:00:00 2001 From: Samuel Gillispie II Date: Thu, 12 Mar 2026 21:23:03 -0400 Subject: [PATCH 1/2] Modify createCommand to use single quotes --- panel/panel.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/panel/panel.js b/panel/panel.js index 77631bf..b4586ee 100644 --- a/panel/panel.js +++ b/panel/panel.js @@ -143,11 +143,11 @@ clear.addEventListener('click', async function() { async function createCommand(json, key_string) { const metadata = JSON.parse(json); - const headerString = Object.entries(metadata.headers).map(([key, value]) => `-H "${key}: ${value.replace(/"/g, "'")}"`).join(' '); + const headerString = Object.entries(metadata.headers).map(([key, value]) => `-H '${key}: ${value.replace(/'/g, '"')}'`).join(' '); const executableName = await SettingsManager.getExecutableName(); const useShaka = await SettingsManager.getUseShakaPackager(); const additionalArgs = await SettingsManager.getAdditionalArguments(); - return `${executableName} "${metadata.url}" ${headerString} ${key_string} ${useShaka ? "--use-shaka-packager " : ""}${additionalArgs}`; + return `${executableName} '${metadata.url}' ${headerString} ${key_string} ${useShaka ? "--use-shaka-packager " : ""}${additionalArgs}`; } async function appendLog(result) { From 6b9a9d0efe1f98058488fe7c6c91e3247256ef14 Mon Sep 17 00:00:00 2001 From: Samuel Gillispie II Date: Fri, 13 Mar 2026 15:27:38 -0400 Subject: [PATCH 2/2] Implement single/double quotes as a choice in the panel --- lib/util.js | 9 +++++++++ panel/panel.html | 2 ++ panel/panel.js | 19 +++++++++++++++++-- 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/lib/util.js b/lib/util.js index 2b802f2..f18f291 100644 --- a/lib/util.js +++ b/lib/util.js @@ -287,6 +287,15 @@ export class SettingsManager { return result["use_shaka"] ?? true; } + static async saveUseSingleQuotes(use_single_quotes) { + await AsyncSyncStorage.setStorage({ use_single_quotes, }); + } + + static async getUseSingleQuotes() { + const result = await AsyncSyncStorage.getStorage(["use_single_quotes"]); + return result["use_single_quotes"] ?? false; + } + static async saveExecutableName(exe_name) { await AsyncSyncStorage.setStorage({ exe_name: exe_name }); } diff --git a/panel/panel.html b/panel/panel.html index 06cf6fe..d2b5247 100644 --- a/panel/panel.html +++ b/panel/panel.html @@ -57,6 +57,8 @@ Command options
+ +

diff --git a/panel/panel.js b/panel/panel.js index b4586ee..b4cfb52 100644 --- a/panel/panel.js +++ b/panel/panel.js @@ -123,6 +123,11 @@ use_shaka.addEventListener('change', async function (){ await SettingsManager.saveUseShakaPackager(use_shaka.checked); }); +const use_single_quotes = document.getElementById('use-single-quotes'); +use_single_quotes.addEventListener('change', async function (){ + await SettingsManager.saveUseSingleQuotes(use_single_quotes.checked); +}); + const downloader_name = document.getElementById('downloader-name'); downloader_name.addEventListener('input', async function (){ await SettingsManager.saveExecutableName(downloader_name.value); @@ -143,11 +148,20 @@ clear.addEventListener('click', async function() { async function createCommand(json, key_string) { const metadata = JSON.parse(json); - const headerString = Object.entries(metadata.headers).map(([key, value]) => `-H '${key}: ${value.replace(/'/g, '"')}'`).join(' '); + + // Based on user choice in the panel, we have the quote character that should be used in the command, + // and a safe quote character that can be used to format the header values. + const useSingleQuotes = await SettingsManager.getUseSingleQuotes(); + const quoteChar = useSingleQuotes ? "'" : '"'; + const safeQuoteChar = useSingleQuotes ? '"' : "'"; + const headerString = Object.entries(metadata.headers).map( + ([key, value]) => `-H ${quoteChar}${key}: ${value.replaceAll(quoteChar, safeQuoteChar)}${quoteChar}` + ).join(' '); + const executableName = await SettingsManager.getExecutableName(); const useShaka = await SettingsManager.getUseShakaPackager(); const additionalArgs = await SettingsManager.getAdditionalArguments(); - return `${executableName} '${metadata.url}' ${headerString} ${key_string} ${useShaka ? "--use-shaka-packager " : ""}${additionalArgs}`; + return `${executableName} ${quoteChar}${metadata.url}${quoteChar} ${headerString} ${key_string} ${useShaka ? "--use-shaka-packager " : ""}${additionalArgs}`; } async function appendLog(result) { @@ -249,6 +263,7 @@ document.addEventListener('DOMContentLoaded', async function () { enabled.checked = await SettingsManager.getEnabled(); SettingsManager.setDarkMode(await SettingsManager.getDarkMode()); use_shaka.checked = await SettingsManager.getUseShakaPackager(); + use_single_quotes.checked = await SettingsManager.getUseSingleQuotes(); downloader_name.value = await SettingsManager.getExecutableName(); downloader_args.value = await SettingsManager.getAdditionalArguments(); SettingsManager.setSelectedDeviceType(await SettingsManager.getSelectedDeviceType());