From 9d473cdba191bb6bd711719a428b56f8fca0a0af Mon Sep 17 00:00:00 2001 From: Ellen-Wittingen Date: Thu, 15 Aug 2024 21:28:18 +0200 Subject: [PATCH 1/6] Rewritten the plugin to use manifest V3 --- SponsorExtensie.iml | 9 - icons/{icon128.png => icon-128.png} | Bin icons/{icon16.png => icon-16.png} | Bin icons/icon-32.png | Bin 0 -> 8315 bytes icons/{icon48.png => icon-48.png} | Bin manifest.json | 57 +-- src/background_service.js | 26 ++ src/bg/background.html | 8 - src/bg/background.js | 35 -- src/constants.js | 12 + src/functions.js | 353 ++++++------------ src/installed.js | 2 +- src/notifications.js | 57 +++ src/options/options.html | 33 ++ .../settings.js => options/options.js} | 13 +- src/settings/settings.html | 31 -- 16 files changed, 289 insertions(+), 347 deletions(-) delete mode 100644 SponsorExtensie.iml rename icons/{icon128.png => icon-128.png} (100%) rename icons/{icon16.png => icon-16.png} (100%) create mode 100644 icons/icon-32.png rename icons/{icon48.png => icon-48.png} (100%) create mode 100644 src/background_service.js delete mode 100644 src/bg/background.html delete mode 100644 src/bg/background.js create mode 100644 src/constants.js create mode 100644 src/notifications.js create mode 100644 src/options/options.html rename src/{settings/settings.js => options/options.js} (69%) delete mode 100644 src/settings/settings.html diff --git a/SponsorExtensie.iml b/SponsorExtensie.iml deleted file mode 100644 index 8021953..0000000 --- a/SponsorExtensie.iml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/icons/icon128.png b/icons/icon-128.png similarity index 100% rename from icons/icon128.png rename to icons/icon-128.png diff --git a/icons/icon16.png b/icons/icon-16.png similarity index 100% rename from icons/icon16.png rename to icons/icon-16.png diff --git a/icons/icon-32.png b/icons/icon-32.png new file mode 100644 index 0000000000000000000000000000000000000000..0ecda056c5c155b121dc60df0ac7a481d40701ed GIT binary patch literal 8315 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 - - - - - - - \ No newline at end of file diff --git a/src/bg/background.js b/src/bg/background.js deleted file mode 100644 index b4c3860..0000000 --- a/src/bg/background.js +++ /dev/null @@ -1,35 +0,0 @@ -var sponsortabs = []; - -checkUpdate(); - -browser.webNavigation.onCommitted.addListener(navigationCompleteListener); - -// GC closing tabs to keep sponsortabs map clean -browser.tabs.onRemoved.addListener(function (tabId) { - if (sponsortabs[tabId]) { - delete sponsortabs[tabId]; - } - browser.notifications.clear(NOTIFICATION_ID); -}); - -// Register for periodic endpoint updates -browser.runtime.onInstalled.addListener(function () { - browser.alarms.create('SLupdateCheck', { - delayInMinutes: UPDATE_CHECK_INTERVAL, - periodInMinutes: UPDATE_CHECK_INTERVAL - }) -}); - -browser.alarms.onAlarm.addListener(function (alarm) { - if (alarm.name === 'SLupdateCheck') { - checkUpdate(); - } -}); - -// Check whether new version is installed -browser.runtime.onInstalled.addListener(function(details){ - if(details.reason === 'update'){ - browser.storage.local.clear(); - checkUpdate(); - } -}); \ No newline at end of file diff --git a/src/constants.js b/src/constants.js new file mode 100644 index 0000000..b60d38c --- /dev/null +++ b/src/constants.js @@ -0,0 +1,12 @@ +export default class Constants { + static CLUBID = 4509; + static API = "https://www.sponsorkliks.com/api/?club="+this.CLUBID+"&call=webshops_club_extension"; + static UPDATE_CHECK_INTERVAL = 600; + static UPDATE_CHECK_ALARM_NAME = "update-sponsor-links-alarm"; + static SPONSOR_DOMAINS_STORAGE_KEY = 'sponsor-domains'; + static LASTCHECK_KEY = 'lastcheck'; + static ALWAYS_REDIRECT_KEY = 'always-redirect'; + static NOTIFICATION_ID = 'sponsor-notification-'; + + static BROWSER = typeof browser === 'undefined' ? chrome : browser; +} diff --git a/src/functions.js b/src/functions.js index 80675cd..d6728b6 100644 --- a/src/functions.js +++ b/src/functions.js @@ -1,262 +1,155 @@ -const CLUBID = 4509; -const API = 'https://www.sponsorkliks.com/api/?club='+CLUBID+'&call=webshops_club_extension'; -const URLS_KEY = 'urls'; -const LASTCHECK_KEY = 'lastcheck'; -const ALWAYS_REDIRECT_KEY = 'always-redirect'; -const NOTIFICATION_ID = 'sponsor-notification-'; -const UPDATE_CHECK_INTERVAL = 600; -const CUSTOM_TARGETS = { - 'coolblue.nl': { - 'category': 'Computers & Electronica', - 'name_short': 'Coolblue', - 'link': 'https://www.sponsorkliks.com/link.php?club=4509&shop_id=61&shop=Coolblue&cn=NL&ln=nl' - }, - 'www.disneylandparis.com': { - 'category': 'Reizen & Vakantie', - 'name_short': 'Disneyland Parijs', - 'link': 'https://www.sponsorkliks.com/link.php?club=4509&shop_id=2283&shop=Disneyland+Parijs&cn=NL&ln=nl' - }, - 'expert.nl': { - 'category': 'Computers & Electronica', - 'name_short': 'Expert', - 'link': 'https://www.sponsorkliks.com/link.php?club=4509&shop_id=2339&shop=Expert&cn=NL&ln=nl' - }, - 'hema.nl': { - 'category': 'Huis & Tuin', - 'name_short': 'HEMA', - 'link': 'https://www.sponsorkliks.com/link.php?club=4509&shop_id=3025&shop=HEMA&cn=nl&ln=nl' - }, - 'klm.com': { - 'category': 'Reizen & Vakantie', - 'name_short': 'KLM', - 'link': 'https://www.sponsorkliks.com/link.php?club=4509&shop_id=2148&shop=KLM&cn=NL&ln=nl' - }, - 'mediamarkt.nl': { - 'category': 'Computers & Electronica', - 'name_short': 'MediaMarkt', - 'link': 'https://www.sponsorkliks.com/link.php?club=4509&shop_id=2158&shop=MediaMarkt&cn=NL&ln=nl' - }, - 'superdry.nl': { - 'category': 'Mode & Cosmetica', - 'name_short': 'Superdry', - 'link': 'https://www.sponsorkliks.com/link.php?club=4509&shop_id=2160&shop=Superdry+NL&cn=nl&ln=nl' - }, - 'schuurman-schoenen.nl': { - 'category': 'Mode & Cosmetica', - 'name_short': 'Schuurman Schoenen', - 'link': 'https://www.sponsorkliks.com/link.php?club=4509&shop_id=3033&shop=Schuurman+Schoenen&cn=nl&ln=nl' - }, - 'thuisbezorgd.nl': { - 'category': 'Eten & Drinken', - 'name_short': 'Thuisbezorgd.nl', - 'link': 'https://www.sponsorkliks.com/link.php?club=4509&shop_id=4&shop=Thuisbezorgd.nl&cn=NL&ln=nl' - }, - 'vikingdirect.nl': { - 'category': 'Zakelijk', - 'name_short': 'viking.nl', - 'link': 'https://www.sponsorkliks.com/link.php?club=4509&shop_id=48&shop=Viking&cn=nl&ln=nl' - } -}; -const CHROME = typeof browser === 'undefined'; - -if (CHROME) { - browser = chrome; -} - -/** - * Check if we should update the websites with affiliate links from the API - * Links are updated every 24 hours - */ -function checkUpdate() { - getStorage([URLS_KEY, LASTCHECK_KEY], storage => { - if (typeof storage[URLS_KEY] !== 'undefined') { - const lastCheck = storage[LASTCHECK_KEY] || 0; +import Constants from "./constants.js"; +import Notifications from "./notifications.js"; + +export default class Functions { + filter = { url: [] }; + sponsoredTabs = {}; + notifications = new Notifications(); + + async setFilter() { + this.filter.url = await chrome.storage.local.get(Constants.SPONSOR_DOMAINS_STORAGE_KEY).then((result) => { + var filterList = []; + Object.keys(result[Constants.SPONSOR_DOMAINS_STORAGE_KEY]).forEach(domain => { + filterList.push({ hostSuffix: domain }) + }) + return filterList; + }); + } + + // const filter = { + // url: [{ hostSuffix: 'google.com' }] + // }; + + /** + * Check if we should update the websites with affiliate links from the API + * Links are updated every 24 hours + */ + async checkUpdateUrls() { + chrome.storage.local.get([Constants.SPONSOR_DOMAINS_STORAGE_KEY, Constants.LASTCHECK_KEY]).then(async (storage) => { + if (typeof storage[Constants.SPONSOR_DOMAINS_STORAGE_KEY] !== 'undefined') { + const lastCheck = storage[Constants.LASTCHECK_KEY] || 0; if (lastCheck < unixDayAgo()) { - browser.storage.local.set({ - [LASTCHECK_KEY]: unixTime(new Date()), + chrome.storage.local.set({ + [Constants.LASTCHECK_KEY]: unixTime(new Date()), }); - updateURLs().catch(() => console.log('Failed to update urls')); + await this.updateUrls(); } } else { - updateURLs().catch(() => console.log('Failed to update urls')); + await this.updateUrls(); } }); -} + } -/** - * Get all the websites with affiliate links from the API - */ -async function updateURLs() { - const response = await fetch(API); + /** + * Get all the websites with affiliate links from the API + */ + async updateUrls() { + const response = await fetch(Constants.API); const data = await response.json(); // Add custom targets that are not present in the API - for (var url in CUSTOM_TARGETS) { - var custom_data = CUSTOM_TARGETS[url]; - custom_data['orig_url'] = url; - data['webshops'].push(custom_data) - } - - browser.storage.local.set({ - [URLS_KEY]: data['webshops'] - .filter(obj => !!obj.orig_url) - .reduce(function (map, obj) { - map[extractHostname(obj.orig_url)] = obj; - return map; - }, {}) - }); -} - -/** - * Change the current website on the specified tab - * @param tabId {number} id of the tab to change the website of - * @param target {string} new website url - */ -function navigateTo(tabId, target) { - browser.tabs.update(tabId, {url: target}); -} - -/** - * Show page action and notification for website which has an affiliate link - * @param link {string} affiliate link - * @param tabId {number} tab id of the website - * @param hostname {string} hostname of the website - * @param referrer {string} url of the website to redirect to after redirect from sponsorkliks.nl - * @param notificationTitle {string} title of the notification - */ -function enableLinking(link, tabId, hostname, referrer, notificationTitle) { - // Page action - browser.pageAction.show(tabId); - browser.pageAction.onClicked.addListener(function () { - sponsortabs[tabId] = {'hostname': hostname, 'referrer': referrer}; - browser.notifications.clear(NOTIFICATION_ID); - navigateTo(tabId, link); - }); - - // Notification - browser.notifications.create(NOTIFICATION_ID+tabId, { - type: 'basic', - title: notificationTitle, - message: 'Klik op deze notificatie of de icoon van de extensie om via die link te gaan.', - iconUrl: browser.extension.getURL('icons/icon128.png') - }, function (nId) { + // for (var url in CUSTOM_TARGETS) { + // var custom_data = CUSTOM_TARGETS[url]; + // custom_data['orig_url'] = url; + // data['webshops'].push(custom_data) + // } + + await chrome.storage.local.set({ + [Constants.SPONSOR_DOMAINS_STORAGE_KEY]: data['webshops'] + .filter(obj => !!obj.orig_url) + .reduce(function (map, obj) { + var urlObj = parseURL(obj.orig_url); + if (urlObj) map[urlObj.host] = obj; + return map; + }, {}), }); - browser.notifications.onClicked.addListener(function (notificationId) { - if (notificationId === NOTIFICATION_ID+tabId) { - sponsortabs[tabId] = {'hostname': hostname, 'referrer': referrer}; - browser.notifications.clear(notificationId); - navigateTo(tabId, link); - } - }); -} - -/** - * Called when a user navigates to an url - * @param event {object} - */ -function navigationCompleteListener(event) { - getStorage([URLS_KEY, ALWAYS_REDIRECT_KEY], storage => { - const tabId = event.tabId; - const url = event.url; - const hostname = extractHostname(url); - const nowww_hostname = hostname.replace(/^(www\.)/,''); - - // If there is no hostname found: return - if (!hostname) { - return; - } - - const urls = storage[URLS_KEY]; - if (!urls) { - // Apparently we were not able to retrieve the urls from the API yet - return; - } - const target = urls[hostname] || urls[nowww_hostname]; - - // If we're not on a sponsored link capable page: return - if (!target) { - return; - } - - // Check if we're still visiting the same site we already went through a sponsored link for - if (sponsortabs[tabId] && hostname === sponsortabs[tabId]['hostname']) { - // If we have a origin location we came for, redirect back to that page - if(sponsortabs[tabId]['referrer']){ - navigateTo(tabId, sponsortabs[tabId]['referrer']); - sponsortabs[tabId]['referrer'] = null; + await this.setFilter(); + } + + /** + * Called when a user navigates to an sponsored domain + * @param event {object} + */ + onTabUpdated(tabId, changeInfo, tab) { + chrome.storage.local.get([Constants.SPONSOR_DOMAINS_STORAGE_KEY, Constants.ALWAYS_REDIRECT_KEY]).then((storage) => { + + if (changeInfo["status"] && changeInfo["status"] == "complete") { + const url = URL.parse(tab["url"]); + + // if url is valid + if (url) { + const hostname = url.hostname; + const no_www_hostname = hostname.replace(/^(www\.)/,''); + const domains = storage[Constants.SPONSOR_DOMAINS_STORAGE_KEY]; + const target = domains[hostname] || domains[no_www_hostname]; + + if (target) { + // Check if we're still visiting the same site we already went through a sponsored link for + if (this.sponsoredTabs[tabId] && this.sponsoredTabs[tabId]['hostname'] === hostname) { + // If we have a origin location we came for, redirect back to that page + if (this.sponsoredTabs[tabId]['referrer']) { + this.navigateTo(tabId, this.sponsoredTabs[tabId]['referrer']); + this.sponsoredTabs[tabId]['referrer'] = null; + this.notifications.notifyOfRedirect(tabId); + } + return; } - return; - } - - if (storage[ALWAYS_REDIRECT_KEY]) { - // Immediately redirect to the affiliated link - sponsortabs[tabId] = {'hostname': hostname, 'referrer': url}; - navigateTo(tabId, target['link']); - } else { - enableLinking( - target['link'], - tabId, - hostname, - url, - target['name_short'] + ' heeft ook een gesponsorde link!' - ); - } + + // We are not an affiliated domain but affiliation is not active yet + if (storage[Constants.ALWAYS_REDIRECT_KEY]) { + // Immediately redirect to the affiliated link + this.sponsoredTabs[tabId] = { 'hostname': hostname, 'referrer': url.toString() }; + this.navigateTo(tabId, target['link']); + return; + } else { + + // Notify the user that there is an afiliation + this.notifications.notifyOfAffiliation(this, tabId, target['name_short'], url, target['link']); + return; + } + }; + }; + } }); + } + + /** + * Change the current website on the specified tab + * @param tabId {number} id of the tab to change the website of + * @param target {string} new website url + */ + navigateTo(tabId, target) { + chrome.tabs.update(tabId, { url: target }); + } } /** - * Extract the hostname from a full url - * Examples: - * http://www.google.com/search?q=example => www.google.com - * https://example.com?example => example.com + * Parse a string url to an URL object * @param url {string} full url * @returns {string} url with the protocol, path and get parameters stripped */ -function extractHostname(url) { - return ((url.indexOf('://') > -1) ? url.split('/')[2] : url.split('/')[0]).split('?')[0]; +function parseURL(url) { + if (!url.match(/^(http|https)/i)) url = "https://" + url; + return URL.parse(url); } -/** - * Get object(s) from local storage - * If the second parameter is not set, the first parameter will be used as callback - * and all objects will be retrieved instead of just the one specified by the key - * @param key {string|string[]=} object(s) to get from storage - * @param callback {function} function to call when the object(s) has/have loaded - */ -function getStorage(key, callback) { - if (!callback || typeof callback !== 'function') { - callback = key; - key = false; - } - - if (CHROME) { - if (key) { - browser.storage.local.get(key, callback); - } else { - browser.storage.local.get(callback); - } - } else { - const promise = (key) ? browser.storage.local.get(key) : browser.storage.local.get(); - promise.then(callback); - } -} /** * Return the unix timestamp of 1 day ago * @returns {number} unix timestamp in seconds */ function unixDayAgo() { - const d = new Date(); - d.setDate(d.getDate() - 1); - return unixTime(d); + const d = new Date(); + d.setDate(d.getDate() - 1); + return unixTime(d); } /** - * Convert Date object to unix time in seconds - * @param date {Date} Date object - * @returns {number} unix time in seconds - */ +* Convert Date object to unix time in seconds +* @param date {Date} Date object +* @returns {number} unix time in seconds +*/ function unixTime(date) { - return Math.round((date.getTime() / 1000)); -} + return Math.round((date.getTime() / 1000)); +} \ No newline at end of file diff --git a/src/installed.js b/src/installed.js index 776327e..4842b79 100644 --- a/src/installed.js +++ b/src/installed.js @@ -1 +1 @@ -document.documentElement.setAttribute('data-sponsorkliks-extension', '1'); \ No newline at end of file +document.documentElement.setAttribute('data-sponsorkliks-extension', '1'); diff --git a/src/notifications.js b/src/notifications.js new file mode 100644 index 0000000..53c2c0d --- /dev/null +++ b/src/notifications.js @@ -0,0 +1,57 @@ +import Constants from "./constants.js"; + +export default class Notifications { + currentAffiliationNoticationOnClickedListener = undefined; + currentRedirectNoticationOnClickedListener = undefined; + + removeAllEventListeners() { + if (this.currentAffiliationNoticationOnClickedListener) { + chrome.action.onClicked.removeListener(this.currentAffiliationNoticationOnClickedListener); + chrome.notifications.onClicked.removeListener(this.currentAffiliationNoticationOnClickedListener); + } + if (this.currentNoticationOnClickedListener) { + chrome.notifications.onClicked.removeListener(this.currentNoticationOnClickedListener); + } + } + + notifyOfRedirect(tabId) { + var id = Constants.NOTIFICATION_ID + 'redirected-' + tabId; + + chrome.notifications.create(id, { + type: 'basic', + title: 'Sponsoring van C.S.V. Alpha geactiveerd!', + message: 'C.S.V. Alpha ontvangt commissie als op op deze website iets koopt.', + iconUrl: chrome.runtime.getURL('icons/icon-128.png') + }); + + this.removeAllEventListeners(); + this.currentNoticationOnClickedListener = (notificationId) => { + if (notificationId === id) { + chrome.notifications.clear(notificationId); + } + }; + chrome.notifications.onClicked.addListener(this.currentNoticationOnClickedListener); + } + + notifyOfAffiliation(functions, tabId, siteName, originalUrl, sponsorUrl) { + var id = Constants.NOTIFICATION_ID + 'affiliation-' + tabId; + + chrome.notifications.create(id, { + type: 'basic', + title: siteName + ' heeft ook een gesponsorde link!', + message: 'Klik op deze notificatie of de icoon van de extensie om via die link te gaan.', + iconUrl: chrome.runtime.getURL('icons/icon-128.png') + }); + + this.removeAllEventListeners(); + this.currentAffiliationNoticationOnClickedListener = notificationId => { + if (notificationId === id || (notificationId.hasOwnProperty('id') && notificationId.id === tabId)) { + chrome.notifications.clear(id); + functions.sponsoredTabs[tabId] = { 'hostname': originalUrl.hostname, 'referrer': originalUrl.toString() }; + functions.navigateTo(tabId, sponsorUrl); + } + }; + chrome.action.onClicked.addListener(this.currentAffiliationNoticationOnClickedListener); + chrome.notifications.onClicked.addListener(this.currentAffiliationNoticationOnClickedListener); + } +} \ No newline at end of file diff --git a/src/options/options.html b/src/options/options.html new file mode 100644 index 0000000..3c8afb4 --- /dev/null +++ b/src/options/options.html @@ -0,0 +1,33 @@ + + + + + + + C.S.V. Alpha Sponsor Extensie - Instellingen + + + + +
+

+ +

+

+
+ + + + \ No newline at end of file diff --git a/src/settings/settings.js b/src/options/options.js similarity index 69% rename from src/settings/settings.js rename to src/options/options.js index e644a77..8787537 100644 --- a/src/settings/settings.js +++ b/src/options/options.js @@ -1,15 +1,16 @@ +import Constants from "../constants.js"; + /** * Called when the DOM is loaded * Restores the saved settings */ function restoreOptions() { - getStorage(ALWAYS_REDIRECT_KEY, storage => { - if (storage[ALWAYS_REDIRECT_KEY]) { + chrome.storage.local.get(Constants.ALWAYS_REDIRECT_KEY).then((storage) => { + if (storage[Constants.ALWAYS_REDIRECT_KEY]) { document.getElementById('always-redirect').checked = true; } }); } -document.addEventListener('DOMContentLoaded', restoreOptions); /** * Called when the form is submitted @@ -18,8 +19,8 @@ document.addEventListener('DOMContentLoaded', restoreOptions); function saveOptions(e) { e.preventDefault(); - browser.storage.local.set({ - [ALWAYS_REDIRECT_KEY]: document.getElementById('always-redirect').checked + chrome.storage.local.set({ + [Constants.ALWAYS_REDIRECT_KEY]: document.getElementById('always-redirect').checked }); const settingsSaved = document.getElementById('settings-saved'); @@ -28,4 +29,6 @@ function saveOptions(e) { settingsSaved.innerText = ''; }, 1000) } + +document.addEventListener('DOMContentLoaded', restoreOptions); document.getElementById('always-redirect').addEventListener('change', saveOptions); \ No newline at end of file diff --git a/src/settings/settings.html b/src/settings/settings.html deleted file mode 100644 index 29d45f4..0000000 --- a/src/settings/settings.html +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - C.S.V. Alpha Sponsor Extensie - Instellingen - - - - -
-

- -

-

-
- - - - \ No newline at end of file From 8e102d7fdf5a9fc242826f65a4157e8dea8bae60 Mon Sep 17 00:00:00 2001 From: Ellen-Wittingen Date: Thu, 15 Aug 2024 21:36:52 +0200 Subject: [PATCH 2/6] Edited notification text --- src/notifications.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/notifications.js b/src/notifications.js index 53c2c0d..2776064 100644 --- a/src/notifications.js +++ b/src/notifications.js @@ -19,8 +19,8 @@ export default class Notifications { chrome.notifications.create(id, { type: 'basic', - title: 'Sponsoring van C.S.V. Alpha geactiveerd!', - message: 'C.S.V. Alpha ontvangt commissie als op op deze website iets koopt.', + title: 'Sponsoring geactiveerd!', + message: 'C.S.V. Alpha ontvangt commissie als je op deze website iets koopt.', iconUrl: chrome.runtime.getURL('icons/icon-128.png') }); From b34153fb93e91deff7762739676537c7b6af854e Mon Sep 17 00:00:00 2001 From: Ellen-Wittingen Date: Fri, 16 Aug 2024 20:36:03 +0200 Subject: [PATCH 3/6] Added additional sponsored websites not returned by the API --- src/functions.js | 31 ++++++++++--------------------- 1 file changed, 10 insertions(+), 21 deletions(-) diff --git a/src/functions.js b/src/functions.js index d6728b6..2b944e5 100644 --- a/src/functions.js +++ b/src/functions.js @@ -1,25 +1,12 @@ import Constants from "./constants.js"; import Notifications from "./notifications.js"; +import AdditionalSponsoredWebsites from "./additional_sponsored_websites.js"; export default class Functions { filter = { url: [] }; sponsoredTabs = {}; notifications = new Notifications(); - async setFilter() { - this.filter.url = await chrome.storage.local.get(Constants.SPONSOR_DOMAINS_STORAGE_KEY).then((result) => { - var filterList = []; - Object.keys(result[Constants.SPONSOR_DOMAINS_STORAGE_KEY]).forEach(domain => { - filterList.push({ hostSuffix: domain }) - }) - return filterList; - }); - } - - // const filter = { - // url: [{ hostSuffix: 'google.com' }] - // }; - /** * Check if we should update the websites with affiliate links from the API * Links are updated every 24 hours @@ -55,16 +42,14 @@ export default class Functions { // } await chrome.storage.local.set({ - [Constants.SPONSOR_DOMAINS_STORAGE_KEY]: data['webshops'] + [Constants.SPONSOR_DOMAINS_STORAGE_KEY]: AdditionalSponsoredWebsites.concat(data['webshops']) .filter(obj => !!obj.orig_url) .reduce(function (map, obj) { var urlObj = parseURL(obj.orig_url); - if (urlObj) map[urlObj.host] = obj; + if (urlObj) map[urlObj.hostname.replace(/^www\./,'')] = obj; return map; }, {}), }); - - await this.setFilter(); } /** @@ -74,14 +59,18 @@ export default class Functions { onTabUpdated(tabId, changeInfo, tab) { chrome.storage.local.get([Constants.SPONSOR_DOMAINS_STORAGE_KEY, Constants.ALWAYS_REDIRECT_KEY]).then((storage) => { - if (changeInfo["status"] && changeInfo["status"] == "complete") { + if (changeInfo["status"] && changeInfo["status"] == "loading") { const url = URL.parse(tab["url"]); // if url is valid if (url) { const hostname = url.hostname; - const no_www_hostname = hostname.replace(/^(www\.)/,''); + const no_www_hostname = hostname.replace(/^\w+\./,''); const domains = storage[Constants.SPONSOR_DOMAINS_STORAGE_KEY]; + if (!domains) { + this.updateUrls(); + return; + } const target = domains[hostname] || domains[no_www_hostname]; if (target) { @@ -108,7 +97,7 @@ export default class Functions { this.notifications.notifyOfAffiliation(this, tabId, target['name_short'], url, target['link']); return; } - }; + } }; } }); From bcffa7615b163ab8bafbac5397d9d653e6309200 Mon Sep 17 00:00:00 2001 From: Ellen Date: Sat, 17 Aug 2024 17:09:52 +0200 Subject: [PATCH 4/6] Added missing file --- manifest.json | 11 +- src/additional_sponsored_websites.js | 382 +++++++++++++++++++++++++++ src/background_service.js | 4 +- src/constants.js | 4 +- src/functions.js | 51 ++-- src/notifications.js | 2 +- src/options/options.js | 28 +- 7 files changed, 427 insertions(+), 55 deletions(-) create mode 100644 src/additional_sponsored_websites.js diff --git a/manifest.json b/manifest.json index bddcbf8..4ef294f 100644 --- a/manifest.json +++ b/manifest.json @@ -19,7 +19,9 @@ ], "content_scripts": [ { - "js": ["src/installed.js"], + "js": [ + "src/installed.js" + ], "matches": [ "*://*.csvalpha.nl/*" ] @@ -27,7 +29,9 @@ ], "background": { "service_worker": "src/background_service.js", - "scripts": ["src/background_service.js"], + "scripts": [ + "src/background_service.js" + ], "type": "module" }, "action": { @@ -41,5 +45,4 @@ "page": "src/options/options.html", "open_in_tab": false } -} - \ No newline at end of file +} \ No newline at end of file diff --git a/src/additional_sponsored_websites.js b/src/additional_sponsored_websites.js new file mode 100644 index 0000000..420234b --- /dev/null +++ b/src/additional_sponsored_websites.js @@ -0,0 +1,382 @@ +export default [ + { + name_short: "Bol.com", + orig_url: "bol.com", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=12&shop=bol.com&link=aHR0cHMlM0ElMkYlMkZwYXJ0bmVyLmJvbC5jb20lMkZjbGljayUyRmNsaWNrJTNGcCUzRDIlMjZ0JTNEdXJsJTI2cyUzRDg5NjglMjZmJTNEVFhMJTI2dXJsJTNEaHR0cHMlM0ElMkYlMkZ3d3cuYm9sLmNvbSUyRm5sJTJGbmwlMkYlMjZuYW1lJTNEZGUlMjUyMHdpbmtlbCUyNTIwdmFuJTI1MjBvbnMlMjUyMGFsbGVtYWFsJTI2c3ViaWQlM0RTS180NTA5" + }, + { + name_short: "Coolblue", + orig_url: "coolblue.nl", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=61&shop=Coolblue&link=aHR0cHMlM0ElMkYlMkZwcmYuaG4lMkZjbGljayUyRmNhbXJlZiUzQTEwMTFsMzQ3NyUyRnB1YnJlZiUzQVNLXzQ1MDk=" + }, + { + name_short: "Expedia", + orig_url: "expedia.nl", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=85&shop=Expedia.nl&link=aHR0cHMlM0ElMkYlMkZ3d3cuZHBib2x2dy5uZXQlMkZjbGljay05MjE2ODgyLTEzODUyOTIxJTNGc2lkJTNEU0tfNDUwOQ==" + }, + { + name_short: "Thuisbezorgd", + orig_url: "thuisbezorgd.nl", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=4&shop=Thuisbezorgd.nl&link=aHR0cHMlM0ElMkYlMkZ3d3cuYXdpbjEuY29tJTJGYXdjbGljay5waHAlM0ZnaWQlM0QzNjUzOTQlMjZtaWQlM0QxMDUxMCUyNmF3aW5hZmZpZCUzRDMyODg0MSUyNmxpbmtpZCUzRDI2NTAwMzYlMjZjbGlja3JlZiUzRFNLXzQ1MDk=" + }, + { + name_short: "Trip.com", + orig_url: "trip.com", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=3951&shop=Trip.com&link=aHR0cHMlM0ElMkYlMkZ3d3cuYW5yZG9lenJzLm5ldCUyRmNsaWNrLTEwMDI5NDYxNi0xNTI1Mzc3NCUzRnNpZCUzRFNLXzQ1MDklMjZ1cmwlM0RodHRwcyUyNTNBJTI1MkYlMjUyRm5sLnRyaXAuY29tJTI1MkZob3RlbHMlMjUyRiUyNTNGbG9jYWxlJTI1M0RubC1OTCUyNTI2Y3VyciUyNTNERVVS" + }, + { + name_short: "MediaMarkt", + orig_url: "mediamarkt.nl", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=2158&shop=MediaMarkt&link=aHR0cHMlM0ElMkYlMkZjbGsudHJhZGVkb3VibGVyLmNvbSUyRmNsaWNrJTNGcCUzRDI2MjMzNiUyNmElM0QyMDQwOTgzJTI2ZyUzRDIyNjI3MzkwJTI2RVBJJTNEU0tfNDUwOQ==" + }, + { + name_short: "Viking", + orig_url: "vikingdirect.nl", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=48&shop=Viking&link=aHR0cCUzQSUyRiUyRnByZi5obiUyRmNsaWNrJTJGY2FtcmVmJTNBMTAxMWwzN3JxJTJGcHVicmVmJTNBU0tfNDUwOQ==" + }, + { + name_short: "Corendon", + orig_url: "corendon.nl", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=3949&shop=Correndon+&link=aHR0cHMlM0ElMkYlMkZyZWZlcnJhbC5jb3JlbmRvbi5ubCUyRmMlM0ZjJTNEMzgxMDglMjZhbXAlM0JtJTNEMjMyMzY2MiUyNmFtcCUzQmElM0Q5NTQ3MSUyNmFtcCUzQnIlM0RTS180NTA5JTI2YW1wJTNCdQ==" + }, + { + name_short: "HEMA", + orig_url: "hema.nl", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=3025&shop=HEMA&link=aHR0cHMlM0ElMkYlMkZ0Yy50cmFkZXRyYWNrZXIubmV0JTJGJTNGYyUzRDI1NDM2JTI2bSUzRDEyJTI2YSUzRDk1NDcxJTI2ciUzRFNLXzQ1MDklMjZ1JTNEJTI1MkY=" + }, + { + name_short: "Expert", + orig_url: "expert.nl", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=2339&shop=Expert&link=aHR0cHMlM0ElMkYlMkZ3d3cuZXhwZXJ0Lm5sJTJGdHQlMkYlM0Z0dCUzRDU1MTVfMTJfOTU0NzFfU0s0NTA5JTI2ciUzRCUyNTJG" + }, + { + name_short: "Tiqets Benelux", + orig_url: "tiqets.com", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=3421&shop=Tiqets+Benelux&link=aHR0cHMlM0ElMkYlMkZ3d3cuYXdpbjEuY29tJTJGY3JlYWQucGhwJTNGYXdpbm1pZCUzRDgxMTElMjZhd2luYWZmaWQlM0QzMjg4NDElMjZjbGlja3JlZiUzRFNLXzQ1MDklMjZ1ZWQlM0Q=" + }, + { + name_short: "Belvilla", + orig_url: "belvilla.nl", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=174&shop=Belvilla+&link=aHR0cCUzQSUyRiUyRnd3dy5hd2luMS5jb20lMkZhd2NsaWNrLnBocCUzRmdpZCUzRDMxNjkxMyUyNm1pZCUzRDgzMjQlMjZhd2luYWZmaWQlM0QzMjg4NDElMjZsaW5raWQlM0QxMDE4MzI0JTI2Y2xpY2tyZWYlM0RTS180NTA5" + }, + { + name_short: "HotelSpecials", + orig_url: "hotelspecials.nl", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=28&shop=HotelSpecials&link=aHR0cHMlM0ElMkYlMkZ3d3cuaG90ZWxzcGVjaWFscy5ubCUyRmhvdGVsJTJGJTNGdHQlM0Q2ODZfMjI5MjdfOTU0NzFfU0s0NTA5JTI2JTNEciUzRA==" + }, + { + name_short: "Plein.nl", + orig_url: "plein.nl", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=2382&shop=Huisdier+Plein&link=aHR0cHMlM0ElMkYlMkZkczEubmwlMkZjJTJGJTNGc2klM0QzMzY2JTI2bGklM0QxMTYxMjI0JTI2d2klM0QxNTA2MzglMjZ3cyUzRFNLXzQ1MDklMjZkbCUzRGh1aXNkaWVyJTI1MkY=" + }, + { + name_short: "GetYourGuide", + orig_url: "getyourguide.com", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=2758&shop=GetYourGuide&link=aHR0cHMlM0ElMkYlMkZ3d3cuZHBib2x2dy5uZXQlMkZjbGljay05MjE2ODgyLTE1MDAyOTc1JTNGc2lkJTNEU0tfNDUwOSUyNGFwaQ==" + }, + { + name_short: "Viator", + orig_url: "viator.com", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=3212&shop=Viator+-+A+TripAdvisor+Company+%28NL%29&link=aHR0cHMlM0ElMkYlMkZ3d3cuYXdpbjEuY29tJTJGY3JlYWQucGhwJTNGYXdpbm1pZCUzRDEzNTk5JTI2YXdpbmFmZmlkJTNEMzI4ODQxJTI2Y2xpY2tyZWYlM0RTS180NTA5JTI0YXBpJTI2cCUzRGh0dHBzJTI1M0ElMjUyRiUyNTJGd3d3LnZpYXRvcmNvbS5ubA==" + }, + { + name_short: "Björn Borg", + orig_url: "bjornborg.com", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=60&shop=Bjorn+Borg&link=aHR0cHMlM0ElMkYlMkZ0by5iam9ybmJvcmcuY29tJTJGdCUyRnQlM0ZhJTNEMTIxMjY5NzE1OCUyNmFzJTNEMTU3NDM5MjkxNiUyNnQlM0QyJTI2dGslM0QxJTI2ZXBpJTNEU0tfNDUwOSUyNGFwaQ==" + }, + { + name_short: "About You", + orig_url: "aboutyou.nl", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=3094&shop=About+You+&link=aHR0cCUzQSUyRiUyRnd3dy5hd2luMS5jb20lMkZhd2NsaWNrLnBocCUzRmdpZCUzRDMzNDE5MyUyNm1pZCUzRDEyMzU0JTI2YXdpbmFmZmlkJTNEMzI4ODQxJTI2bGlua2lkJTNEMjEzNjcxOSUyNmNsaWNrcmVmJTNEU0tfNDUwOSUyNGFwaQ==" + }, + { + name_short: "Guess", + orig_url: "guess.eu", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=3927&shop=Guess&link=aHR0cHMlM0ElMkYlMkZ3d3cuYXdpbjEuY29tJTJGY3JlYWQucGhwJTNGYXdpbm1pZCUzRDEyMjgxJTI2YXdpbmFmZmlkJTNEMzI4ODQxJTI2Y2xpY2tyZWYlM0RTS180NTA5JTI0YXBp" + }, + { + name_short: "Hallmark", + orig_url: "hallmark.nl", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=3930&shop=Hallmark&link=aHR0cHMlM0ElMkYlMkZ3d3cuYXdpbjEuY29tJTJGYXdjbGljay5waHAlM0ZnaWQlM0Q0NzYyMjglMjZtaWQlM0Q2MzAzNCUyNmF3aW5hZmZpZCUzRDMyODg0MSUyNmxpbmtpZCUzRDM0OTk5NDklMjZjbGlja3JlZiUzRFNLXzQ1MDklMjRhcGk=" + }, + { + name_short: "TradeInn", + orig_url: "tradeinn.com", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=3962&shop=TradeInn&link=aHR0cHMlM0ElMkYlMkZ0bmtkYmYudHJhZGVpbm4uY29tJTJGdHMlMkZpNTAzNDc3NiUyRnRzYyUzRmFtYyUzRGluYy5ibGJuLjUyNjE2Ny41MzYwMzMuMTQxMTk3ODUlMjZybWQlM0QzJTI2c21jMSUzRFNLXzQ1MDklMjRhcGklMjZ0cmclM0RodHRwcyUyNTNBJTI1MkYlMjUyRnd3dy50cmFkZWlubi5jb20lMjUyRm5s" + }, + { + name_short: "Welhof", + orig_url: "welhof.com", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=3964&shop=Welhof&link=aHR0cHMlM0ElMkYlMkZ3d3cuYXdpbjEuY29tJTJGY3JlYWQucGhwJTNGcyUzRDMzNDQzMDclMjZ2JTNENDQ3MjclMjZxJTNENDU5NDczJTI2ciUzRDMyODg0MSUyNmNsaWNrcmVmJTNEU0tfNDUwOSUyNGFwaQ==" + }, + { + name_short: "Allesvoorbqq.nl", + orig_url: "barbecueshop.nl", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=3861&shop=Allesvoorbbq.nl&link=aHR0cHMlM0ElMkYlMkZ0Yy50cmFkZXRyYWNrZXIubmV0JTJGJTNGYyUzRDI3MDI0JTI2bSUzRDEyJTI2YSUzRDk1NDcxJTI2ciUzRFNLXzQ1MDklMjRhcGklMjZ1JTNE" + }, + { + name_short: "WE Fashion", + orig_url: "wefashion.com", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=127&shop=WE+Fashion&link=aHR0cHMlM0ElMkYlMkZwaW4ud2VmYXNoaW9uLmNvbSUyRnQlMkZ0JTNGYSUzRDE4NDA5NTQ5MjIlMjZhcyUzRDE1NzQzOTI5MTYlMjZ0JTNEMiUyNnRrJTNEMSUyNmVwaSUzRFNLXzQ1MDklMjRhcGk=" + }, + { + name_short: "Garcia", + orig_url: "wearegarcia.nl", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=3623&shop=Garcia+NL-BE&link=aHR0cHMlM0ElMkYlMkZ3d3cuYXdpbjEuY29tJTJGY3JlYWQucGhwJTNGYXdpbm1pZCUzRDE5NTg3JTI2YXdpbmFmZmlkJTNEMzI4ODQxJTI2Y2xpY2tyZWYlM0RTS180NTA5JTI0YXBp" + }, + { + name_short: "Steigerhouttrend", + orig_url: "loodsxl.nl", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=3533&shop=Steigerhouttrend+NL&link=aHR0cHMlM0ElMkYlMkZ3d3cuYXdpbjEuY29tJTJGY3JlYWQucGhwJTNGYXdpbm1pZCUzRDIxMTYzJTI2YXdpbmFmZmlkJTNEMzI4ODQxJTI2Y2xpY2tyZWYlM0RTS180NTA5JTI0YXBp" + }, + { + name_short: "Motorbandmarkt", + orig_url: "motorbandenmarkt.nl", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=3411&shop=Motorbandenmarkt+NL&link=aHR0cHMlM0ElMkYlMkZ3d3cuYXdpbjEuY29tJTJGY3JlYWQucGhwJTNGYXdpbm1pZCUzRDgyODclMjZhd2luYWZmaWQlM0QzMjg4NDElMjZjbGlja3JlZiUzRFNLXzQ1MDklMjRhcGklMjZ1ZWQlM0Q=" + }, + { + name_short: "Kixx", + orig_url: "kixx.nl", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=1832&shop=Kixx-online.nl&link=aHR0cHMlM0ElMkYlMkZ3d3cuYXdpbjEuY29tJTJGY3JlYWQucGhwJTNGYXdpbm1pZCUzRDEyNDgzJTI2YXdpbmFmZmlkJTNEMzI4ODQxJTI2Y2xpY2tyZWYlM0RTS180NTA5JTI0YXBpJTI2cCUzRGh0dHAlMjUzQSUyNTJGJTI1MkZ3d3cua2l4eC1vbmxpbmUubmw=" + }, + { + name_short: "Tellsell", + orig_url: "telsell.com functions.js:103:23", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=3598&shop=Telsell+NL&link=aHR0cHMlM0ElMkYlMkZ3d3cuYXdpbjEuY29tJTJGY3JlYWQucGhwJTNGYXdpbm1pZCUzRDg1MTUlMjZhd2luYWZmaWQlM0QzMjg4NDElMjZjbGlja3JlZiUzRFNLXzQ1MDklMjRhcGk=" + }, + { + name_short: "Ugg", + orig_url: "ugg.com", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=3047&shop=Ugg+NL&link=aHR0cHMlM0ElMkYlMkZ3d3cuYXdpbjEuY29tJTJGY3JlYWQucGhwJTNGYXdpbm1pZCUzRDg2NDYlMjZhd2luYWZmaWQlM0QzMjg4NDElMjZjbGlja3JlZiUzRFNLXzQ1MDklMjRhcGklMjZwJTNEaHR0cHMlM0ElMkYlMkZ3d3cudWdnLmNvbSUyRmV1JTJGbmwlMkZubCUyRmhvbWU=" + }, + { + name_short: "Vattenfall", + orig_url: "vattenfall.nl", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=208&shop=Vattenfall&link=aHR0cHMlM0ElMkYlMkZsdDQ1Lm5ldCUyRmMlMkYlM0ZzaSUzRDIwMzYlMjZsaSUzRDExOTk4NiUyNndpJTNEMTUwNjM4JTI2d3MlM0RTS180NTA5JTI0YXBpJTI2ZGwlM0Q=" + }, + { + name_short: "Duijvenstein", + orig_url: "duijvestein-winterstore.nl", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=3537&shop=Duijvenstein+NL&link=aHR0cHMlM0ElMkYlMkZ3d3cuYXdpbjEuY29tJTJGY3JlYWQucGhwJTNGYXdpbm1pZCUzRDIwMzQ3JTI2YXdpbmFmZmlkJTNEMzI4ODQxJTI2Y2xpY2tyZWYlM0RTS180NTA5JTI0YXBp" + }, + { + name_short: "Reebok", + orig_url: "reebok.eu", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=3252&shop=Reebok+NL&link=aHR0cHMlM0ElMkYlMkZyZWVib2sucHJmLmhuJTJGY2xpY2slMkZjYW1yZWYlM0ExMTAwbHpYOUUlMkZwdWJyZWYlM0FTS180NTA5JTI0YXBpJTJGJTVCcF9pZCUzQTEwbDIyOTExJTVE" + }, + { + name_short: "Kalenderwinkel", + orig_url: "kalenderwinkel.nl", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=3335&shop=Kalenderwinkel.nl&link=aHR0cHMlM0ElMkYlMkZ3d3cua2FsZW5kZXJ3aW5rZWwubmwlMkZ0cmFja2luZyUyRnRyYWRldHJhY2tlciUyRnJlZGlyZWN0JTJGJTNGdHQlM0QyOTg1Nl8xMl85NTQ3MV9TSzQ1MDklMjRhcGk=" + }, + { + name_short: "NordVPN", + orig_url: "nordvpn.com", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=3618&shop=NordVPN+NL&link=aHR0cHMlM0ElMkYlMkZ0cmFjay5hZHRyYWN0aW9uLmNvbSUyRnQlMkZ0JTNGYSUzRDE0MDE0MzI1NzglMjZhcyUzRDE1NzQzOTI5MTYlMjZ0JTNEMiUyNnRrJTNEMSUyNmVwaSUzRFNLXzQ1MDklMjRhcGk=" + }, + { + name_short: "Luisterrijk", + orig_url: "luisterrijk.nl", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=3724&shop=Luisterrijk+NL&link=aHR0cHMlM0ElMkYlMkZpb24ubHVpc3RlcnJpamsubmwlMkZ0JTJGdCUzRmElM0QxNjIxMjE5OTExJTI2YXMlM0QxNTc0MzkyOTE2JTI2dCUzRDIlMjZ0ayUzRDElMjZlcGklM0RTS180NTA5JTI0YXBp" + }, + { + name_short: "Intergard", + orig_url: "intergard.eu", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=3622&shop=InterGard+tuinartikelen+NL&link=aHR0cHMlM0ElMkYlMkZ3d3cuYXdpbjEuY29tJTJGY3JlYWQucGhwJTNGYXdpbm1pZCUzRDIxODYxJTI2YXdpbmFmZmlkJTNEMzI4ODQxJTI2Y2xpY2tyZWYlM0RTS180NTA5JTI0YXBp" + }, + { + name_short: "Smartphoto", + orig_url: "smartphoto.nl", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=3745&shop=Smartphoto.nl&link=aHR0cHMlM0ElMkYlMkZ3d3cuc21hcnRwaG90by5ubCUyRnByaW50JTJGaW5kZXguYXNweCUzRnR0JTNENDkwM18xMl85NTQ3MV9TSzQ1MDklMjRhcGklMjZyJTNE" + }, + { + name_short: "Wonderbox", + orig_url: "wonderbox.nl", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=3401&shop=Wonderbox&link=aHR0cHMlM0ElMkYlMkZjbGsudHJhZGVkb3VibGVyLmNvbSUyRmNsaWNrJTNGcCUzRDMwNTk5NCUyNmElM0QyMDQwOTgzJTI2ZyUzRDI0NzcyMzQ4JTI2RVBJJTNEU0tfNDUwOSUyNGFwaQ==" + }, + { + name_short: "Kabelmix", + orig_url: "kabelmix.nl", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=3615&shop=Kabelmix+NL&link=aHR0cHMlM0ElMkYlMkZ0cmFjay5hZHRyYWN0aW9uLmNvbSUyRnQlMkZ0JTNGYSUzRDE1NTI3NDUwMjklMjZhcyUzRDE1NzQzOTI5MTYlMjZ0JTNEMiUyNnRrJTNEMSUyNmVwaSUzRFNLXzQ1MDklMjRhcGk=" + }, + { + name_short: "Lucky Day", + orig_url: "luckyday.nederlandseloterij.nl", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=3296&shop=Lucky+Day+NL&link=aHR0cHMlM0ElMkYlMkZ3d3cuYXdpbjEuY29tJTJGY3JlYWQucGhwJTNGYXdpbm1pZCUzRDMxMzQ3JTI2YXdpbmFmZmlkJTNEMzI4ODQxJTI2Y2xpY2tyZWYlM0RTS180NTA5JTI0YXBp" + }, + { + name_short: "HoriznStudios", + orig_url: "horizn-studios.com", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=3396&shop=HoriznStudios&link=aHR0cHMlM0ElMkYlMkZ3d3cuZHBib2x2dy5uZXQlMkZjbGljay05MjE2ODgyLTEzOTk3ODI4JTNGc2lkJTNEU0tfNDUwOSUyNGFwaQ==" + }, + { + name_short: "Parknfly", + orig_url: "parknfly.nl", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=3756&shop=Parknfly&link=aHR0cHMlM0ElMkYlMkZjbGsudHJhZGVkb3VibGVyLmNvbSUyRmNsaWNrJTNGcCUzRDMyMTEyMCUyNmElM0QyMDQwOTgzJTI2ZyUzRDI1MDU2MzY2JTI2RVBJJTNEU0tfNDUwOSUyNGFwaQ==" + }, + { + name_short: "Benetton", + orig_url: "benetton.com", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=3364&shop=Benetton&link=aHR0cCUzQSUyRiUyRmNsaWNrLmxpbmtzeW5lcmd5LmNvbSUyRmZzLWJpbiUyRmNsaWNrJTNGaWQlM0RTZWZtTnRYWUJZbyUyNm9mZmVyaWQlM0Q3MjA0MjklMjZ0eXBlJTNEMyUyNnN1YmlkJTNEMCUyNnUxJTNEU0tfNDUwOSUyNGFwaQ==" + }, + { + name_short: "De Friesland", + orig_url: "defriesland.nl", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=3525&shop=De+Friesland+&link=aHR0cHMlM0ElMkYlMkZ3d3cuYXdpbjEuY29tJTJGY3JlYWQucGhwJTNGYXdpbm1pZCUzRDgzNDYlMjZhd2luYWZmaWQlM0QzMjg4NDElMjZjbGlja3JlZiUzRFNLXzQ1MDklMjRhcGk=" + }, + { + name_short: "Hostnet", + orig_url: "hostnet.nl", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=3602&shop=Hostnet+NL&link=aHR0cHMlM0ElMkYlMkZ3d3cuYXdpbjEuY29tJTJGY3JlYWQucGhwJTNGYXdpbm1pZCUzRDIxMTg5JTI2YXdpbmFmZmlkJTNEMzI4ODQxJTI2Y2xpY2tyZWYlM0QlMjU3Q2NsdWIlMjU3Qw==" + }, + { + name_short: "The Social Hub", + orig_url: "thesocialhub.co", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=3332&shop=The+Social+Hub&link=aHR0cHMlM0ElMkYlMkZjbGsudHJhZGVkb3VibGVyLmNvbSUyRmNsaWNrJTNGcCUzRDI5OTM0NyUyNmElM0QyMDQwOTgzJTI2ZyUzRDI1MjY2NTA0JTI2RVBJJTNEU0tfNDUwOSUyNGFwaQ==" + }, + { + name_short: "Vonroc", + orig_url: "vonroc.com", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=3843&shop=Vonroc+NL&link=aHR0cHMlM0ElMkYlMkZjbGsudHJhZGVkb3VibGVyLmNvbSUyRmNsaWNrJTNGcCUzRDMzMjU3MCUyNmElM0QyMDQwOTgzJTI2ZyUzRDI1Mjg0Nzc0JTI2RVBJJTNEU0tfNDUwOSUyNGFwaQ==" + }, + { + name_short: "Youfone", + orig_url: "youfone.nl", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=2192&shop=Youfone+NL&link=aHR0cHMlM0ElMkYlMkZ3d3cuYXdpbjEuY29tJTJGY3JlYWQucGhwJTNGYXdpbm1pZCUzRDg1MDUlMjZhd2luYWZmaWQlM0QzMjg4NDElMjZjbGlja3JlZiUzRFNLXzQ1MDklMjRhcGk=" + }, + { + name_short: "Knaldeals", + orig_url: "knaldeals.com", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=3410&shop=Knaldeals+&link=aHR0cHMlM0ElMkYlMkZ3d3cuYXdpbjEuY29tJTJGY3JlYWQucGhwJTNGYXdpbm1pZCUzRDgyMzYlMjZhd2luYWZmaWQlM0QzMjg4NDElMjZjbGlja3JlZiUzRFNLXzQ1MDklMjRhcGklMjZ1ZWQlM0Q=" + }, + { + name_short: "AV-Tours", + orig_url: "avtours.nl", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=2723&shop=AV-Tours&link=aHR0cCUzQSUyRiUyRmF2dG91cnMubmwlMkZyb25kcmVpcyUyRiUzRnR0JTNEMjI3NTJfMTJfOTU0NzFfJTI2ciUzRFNLXzQ1MDklMjRhcGk=" + }, + { + name_short: "Canal Digitaal", + orig_url: "canalplus.nl", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=2733&shop=Canal+Digitaal+NL&link=aHR0cHMlM0ElMkYlMkZ3d3cuYXdpbjEuY29tJTJGY3JlYWQucGhwJTNGYXdpbm1pZCUzRDE5MTI5JTI2YXdpbmFmZmlkJTNEMzI4ODQxJTI2Y2xpY2tyZWYlM0RTS180NTA5JTI0YXBp" + }, + { + name_short: "Peeq", + orig_url: "peeq.nl", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=2595&shop=DmLights&link=aHR0cCUzQSUyRiUyRmRzMS5ubCUyRmMlMkYlM0Z3aSUzRDE1MDYzOCUyNnNpJTNEOTk3NiUyNmxpJTNEMTQ1MzA5MyUyNndzJTNEU0tfNDUwOSUyNGFwaQ==" + }, + { + name_short: "HappyRainyDays", + orig_url: "happyrainydays.com", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=2543&shop=HappyRainyDays&link=aHR0cCUzQSUyRiUyRnRjLnRyYWRldHJhY2tlci5uZXQlMkYlM0ZjJTNEMjc0OCUyNm0lM0QxMiUyNmElM0Q5NTQ3MSUyNnUlM0QlMjUyRiUyNnIlM0RTS180NTA5JTI0YXBp" + }, + { + name_short: "Heine", + orig_url: "heine-shop.nl", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=105&shop=Heine&link=aHR0cCUzQSUyRiUyRmNsay50cmFkZWRvdWJsZXIuY29tJTJGY2xpY2slM0ZwJTNENjMwNDIlMjZhJTNEMjA0MDk4MyUyNmclM0QxNzE0MTAzMCUyNkVQSSUzRFNLXzQ1MDklMjRhcGk=" + }, + { + name_short: "JHP Fasion", + orig_url: "jhpfashion.nl", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=2533&shop=JHP-Fashion.nl&link=aHR0cCUzQSUyRiUyRnd3dy5qaHBmYXNoaW9uLm5sJTJGJTNGdHQlM0QxODQ4M18xMl85NTQ3MV9TSzQ1MDklMjRhcGklMjZyJTNE" + }, + { + name_short: "The Surprise Factory", + orig_url: "surprisefactory.nl", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=2552&shop=Kadopagina.nl&link=aHR0cCUzQSUyRiUyRnd3dy5rYWRvcGFnaW5hLm5sJTJGa2FkbyUyRiUzRnR0JTNENzI0Nl8xMl85NTQ3MV9TSzQ1MDklMjRhcGklMjZyJTNE" + }, + { + name_short: "Kaspersky", + orig_url: "kaspersky.nl", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=3497&shop=Kaspersky+NL&link=aHR0cHMlM0ElMkYlMkZ3d3cuYXdpbjEuY29tJTJGY3JlYWQucGhwJTNGYXdpbm1pZCUzRDE5NDg3JTI2YXdpbmFmZmlkJTNEMzI4ODQxJTI2Y2xpY2tyZWYlM0RTS180NTA5JTI0YXBpJTI2dWVkJTNE" + }, + { + name_short: "Lopesan Hotels", + orig_url: "lopesan.com", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=2946&shop=Lopesanhotels.com&link=aHR0cCUzQSUyRiUyRnRjLnRyYWRldHJhY2tlci5uZXQlMkYlM0ZjJTNEMzcxNyUyNm0lM0QxMiUyNmElM0Q5NTQ3MSUyNnIlM0RTS180NTA5JTI0YXBp" + }, + { + name_short: "Kledingwinkel", + orig_url: "kledingwinkel.nl", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=2952&shop=Riemenzo.nl&link=aHR0cHMlM0ElMkYlMkZ3d3cucmllbWVuem8ubmwlMkZwcm9kdWN0ZW4lMkYlM0Z0dCUzRDIzOTE4XzEyXzk1NDcxX1NLNDUwOSUyNGFwaSUyNnIlM0Q=" + }, + { + name_short: "Audioshop", + orig_url: "audioshop.nl", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=2452&shop=Soundmaster-shop.nl&link=aHR0cCUzQSUyRiUyRnd3dy5zb3VuZG1hc3Rlci1zaG9wLm5sJTJGc291bmQlMkYlM0Z0dCUzRDIwNzkwXzEyXzk1NDcxX1NLNDUwOSUyNGFwaSUyNnIlM0Q=" + }, + { + name_short: "Plustoys", + orig_url: "plustoys.nl", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=2958&shop=Speelgoedindeton.nl&link=aHR0cCUzQSUyRiUyRnd3dy5zcGVlbGdvZWRpbmRldG9uLm5sJTJGc3BlZWxnb2VkJTJGJTNGdHQlM0QxNzI0OF8xMl85NTQ3MV9TSzQ1MDklMjRhcGklMjZyJTNE" + }, + { + name_short: "Sunparks", + orig_url: "sunparks.com", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=2666&shop=Sunparks&link=aHR0cHMlM0ElMkYlMkZjbGsudHJhZGVkb3VibGVyLmNvbSUyRmNsaWNrJTNGcCUzRDI3NTIyNSUyNmElM0QyMDQwOTgzJTI2ZyUzRDIzNjI4Njc4JTI2RVBJJTNEU0tfNDUwOSUyNGFwaQ==" + }, + { + name_short: "Timarco", + orig_url: "timarco.com", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=2905&shop=Timarco.nl&link=aHR0cCUzQSUyRiUyRnRjLnRyYWRldHJhY2tlci5uZXQlMkYlM0ZjJTNEMTc2NjAlMjZtJTNEMTIlMjZhJTNEOTU0NzFfJTI2ciUzRFNLXzQ1MDklMjRhcGk=" + }, + { + name_short: "Voetbalshop", + orig_url: "voetbalshop.nl", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=2522&shop=Trainingspakken.nl&link=aHR0cCUzQSUyRiUyRnd3dy50cmFpbmluZ3NwYWtrZW4ubmwlMkYlM0Z0dCUzRDIwMTg0XzEyXzk1NDcxX1NLNDUwOSUyNGFwaSUyNnIlM0Q=" + }, + { + name_short: "iPhome-cases", + orig_url: "iphone-cases.nl", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=3593&shop=iPhone-Cases+NL&link=aHR0cHMlM0ElMkYlMkZ3d3cuYXdpbjEuY29tJTJGY3JlYWQucGhwJTNGYXdpbm1pZCUzRDIwMzU5JTI2YXdpbmFmZmlkJTNEMzI4ODQxJTI2Y2xpY2tyZWYlM0RTS180NTA5JTI0YXBp" + }, + { + name_short: "Tirendo", + orig_url: "tirendo.nl", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=3412&shop=Tirendo+NL&link=aHR0cHMlM0ElMkYlMkZ3d3cuYXdpbjEuY29tJTJGY3JlYWQucGhwJTNGYXdpbm1pZCUzRDg2NzYlMjZhd2luYWZmaWQlM0QzMjg4NDElMjZjbGlja3JlZiUzRFNLXzQ1MDklMjRhcGklMjZ1ZWQlM0Q=" + }, + { + name_short: "After Eden", + orig_url: "aftereden.nl", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=3405&shop=After+Eden+NL&link=aHR0cHMlM0ElMkYlMkZ3d3cuYXdpbjEuY29tJTJGY3JlYWQucGhwJTNGYXdpbm1pZCUzRDgyMzklMjZhd2luYWZmaWQlM0QzMjg4NDElMjZjbGlja3JlZiUzRFNLXzQ1MDklMjRhcGklMjZ1ZWQlM0Q=" + }, + { + name_short: "Bunzl", + orig_url: "bunzlonline.nl", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=3300&shop=Bunzlonline.nl&link=aHR0cHMlM0ElMkYlMkZ0Yy50cmFkZXRyYWNrZXIubmV0JTJGJTNGYyUzRDI5OTY1JTI2bSUzRDEyJTI2YSUzRDk1NDcxJTI2ciUzRFNLXzQ1MDklMjRhcGk=" + }, + { + name_short: "Douchezaak", + orig_url: "douchezaak.nl", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=3725&shop=Douchezaak+NL&link=aHR0cHMlM0ElMkYlMkZ3d3cuYXdpbjEuY29tJTJGY3JlYWQucGhwJTNGYXdpbm1pZCUzRDI0NjEyJTI2YXdpbmFmZmlkJTNEMzI4ODQxJTI2Y2xpY2tyZWYlM0RTS180NTA5JTI0YXBp" + }, + { + name_short: "Delife", + orig_url: "delife.nl", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=3761&shop=Delife+NL&link=aHR0cHMlM0ElMkYlMkZ0b25sLmRlbGlmZS5ldSUyRnQlMkZ0JTNGYSUzRDE1MDU4MzEwMDQlMjZhcyUzRDE1NzQzOTI5MTYlMjZ0JTNEMiUyNnRrJTNEMSUyNmVwaSUzRFNLXzQ1MDklMjRhcGk=" + }, + { + name_short: "Stacker", + orig_url: "stackeronline.com", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=3534&shop=Stackeronline.com&link=aHR0cHMlM0ElMkYlMkZ0Yy50cmFkZXRyYWNrZXIubmV0JTJGJTNGYyUzRDMyNzY3JTI2bSUzRDEyJTI2YSUzRDk1NDcxJTI2ciUzRFNLXzQ1MDklMjRhcGk=" + }, + { + name_short: "Brightday", + orig_url: "bright.nl", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=3276&shop=Brightday.nl&link=aHR0cHMlM0ElMkYlMkZ3d3cuYnJpZ2h0ZGF5Lm5sJTJGZGF5JTJGJTNGdHQlM0QzMDQ2Ml8xMl85NTQ3MV9TSzQ1MDklMjRhcGk=" + }, + { + name_short: "Backjoy", + orig_url: "backjoy.eu", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=3536&shop=Backjoy+Europe+NL&link=aHR0cHMlM0ElMkYlMkZ3d3cuYXdpbjEuY29tJTJGY3JlYWQucGhwJTNGYXdpbm1pZCUzRDIxNDQ4JTI2YXdpbmFmZmlkJTNEMzI4ODQxJTI2Y2xpY2tyZWYlM0RTS180NTA5JTI0YXBp" + }, + { + name_short: "Ivacy", + orig_url: "ivacy.com", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=3535&shop=Ivacy+VPN&link=aHR0cHMlM0ElMkYlMkZ3d3cuYXdpbjEuY29tJTJGY3JlYWQucGhwJTNGYXdpbm1pZCUzRDE1MzcxJTI2YXdpbmFmZmlkJTNEMzI4ODQxJTI2Y2xpY2tyZWYlM0RTS180NTA5JTI0YXBp" + }, + { + name_short: "NH Hotels", + orig_url: "nh-hotels.com", + link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=3936&shop=NH+Hotel&link=aHR0cHMlM0ElMkYlMkZuaGhvdGVsZ3JvdXAuc2p2LmlvJTJGcTRYejQ1" + } +]; \ No newline at end of file diff --git a/src/background_service.js b/src/background_service.js index cc02596..a23cbd3 100644 --- a/src/background_service.js +++ b/src/background_service.js @@ -12,9 +12,9 @@ async function setAlarm() { if (!alarm) { // Register for periodic endpoint updates - await chrome.alarms.create("update-sponsor-links-alarm", { + await chrome.alarms.create("update-sponsor-links-alarm", { delayInMinutes: Constants.UPDATE_CHECK_INTERVAL, - periodInMinutes: Constants.UPDATE_CHECK_INTERVAL + periodInMinutes: Constants.UPDATE_CHECK_INTERVAL }); chrome.alarms.onAlarm.addListener(function (alarm) { diff --git a/src/constants.js b/src/constants.js index b60d38c..a642797 100644 --- a/src/constants.js +++ b/src/constants.js @@ -1,12 +1,10 @@ export default class Constants { static CLUBID = 4509; - static API = "https://www.sponsorkliks.com/api/?club="+this.CLUBID+"&call=webshops_club_extension"; + static API = "https://www.sponsorkliks.com/api/?club=" + this.CLUBID + "&call=webshops_club_extension"; static UPDATE_CHECK_INTERVAL = 600; static UPDATE_CHECK_ALARM_NAME = "update-sponsor-links-alarm"; static SPONSOR_DOMAINS_STORAGE_KEY = 'sponsor-domains'; static LASTCHECK_KEY = 'lastcheck'; static ALWAYS_REDIRECT_KEY = 'always-redirect'; static NOTIFICATION_ID = 'sponsor-notification-'; - - static BROWSER = typeof browser === 'undefined' ? chrome : browser; } diff --git a/src/functions.js b/src/functions.js index 2b944e5..1a16a0a 100644 --- a/src/functions.js +++ b/src/functions.js @@ -13,17 +13,17 @@ export default class Functions { */ async checkUpdateUrls() { chrome.storage.local.get([Constants.SPONSOR_DOMAINS_STORAGE_KEY, Constants.LASTCHECK_KEY]).then(async (storage) => { - if (typeof storage[Constants.SPONSOR_DOMAINS_STORAGE_KEY] !== 'undefined') { - const lastCheck = storage[Constants.LASTCHECK_KEY] || 0; - if (lastCheck < unixDayAgo()) { - chrome.storage.local.set({ - [Constants.LASTCHECK_KEY]: unixTime(new Date()), - }); - await this.updateUrls(); - } - } else { + if (typeof storage[Constants.SPONSOR_DOMAINS_STORAGE_KEY] !== 'undefined') { + const lastCheck = storage[Constants.LASTCHECK_KEY] || 0; + if (lastCheck < unixDayAgo()) { + chrome.storage.local.set({ + [Constants.LASTCHECK_KEY]: unixTime(new Date()), + }); await this.updateUrls(); } + } else { + await this.updateUrls(); + } }); } @@ -45,8 +45,8 @@ export default class Functions { [Constants.SPONSOR_DOMAINS_STORAGE_KEY]: AdditionalSponsoredWebsites.concat(data['webshops']) .filter(obj => !!obj.orig_url) .reduce(function (map, obj) { - var urlObj = parseURL(obj.orig_url); - if (urlObj) map[urlObj.hostname.replace(/^www\./,'')] = obj; + var urlObj = URL.parse(obj.orig_url); + if (urlObj) map[urlObj.hostname.replace(/^www\./, '')] = obj; return map; }, {}), }); @@ -65,7 +65,7 @@ export default class Functions { // if url is valid if (url) { const hostname = url.hostname; - const no_www_hostname = hostname.replace(/^\w+\./,''); + const no_www_hostname = hostname.replace(/^\w+\./, ''); const domains = storage[Constants.SPONSOR_DOMAINS_STORAGE_KEY]; if (!domains) { this.updateUrls(); @@ -84,18 +84,18 @@ export default class Functions { } return; } - + // We are not an affiliated domain but affiliation is not active yet if (storage[Constants.ALWAYS_REDIRECT_KEY]) { - // Immediately redirect to the affiliated link - this.sponsoredTabs[tabId] = { 'hostname': hostname, 'referrer': url.toString() }; - this.navigateTo(tabId, target['link']); - return; + // Immediately redirect to the affiliated link + this.sponsoredTabs[tabId] = { 'hostname': hostname, 'referrer': url.toString() }; + this.navigateTo(tabId, target['link']); + return; } else { - // Notify the user that there is an afiliation - this.notifications.notifyOfAffiliation(this, tabId, target['name_short'], url, target['link']); - return; + // Notify the user that there is an afiliation + this.notifications.notifyOfAffiliation(this, tabId, target['name_short'], url, target['link']); + return; } } }; @@ -113,17 +113,6 @@ export default class Functions { } } -/** - * Parse a string url to an URL object - * @param url {string} full url - * @returns {string} url with the protocol, path and get parameters stripped - */ -function parseURL(url) { - if (!url.match(/^(http|https)/i)) url = "https://" + url; - return URL.parse(url); -} - - /** * Return the unix timestamp of 1 day ago * @returns {number} unix timestamp in seconds diff --git a/src/notifications.js b/src/notifications.js index 2776064..75ea6af 100644 --- a/src/notifications.js +++ b/src/notifications.js @@ -13,7 +13,7 @@ export default class Notifications { chrome.notifications.onClicked.removeListener(this.currentNoticationOnClickedListener); } } - + notifyOfRedirect(tabId) { var id = Constants.NOTIFICATION_ID + 'redirected-' + tabId; diff --git a/src/options/options.js b/src/options/options.js index 8787537..dd0a926 100644 --- a/src/options/options.js +++ b/src/options/options.js @@ -5,11 +5,11 @@ import Constants from "../constants.js"; * Restores the saved settings */ function restoreOptions() { - chrome.storage.local.get(Constants.ALWAYS_REDIRECT_KEY).then((storage) => { - if (storage[Constants.ALWAYS_REDIRECT_KEY]) { - document.getElementById('always-redirect').checked = true; - } - }); + chrome.storage.local.get(Constants.ALWAYS_REDIRECT_KEY).then((storage) => { + if (storage[Constants.ALWAYS_REDIRECT_KEY]) { + document.getElementById('always-redirect').checked = true; + } + }); } /** @@ -17,17 +17,17 @@ function restoreOptions() { * @param e {object} submit event */ function saveOptions(e) { - e.preventDefault(); + e.preventDefault(); - chrome.storage.local.set({ - [Constants.ALWAYS_REDIRECT_KEY]: document.getElementById('always-redirect').checked - }); + chrome.storage.local.set({ + [Constants.ALWAYS_REDIRECT_KEY]: document.getElementById('always-redirect').checked + }); - const settingsSaved = document.getElementById('settings-saved'); - settingsSaved.innerHTML = 'Wijzigingen opgeslagen'; - setTimeout(function() { - settingsSaved.innerText = ''; - }, 1000) + const settingsSaved = document.getElementById('settings-saved'); + settingsSaved.innerHTML = 'Wijzigingen opgeslagen'; + setTimeout(function () { + settingsSaved.innerText = ''; + }, 1000) } document.addEventListener('DOMContentLoaded', restoreOptions); From 5dfb9c56732c8cb0a104cf7aee46f0cfe088fba8 Mon Sep 17 00:00:00 2001 From: Ellen Date: Sat, 17 Aug 2024 17:42:35 +0200 Subject: [PATCH 5/6] some small fixes --- src/functions.js | 52 +++++++++++++++++++++++++++++------------------- 1 file changed, 31 insertions(+), 21 deletions(-) diff --git a/src/functions.js b/src/functions.js index 1a16a0a..72b2c2b 100644 --- a/src/functions.js +++ b/src/functions.js @@ -15,9 +15,9 @@ export default class Functions { chrome.storage.local.get([Constants.SPONSOR_DOMAINS_STORAGE_KEY, Constants.LASTCHECK_KEY]).then(async (storage) => { if (typeof storage[Constants.SPONSOR_DOMAINS_STORAGE_KEY] !== 'undefined') { const lastCheck = storage[Constants.LASTCHECK_KEY] || 0; - if (lastCheck < unixDayAgo()) { + if (lastCheck < this.unixDayAgo()) { chrome.storage.local.set({ - [Constants.LASTCHECK_KEY]: unixTime(new Date()), + [Constants.LASTCHECK_KEY]: this.unixTime(new Date()), }); await this.updateUrls(); } @@ -44,8 +44,8 @@ export default class Functions { await chrome.storage.local.set({ [Constants.SPONSOR_DOMAINS_STORAGE_KEY]: AdditionalSponsoredWebsites.concat(data['webshops']) .filter(obj => !!obj.orig_url) - .reduce(function (map, obj) { - var urlObj = URL.parse(obj.orig_url); + .reduce((map, obj) => { + var urlObj = this.parseURLFromApi(obj.orig_url); if (urlObj) map[urlObj.hostname.replace(/^www\./, '')] = obj; return map; }, {}), @@ -103,6 +103,16 @@ export default class Functions { }); } + /** + * Parse a string url to an URL object + * @param url {string} full url + * @returns {string} url with the protocol, path and get parameters stripped + */ + parseURLFromApi(url) { + if (!url.match(/^(http|https)/i)) url = "https://" + url; + return URL.parse(url); + } + /** * Change the current website on the specified tab * @param tabId {number} id of the tab to change the website of @@ -111,23 +121,23 @@ export default class Functions { navigateTo(tabId, target) { chrome.tabs.update(tabId, { url: target }); } -} -/** - * Return the unix timestamp of 1 day ago - * @returns {number} unix timestamp in seconds - */ -function unixDayAgo() { - const d = new Date(); - d.setDate(d.getDate() - 1); - return unixTime(d); -} + /** + * Return the unix timestamp of 1 day ago + * @returns {number} unix timestamp in seconds + */ + unixDayAgo() { + const d = new Date(); + d.setDate(d.getDate() - 1); + return this.unixTime(d); + } -/** -* Convert Date object to unix time in seconds -* @param date {Date} Date object -* @returns {number} unix time in seconds -*/ -function unixTime(date) { - return Math.round((date.getTime() / 1000)); + /** + * Convert Date object to unix time in seconds + * @param date {Date} Date object + * @returns {number} unix time in seconds + */ + unixTime(date) { + return Math.round((date.getTime() / 1000)); + } } \ No newline at end of file From 9f18bcc4b54cc9a8d7d4ba200965992dac74d6c4 Mon Sep 17 00:00:00 2001 From: Ellen Date: Sat, 17 Aug 2024 17:47:09 +0200 Subject: [PATCH 6/6] removed debug / old code --- src/additional_sponsored_websites.js | 2 +- src/functions.js | 10 +--------- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/src/additional_sponsored_websites.js b/src/additional_sponsored_websites.js index 420234b..860edac 100644 --- a/src/additional_sponsored_websites.js +++ b/src/additional_sponsored_websites.js @@ -141,7 +141,7 @@ export default [ }, { name_short: "Tellsell", - orig_url: "telsell.com functions.js:103:23", + orig_url: "telsell.com", link: "https://www.sponsorkliks.com/link.php?club=4509&shop_id=3598&shop=Telsell+NL&link=aHR0cHMlM0ElMkYlMkZ3d3cuYXdpbjEuY29tJTJGY3JlYWQucGhwJTNGYXdpbm1pZCUzRDg1MTUlMjZhd2luYWZmaWQlM0QzMjg4NDElMjZjbGlja3JlZiUzRFNLXzQ1MDklMjRhcGk=" }, { diff --git a/src/functions.js b/src/functions.js index 72b2c2b..4a776b9 100644 --- a/src/functions.js +++ b/src/functions.js @@ -34,13 +34,6 @@ export default class Functions { const response = await fetch(Constants.API); const data = await response.json(); - // Add custom targets that are not present in the API - // for (var url in CUSTOM_TARGETS) { - // var custom_data = CUSTOM_TARGETS[url]; - // custom_data['orig_url'] = url; - // data['webshops'].push(custom_data) - // } - await chrome.storage.local.set({ [Constants.SPONSOR_DOMAINS_STORAGE_KEY]: AdditionalSponsoredWebsites.concat(data['webshops']) .filter(obj => !!obj.orig_url) @@ -58,8 +51,7 @@ export default class Functions { */ onTabUpdated(tabId, changeInfo, tab) { chrome.storage.local.get([Constants.SPONSOR_DOMAINS_STORAGE_KEY, Constants.ALWAYS_REDIRECT_KEY]).then((storage) => { - - if (changeInfo["status"] && changeInfo["status"] == "loading") { + if (changeInfo["status"] && changeInfo["status"] == "complete") { const url = URL.parse(tab["url"]); // if url is valid