diff --git a/src/Makefile b/src/Makefile index bbdfeb67..76516b21 100644 --- a/src/Makefile +++ b/src/Makefile @@ -24,15 +24,15 @@ css/options.dist.css: $(LESSC) options/*.less [ -d css ] || mkdir -p css $(LESSC) options/options.less css/options.dist.css -js/background.dist.js: $(BROWSERIFY) background.js helpers.js +js/background.dist.js: $(BROWSERIFY) background.js helpers/*.js [ -d js ] || mkdir -p js $(BROWSERIFY) -o js/background.dist.js background.js -js/popup.dist.js: $(BROWSERIFY) popup/*.js helpers.js +js/popup.dist.js: $(BROWSERIFY) popup/*.js helpers/*.js [ -d js ] || mkdir -p js $(BROWSERIFY) -o js/popup.dist.js popup/popup.js -js/offscreen.dist.js: $(BROWSERIFY) offscreen/*.js +js/offscreen.dist.js: $(BROWSERIFY) offscreen/*.js helpers/*.js [ -d js ] || mkdir -p js $(BROWSERIFY) -o js/offscreen.dist.js offscreen/offscreen.js diff --git a/src/background.js b/src/background.js index 53b285c8..9f2ac8ec 100644 --- a/src/background.js +++ b/src/background.js @@ -5,7 +5,8 @@ require("chrome-extension-async"); const sha1 = require("sha1"); const idb = require("idb"); const BrowserpassURL = require("@browserpass/url"); -const helpers = require("./helpers"); +const helpers = require("./helpers/base"); +const clipboard = require("./helpers/clipboard"); // native application id var appID = "com.github.browserpass.native"; @@ -262,15 +263,7 @@ async function copyToClipboard(text, clear = true) { data: text, }); } else { - document.addEventListener( - "copy", - function (e) { - e.clipboardData.setData("text/plain", text); - e.preventDefault(); - }, - { once: true } - ); - document.execCommand("copy"); + clipboard.writeToClipboard(text); } if (clear) { @@ -306,16 +299,7 @@ async function readFromClipboard() { return response.message; } else { - const ta = document.createElement("textarea"); - // these lines are carefully crafted to make paste work in both Chrome and Firefox - ta.contentEditable = true; - ta.textContent = ""; - document.body.appendChild(ta); - ta.select(); - document.execCommand("paste"); - const content = ta.value; - document.body.removeChild(ta); - return content; + return clipboard.readFromClipboard(); } } @@ -324,7 +308,6 @@ async function readFromClipboard() { * @since 3.10.0 * @param string path - location of html document to be created */ -let creatingOffscreen; // A global promise to avoid concurrency issues async function setupOffscreenDocument(path) { // Check all windows controlled by the service worker to see if one // of them is the offscreen document with the given path @@ -339,18 +322,11 @@ async function setupOffscreenDocument(path) { } // create offscreen document - if (!creatingOffscreen) { - creatingOffscreen = chrome.offscreen.createDocument({ - url: path, - reasons: [chrome.offscreen.Reason.CLIPBOARD], - justification: "Read / write text to the clipboard", - }); - } - - if (creatingOffscreen) { - await creatingOffscreen; - creatingOffscreen = null; - } + await chrome.offscreen.createDocument({ + url: path, + reasons: [chrome.offscreen.Reason.CLIPBOARD], + justification: "Read / write text to the clipboard", + }); } /** @@ -630,13 +606,6 @@ async function fillFields(settings, login, fields) { async function getLocalSettings() { var settings = helpers.deepCopy(defaultSettings); - try { - // use for debugging only, since dev tools does not show extension storage - await chrome.storage.local.get(console.dir); - } catch (err) { - console.warn("could not display extension local storage"); - } - var items = await chrome.storage.local.get(Object.keys(defaultSettings)); for (var key in defaultSettings) { var value = null; @@ -645,11 +614,7 @@ async function getLocalSettings() { } if (value !== null && Boolean(value)) { - try { - settings[key] = value; - } catch (err) { - console.error(`getLocalSettings(), error JSON.parse(value):`, err, { key, value }); - } + settings[key] = value; } } diff --git a/src/helpers.js b/src/helpers/base.js similarity index 96% rename from src/helpers.js rename to src/helpers/base.js index 50304746..6b888adc 100644 --- a/src/helpers.js +++ b/src/helpers/base.js @@ -94,23 +94,6 @@ function getSetting(key, login, settings) { */ function isChrome() { return chrome.runtime.getURL("/").startsWith("chrom"); - /** - * Alternate approach to checking if current browser is chrome or - * chromium based. - * - * @TODO: remove one of these two after probationary period - * to determine which will approach will best suite browserpass - * purposes in the wild. - * - * Above: .getURL("/") will error on "chrome://" protocols - * Below: check user agent, can be altered depending vendor - */ - // const ua = navigator.userAgent; - // const matches = ua.match(/(chrom)/i) || []; - // if (Object.keys(matches).length > 2 && /chrom/i.test(matches[1])) { - // return true; - // } - // return false; } /** diff --git a/src/helpers/clipboard.js b/src/helpers/clipboard.js new file mode 100644 index 00000000..00e9a78e --- /dev/null +++ b/src/helpers/clipboard.js @@ -0,0 +1,53 @@ +//------------------------------------- Initialization --------------------------------------// +"use strict"; + +module.exports = { + readFromClipboard, + writeToClipboard, +}; +//----------------------------------- Function definitions ----------------------------------// + +/** + * Read plain text from clipboard + * + * @since 3.2.0 + * + * @return string The current plaintext content of the clipboard + */ +function readFromClipboard() { + const ta = document.createElement("textarea"); + // these lines are carefully crafted to make paste work in both Chrome and Firefox + ta.contentEditable = true; + ta.textContent = ""; + document.body.appendChild(ta); + ta.select(); + document.execCommand("paste"); + const content = ta.value; + document.body.removeChild(ta); + return content; +} + +/** + * Copy text to clipboard and optionally clear it from the clipboard after one minute + * + * @since 3.2.0 + * + * @param string text Text to copy + * @return void + */ +async function writeToClipboard(text) { + // Error if we received the wrong kind of data. + if (typeof text !== "string") { + throw new TypeError(`Value provided must be a 'string', got '${typeof text}'.`); + } + + document.addEventListener( + "copy", + function (e) { + e.clipboardData.setData("text/plain", text); + e.preventDefault(); + }, + { once: true } + ); + document.execCommand("copy"); +} diff --git a/src/helpers.redraw.js b/src/helpers/redraw.js similarity index 100% rename from src/helpers.redraw.js rename to src/helpers/redraw.js diff --git a/src/helpers.ui.js b/src/helpers/ui.js similarity index 96% rename from src/helpers.ui.js rename to src/helpers/ui.js index 1fa18889..2c936bd7 100644 --- a/src/helpers.ui.js +++ b/src/helpers/ui.js @@ -2,9 +2,9 @@ "use strict"; const m = require("mithril"); -const dialog = require("./popup/modalDialog"); -const notify = require("./popup/notifications"); -const helpers = require("./helpers"); +const dialog = require("../popup/modalDialog"); +const notify = require("../popup/notifications"); +const helpers = require("../helpers/base"); const containsNumbersRegEx = RegExp(/[0-9]/); const containsSymbolsRegEx = RegExp(/[\p{P}\p{S}]/, "u"); diff --git a/src/offscreen/offscreen.html b/src/offscreen/offscreen.html index 5e47e2a6..c621e556 100644 --- a/src/offscreen/offscreen.html +++ b/src/offscreen/offscreen.html @@ -1,3 +1,5 @@ - - + +
+ + diff --git a/src/offscreen/offscreen.js b/src/offscreen/offscreen.js index 349b980c..6cb7bfb6 100644 --- a/src/offscreen/offscreen.js +++ b/src/offscreen/offscreen.js @@ -1,5 +1,6 @@ //------------------------------------- Initialization --------------------------------------// "use strict"; +const clipboard = require("../helpers/clipboard"); //----------------------------------- Function definitions ----------------------------------// chrome.runtime.onMessage.addListener(handleMessage); @@ -20,10 +21,10 @@ async function handleMessage(message, sender, sendResponse) { try { switch (message.type) { case "copy-data-to-clipboard": - writeToClipboard(message.data); + clipboard.writeToClipboard(message.data); break; case "read-from-clipboard": - reply = readFromClipboard(); + reply = clipboard.readFromClipboard(); break; default: console.warn(`Unexpected message type received: '${message.type}'.`); @@ -33,47 +34,3 @@ async function handleMessage(message, sender, sendResponse) { sendResponse({ status: "error", message: e.toString() }); } } - -/** - * Read plain text from clipboard - * - * @since 3.2.0 - * - * @return string The current plaintext content of the clipboard - */ -function readFromClipboard() { - const ta = document.querySelector("#text"); - // these lines are carefully crafted to make paste work in both Chrome and Firefox - ta.contentEditable = true; - ta.textContent = ""; - ta.select(); - document.execCommand("paste"); - const content = ta.value; - return content; -} - -/** - * Copy text to clipboard and optionally clear it from the clipboard after one minute - * - * @since 3.2.0 - * - * @param string text Text to copy - * @param boolean clear Whether to clear the clipboard after one minute - * @return void - */ -async function writeToClipboard(text) { - // Error if we received the wrong kind of data. - if (typeof text !== "string") { - throw new TypeError(`Value provided must be a 'string', got '${typeof text}'.`); - } - - document.addEventListener( - "copy", - function (e) { - e.clipboardData.setData("text/plain", text); - e.preventDefault(); - }, - { once: true } - ); - document.execCommand("copy"); -} diff --git a/src/popup/addEditInterface.js b/src/popup/addEditInterface.js index dca5d188..1a988929 100644 --- a/src/popup/addEditInterface.js +++ b/src/popup/addEditInterface.js @@ -4,8 +4,8 @@ const Settings = require("./models/Settings"); const Tree = require("./models/Tree"); const notify = require("./notifications"); const dialog = require("./modalDialog"); -const helpers = require("../helpers"); -const helpersUI = require("../helpers.ui"); +const helpers = require("../helpers/base"); +const helpersUI = require("../helpers/ui"); const layout = require("./layoutInterface"); module.exports = AddEditInterface; diff --git a/src/popup/detailsInterface.js b/src/popup/detailsInterface.js index 5ca2ad27..295232e0 100644 --- a/src/popup/detailsInterface.js +++ b/src/popup/detailsInterface.js @@ -2,8 +2,8 @@ module.exports = DetailsInterface; const m = require("mithril"); const Moment = require("moment"); -const helpers = require("../helpers"); -const helpersUI = require("../helpers.ui"); +const helpers = require("../helpers/base"); +const helpersUI = require("../helpers/ui"); const layout = require("./layoutInterface"); const Login = require("./models/Login"); const Settings = require("./models/Settings"); diff --git a/src/popup/interface.js b/src/popup/interface.js index 9c7f819e..a08545c6 100644 --- a/src/popup/interface.js +++ b/src/popup/interface.js @@ -5,7 +5,7 @@ const Moment = require("moment"); const SearchInterface = require("./searchinterface"); const BrowserpassURL = require("@browserpass/url"); const dialog = require("./modalDialog"); -const helpers = require("../helpers"); +const helpers = require("../helpers/base"); const layout = require("./layoutInterface"); let overrideDefaultSearchOnce = true; diff --git a/src/popup/modalDialog.js b/src/popup/modalDialog.js index 58f25d94..ea224896 100644 --- a/src/popup/modalDialog.js +++ b/src/popup/modalDialog.js @@ -1,5 +1,5 @@ const m = require("mithril"); -const redraw = require("../helpers.redraw"); +const redraw = require("../helpers/redraw"); const modalId = "browserpass-modal"; const CANCEL = "Cancel"; diff --git a/src/popup/models/Login.js b/src/popup/models/Login.js index 7acd2ca9..f3ba353a 100644 --- a/src/popup/models/Login.js +++ b/src/popup/models/Login.js @@ -2,8 +2,8 @@ require("chrome-extension-async"); const sha1 = require("sha1"); -const helpers = require("../../helpers"); -const helpersUI = require("../../helpers.ui"); +const helpers = require("../../helpers/base"); +const helpersUI = require("../../helpers/ui"); const Settings = require("./Settings"); // Search for one of the secret prefixes diff --git a/src/popup/notifications.js b/src/popup/notifications.js index b4e4dc3a..23767357 100644 --- a/src/popup/notifications.js +++ b/src/popup/notifications.js @@ -5,7 +5,7 @@ */ const m = require("mithril"); -const redraw = require("../helpers.redraw"); +const redraw = require("../helpers/redraw"); const uuidPrefix = RegExp(/^([a-z0-9]){8}-/); const NOTIFY_CLASS = "m-notifications"; diff --git a/src/popup/popup.js b/src/popup/popup.js index 41f128e3..3e2ffb2c 100644 --- a/src/popup/popup.js +++ b/src/popup/popup.js @@ -7,7 +7,7 @@ require("chrome-extension-async"); const Login = require("./models/Login"); const Settings = require("./models/Settings"); // utils, libs -const helpers = require("../helpers.ui"); +const helpers = require("../helpers/ui"); const m = require("mithril"); // components const AddEditInterface = require("./addEditInterface"); diff --git a/src/popup/searchinterface.js b/src/popup/searchinterface.js index 69650245..c2d2ec7a 100644 --- a/src/popup/searchinterface.js +++ b/src/popup/searchinterface.js @@ -2,7 +2,7 @@ module.exports = SearchInterface; const BrowserpassURL = require("@browserpass/url"); const dialog = require("./modalDialog"); -const helpers = require("../helpers"); +const helpers = require("../helpers/base"); const m = require("mithril"); /**