Files
speeder/extension/shared/import-export.js
T

200 lines
5.1 KiB
JavaScript

(function(root, factory) {
var exports = factory();
if (typeof module === "object" && module.exports) {
module.exports = exports;
}
root.SpeederShared = root.SpeederShared || {};
root.SpeederShared.importExport = exports;
})(typeof globalThis !== "undefined" ? globalThis : this, function() {
var rawSettingsKeys = new Set([
"audioBoolean",
"controllerButtons",
"controllerLocation",
"controllerMarginBottom",
"controllerMarginLeft",
"controllerMarginRight",
"controllerMarginTop",
"controllerOpacity",
"enableSubtitleNudge",
"enabled",
"forceLastSavedSpeed",
"hideWithControls",
"hideWithControlsTimer",
"hideWithYouTubeControls",
"keyBindings",
"lastSpeed",
"popupControllerButtons",
"popupMatchHoverControls",
"rememberSpeed",
"shortcutTargetMode",
"showAmbientLoopControls",
"showPopupControlBar",
"siteRules",
"siteRulesFormat",
"siteRulesMeta",
"speed",
"startHidden",
"subtitleNudgeAmount",
"subtitleNudgeEnabledByDefault",
"subtitleNudgeInterval",
"resetSpeed",
"speedStep",
"fastSpeed",
"rewindTime",
"advanceTime",
"resetKeyCode",
"slowerKeyCode",
"fasterKeyCode",
"rewindKeyCode",
"advanceKeyCode",
"fastKeyCode",
"displayKeyCode",
"blacklist"
]);
function isRecognizedRawSettingsObject(backup) {
if (!backup || typeof backup !== "object" || Array.isArray(backup)) {
return false;
}
return Object.keys(backup).some(function(key) {
return rawSettingsKeys.has(key);
});
}
/**
* Only user-authored local settings belong in backups. Disposable caches,
* per-source speed history, and future runtime data stay installation-local.
*/
function filterLocalSettingsForExport(local) {
if (!local || typeof local !== "object" || Array.isArray(local)) {
return {};
}
var out = {};
if (
local.customButtonIcons &&
typeof local.customButtonIcons === "object" &&
!Array.isArray(local.customButtonIcons)
) {
out.customButtonIcons = local.customButtonIcons;
}
return out;
}
function generateBackupFilename(now) {
var date = now instanceof Date ? now : new Date(now || Date.now());
var year = date.getFullYear();
var month = String(date.getMonth() + 1).padStart(2, "0");
var day = String(date.getDate()).padStart(2, "0");
var hours = String(date.getHours()).padStart(2, "0");
var minutes = String(date.getMinutes()).padStart(2, "0");
var seconds = String(date.getSeconds()).padStart(2, "0");
return (
"speeder-backup_" +
year +
"-" +
month +
"-" +
day +
"_" +
hours +
"." +
minutes +
"." +
seconds +
".json"
);
}
function buildBackupPayload(settings, localSettings, now) {
return {
version: "1.1",
exportDate: new Date(now || Date.now()).toISOString(),
settings: settings,
localSettings: localSettings || {}
};
}
function extractImportSettings(backup) {
var settingsToImport = null;
var isWrappedBackup = false;
var backupIsObject =
backup && typeof backup === "object" && !Array.isArray(backup);
var hasWrappedSettings =
backupIsObject &&
Object.prototype.hasOwnProperty.call(backup, "settings");
if (hasWrappedSettings) {
if (
!backup.settings ||
typeof backup.settings !== "object" ||
Array.isArray(backup.settings)
) {
return null;
}
settingsToImport = backup.settings;
isWrappedBackup = true;
} else if (backupIsObject && isRecognizedRawSettingsObject(backup)) {
settingsToImport = backup;
}
if (!settingsToImport) return null;
if (
isWrappedBackup &&
Object.prototype.hasOwnProperty.call(backup, "localSettings") &&
(
!backup.localSettings ||
typeof backup.localSettings !== "object" ||
Array.isArray(backup.localSettings)
)
) {
return null;
}
if (
isWrappedBackup &&
backup.localSettings &&
Object.prototype.hasOwnProperty.call(
backup.localSettings,
"customButtonIcons"
) &&
(
!backup.localSettings.customButtonIcons ||
typeof backup.localSettings.customButtonIcons !== "object" ||
Array.isArray(backup.localSettings.customButtonIcons)
)
) {
return null;
}
return {
isWrappedBackup: isWrappedBackup,
settings: settingsToImport,
localSettings:
backup &&
backup.localSettings &&
typeof backup.localSettings === "object" &&
!Array.isArray(backup.localSettings)
? backup.localSettings
: null
};
}
function parseImportText(text) {
return extractImportSettings(JSON.parse(text));
}
return {
buildBackupPayload: buildBackupPayload,
extractImportSettings: extractImportSettings,
filterLocalSettingsForExport: filterLocalSettingsForExport,
generateBackupFilename: generateBackupFilename,
isRecognizedRawSettingsObject: isRecognizedRawSettingsObject,
parseImportText: parseImportText
};
});