Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

improving editor.js file #1366

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
225 changes: 124 additions & 101 deletions src/core/bg/editor.js
Original file line number Diff line number Diff line change
@@ -1,129 +1,152 @@
/*
/*
* Copyright 2010-2020 Gildas Lormeau
* contact : gildas.lormeau <at> gmail.com
*
* This file is part of SingleFile.
*
* The code in this file is free software: you can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License
* (GNU AGPL) as published by the Free Software Foundation, either version 3
* of the License, or (at your option) any later version.
* The code in this file is free software: you can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License
* (GNU AGPL) as published by the Free Software Foundation, either version 3
* of the License, or (at your option) any later version.
*
* The code in this file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
* General Public License for more details.
* The code in this file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
* General Public License for more details.
*
* As additional permission under GNU AGPL version 3 section 7, you may
* distribute UNMODIFIED VERSIONS OF THIS file without the copy of the GNU
* AGPL normally required by section 4, provided you include this license
* notice and a URL through which recipients can access the Corresponding
* Source.
* As additional permission under GNU AGPL version 3 section 7, you may
* distribute UNMODIFIED VERSIONS OF THIS file without the copy of the GNU
* AGPL normally required by section 4, provided you include this license
* notice and a URL through which recipients can access the Corresponding
* Source.
*/

/* global browser */

import * as config from "./config.js";

// Constants
const MAX_CONTENT_SIZE = 32 * (1024 * 1024);
const EDITOR_PAGE_URL = "/src/ui/pages/editor.html";
const EDITOR_URL = browser.runtime.getURL(EDITOR_PAGE_URL);

// Data storage
const tabsData = new Map();
const partialContents = new Map();
const EDITOR_URL = browser.runtime.getURL(EDITOR_PAGE_URL);

export {
onMessage,
onTabRemoved,
isEditor,
open,
EDITOR_URL
};
// Exported functions
export { onMessage, onTabRemoved, isEditor, open, EDITOR_URL };

// Handle incoming messages
async function onMessage(message, sender) {
if (message.method.endsWith(".getTabData")) {
await sendTabDataToEditor(sender.tab);
return {};
}

if (message.method.endsWith(".open")) {
await processOpenMessage(message, sender.tab);
return {};
}

if (message.method.endsWith(".ping")) {
return {};
}
}

// Open a new editor tab
async function open({ tabIndex, content, filename, compressContent, selfExtractingArchive, extractDataFromPage, insertTextBody }) {
const createTabProperties = { active: true, url: EDITOR_PAGE_URL };
if (tabIndex != null) {
createTabProperties.index = tabIndex;
}
const tab = await browser.tabs.create(createTabProperties);
tabsData.set(tab.id, {
content,
filename,
compressContent,
selfExtractingArchive,
extractDataFromPage,
insertTextBody
});
const createTabProperties = { active: true, url: EDITOR_PAGE_URL };

if (tabIndex != null) {
createTabProperties.index = tabIndex;
}

const tab = await browser.tabs.create(createTabProperties);
const tabData = {
content,
filename,
compressContent,
selfExtractingArchive,
extractDataFromPage,
insertTextBody
};

tabsData.set(tab.id, tabData);
}

// Handle tab removal
function onTabRemoved(tabId) {
tabsData.delete(tabId);
tabsData.delete(tabId);
}

// Check if a tab is an editor tab
function isEditor(tab) {
return tab.url == EDITOR_URL;
return tab.url === EDITOR_URL;
}

// Send tab data to the editor
async function sendTabDataToEditor(tab) {
const tabData = tabsData.get(tab.id);

if (tabData) {
const options = await config.getOptions(tabData.url);
const content = JSON.stringify(tabData);

for (let blockIndex = 0; blockIndex * MAX_CONTENT_SIZE < content.length; blockIndex++) {
const message = {
method: "editor.setTabData",
compressContent: tabData.compressContent,
};

message.truncated = content.length > MAX_CONTENT_SIZE;

if (message.truncated) {
message.finished = (blockIndex + 1) * MAX_CONTENT_SIZE > content.length;
message.content = content.substring(blockIndex * MAX_CONTENT_SIZE, (blockIndex + 1) * MAX_CONTENT_SIZE);

if (message.finished) {
message.options = options;
}
} else {
message.content = content;
message.options = options;
}

await browser.tabs.sendMessage(tab.id, message);
}
}
}

// Process open message from content script
async function processOpenMessage(message, tab) {
let contents;

if (message.truncated) {
contents = partialContents.get(tab.id) || [];
contents.push(message.content);

if (message.finished) {
partialContents.delete(tab.id);
}
} else if (message.content) {
contents = [message.content];
}

if (!message.truncated || message.finished) {
const updateTabProperties = { url: EDITOR_PAGE_URL };
await browser.tabs.update(tab.id, updateTabProperties);

const content = message.compressContent ? contents.flat().join("") : contents.join("");
tabsData.set(tab.id, {
url: tab.url,
content,
filename: message.filename,
compressContent: message.compressContent,
selfExtractingArchive: message.selfExtractingArchive,
extractDataFromPageTags: message.extractDataFromPageTags,
insertTextBody: message.insertTextBody,
});
}
}

async function onMessage(message, sender) {
if (message.method.endsWith(".getTabData")) {
const tab = sender.tab;
const tabData = tabsData.get(tab.id);
if (tabData) {
const options = await config.getOptions(tabData.url);
const content = JSON.stringify(tabData);
for (let blockIndex = 0; blockIndex * MAX_CONTENT_SIZE < content.length; blockIndex++) {
const message = {
method: "editor.setTabData",
compressContent: tabData.compressContent
};
message.truncated = content.length > MAX_CONTENT_SIZE;
if (message.truncated) {
message.finished = (blockIndex + 1) * MAX_CONTENT_SIZE > content.length;
message.content = content.substring(blockIndex * MAX_CONTENT_SIZE, (blockIndex + 1) * MAX_CONTENT_SIZE);
if (message.finished) {
message.options = options;
}
} else {
message.content = content;
message.options = options;
}
await browser.tabs.sendMessage(tab.id, message);
}
}
return {};
}
if (message.method.endsWith(".open")) {
let contents;
const tab = sender.tab;
if (message.truncated) {
contents = partialContents.get(tab.id);
if (!contents) {
contents = [];
partialContents.set(tab.id, contents);
}
contents.push(message.content);
if (message.finished) {
partialContents.delete(tab.id);
}
} else if (message.content) {
contents = [message.content];
}
if (!message.truncated || message.finished) {
const updateTabProperties = { url: EDITOR_PAGE_URL };
await browser.tabs.update(tab.id, updateTabProperties);
const content = message.compressContent ? contents.flat() : contents.join("");
tabsData.set(tab.id, {
url: tab.url,
content,
filename: message.filename,
compressContent: message.compressContent,
selfExtractingArchive: message.selfExtractingArchive,
extractDataFromPageTags: message.extractDataFromPageTags,
insertTextBody: message.insertTextBody
});
}
return {};
}
if (message.method.endsWith(".ping")) {
return {};
}
}