From a4fe7941bdbfd7621001d5a8c66d2c1601d7293e Mon Sep 17 00:00:00 2001 From: Bianca Danforth Date: Thu, 12 Jul 2018 12:55:03 -0700 Subject: [PATCH] Incorporate feedback from Osmose. Created a 'utils.js' file that is imported into the content script 'product_info.js'. These are now bundled by webpack into a single script. --- .eslintignore | 1 + src/manifest.json | 2 +- src/product_info.js | 99 ++++++++++++++++++++------------------------- src/utils.js | 33 +++++++++++++++ webpack.config.js | 3 +- 5 files changed, 80 insertions(+), 58 deletions(-) create mode 100644 src/utils.js diff --git a/.eslintignore b/.eslintignore index 378eac2..40e72a9 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1 +1,2 @@ build +src/product_info.js diff --git a/src/manifest.json b/src/manifest.json index 51d7b94..045fa30 100644 --- a/src/manifest.json +++ b/src/manifest.json @@ -23,7 +23,7 @@ "content_scripts": [ { "matches": [""], - "js": ["product_info.js"] + "js": ["product_info.bundle.js"] } ], "sidebar_action": { diff --git a/src/product_info.js b/src/product_info.js index ee28d07..dafb325 100644 --- a/src/product_info.js +++ b/src/product_info.js @@ -1,66 +1,55 @@ +import utils from './utils'; + /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -const OpenGraphPropertyValues = { - title: 'og:title', - image: 'og:image', - price: 'og:price:amount', -}; +(async function main() { + const OpenGraphPropertyValues = { + title: 'og:title', + image: 'og:image', + price: 'og:price:amount', + }; -function openBackgroundPort() { - return new Promise((resolve, reject) => { - const port = browser.runtime.connect(); - port.onMessage.addListener((message) => { - if (message.type === 'background-ready') { - resolve(port); + function openBackgroundPort() { + return new Promise((resolve, reject) => { + const port = browser.runtime.connect(); + port.onMessage.addListener((message) => { + if (message.type === 'background-ready') { + resolve(port); + } + }); + port.onDisconnect.addListener(() => { + reject(); + }); + }); + } + + function getProductData(port) { + const data = {}; + for (const [key, value] of Object.entries(OpenGraphPropertyValues)) { + const metaEle = document.querySelector(`meta[property="${value}"]`); + if (metaEle) { + data[key] = metaEle.getAttribute('content'); } - }); - port.onDisconnect.addListener(() => { - reject(); - }); - }); -} - -function getProductData(port) { - const data = {}; - for (const [key, value] of Object.entries(OpenGraphPropertyValues)) { - const metaEle = document.querySelector(`meta[property="${value}"]`); - if (metaEle) { - data[key] = metaEle.getAttribute('content'); } - } - port.postMessage({ - type: 'product-data', - data, - }); -} - -function portSuccess(port) { - // Make sure page has finished loading, as JS could alter the DOM. - if (document.readyState === 'complete') { - getProductData(port); - } else { - window.addEventListener('load', () => { - getProductData(port); + port.postMessage({ + type: 'product-data', + data, }); } -} -let delay = 2; // seconds -const DELAY_MULTIPLIER = 2; -const NUM_ATTEMPTS = 5; -const DELAY_MAX = delay ** NUM_ATTEMPTS; -// Connect to the background script until it's available. See Issue #17 and bug 1474727. -function portFail() { - if (delay > DELAY_MAX) { - console.error(`Could not establish a connection after ${NUM_ATTEMPTS} attempts.`); - return; + try { + const port = await utils.retry(openBackgroundPort); + // Make sure page has finished loading, as JS could alter the DOM. + if (document.readyState === 'complete') { + getProductData(port); + } else { + window.addEventListener('load', () => { + getProductData(port); + }); + } + } catch (err) { + console.error('Could not establish connection to background script.'); } - setTimeout(() => { - openBackgroundPort().then(portSuccess, portFail); - delay *= DELAY_MULTIPLIER; - }, delay * 1000); // ms -} - -openBackgroundPort().then(portSuccess, portFail); +}()); diff --git a/src/utils.js b/src/utils.js new file mode 100644 index 0000000..c94b51c --- /dev/null +++ b/src/utils.js @@ -0,0 +1,33 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +const utils = { + /* eslint-disable arrow-body-style */ + wait: async (delay) => { + return new Promise((resolve) => { + window.setTimeout(resolve, delay); + }); + }, + + retry: async (callback, maxRetries = 5, delayFactor = 2, initialDelay = 2) => { + /* eslint-disable no-await-in-loop */ + let delay = initialDelay; + let lastError = null; + for (let k = 0; k < maxRetries; k++) { + try { + // If we don't await here, the callback's promise will be returned + // immediately instead of potentially failing. + return await callback(); + } catch (err) { + lastError = err; + await utils.wait(delay); + delay *= delayFactor; + } + } + throw lastError; + }, +}; + +export default utils; diff --git a/webpack.config.js b/webpack.config.js index d5d4aee..fe7a4a1 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -13,6 +13,7 @@ module.exports = { entry: { background: './src/background.js', sidebar: './src/sidebar.jsx', + product_info: './src/product_info.js', }, output: { path: BUILD_DIR, @@ -31,8 +32,6 @@ module.exports = { }, plugins: [ new CopyWebpackPlugin([ - {from: 'product_info.js'}, - // Static files {from: '**/*.svg'}, {from: '**/*.html'},