Changed URL loading from window.create to browser.tabs.create

This commit is contained in:
itdominator 2024-05-09 19:00:52 -05:00
parent 6ea60a0723
commit 41e70b1c3e
12 changed files with 304 additions and 37 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.3 # Version: 0.2.3.4
* Fixed tab open logic to exclude urls not valid for api opening (due to security). * Changed URL loading from window.create to browser.tabs.create
# Images # Images

BIN
src/images/icons/error.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

View File

@ -1,7 +1,7 @@
{ {
"manifest_version": 2, "manifest_version": 2,
"name": "Easy Session Manager", "name": "Easy Session Manager",
"version": "0.2.3.3", "version": "0.2.3.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.",
"browser_specific_settings": { "browser_specific_settings": {
@ -23,7 +23,11 @@
"unlimitedStorage" "unlimitedStorage"
], ],
"background": { "page": "pages/import.html" }, "background": {
"scripts": [
"scripts/listener.js"
]
},
"browser_action": { "browser_action": {
"default_icon": "images/icons/sessionManager.png", "default_icon": "images/icons/sessionManager.png",

24
src/pages/replaced.html Normal file
View File

@ -0,0 +1,24 @@
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>PyGObject API Reference</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.
</div>
</div>
</body>
</html>

View File

@ -168,6 +168,7 @@
<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">

View File

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

75
src/scripts/listener.js Normal file
View File

@ -0,0 +1,75 @@
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);

54
src/scripts/replaced.js Normal file
View File

@ -0,0 +1,54 @@
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;
}

62
src/scripts/replaced_.js Normal file
View File

@ -0,0 +1,62 @@
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 = browser.i18n.getMessage("copiedLabel");
};
document.querySelector(".copyButton").onclick = copy;
document.querySelector(".copyButton").innerText = browser.i18n.getMessage("copyUrlLabel");
if (parameter.state == "open_faild") {
document.getElementsByClassName("replacedPageMessage")[0].innerText = browser.i18n.getMessage(
"replacedPageMessage"
);
}
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

@ -37,17 +37,12 @@ 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 invalidURLsMessage = document.createElement("P")
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');
invalidURLsMessage.innerText = "The Session has invalid URLs (highlighted for convenience). They might break loading of a session...";
invalidURLsMessage.classList.add("warning");
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');
@ -60,7 +55,6 @@ const generateSelectionWindow = (json = "", keys = null, keysLength = 0) => {
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;
let hasInvalidURLs = false;
container.id = "editSelectionContainer"; container.id = "editSelectionContainer";
selAll.id = "selectAllWin" + i; selAll.id = "selectAllWin" + i;
@ -99,13 +93,6 @@ const generateSelectionWindow = (json = "", keys = null, keysLength = 0) => {
inptTag.setAttribute("name", "Win" + i); // Used for toggle select all inptTag.setAttribute("name", "Win" + i); // Used for toggle select all
if (/(file:\/\/|ws:\/\/|wss:\/\/|moz-extension:\/\/|about:)/.test(tab.link)) {
liTag.classList.add("error-bg");
lblTag.classList.add("error");
lblTag2.classList.add("error");
hasInvalidURLs = true;
}
lblTag.appendChild(labelTxt); lblTag.appendChild(labelTxt);
lblTag2.appendChild(labelTxt2); lblTag2.appendChild(labelTxt2);
@ -114,10 +101,6 @@ const generateSelectionWindow = (json = "", keys = null, keysLength = 0) => {
j++; j++;
}); });
if (hasInvalidURLs) {
container.appendChild(invalidURLsMessage);
}
container.appendChild(ulClone); container.appendChild(ulClone);
} }
@ -171,13 +154,11 @@ 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++) {
if (!windows[i].tabs[ii].url.includes("about:")) {
links.push( links.push(
{"link" : windows[i].tabs[ii].url.trim(), {"link" : windows[i].tabs[ii].url.trim(),
"title" : windows[i].tabs[ii].title.trim()} "title" : windows[i].tabs[ii].title.trim()}
); );
} }
}
sessionData["WindowID:" + windows[i].id] = links; sessionData["WindowID:" + windows[i].id] = links;
} }
return sessionData; return sessionData;

62
src/styles/replaced.css Normal file
View File

@ -0,0 +1,62 @@
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

@ -120,12 +120,13 @@ li {
} }
.error-bg { background-color: rgba(44, 44, 44, 0.64); } .error-bg { background-color: rgba(44, 44, 44, 0.34); }
.warning-bg { background-color: rgba(44, 44, 44, 0.64); } .warning-bg { background-color: rgba(44, 44, 44, 0.34); }
.success-bg { background-color: rgba(44, 44, 44, 0.64); } .success-bg { background-color: rgba(44, 44, 44, 0.34); }
.error { color: rgb(170, 18, 18); } .error { color: rgb(170, 18, 18); }
.warning { color: rgb(255, 168, 0); } .warning { color: rgb(255, 168, 0); }
.success { color: rgb(136, 204, 39); } .success { color: rgb(136, 204, 39); }
.hidden { display: none; }