Compare commits

..

1 Commits

Author SHA1 Message Date
maximstewart 5b1f47725e renamed feature 2021-02-15 21:34:01 -06:00
14 changed files with 73 additions and 379 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.3.7 # Version: 0.2.1.8
* Added unhandled error handler to display any uncaught errors to the user. * Renamed feature
# Images # Images
@ -16,4 +16,4 @@ https://addons.mozilla.org/en-US/firefox/addon/easy-session-manager/
![5 Deleting a selected session. ](images/pic5.png) ![5 Deleting a selected session. ](images/pic5.png)
![6 Editing a selected session. ](images/pic6.png) ![6 Editing a selected session. ](images/pic6.png)
![7 Downloading a selected session. ](images/pic7.png) ![7 Downloading a selected session. ](images/pic7.png)
![8 Importing a session JSON file. ](images/pic8.png) ![8 Importing a session JSON file. ](images/pic8.png)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

View File

@ -1,13 +1,13 @@
{ {
"manifest_version": 2, "manifest_version": 2,
"name": "Easy Session Manager", "name": " Easy Session Manager",
"version": "0.2.3.7", "version": "0.2.2.8",
"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.",
"browser_specific_settings": { "applications": {
"gecko": { "gecko": {
"id": "sessionManager@itdominator.com", "id": "sessionManager@itdominator.com",
"strict_min_version": "79.0" "strict_min_version": "57.0"
} }
}, },
@ -23,11 +23,7 @@
"unlimitedStorage" "unlimitedStorage"
], ],
"background": { "background": { "page": "pages/import.html" },
"scripts": [
"scripts/listener.js"
]
},
"browser_action": { "browser_action": {
"default_icon": "images/icons/sessionManager.png", "default_icon": "images/icons/sessionManager.png",
@ -35,4 +31,4 @@
"default_popup": "pages/sessionManager.html" "default_popup": "pages/sessionManager.html"
} }
} }

View File

@ -1,25 +0,0 @@
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>[Replaced Tab]</title>
<script defer="defer" src="../scripts/replaced.js">
</script>
<link href="../styles/replaced.css" rel="stylesheet">
<link rel="shortcut icon" href="">
</head>
<body>
<div class=container>
<div class=title>Title</div>
<input class="replacedUrl caption" type="text" value="about:example">
<a class="copyButton">Copy URL</a>
<div class="replacedPageMessage caption">
This page can not be opened by Easy Session Manager due to Firefox API limitations OR being a(n) invalid/malformed URL.
Please try manually opening it by editing and/or copying and pasting the URL below to the URL entry.
</div>
</div>
</body>
</html>

View File

@ -21,11 +21,9 @@
<li><button name="saveModalLauncher" class="button-primary" type="button">Save</button></li> <li><button name="saveModalLauncher" class="button-primary" type="button">Save</button></li>
<li><button name="editModalLauncher" class="button-primary" type="button">Edit</button></li> <li><button name="editModalLauncher" class="button-primary" type="button">Edit</button></li>
<li><button name="deleteModalLauncher" class="button-danger" type="button">Delete</button></li> <li><button name="deleteModalLauncher" class="button-danger" type="button">Delete</button></li>
<br/><br/> <br/><br/><br/>
<li><button name="freeSessionMeory" class="button-info" type="button">Free Memory</button></li>
<br/><br/>
<li><button name="import" class="button-primary" type="button">Import</button></li> <li><button name="import" class="button-primary" type="button">Import</button></li>
<li><button name="downloadModalLauncher" class="button-primary" type="button">Backup</button></li> <li><button name="backupModalLauncher" class="button-primary" type="button">Backup</button></li>
<li><button name="donate" class="button-warning" type="button">Donate</button></li> <li><button name="donate" class="button-warning" type="button">Donate</button></li>
</ul> </ul>
</div> </div>
@ -168,7 +166,6 @@
<div class="modal"> <div class="modal">
<div class="modal-head"> <div class="modal-head">
<p class="modal-title">Selective Open</p> <p class="modal-title">Selective Open</p>
<p class="lm1 warning hidden">"The Session has potentially invalid URLs (highlighted for convenience) which might not load or break loading of the session..."</p>
</div> </div>
<div class="modal-body"> <div class="modal-body">
<div class="row"> <div class="row">
@ -235,9 +232,10 @@
<script src="../scripts/session-manager.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/events.js"></script> <script src="../scripts/events.js"></script>
</body> </body>
</html> </html>

View File

@ -48,16 +48,13 @@ const deleteFromStorage = (elm = null, name = null) => {
} }
const windowMaker = (i, keysLength, keys, json) => { const windowMaker = (i, keysLength, keys, json) => {
for (; i < keysLength; i++) { for (; i < keysLength; i++) {
let store = json[keys[i]];
let urls = [];
let _store = json[keys[i]]; for (let j = 0; j < store.length; j++) {
urls.push(store[j].link);
browser.runtime.sendMessage( }
{ windowApi.create({ url: urls });
action: "new-window",
store: _store
}
)
} }
} }

View File

@ -1,11 +1,12 @@
const message2 = "Name too long or none provided; or, unacceptable character used."; 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
let data = null; let data = null;
const prePprocessor = (obj, enteryName = '', message = "") => { const prePprocessor = (obj, enteryName = '', message = "") => {
let inputTag = document.getElementsByName("toSaveNameImport")[0]; let inputTag = document.getElementsByName("toSaveNameImport")[0];
inputTag.value = enteryName.replace(/ /g, "_").replace(/session_/g, ""); inputTag.value = enteryName.replace(/ /g, "_");
data = obj.target.result; data = obj.target.result;
document.getElementsByName("toSaveImportErrMessage")[0].innerText = message; document.getElementsByName("toSaveImportErrMessage")[0].innerText = message;
} }
@ -17,6 +18,7 @@ const processor = () => {
if (enteryName.length < 0 || enteryName.length > 54 || enteryName.search(regexp) == -1) { if (enteryName.length < 0 || enteryName.length > 54 || enteryName.search(regexp) == -1) {
messageWindow("danger", message2, "modal-gutter"); messageWindow("danger", message2, "modal-gutter");
// prePprocessor(obj, "", message2);
return ; return ;
} }

View File

@ -1,26 +1,11 @@
window.onload = (eve) => { getSavedSessionIDs();
console.log("Loaded...");
getSavedSessionIDs();
}
window.onerror = function(msg, url, line, col, error) {
// Note that col & error are new to the HTML 5 spec and may not be supported in every browser.
let suppressErrorAlert = false;
let extra = !col ? '' : '\ncolumn: ' + col;
extra += !error ? '' : '\nerror: ' + error;
const data = `Error: ${msg} \nurl: ${url} \nline: ${line} ${extra}`
messageWindow("danger", data, "", -1);
// If you return true, then error alerts (like in older versions of Internet Explorer) will be suppressed.
return suppressErrorAlert;
};
document.addEventListener("click", (e) => { document.addEventListener("click", (e) => {
if (e.button == 0) { // Left click if (e.button == 0) { // Left click
const target = e.target; const target = e.target;
const action = target.getAttribute("name"); const action = target.getAttribute("name");
// Set selection first before doing any actions... // Set selection first before doing any actions...
if (target.tagName == "LI" && target.className.includes("sessionLI")) { if (target.tagName == "LI" && target.className.includes("sessionLI")) {
if (selectedItem) { if (selectedItem) {
@ -41,18 +26,13 @@ document.addEventListener("click", (e) => {
const selectedItemName = (selectedItem !== null) ? selectedItem.getAttribute("name") : ""; const selectedItemName = (selectedItem !== null) ? selectedItem.getAttribute("name") : "";
// Modals // Modals
if (/(saveModalLauncher|freeSessionMeory|editModalLauncher|deleteModalLauncher|downloadModalLauncher)/.test(action)) { if (/(saveModalLauncher|editModalLauncher|deleteModalLauncher|backupModalLauncher)/.test(action)) {
if (action == "saveModalLauncher") { if (action == "saveModalLauncher") {
preSaveSession(selectedItem, selectedItemName); preSaveSession(selectedItem, selectedItemName);
showModal("saveModal"); showModal("saveModal");
return ; return ;
} }
if (action == "freeSessionMeory") {
freeSessionMeory();
return ;
}
if (selectedItem) { if (selectedItem) {
if (action == "editModalLauncher") { if (action == "editModalLauncher") {
preEditSession(selectedItem, selectedItemName); preEditSession(selectedItem, selectedItemName);
@ -60,7 +40,7 @@ document.addEventListener("click", (e) => {
} else if (action == "deleteModalLauncher") { } else if (action == "deleteModalLauncher") {
document.getElementsByName("toDeleteName")[0].innerText = selectedItemName; document.getElementsByName("toDeleteName")[0].innerText = selectedItemName;
showModal("deleteModal"); showModal("deleteModal");
} else if (action == "downloadModalLauncher") { } else if (action == "backupModalLauncher") {
preDownloadSession(selectedItemName); preDownloadSession(selectedItemName);
showModal("downloadModal"); showModal("downloadModal");
} }
@ -71,8 +51,6 @@ document.addEventListener("click", (e) => {
return ; return ;
} }
if (!action) return;
if (/(closeSave|closeEdit|closeDownload|closeDelete|closeConfirm|closeLoad)/.test(action)) { if (/(closeSave|closeEdit|closeDownload|closeDelete|closeConfirm|closeLoad)/.test(action)) {
if (action.includes("closeSave")) { if (action.includes("closeSave")) {
hideModal("saveModal"); hideModal("saveModal");
@ -88,7 +66,7 @@ document.addEventListener("click", (e) => {
hideModal("loadModal"); hideModal("loadModal");
} }
} else if (action.includes("deselectAll")) { } else if (action.includes("deselectAll")) {
let container = document.getElementById("editSelectionContainer"); const container = document.getElementById("editSelectionContainer");
deselectAll(container); deselectAll(container);
} }

View File

@ -1,75 +0,0 @@
const onMessageListener = async (request, sender, sendResponse) => {
switch (request.action) {
case "new-window": {
let store = request.store;
let newWindow = await browser.windows.create({focused: false});
for (let i = 0; i < store.length; i++) {
let createOption = (store[i].link !== "about:newtab") ?
{
active: false,
discarded: true,
pinned: false,
url: store[i].link,
windowId: newWindow.id,
index: i + 1
}
: { };
browser.tabs.create(createOption).catch( async (e) => {
createOption.url = returnReplaceURL(
"open_faild",
store[i].title,
store[i].link,
"../images/icons/error.png"
);
await browser.tabs.create(createOption);
});
}
let tabs = await browser.tabs.query({currentWindow: true});
browser.tabs.update(tabs.at(-1).id, { active: true });
browser.tabs.remove( tabs.at(0).id )
}
}
}
const returnReplaceURL = (state, title, url, favIconUrl) => {
let retUrl =
"/pages/replaced.html"
+ "?state="
+ encodeURIComponent(state)
+ "&title="
+ encodeURIComponent(title)
+ "&url="
+ encodeURIComponent(url)
+ "&favIconUrl="
+ encodeURIComponent(favIconUrl)
+ "&theme=dark";
// Reader mode
if (url.startsWith("about:reader?url=")) {
retUrl =
"/pages/replaced.html?state="
+ encodeURIComponent(state)
+ "&title="
+ encodeURIComponent(title)
+ "&url="
+ url.slice(17)
+ "&favIconUrl="
+ encodeURIComponent(favIconUrl)
+ "&openInReaderMode=true&theme=dark"
+ "&theme=dark";
}
return retUrl;
}
browser.runtime.onMessage.addListener(onMessageListener);

View File

@ -1,54 +0,0 @@
const sanitaize = {
encode: str => {
str = str || "";
return str
.replace(/&/g, "&amp;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/"/g, "&quot;")
.replace(/'/g, "&#39;");
},
decode: str => {
str = str || "";
return str
.replace(/&lt;/g, "<")
.replace(/&gt;/g, ">")
.replace(/&quot;/g, '"')
.replace(/&#39;/g, "'")
.replace(/&amp;/g, "&");
}
};
let parameter = returnReplaceParameter(location.href);
document.title = parameter.title;
document.getElementsByClassName("title")[0].innerText = parameter.title;
document.getElementsByClassName("replacedUrl")[0].value = parameter.url;
if (parameter.favIconUrl === "" || parameter.favIconUrl === "undefined") {
parameter.favIconUrl = "../icons/nofavicon.png";
}
document.head.insertAdjacentHTML(
"beforeend",
`<link rel="shortcut icon" href="${sanitaize.encode(parameter.favIconUrl)}">`
);
document.body.dataset.theme = parameter.theme || "light";
const copy = () => {
const url = document.querySelector(".replacedUrl");
url.select();
document.execCommand("Copy");
document.querySelector(".copyButton").innerText = "Copied.";
};
document.querySelector(".copyButton").onclick = copy;
function returnReplaceParameter(url) {
let parameter = {};
let paras = url.split("?")[1].split("&");
for (let p of paras) {
parameter[p.split("=")[0]] = decodeURIComponent(p.split("=")[1]);
}
return parameter;
}

View File

@ -201,7 +201,6 @@ const setKeyData = (_keys, _keysLength) => {
const startLoadSession = () => { const startLoadSession = () => {
sessionData = getSelectionData(container, keys, keysLength); sessionData = getSelectionData(container, keys, keysLength);
keysLength = Object.keys(sessionData).length; keysLength = Object.keys(sessionData).length;
if (keysLength > 0) { if (keysLength > 0) {
loadSession(sessionData, replaceTabs.checked); loadSession(sessionData, replaceTabs.checked);
@ -215,9 +214,8 @@ const startLoadSession = () => {
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;
try { try {
windowApi.getAll().then(windows => { browser.windows.getAll().then(windows => {
windowApi.getCurrent({populate: true}).then(currentWindow => { windowApi.getCurrent({populate: true}).then(currentWindow => {
let wasCurrentTabId = null; let wasCurrentTabId = null;
@ -245,42 +243,20 @@ const loadSession = (json = null, replaceTabs = false) => {
// First load tabs to current window. // First load tabs to current window.
let store = json[keys[0]]; let store = json[keys[0]];
for (let i = 0; i < store.length; i++) { store.forEach(tab => {
let createOption = (store[i].link !== "about:newtab") ? tabsApi.create({ url: tab.link });
{ });
active: false,
discarded: true,
pinned: false,
url: store[i].link,
index: i + 1
}
: { };
tabsApi.create(createOption).catch( async (e) => {
createOption.url = returnReplaceURL(
"open_faild",
store[i].title,
store[i].link,
"../images/icons/error.png"
);
await tabsApi.create(createOption);
});
}
let tab = json[keys[0]].at(-1);
tabsApi.update(tab.id, { active: true });
tabsApi.remove(wasCurrentTabId); tabsApi.remove(wasCurrentTabId);
// If more than one window, load tabs to new windows. // If more than one window, load tabs to new windows.
if (keysLength > 1) { if (keysLength > 1) {
windowMaker(1, keysLength, keys, json); windowMaker(1, keysLength, keys, json)
} }
} else { // Load into new windows... } else { // Load into new windows...
if (keysLength == 0) { if (keysLength == 1) {
windowMaker(0, keysLength, keys, json)
} else if (keysLength == 0) {
messageWindow("error", "Canceled operation; no tabs in session..."); messageWindow("error", "Canceled operation; no tabs in session...");
} else if (keysLength > 0) {
windowMaker(0, keysLength, keys, json);
} }
} }
}); });
@ -292,21 +268,6 @@ const loadSession = (json = null, replaceTabs = false) => {
const freeSessionMeory = () => {
windowApi.getAll({populate: true}).then(windows => {
for (let i = 0; i < windows.length; i++) {
windows[i].tabs.forEach(tab => {
let discarding = tabsApi.discard(tab.id);
discarding.then(onDiscarded, onError);
});
}
});
messageWindow("success", "Freed session memory...");
}
const confirmSessionOverwrite = () => { const confirmSessionOverwrite = () => {
storageApi.set({[holderName]: holderData}); storageApi.set({[holderName]: holderData});
holderElm = document.getElementsByName(holderName)[0]; holderElm = document.getElementsByName(holderName)[0];
@ -315,13 +276,3 @@ const confirmSessionOverwrite = () => {
messageWindow("warning", "Overwrote session..."); messageWindow("warning", "Overwrote session...");
resetArgs("confModal"); resetArgs("confModal");
} }
function onDiscarded() {
console.log(`Discarded`);
}
function onError(error) {
console.log(`Error: ${error}`);
}

View File

@ -1,7 +1,7 @@
let selectedItem = null; let selectedItem = null;
const messageWindow = (type = "warning", message = "No message passed in...", target = "", timeout = 3200) => { const messageWindow = (type = "warning", message = "No message passed in...", target = "") => {
let pTag = document.createElement("P"); let pTag = document.createElement("P");
let text = document.createTextNode(message); let text = document.createTextNode(message);
let gutter = document.getElementById("message-gutter"); let gutter = document.getElementById("message-gutter");
@ -14,11 +14,9 @@ const messageWindow = (type = "warning", message = "No message passed in...", ta
pTag.appendChild(text); pTag.appendChild(text);
gutter.prepend(pTag); gutter.prepend(pTag);
timeout = (timeout === -1) ? 6200 : (timeout > 0) ? timeout : 3200;
setTimeout(function () { setTimeout(function () {
clearChildNodes(gutter); clearChildNodes(gutter);
}, timeout); }, 3200);
} }
@ -39,30 +37,31 @@ const loadContainer = (sessionData, keys, keysLength, divID) => {
/* 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");
let ulTemplate = document.querySelector('#ulTemplate'); let ulTemplate = document.querySelector('#ulTemplate');
let liTemplate = document.querySelector('#liTemplate'); let liTemplate = document.querySelector('#liTemplate');
for (let i = 0; i < keysLength; i++) { for (let i = 0; i < keysLength; i++) {
let ulClone = document.importNode(ulTemplate.content, true); let ulClone = document.importNode(ulTemplate.content, true);
let ulTag = ulClone.querySelector('.collection'); let ulTag = ulClone.querySelector('.collection');
let h2Tag = ulClone.querySelector('.ulHeader'); let h2Tag = ulClone.querySelector('.ulHeader');
let h2Txt = document.createTextNode("Window: " + (i + 1)); let h2Txt = document.createTextNode("Window: " + (i + 1));
let selAll = ulClone.querySelector('.selAll'); let selAll = ulClone.querySelector('.selAll');
let titleAll = ulClone.querySelector('.titleAll'); let titleAll = ulClone.querySelector('.titleAll');
let ulLblTag = ulClone.querySelector('.selAllLbl'); let ulLblTag = ulClone.querySelector('.selAllLbl');
let ulLblTag2 = ulClone.querySelector('.titleAllLbl'); let ulLblTag2 = ulClone.querySelector('.titleAllLbl');
let store = json[keys[i]]; let store = json[keys[i]];
let j = 0; let j = 0;
container.id = "editSelectionContainer"; container.id = "editSelectionContainer";
selAll.id = "selectAllWin" + i; selAll.id = "selectAllWin" + i;
titleAll.id = "selectAllTitle" + i; titleAll.id = "selectAllTitle" + i;
ulLblTag.htmlFor = "selectAllWin" + i; ulLblTag.htmlFor = "selectAllWin" + i;
ulLblTag2.htmlFor = "selectAllTitle" + i; ulLblTag2.htmlFor = "selectAllTitle" + i;
selAll.addEventListener("click", function (eve) { selAll.addEventListener("click", function (eve) {
toggleSelect(eve.target, "Win" + i); toggleSelect(eve.target, "Win" + i);
@ -73,12 +72,12 @@ const generateSelectionWindow = (json = "", keys = null, keysLength = 0) => {
toggleTitles(eve.target, "Win" + i); toggleTitles(eve.target, "Win" + i);
}); });
h2Tag.prepend(h2Txt); h2Tag.prepend(h2Txt);
store.forEach(tab => { store.forEach(tab => {
let liClone = document.importNode(liTemplate.content, true); let liClone = document.importNode(liTemplate.content, true);
let liTag = liClone.querySelector("li");
let inptTag = liClone.querySelector("input"); let inptTag = liClone.querySelector("input");
// link lbl // link lbl
let lblTag = liClone.querySelector(".linkLbl"); let lblTag = liClone.querySelector(".linkLbl");
let labelTxt = document.createTextNode(tab.link); let labelTxt = document.createTextNode(tab.link);
@ -156,10 +155,12 @@ const getSessionData = (windows) => {
for (let i = 0; i < windows.length; i++) { for (let i = 0; i < windows.length; i++) {
let links = []; let links = [];
for (var ii = 0; ii < windows[i].tabs.length; ii++) { for (var ii = 0; ii < windows[i].tabs.length; ii++) {
links.push( if (!windows[i].tabs[ii].url.includes("about:")) {
{"link" : windows[i].tabs[ii].url.trim(), links.push(
"title" : windows[i].tabs[ii].title.trim()} {"link" : windows[i].tabs[ii].url.trim(),
); "title" : windows[i].tabs[ii].title.trim()}
);
}
} }
sessionData["WindowID:" + windows[i].id] = links; sessionData["WindowID:" + windows[i].id] = links;
} }
@ -253,7 +254,7 @@ function sleep(ms) {
const importSession = () => { const importSession = () => {
browser.tabs.create({ browser.tabs.create({
url: browser.runtime.getURL("../pages/import.html"), url: browser.extension.getURL("../pages/import.html"),
active: true active: true
}); });
} }

View File

@ -1,62 +0,0 @@
body {
font-family: "Segoe UI", "San Francisco", "Ubuntu", "Fira Sans", "Roboto", "Arial", "Helvetica",
sans-serif;
font-size: 15px;
font-weight: 400;
color: var(--main-text);
background-color: var(--main-bg);
line-height: 1.5;
display: flex;
flex-direction: row;
--main-text: #e6e6e6;
--sub-text: #aaaaaa;
--line: #373737;
--button: #929292;
--highlight: #36b2b2;
--main-bg:#181818;
}
.container {
display: flex;
flex-direction: column;
width: 100%;
padding-left: 20px;
}
.title {
font-size: 22px;
font-weight: 600;
color: var(--sub-text);
line-height: 2;
}
.caption {
font-size: 13px;
font-weight: 400;
color: var(--sub-text);
}
hr {
width: 100%;
background-color: var(--line);
height: 1px;
border: none;
margin-top: 20px;
margin-bottom: 20px;
}
input {
border: none;
background-color: var(--main-bg);
}
a {
font-size: 13px;
color: var(--highlight);
cursor: pointer;
width: max-content;
}
a:hover {
text-decoration: underline;
}

View File

@ -11,7 +11,6 @@ ul, li {
li { li {
user-select: none; /* Non-prefixed version, currently user-select: none; /* Non-prefixed version, currently
supported by Chrome, Opera and Firefox */ supported by Chrome, Opera and Firefox */
margin-bottom: 0.5em;
} }
@ -35,9 +34,9 @@ li {
#master-gutter { #master-gutter {
position: absolute; position: absolute;
width: 100%; width: 100%;
bottom: 0.2em; bottom: 0.5em;
max-height: 4em; max-height: 6em;
overflow: hidden; overflow: auto;
} }
#savedSessions { #savedSessions {
@ -94,8 +93,8 @@ li {
} }
.scroller { .scroller {
scrollbar-color: #00000084 #ffffff64; scrollbar-color: #00000084 #ffffff64;
scrollbar-width: thin; scrollbar-width: thin;
} }
@ -118,15 +117,3 @@ li {
background-color: rgba(41, 95, 115, 0.65); background-color: rgba(41, 95, 115, 0.65);
cursor: pointer; cursor: pointer;
} }
.error-bg { background-color: rgba(44, 44, 44, 0.34); }
.warning-bg { background-color: rgba(44, 44, 44, 0.34); }
.success-bg { background-color: rgba(44, 44, 44, 0.34); }
.error { color: rgb(170, 18, 18); }
.warning { color: rgb(255, 168, 0); }
.success { color: rgb(136, 204, 39); }
.hidden { display: none; }