Removedc SweetAlerts; using Mustard UI

This commit is contained in:
Maxim Stewart 2020-02-29 15:30:44 -06:00
parent c27108e3df
commit 8591ce8905
20 changed files with 748 additions and 3382 deletions

View File

@ -4,8 +4,8 @@ Easy Session Manager allows you to manage your Firefox session by backing up or
# Download # Download
https://addons.mozilla.org/en-US/firefox/addon/easy-session-manager/ https://addons.mozilla.org/en-US/firefox/addon/easy-session-manager/
# Version: 0.2.2.0 # Version: 0.2.1.4
Refactored code and added tab count per session. Removed SweetAlerts and am using Mustard UI
# Images # Images
![1 Default interface with no sessions. ](images/pic1.png) ![1 Default interface with no sessions. ](images/pic1.png)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

After

Width:  |  Height:  |  Size: 32 KiB

View File

@ -1,7 +1,7 @@
{ {
"manifest_version": 2, "manifest_version": 2,
"name": " Easy Session Manager", "name": " Easy Session Manager",
"version": "0.2.2.2", "version": "0.2.2.4",
"description": "Easy Session Manager allows you to manage your Firefox session by backing up or loading your saved sessions.", "description": "Easy Session Manager allows you to manage your Firefox session by backing up or loading your saved sessions.",
"applications": { "applications": {

View File

@ -4,32 +4,74 @@
<meta charset="utf-8"> <meta charset="utf-8">
<title>Easy Session Manager Import</title> <title>Easy Session Manager Import</title>
<link rel="shortcut icon" href="../images/icons/import.png"> <link rel="shortcut icon" href="../images/icons/import.png">
<!-- Mustard UI CSS -->
<link rel="stylesheet" href="../styles/libs/mustard-ui.min.css"/>
<!-- App CSS -->
<link rel="stylesheet" href="../styles/styles.css"/> <link rel="stylesheet" href="../styles/styles.css"/>
<style media="screen">
<style media="screen">
body, html { body, html {
width: 100%; width: 100%;
height: 100%; height: 100%;
padding: 0em; padding: 0em;
margin: 0em; margin: 0em;
} }
</style> </style>
</head> </head>
<body> <body>
<div class="container" name="import"> <div class="download-container" name="import">
<h1 id="lableTag">Select File</h1> <h1 id="lableTag">Select File</h1>
<input id="inputId" type="file" enctype='multipart/form-data' multiple accept="application/json"/> <input id="inputId" type="file" enctype='multipart/form-data' accept="application/json"/>
<!-- FIXME: Broke multiple imports because of event setup. Need a way to popup modals and process through linearly -->
<!-- <input id="inputId" type="file" enctype='multipart/form-data' multiple accept="application/json"/> -->
</div> </div>
<span id="allertMessage"> <!-- Message Gutter -->
<div id="master-gutter" class="row">
<div class="col">
<div id="message-gutter" class="scroller">
</div>
</div>
</div>
<!-- Save Modal -->
<div id="saveModal" class="modal-mask" style="display:none; opacity: 0%;">
<div class="modal">
<div class="modal-head">
<p class="modal-title">Save - Allowed: a-z, A-Z, 0-9, -, _</p>
</div>
<div class="modal-body">
<div class="row">
<div class="col">
<p>What is this session's name?</p>
<p name="toSaveImportErrMessage"></p>
<input type="text" name="toSaveNameImport" value="">
</div>
</div>
</div>
<div class="row">
<div class="col">
<div id="modal-gutter" class="scroller">
</div>
</div>
</div>
<div class="modal-footer align-right">
<button class="button-secondary" name="closeImportSave">Close</button>
<button class="button-primary" name="importSave">OK</button>
</div>
</div>
</div>
</span>
<script src="../scripts/libs//sweetalert2.all.js"></script>
<script src="../scripts/background.js"></script> <script src="../scripts/background.js"></script>
</body> </body>
</html> </html>

View File

@ -2,29 +2,208 @@
<html> <html>
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Mustard UI CSS -->
<link rel="stylesheet" href="../styles/libs/mustard-ui.min.css"/>
<!-- App CSS -->
<link rel="stylesheet" href="../styles/styles.css"/> <link rel="stylesheet" href="../styles/styles.css"/>
</head> </head>
<body> <body>
<a id="downloadAnchorElem" href="#"></a>
<center> <!-- Main Content -->
<input type="image" name="save" src="../images/icons/save.png" title="Save..." alt="Save" /> <div class="row">
<input type="image" name="edit" src="../images/icons/edit.png" title="Edit..." alt="Edit" /> <div class="col col-sm-3">
<input type="image" name="delete" src="../images/icons/delete.png" title="Delete..." alt="Delete" /> <ul id="master-left-column" class="menu">
<br/>
<br/><br/> <li><button name="saveModalLauncher" class="button-primary" type="button">Save</button></li>
<input id="replaceTabs" name="replaceTabs" type="checkbox" /> <li><button name="editModalLauncher" class="button-primary" type="button">Edit</button></li>
<label for="replaceTabs">Replace Current Tabs</label> <li><button name="deleteModalLauncher" class="button-danger" type="button">Delete</button></li>
<input id="selectiveOpen" name="selectiveOpen" type="checkbox" checked /> <br/><br/><br/><br/>
<label for="selectiveOpen">Selective Open</label> <li><button name="import" class="button-primary" type="button">Import</button></li>
<li><button name="downloadModalLauncher" class="button-primary" type="button">Download</button></li>
<div id="savedSessions"> <li><button name="donate" class="button-warning" type="button">Donate</button></li>
</ul>
</div> </div>
<input type="image" name="import" src="../images/icons/import.png" title="Import..." alt="Import" /> <div id="master-right-column" class="col col-sm-9">
<input type="image" name="donate" src="../images/icons/donate.png" title="Donate..." alt="Donate" /> <div class="row">
<input type="image" name="download" id="dl" src="../images/icons/download.png" title="Download..." alt="Download" /> <div class="col">
</center> <label for="replaceTabs">Replace Current Tabs
<input id="replaceTabs" name="replaceTabs" type="checkbox" />
</label>
<label for="selectiveOpen">Selective Open
<input id="selectiveOpen" name="selectiveOpen" type="checkbox" checked />
</label>
</div>
</div>
<hr/>
<div class="row">
<div class="col">
<div id="savedSessions" class="scroller">
</div>
</div>
</div>
</div>
</div>
<!-- Message Gutter -->
<div id="master-gutter" class="row">
<div class="col">
<div id="message-gutter" class="scroller">
</div>
</div>
</div>
<!-- Modals -->
<!-- Save Modal -->
<div id="saveModal" class="modal-mask" style="display:none; opacity: 0%;">
<div class="modal">
<div class="modal-head">
<p class="modal-title">Save - Allowed: a-z, A-Z, 0-9, -, _</p>
</div>
<div class="modal-body">
<div class="row">
<div class="col">
<div id="saveList" class="row scroller">
</div>
<p name="toSaveErrMessage"></p>
<input type="text" name="toSaveName" value="">
</div>
</div>
</div>
<div class="modal-footer align-right">
<button class="button-secondary" name="closeSave">Close</button>
<button class="button-primary" name="save">OK</button>
</div>
</div>
</div>
<!-- Edit Modal -->
<div id="editModal" class="modal-mask" style="display:none; opacity: 0%;">
<div class="modal">
<div class="modal-head">
<p class="modal-title">Edit - Allowed: a-z, A-Z, 0-9, -, _</p>
</div>
<div class="modal-body">
<div class="row">
<div class="col">
<div id="editList" class="row scroller">
</div>
<p name="toEditErrMessage"></p>
<label>Create New Session<input type="checkbox" name="toEditNewSession"></label>
<input type="text" name="toEditName" value="">
</div>
</div>
</div>
<div class="modal-footer align-right">
<button class="button-secondary" name="closeEdit">Close</button>
<button class="button-primary" name="edit">OK</button>
</div>
</div>
</div>
<!-- Delete Modal -->
<div id="deleteModal" class="modal-mask" style="display:none; opacity: 0%;">
<div class="modal">
<div class="modal-head">
<p class="modal-title">Are you sure?</p>
</div>
<div class="modal-body">
<div class="row">
<div class="col">
<p>
Do you wish to delete session:&nbsp;&nbsp;<label name="toDeleteName"></label>&nbsp;&nbsp;?
</p>
</div>
</div>
</div>
<div class="modal-footer align-right">
<button class="button-primary" name="closeDelete">Cancel</button>
<button class="button-danger" name="delete">Delete</button>
</div>
</div>
</div>
<!-- Download Modal -->
<div id="downloadModal" class="modal-mask" style="display:none; opacity: 0%;">
<div class="modal">
<div class="modal-head">
<p class="modal-title">Download - Allowed: a-z, A-Z, 0-9, -, _</p>
</div>
<div class="modal-body">
<div class="row">
<div class="col">
<!-- Field Grouping -->
<div class="form-control-group">
<div class="form-control">
<label>Append Date
<input type="checkbox" name="appendDateDlModal">
</label>
</div>
<div class="form-control grow-2x">
<input type="text" name="toDownloadName" value="">
</div>
</div>
</div>
</div>
</div>
<div class="modal-footer align-right">
<button class="button-secondary" name="closeDownload">Cancel</button>
<button class="button-primary" name="download">OK</button>
</div>
</div>
</div>
<!-- Load Modal -->
<div id="loadModal" class="modal-mask" style="display:none; opacity: 0%;">
<div class="modal">
<div class="modal-head">
<p class="modal-title">Selective Open</p>
</div>
<div class="modal-body">
<div class="row">
<div class="col">
<div id="loadList" class="row scroller">
</div>
</div>
</div>
</div>
<div class="modal-footer align-right">
<button class="button-secondary" name="closeLoad">Close</button>
<button class="button-primary" name="load">OK</button>
</div>
</div>
</div>
<!-- Confirm Overwrite Modal -->
<div id="confModal" class="modal-mask" style="display:none; opacity: 0%;">
<div class="modal">
<div class="modal-head">
<p class="modal-title">Replace?</p>
</div>
<div class="modal-body">
<div class="row">
<div class="col">
<p>Found a session with that name! Do you want to replace it?</p>
</div>
</div>
</div>
<div class="modal-footer align-right">
<button class="button-primary" name="closeConfirm">Cancel</button>
<button class="button-danger" name="confirm">OK</button>
</div>
</div>
</div>
<!-- Templates -->
<template id="ulTemplate"> <template id="ulTemplate">
<h2 class="ulHeader"></h2> <h2 class="ulHeader"></h2>
<input type="checkbox" id="selectAll" checked="true" /> <input type="checkbox" id="selectAll" checked="true" />
@ -41,11 +220,11 @@
</template> </template>
<a id="downloadAnchorElem" href="#"></a>
<script src="../scripts/libs//sweetalert2.all.js"></script>
<script src="../scripts/utils.js"></script> <script src="../scripts/utils.js"></script>
<script src="../scripts/actions.js"></script> <script src="../scripts/actions.js"></script>
<script src="../scripts/session-manager.js"></script> <script src="../scripts/session-manager.js"></script>
<script src="../scripts/events.js"></script> <script src="../scripts/events.js"></script>
</body> </body>
</html> </html>

View File

@ -1,10 +1,3 @@
const messageWindow = (type = "warning", message = "No message passed in...") => {
Swal.fire({
text: message,
icon: type
});
}
const getSavedSessionIDs = () => { const getSavedSessionIDs = () => {
storageApi.get(null).then((results) => { storageApi.get(null).then((results) => {
const sessions = Object.keys(results); const sessions = Object.keys(results);
@ -23,22 +16,10 @@ const saveToStorage = (name, data, action = "undefined", willReplace = false, sv
try { try {
const json = JSON.parse(results[name]); // If a session is found const json = JSON.parse(results[name]); // If a session is found
if (!willReplace) { if (!willReplace) {
Swal.fire({ holderName = name;
title: "Replace?", holderData = data;
text: "Found a session with that name! Do you want to replace it?", holderSize = size;
icon: "warning", showModal("confModal");
showCloseButton: true,
showCancelButton: true,
}).then((willReplace) => {
if (willReplace.value) {
storageApi.set({[name]: data});
sveElm.innerText = size + " | " + name;
sveElm.name = name;
messageWindow("warning", "Overwrote session...");
} else {
messageWindow("warning", "Canceled " + action + "...");
}
});
} else { } else {
sveElm.innerText = size + " | " + name; sveElm.innerText = size + " | " + name;
sveElm.name = name; sveElm.name = name;
@ -59,23 +40,11 @@ const saveToStorage = (name, data, action = "undefined", willReplace = false, sv
} }
const deleteFromStorage = (elm = null, name = null) => { const deleteFromStorage = (elm = null, name = null) => {
Swal.fire({
title: "Are you sure?",
text: "Do you wish to delete session:\n" + name + "?",
icon: "warning",
showCloseButton: true,
showCancelButton: true,
}).then((willDelete) => {
if (willDelete.value) {
storageApi.remove(name).then(() => { storageApi.remove(name).then(() => {
elm.parentElement.removeChild(elm); elm.parentElement.removeChild(elm);
}); });
selectedItem = null; // reset selectedItem selectedItem = null; // reset selectedItem
messageWindow("success", "Deleted session successfully..."); messageWindow("success", "Deleted session successfully...");
} else {
messageWindow("warning", "Canceled deletion...");
}
});
} }
const windowMaker = (i, keysLength, keys, json) => { const windowMaker = (i, keysLength, keys, json) => {

View File

@ -1,40 +1,24 @@
const message1 = "What is this session's name? Allowed: a-z, A-Z, -, _"; const message2 = "Name too long or none provided; or, unacceptable character used.";
const regexp = /^[a-zA-Z0-9-_]+$/; // Alphanumeric, dash, underscore const regexp = /^[a-zA-Z0-9-_]+$/; // Alphanumeric, dash, underscore
const messageWindow = (type = "warning", message = "No message passed in...") => { let data = null;
Swal.fire({
text: message,
icon: type const prePprocessor = (obj, enteryName = '', message = "") => {
}); let inputTag = document.getElementsByName("toSaveNameImport")[0];
inputTag.value = enteryName.replace(/ /g, "_");
data = obj.target.result;
document.getElementsByName("toSaveImportErrMessage")[0].innerText = message;
} }
const processor = (obj, enteryName = '', message = message1) => { const processor = () => {
let data = obj.target.result; let inputTag = document.getElementsByName("toSaveNameImport")[0];
let inputTag = document.createElement("INPUT"); enteryName = inputTag.value.replace(/ /g, "_");
let pTag = document.createElement("P");
let brTag = document.createElement("BR");
let textTag = document.createTextNode(message);
inputTag.value = enteryName; inputTag.value = enteryName;
pTag.append(textTag);
pTag.appendChild(brTag);
pTag.appendChild(inputTag);
Swal.fire({
title: "Session Name:",
text: message,
html: pTag,
showCloseButton: true,
showCancelButton: true,
customClass: 'swal-modal',
}).then((result) => {
if (result.value) {
enteryName = inputTag.value.replace(/ /g, "_");
if (enteryName.length < 0 || enteryName.length > 54 || enteryName.search(regexp) == -1) { if (enteryName.length < 0 || enteryName.length > 54 || enteryName.search(regexp) == -1) {
processor(obj, "", "Allowed: a-z, A-Z, 0-9, -, _ Please try again...\nName too long or none provided; or, unacceptable character used."); messageWindow("danger", message2, "modal-gutter");
// prePprocessor(obj, "", message2);
return ; return ;
} }
@ -43,37 +27,106 @@ const processor = (obj, enteryName = '', message = message1) => {
JSON.parse(data); // See if parsing fails and throw error JSON.parse(data); // See if parsing fails and throw error
browser.storage.local.set({[enteryName]: data}); browser.storage.local.set({[enteryName]: data});
messageWindow("success", "Imported file successfully."); messageWindow("success", "Imported file successfully.");
hideModal();
} catch (e) { } catch (e) {
hideModal();
messageWindow("error", "Failed to import data. Not a JSON parsable file."); messageWindow("error", "Failed to import data. Not a JSON parsable file.");
return ; return ;
} }
} else {
messageWindow("warning", "Canceled import.");
}
});
}; };
// Get files after being chosen
document.getElementById("inputId").onchange = (e) => { document.getElementById("inputId").onchange = (e) => {
let size = e.target.files.length; let size = e.target.files.length;
let fileArry = e.target.files; let fileArry = e.target.files;
// Loop throughg the chosen files...
for (var i = 0; i < size; i++) { for (var i = 0; i < size; i++) {
let reader = new FileReader(); let reader = new FileReader();
let name = fileArry[i].name; let name = fileArry[i].name;
name = name.split(".")[0]; name = name.split(".")[0];
reader.onloadend = (obj) => { processor(obj, name); }; reader.onloadend = (obj) => {
prePprocessor(obj, name);
showModal();
};
if (fileArry[i].type == "application/json") if (fileArry[i].type == "application/json")
reader.readAsText(fileArry[i], {encoding: "string"}); reader.readAsText(fileArry[i], {encoding: "string"});
} }
}; };
// Bring up file selector...
document.addEventListener("click", (e) => { document.addEventListener("click", (e) => {
if (e.button == 0) { // Left click if (e.button == 0) { // Left click
if (e.target.className == "container") { const target = e.target;
const action = target.name;
if (target.className.includes("container")) {
document.getElementById("inputId").click(); document.getElementById("inputId").click();
} else if (action == "importSave") {
processor();
} }
} }
}); });
const showModal = async (modalID = "saveModal") => {
tween(1600, "up", modalID); // in miliseconds
}
const hideModal = (modalID = "saveModal") => {
tween(1600, "down", modalID); // in miliseconds
}
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
const tween = async (miliseconds, direction, modalID) => {
const elm = document.getElementById(modalID);
const timeStep = 1000 / miliseconds;
const steps = timeStep * 100
if (direction == "up") { // Go up
elm.style.display = "";
// elm.style.opacity = "1";
for (var i = 1; i <= steps; i++) {
await sleep(timeStep);
elm.style.opacity = i/steps;
}
} else { // Go down
for (var i = steps; i > 1; i--) {
await sleep(timeStep);
elm.style.opacity = i/steps;
}
// elm.style.opacity = "0";
elm.style.display = "none";
}
}
const messageWindow = (type = "warning", message = "No message passed in...", target = "") => {
let pTag = document.createElement("P");
let text = document.createTextNode(message);
let gutter = document.getElementById("message-gutter");
if (target !== "") {
gutter = document.getElementById(target);
}
pTag.className = "alert alert-" + type;
pTag.appendChild(text);
gutter.prepend(pTag);
setTimeout(function () {
clearChildNodes(gutter);
}, 3200);
}
const clearChildNodes = (parent) => {
while (parent.firstChild) {
parent.removeChild(parent.firstChild);
}
}

View File

@ -22,21 +22,69 @@ document.addEventListener("click", (e) => {
} }
} }
// If elm has certain action do it.
const selectedItemName = (selectedItem !== null) ? selectedItem.getAttribute("name") : ""; const selectedItemName = (selectedItem !== null) ? selectedItem.getAttribute("name") : "";
if (/(download|delete|edit)/.test(action)) {
// Modals
if (/(saveModalLauncher|editModalLauncher|deleteModalLauncher|downloadModalLauncher)/.test(action)) {
if (action == "saveModalLauncher") {
preSaveSession(selectedItem, selectedItemName);
showModal("saveModal");
return ;
}
if (selectedItem) { if (selectedItem) {
if (action == "download") if (action == "editModalLauncher") {
downloadSession(selectedItemName); preEditSession(selectedItem, selectedItemName);
else if (action == "delete") showModal("editModal");
deleteFromStorage(selectedItem, selectedItemName); } else if (action == "deleteModalLauncher") {
else if (action == "edit") document.getElementsByName("toDeleteName")[0].innerText = selectedItemName;
editSession(selectedItem, selectedItemName); showModal("deleteModal");
} else if (action == "downloadModalLauncher") {
preDownloadSession(selectedItemName);
showModal("downloadModal");
}
} else { } else {
messageWindow("warning", "Select a session first..."); messageWindow("warning", "Select a session first...");
} }
return ;
}
if (/(closeSave|closeEdit|closeDownload|closeDelete|closeConfirm|closeLoad)/.test(action)) {
if (action.includes("closeSave")) {
hideModal("saveModal");
} else if (action.includes("closeEdit")) {
hideModal("editModal");
} else if (action.includes("closeDownload")) {
hideModal("downloadModal");
} else if (action.includes("closeDelete")) {
hideModal("deleteModal");
} else if (action.includes("closeConfirm")) {
hideModal("confModal");
} else if (action.includes("closeLoad")) {
hideModal("loadModal");
}
}
// Actions
if (/(download|delete|edit|load)/.test(action)) {
if (selectedItem) {
if (action == "download") {
downloadSession(selectedItemName);
} else if (action == "delete") {
deleteFromStorage(selectedItem, selectedItemName);
hideModal("deleteModal");
} else if (action == "edit") {
editSession(selectedItem, selectedItemName);
} else if (action == "load") {
startLoadSession();
}
}
} else if (action == "save") { } else if (action == "save") {
saveSession(selectedItem, selectedItemName); saveSession(selectedItem, selectedItemName);
} else if (action == "confirm") {
confirmSessionOverwrite();
} else if (action == "import") { } else if (action == "import") {
importSession(); importSession();
} else if (action == "donate") { } else if (action == "donate") {
@ -45,6 +93,7 @@ document.addEventListener("click", (e) => {
} }
}); });
document.addEventListener("dblclick", (e) => { document.addEventListener("dblclick", (e) => {
if (e.button == 0) { // Left click if (e.button == 0) { // Left click
if (e.target.tagName == "LI" && e.target.className.includes("sessionLI")) { if (e.target.tagName == "LI" && e.target.className.includes("sessionLI")) {

View File

@ -0,0 +1 @@
...

File diff suppressed because one or more lines are too long

View File

@ -1,14 +1,40 @@
const message1 = "[ Session Name ] Allowed: a-z, A-Z, 0-9, -, _"; const message2 = "Name too long or none provided; or, unacceptable character used.";
const message2 = "Allowed: a-z, A-Z, 0-9, -, _ Please try again...\nName too long or none provided; or, unacceptable character used.";
const storageApi = browser.storage.local; const storageApi = browser.storage.local;
const tabsApi = browser.tabs; const tabsApi = browser.tabs;
const windowApi = browser.windows; const windowApi = browser.windows;
const regexp = /^[a-zA-Z0-9-_]+$/; // Alphanumeric, dash, underscore const regexp = /^[a-zA-Z0-9-_]+$/; // Alphanumeric, dash, underscore
const saveSession = (elm = null, name = null, message = message1) => {
let inputTag = document.createElement("INPUT");
let willReplace = false; let willReplace = false;
// Used as holder for vertain actions and 'cross' modal routs
let container = null;
let holderElm = null;
let holderName = null;
let holderData = null;
let holderSize = null;
let keys = null;
let keysLength = null;
const resetArgs = (modal = "") => {
if (modal !== "") {
hideModal(modal);
}
willReplace = false;
container = null;
holderElm = null;
holderName = null;
holderData = null;
holderSize = null;
keys = null;
keysLength = null;
}
const preSaveSession = (elm = null, name = null, message = "") => {
let inputTag = document.getElementsByName("toSaveName")[0];
inputTag.value = new Date().toLocaleString().split(',')[0].replace(/\//g, '-'); inputTag.value = new Date().toLocaleString().split(',')[0].replace(/\//g, '-');
if (elm !== null) { if (elm !== null) {
@ -16,98 +42,68 @@ const saveSession = (elm = null, name = null, message = message1) => {
willReplace = true; willReplace = true;
} }
document.getElementsByName("toSaveErrMessage")[0].innerText = message;
windowApi.getAll({ populate: true, windowTypes: ["normal"] }).then((windows) => { windowApi.getAll({ populate: true, windowTypes: ["normal"] }).then((windows) => {
let sessionData = getSessionData(windows); let sessionData = getSessionData(windows);
let keys = Object.keys(sessionData); keys = Object.keys(sessionData);
let keysLength = Object.keys(sessionData).length; keysLength = Object.keys(sessionData).length;
let container = generateSelectionWindow(sessionData, keys, keysLength); container = loadContainer(sessionData, keys, keysLength, "saveList");
let textTag = document.createTextNode(message); });
let brTag = document.createElement("BR"); }
container.prepend(inputTag); const saveSession = (elm = null, name = null) => {
container.prepend(brTag); let inputTag = document.getElementsByName("toSaveName")[0];
container.prepend(message);
Swal.fire({
html: container,
showCloseButton: true,
showCancelButton: true,
customClass: 'swal-modal',
}).then((result) => {
if (result.value) {
let enteryName = inputTag.value.replace(/ /g, "_"); let enteryName = inputTag.value.replace(/ /g, "_");
if (enteryName.length < 0 || enteryName.length > 54 || enteryName.search(regexp) == -1) { if (enteryName.length < 0 || enteryName.length > 54 || enteryName.search(regexp) == -1) {
saveSession(elm, name, message2); preSaveSession(elm, name, message2);
return ; return ;
} }
console.log("Saving session..."); console.log("Saving session...");
sessionData = getSelectionData(container, keys, keysLength); sessionData = getSelectionData(container, keys, keysLength);
saveToStorage(enteryName, JSON.stringify(sessionData), "save", willReplace, elm); saveToStorage(enteryName, JSON.stringify(sessionData), "save", willReplace, elm);
} else { resetArgs("saveModal");
messageWindow("warning", "Canceled save...");
}
});
});
} }
const editSession = (elm = null, name = null, message = message1) => {
const preEditSession = (elm = null, name = null, message = "") => {
let inputTag = document.getElementsByName("toEditName")[0];
let id = name; let id = name;
let inputTag = document.createElement("INPUT"); inputTag.value = name;
let newSessionTag = document.createElement("INPUT");
let labelTag = document.createElement("LABEL");
let brTag = document.createElement("BR");
let brTag2 = document.createElement("BR");
inputTag.value = id; document.getElementsByName("toEditErrMessage")[0].innerText = message;
newSessionTag.type = "checkbox";
newSessionTag.id = "newSession";
newSessionTag.checked = false;
labelTag.innerText = "Create New Session";
labelTag.htmlFor = "newSession";
storageApi.get(id).then((results) => { storageApi.get(id).then((results) => {
let json = null;
let keys = null;
let keysLength = null;
try { try {
json = JSON.parse(results[id]); let sessionData = JSON.parse(results[id]);
keys = Object.keys(json); keys = Object.keys(sessionData);
keysLength = Object.keys(json).length; keysLength = Object.keys(sessionData).length;
container = loadContainer(sessionData, keys, keysLength, "editList");
} catch (e) { } catch (e) {
messageWindow("warning", "Canceled edit; couldn't load any data..."); messageWindow("warning", "Canceled edit; couldn't load any data...");
resetArgs();
return ; return ;
} }
});
}
let container = generateSelectionWindow(json, keys, keysLength); const editSession = (elm = null, name = null, message = "") => {
let textTag = document.createTextNode(message); let newSessionTag = document.getElementsByName("toEditNewSession")[0];
let inputTag = document.getElementsByName("toEditName")[0];
container.prepend(labelTag);
container.prepend(newSessionTag);
container.prepend(brTag);
container.prepend(inputTag);
container.prepend(brTag2);
container.prepend(message);
console.log("Editing session...");
Swal.fire({
html: container,
showCloseButton: true,
showCancelButton: true,
customClass: 'swal-modal',
}).then((result) => {
if (result.value) {
let newName = inputTag.value.replace(/ /g, "_"); let newName = inputTag.value.replace(/ /g, "_");
const id = name;
if (newName.length < 0 || newName.length > 54 || newName.search(regexp) == -1) { if (newName.length < 0 || newName.length > 54 || newName.search(regexp) == -1) {
editSession(elm, name, message2); preEditSession(elm, name, message2);
return ; return ;
} }
json = getSelectionData(container, keys, keysLength); let sessionData = getSelectionData(container, keys, keysLength);
const strData = JSON.stringify(json); const strData = JSON.stringify(sessionData);
if (newSessionTag.checked) { // If creating new session if (newSessionTag.checked) { // If creating new session
newName = checkSessionListForDuplicate(newName); newName = checkSessionListForDuplicate(newName);
saveToStorage(newName, strData, "save", false, elm); saveToStorage(newName, strData, "save", false, elm);
@ -133,86 +129,63 @@ const editSession = (elm = null, name = null, message = message1) => {
}); });
} }
} }
} else {
messageWindow("warning", "Canceled edit..."); resetArgs("editModal");
} }
});
});
const preDownloadSession = (session = null) => {
let fileName = session;
document.getElementsByName("toDownloadName")[0].value = fileName;
} }
const downloadSession = (session = null) => { const downloadSession = (session = null) => {
let pTag = document.createElement("P"); let chkBoxTag = document.getElementsByName("appendDateDlModal")[0];
let inputTag = document.createElement("INPUT"); let fileName = document.getElementsByName("toDownloadName")[0].value;
let chkBoxTag = document.createElement("INPUT"); const id = session;
let lblTag = document.createElement("LABEL");
let brTag = document.createElement("BR");
let aTagElm = document.getElementById('downloadAnchorElem');
let text = document.createTextNode("Append Date?");
let fileName = "session:" + session + ".json";
let id = session;
chkBoxTag.type = "checkbox";
inputTag.value = fileName;
chkBoxTag.id = "chkbx";
lblTag.htmlFor = "chkbx";
lblTag.append(text);
pTag.append(lblTag);
pTag.append(chkBoxTag);
pTag.append(brTag);
pTag.append(inputTag);
Swal.fire({
text: "Download Session?",
html: pTag,
showCloseButton: true,
showCancelButton: true,
customClass: 'swal-modal',
}).then((willDl) => {
if (willDl.value) {
if (chkBoxTag.checked) { if (chkBoxTag.checked) {
fileName = "session:" + id + ":" + new Date().toLocaleString() fileName = "session_" + fileName + "_" + new Date().toLocaleString()
.split(',')[0] .split(',')[0]
.replace(/\//g, "-") + ".json"; .replace(/\//g, "-") + ".json";
} else {
fileName = "session_" + fileName + ".json";
} }
storageApi.get(id).then((results) => { storageApi.get(id).then((results) => {
let json = JSON.parse(results[id]); let sessionData = JSON.parse(results[id]);
let dataStr = "data:text/json;charset=utf-8," + encodeURIComponent(JSON.stringify(json)); let dataStr = "data:text/json;charset=utf-8," + encodeURIComponent(JSON.stringify(sessionData));
console.log("Downloading: " + id); console.log("Downloading: " + id);
doUrlAction(dataStr, fileName, true); doUrlAction(dataStr, fileName, true);
}); });
} }
});
}
const preLoadSession = (id) => { const preLoadSession = (id) => {
storageApi.get(id).then(results => { storageApi.get(id).then(results => {
try { try {
let json = JSON.parse(results[id]); let sessionData = JSON.parse(results[id]);
let keys = Object.keys(json); let keys = Object.keys(sessionData);
let keysLength = Object.keys(json).length; let keysLength = Object.keys(sessionData).length;
let replaceTabs = document.getElementsByName("replaceTabs")[0]; let replaceTabs = document.getElementsByName("replaceTabs")[0];
let selectiveOpen = document.getElementsByName("selectiveOpen")[0]; let selectiveOpen = document.getElementsByName("selectiveOpen")[0];
if (!selectiveOpen.checked) { if (!selectiveOpen.checked) {
loadSession(json, replaceTabs.checked); asyn = () => {
} else { loadSession(sessionData, replaceTabs.checked);
let container = generateSelectionWindow(json, keys, keysLength);
Swal.fire({
text: "Selective Open",
html: container,
showCloseButton: true,
showCancelButton: true,
}).then((willOpen) => {
if (willOpen.value) {
json = getSelectionData(container, keys, keysLength);
keysLength = Object.keys(json).length;
if (keysLength > 0) {
loadSession(json, replaceTabs.checked);
} else {
messageWindow("warning", "Canceled Operation: No tabs were selected...");
} }
asyn();
} else {
container = loadContainer(sessionData, keys, keysLength, "loadList");
asyn = () => {
setKeyData(keys, keysLength);
} }
}); asyn();
showModal("loadModal");
} }
} catch (e) { } catch (e) {
messageWindow("error", "Couldn't load session:\n" + e); messageWindow("error", "Couldn't load session:\n" + e);
@ -220,6 +193,24 @@ const preLoadSession = (id) => {
}); });
} }
// Supports startLoadSession getting the proper data...
const setKeyData = (_keys, _keysLength) => {
keys = _keys;
keysLength = _keysLength;
}
const startLoadSession = () => {
sessionData = getSelectionData(container, keys, keysLength);
keysLength = Object.keys(sessionData).length;
if (keysLength > 0) {
loadSession(sessionData, replaceTabs.checked);
hideModal("loadModal");
} else {
hideModal("loadModal");
messageWindow("warning", "Canceled Operation: No tabs were selected...");
}
}
const loadSession = (json = null, replaceTabs = false) => { const loadSession = (json = null, replaceTabs = false) => {
let keys = Object.keys(json); let keys = Object.keys(json);
let keysLength = Object.keys(json).length; let keysLength = Object.keys(json).length;
@ -274,3 +265,14 @@ const loadSession = (json = null, replaceTabs = false) => {
messageWindow("error", "Couldn't load session:\n" + e); messageWindow("error", "Couldn't load session:\n" + e);
} }
} }
const confirmSessionOverwrite = () => {
storageApi.set({[holderName]: holderData});
holderElm = document.getElementsByName(holderName)[0];
holderElm.innerText = holderSize + " | " + holderName;
holderElm.name = holderName;
messageWindow("warning", "Overwrote session...");
resetArgs("confModal");
}

View File

@ -1,7 +1,43 @@
let selectedItem = null; let selectedItem = null;
const messageWindow = (type = "warning", message = "No message passed in...", target = "") => {
let pTag = document.createElement("P");
let text = document.createTextNode(message);
let gutter = document.getElementById("message-gutter");
if (target !== "") {
gutter = document.getElementById(target);
}
pTag.className = "alert alert-" + type;
pTag.appendChild(text);
gutter.prepend(pTag);
setTimeout(function () {
clearChildNodes(gutter);
}, 3200);
}
// UI supporters // UI supporters
const loadContainer = (sessionData, keys, keysLength, divID) => {
let container = generateSelectionWindow(sessionData, keys, keysLength);
let divElm = document.getElementById(divID);
container.className = "col";
clearChildNodes(divElm);
divElm.append(container);
return container;
}
/* Selection Process */ /* Selection Process */
const generateSelectionWindow = (json = "", keys = null, keysLength = 0) => { const generateSelectionWindow = (json = "", keys = null, keysLength = 0) => {
let container = document.createElement("DIV"); let container = document.createElement("DIV");
@ -139,6 +175,45 @@ const doUrlAction = (url = "https://www.paypal.me/ITDominator", fileName = "", i
aTagElm.click(); aTagElm.click();
} }
const showModal = async (modalID = "saveModal") => {
tween(1600, "up", modalID); // in miliseconds
}
const hideModal = (modalID = "saveModal") => {
tween(1600, "down", modalID); // in miliseconds
}
const tween = async (miliseconds, direction, modalID) => {
const elm = document.getElementById(modalID);
const timeStep = 1000 / miliseconds;
const steps = timeStep * 100
if (direction == "up") { // Go up
elm.style.display = "";
// elm.style.opacity = "1";
for (var i = 1; i <= steps; i++) {
await sleep(timeStep);
elm.style.opacity = i/steps;
}
} else { // Go down
for (var i = steps; i > 1; i--) {
await sleep(timeStep);
elm.style.opacity = i/steps;
}
// elm.style.opacity = "0";
elm.style.display = "none";
}
}
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
const importSession = () => { const importSession = () => {
browser.tabs.create({ browser.tabs.create({
url: browser.extension.getURL("../pages/import.html"), url: browser.extension.getURL("../pages/import.html"),
@ -152,3 +227,9 @@ const toggleSelect = (source, name) => {
checkboxes[i].checked = source.checked; checkboxes[i].checked = source.checked;
} }
} }
const clearChildNodes = (parent) => {
while (parent.firstChild) {
parent.removeChild(parent.firstChild);
}
}

7
src/styles/libs/mustard-ui.min.css vendored Normal file

File diff suppressed because one or more lines are too long

View File

@ -20,8 +20,34 @@ input[type=image]:hover {
color: #ffffff; color: #ffffff;
} }
/* IDs */
#master-row {
padding: 2em;
}
#master-left-column {
background-color:grey
}
#master-right-column {
padding: 0em 4em;
}
#master-left-column > li > button {
width: 14em;
}
#master-gutter {
position: absolute;
width: 100%;
bottom: 0.5em;
max-height: 6em;
overflow: auto;
}
#savedSessions { #savedSessions {
width: 85%; width: 100%;
height: 450px; height: 450px;
min-height: 450px; min-height: 450px;
max-height: 450px; max-height: 450px;
@ -30,6 +56,13 @@ input[type=image]:hover {
margin: 0em auto; margin: 0em auto;
} }
#editList,
#saveList,
#loadList {
max-height: 250px;
overflow: auto;
}
#editSelectionContainer { #editSelectionContainer {
width: 100%; width: 100%;
height: auto; height: auto;
@ -61,11 +94,17 @@ input[type=image]:hover {
color: rgba(255, 255, 255, 0.5); color: rgba(255, 255, 255, 0.5);
} }
/* Overide sweetalert modal size */
.swal-modal{ /* Classes */
top: 2em !important;
width: 650px !important; .modal {
height: auto !important; width: 650px;
height: auto;
}
.scroller {
scrollbar-color: #00000084 #ffffff64;
scrollbar-width: thin;
} }
.collection { .collection {
@ -73,7 +112,7 @@ input[type=image]:hover {
padding-bottom: 1em; padding-bottom: 1em;
} }
.container { .download-container {
width: 100%; width: 100%;
height: 100%; height: 100%;
background-image: url('../images/icons/import.png'); background-image: url('../images/icons/import.png');
@ -84,7 +123,7 @@ input[type=image]:hover {
transition: 0.6s; transition: 0.6s;
} }
.container:hover { .download-container:hover {
transition: 0.6s; transition: 0.6s;
background-color: rgba(41, 95, 115, 0.65); background-color: rgba(41, 95, 115, 0.65);
cursor: pointer; cursor: pointer;