Add option to disable extension on domains and to clear caches

main
Elbert Alias 4 years ago
parent 59240ffb93
commit 8be327e141

@ -10,6 +10,8 @@
"optionTracking": { "message": "Enviar les tecnologies identificades de forma anònima a wappalyzer.com" },
"optionThemeMode": { "message": "Habilitar la compatibilitat de la manera fosc." },
"optionBadge": { "message": "Show the number of identified technologies on the icon" },
"disableOnDomain": { "message": "Disable on this website" },
"clearCache": { "message": "Clear cached detections" },
"nothingToDo": { "message": "Res a fer aquí." },
"noAppsDetected": { "message": "No s'ha detectat cap tecnologia." },
"categoryPin": { "message": "Mostrar sempre la icona" },

@ -10,6 +10,8 @@
"optionTracking": { "message": "Anonyme Statistiken an wappalyzer.com übermitteln" },
"optionThemeMode": { "message": "Aktivieren dunklen Modus Kompatibilität." },
"optionBadge": { "message": "Show the number of identified technologies on the icon" },
"disableOnDomain": { "message": "Disable on this website" },
"clearCache": { "message": "Clear cached detections" },
"nothingToDo": { "message": "Nichts zu tun." },
"noAppsDetected": { "message": "Keine Applikation entdeckt." },
"categoryPin": { "message": "Immer Icon anzeigen" },

@ -10,6 +10,8 @@
"optionTracking": { "message": "Ανώνυμη αποστολή αναφορών για εντοπισμένες εφαρμογές στο wappalyzer.com για έρευνα" },
"optionThemeMode": { "message": "Ενεργοποίηση συμβατότητας σκοτεινό τρόπο." },
"optionBadge": { "message": "Show the number of identified technologies on the icon" },
"disableOnDomain": { "message": "Disable on this website" },
"clearCache": { "message": "Clear cached detections" },
"nothingToDo": { "message": "Καμία ενέργεια." },
"noAppsDetected": { "message": "Δεν ανιχνεύθηκαν εφαρμογές." },
"categoryPin": { "message": "Always show icon" },

@ -10,6 +10,8 @@
"optionTracking": { "message": "Anonymously send identified technologies to wappalyzer.com" },
"optionThemeMode": { "message": "Enable dark mode compatibility" },
"optionBadge": { "message": "Show the number of identified technologies on the icon" },
"disableOnDomain": { "message": "Disable on this website" },
"clearCache": { "message": "Clear cached detections" },
"nothingToDo": { "message": "Nothing to do here." },
"noAppsDetected": { "message": "No technologies detected." },
"categoryPin": { "message": "Always show icon" },

@ -10,6 +10,8 @@
"optionTracking": { "message": "Enviar informes anónimos sobre las aplicaciones detectadas a wappalyzer.com para análisis" },
"optionThemeMode": { "message": "Habilitar la compatibilidad del modo oscuro." },
"optionBadge": { "message": "Show the number of identified technologies on the icon" },
"disableOnDomain": { "message": "Disable on this website" },
"clearCache": { "message": "Clear cached detections" },
"nothingToDo": { "message": "Nada que hacer aquí." },
"noAppsDetected": { "message": "Aplicaciones no detectadas." },
"categoryPin": { "message": "Always show icon" },

@ -11,6 +11,8 @@
"optionThemeMode": { "message": "فعال کردن حالت سازگاری تاریک." },
"nothingToDo": { "message": "هیچ چیز برای انجام اینجا نیست." },
"optionBadge": { "message": "Show the number of identified technologies on the icon" },
"disableOnDomain": { "message": "Disable on this website" },
"clearCache": { "message": "Clear cached detections" },
"noAppsDetected": { "message": "هیچ فن‌آوری شناسایی نشده است." },
"categoryPin": { "message": "همیشه نماد را نشان بده" },
"termsAccept": { "message": "قبول" },

@ -10,6 +10,8 @@
"optionsSave": { "message": "Sauvegarder les options" },
"optionsSaved": { "message": "Sauvegardé" },
"optionBadge": { "message": "Show the number of identified technologies on the icon" },
"disableOnDomain": { "message": "Disable on this website" },
"clearCache": { "message": "Clear cached detections" },
"twitter": { "message": "Suivre Wappalyzer sur Twitter" },
"website": { "message": "Aller sur wappalyzer.com" },
"categoryPin": { "message": " Toujours afficher l'icône" },

@ -10,6 +10,8 @@
"optionTracking": { "message": "Envía anonimamente aplicativos identificados a wappalyzer.com" },
"optionThemeMode": { "message": "Permitir a compatibilidade modo escuro." },
"optionBadge": { "message": "Show the number of identified technologies on the icon" },
"disableOnDomain": { "message": "Disable on this website" },
"clearCache": { "message": "Clear cached detections" },
"nothingToDo": { "message": "Nada que facer por aquí." },
"noAppsDetected": { "message": "Non se identificaron aplicativos." },
"categoryPin": { "message": "Amosar sempre icono" },

@ -10,6 +10,8 @@
"optionTracking": { "message": "Ανώνυμη αποστολή αναφορών για εντοπισμένες εφαρμογές στο wappalyzer.com για έρευνα" },
"optionThemeMode": { "message": "Ενεργοποίηση συμβατότητας σκοτεινό τρόπο." },
"optionBadge": { "message": "Show the number of identified technologies on the icon" },
"disableOnDomain": { "message": "Disable on this website" },
"clearCache": { "message": "Clear cached detections" },
"nothingToDo": { "message": "Καμία ενέργεια." },
"noAppsDetected": { "message": "Δεν ανιχνεύθηκαν εφαρμογές." },
"categoryPin": { "message": "Always show icon" },

@ -10,6 +10,8 @@
"optionTracking": { "message": "Secara anonim kirimkan laporan tentang aplikasi yang terdeteksi ke wappalyzer.com untuk penelitian" },
"optionThemeMode": { "message": "Aktifkan kompatibilitas modus gelap." },
"optionBadge": { "message": "Show the number of identified technologies on the icon" },
"disableOnDomain": { "message": "Disable on this website" },
"clearCache": { "message": "Clear cached detections" },
"nothingToDo": { "message": "Tak ada yang dilakukan disini." },
"noAppsDetected": { "message": "Tidak ada aplikasi yang terdeteksi." },
"categoryPin": { "message": "Always show icon" },

@ -10,6 +10,8 @@
"optionTracking": { "message": "Inviare anonimamente un report sulle applicazioni rilevate a wappalyzer.com per l'analisi" },
"optionThemeMode": { "message": "Abilita compatibilità con la modalità scura." },
"optionBadge": { "message": "Show the number of identified technologies on the icon" },
"disableOnDomain": { "message": "Disable on this website" },
"clearCache": { "message": "Clear cached detections" },
"nothingToDo": { "message": "Niente da fare qui." },
"noAppsDetected": { "message": "Nessuna applicazione rilevata." },
"categoryPin": { "message": "Always show icon" },

@ -10,6 +10,8 @@
"optionTracking": { "message": "特定した技術を匿名でwappalyzer.comに送信する" },
"optionThemeMode": { "message": "Enable dark mode compatibility." },
"optionBadge": { "message": "Show the number of identified technologies on the icon" },
"disableOnDomain": { "message": "Disable on this website" },
"clearCache": { "message": "Clear cached detections" },
"nothingToDo": { "message": "ここでは特定出来ません。" },
"noAppsDetected": { "message": "技術は検出されませんでした。" },
"categoryPin": { "message": "常にアイコンを表示" },

@ -10,6 +10,8 @@
"optionTracking": { "message": "Przesyłaj anonimowe statystyki aplikacji wykrytych przez Wappalyzer do twórców" },
"optionThemeMode": { "message": "Włącz kompatybilność z ciemnym motywem." },
"optionBadge": { "message": "Show the number of identified technologies on the icon" },
"disableOnDomain": { "message": "Disable on this website" },
"clearCache": { "message": "Clear cached detections" },
"nothingToDo": { "message": "Nic tu nie ma." },
"noAppsDetected": { "message": "Nie wykryto żadnych aplikacji." },
"categoryPin": { "message": "Zawsze pokazuj tą ikonę" },

@ -10,6 +10,8 @@
"optionsSave": { "message": "Opções de Guardar" },
"optionsSaved": { "message": "Guardado" },
"optionBadge": { "message": "Show the number of identified technologies on the icon" },
"disableOnDomain": { "message": "Disable on this website" },
"clearCache": { "message": "Clear cached detections" },
"twitter": { "message": "Seguir Wappalyzer no Twitter" },
"website": { "message": "Ir para wappalyzer.com" },
"categoryPin": { "message": "Mostrar sempre ícone" },

@ -10,6 +10,8 @@
"optionTracking": { "message": "Enviar relatórios anônimos para wappalyzer.com sobre tecnologias identificadas" },
"optionThemeMode": { "message": "Permitir a compatibilidade modo escuro." },
"optionBadge": { "message": "Show the number of identified technologies on the icon" },
"disableOnDomain": { "message": "Disable on this website" },
"clearCache": { "message": "Clear cached detections" },
"nothingToDo": { "message": "Nada a fazer aqui." },
"noAppsDetected": { "message": "Nenhuma tecnologia identificada." },
"categoryPin": { "message": "Sempre mostrar ícone" },

@ -10,6 +10,8 @@
"optionTracking": { "message": "Trimite rapoarte anonime despre aplicațiile detectate către wappalyzer.com pentru cercetare" },
"optionThemeMode": { "message": "Activează modul de compatibilitate întuneric." },
"optionBadge": { "message": "Show the number of identified technologies on the icon" },
"disableOnDomain": { "message": "Disable on this website" },
"clearCache": { "message": "Clear cached detections" },
"nothingToDo": { "message": "Nimic de făcut pe pagina curentă." },
"noAppsDetected": { "message": "Nici o aplicație detectată." },
"categoryPin": { "message": "Afișează icon tot timpul" },

@ -10,6 +10,8 @@
"optionTracking": { "message": "Анонимно отправлять статистику распознанных данных на wappalyzer.com" },
"optionThemeMode": { "message": "Темная тема" },
"optionBadge": { "message": "Show the number of identified technologies on the icon" },
"disableOnDomain": { "message": "Disable on this website" },
"clearCache": { "message": "Clear cached detections" },
"nothingToDo": { "message": "Здесь нечего делать" },
"noAppsDetected": { "message": "Не удалось определить ни одну технологию" },
"categoryPin": { "message": "Всегда отображать эту категорию иконкой"},

@ -10,6 +10,8 @@
"optionTracking": { "message": "Anonymne posielať správy o zistených aplikáciách na wappalyzer.com pre výskum" },
"optionThemeMode": { "message": "Povoliť kompatibilitu tmavú režim." },
"optionBadge": { "message": "Show the number of identified technologies on the icon" },
"disableOnDomain": { "message": "Disable on this website" },
"clearCache": { "message": "Clear cached detections" },
"nothingToDo": { "message": "Nie je tu čo robiť." },
"noAppsDetected": { "message": "Žiadne aplikácie neboli zistené." },
"categoryPin": { "message": "Always show icon" },

@ -10,6 +10,8 @@
"optionTracking": { "message": "Anonim olarak tespit edilen uygulamalar hakkında wappalyzer.com'a araştırma raporları gönderin" },
"optionThemeMode": { "message": "Karanlık modu uyumluluğu etkinleştirin." },
"optionBadge": { "message": "Show the number of identified technologies on the icon" },
"disableOnDomain": { "message": "Disable on this website" },
"clearCache": { "message": "Clear cached detections" },
"nothingToDo": { "message": "Burada yapacak birşey yok." },
"noAppsDetected": { "message": "Uygulamalar tespit edilemedi." },
"categoryPin": { "message": "Her zaman bu kategorinin ikonunu kullan" },

@ -10,6 +10,8 @@
"optionTracking": { "message": "Анонімно надсилати статистику розпізнавань на сервер для досліджень" },
"optionThemeMode": { "message": "Включити сумісність темного режиму." },
"optionBadge": { "message": "Show the number of identified technologies on the icon" },
"disableOnDomain": { "message": "Disable on this website" },
"clearCache": { "message": "Clear cached detections" },
"nothingToDo": { "message": "Тут нічого робити." },
"noAppsDetected": { "message": "Нічого не знайдено." },
"categoryPin": { "message": "Завжди показувати іконку Wappalyzer" },

@ -10,6 +10,8 @@
"optionTracking": { "message": "Wappalyzer takomillashtirish uchun hisobotlarni maxfiy ravishda serverga jo'natish" },
"optionThemeMode": { "message": "qorong'i rejimi mosligini yoqish." },
"optionBadge": { "message": "Show the number of identified technologies on the icon" },
"disableOnDomain": { "message": "Disable on this website" },
"clearCache": { "message": "Clear cached detections" },
"nothingToDo": { "message": "Bu yerda tekshirib bolmaydi." },
"noAppsDetected": { "message": "Hech qanday dastur aniqlanmadi." },
"categoryPin": { "message": "Always show icon" },

@ -10,6 +10,8 @@
"optionTracking": { "message": "匿名发送检测到的技术至 wappalyzer.com" },
"optionThemeMode": { "message": "启用深色模式的兼容。" },
"optionBadge": { "message": "Show the number of identified technologies on the icon" },
"disableOnDomain": { "message": "Disable on this website" },
"clearCache": { "message": "Clear cached detections" },
"nothingToDo": { "message": "这儿啥也没有。" },
"noAppsDetected": { "message": "未检测到任何技术。" },
"categoryPin": { "message": "总是显示图标" },

@ -10,6 +10,8 @@
"optionTracking": { "message": "匿名傳送已識別的技術至 wappalyzer.com" },
"optionThemeMode": { "message": "啟用暗模式的兼容性。" },
"optionBadge": { "message": "Show the number of identified technologies on the icon" },
"disableOnDomain": { "message": "Disable on this website" },
"clearCache": { "message": "Clear cached detections" },
"nothingToDo": { "message": "這裡什麼也沒有。" },
"noAppsDetected": { "message": "未識別到技術。" },
"categoryPin": { "message": "永遠顯示圖示" },

@ -20,7 +20,7 @@ body {
font-size: .9rem;
line-height: 1.5rem;
margin: 0;
min-width: 35rem;
min-width: 24rem;
overflow-x: hidden;
padding-bottom: 3rem;
}
@ -59,7 +59,6 @@ a:hover {
align-items: center;
background: #fff;
bottom: 0;
justify-content: space-between;
border-top: 1px solid var(--color-secondary);
height: 3rem;
display: flex;
@ -68,6 +67,10 @@ a:hover {
width: 100%;
}
.alerts {
white-space: nowrap;
}
.alerts--hidden {
visibility: hidden;
}
@ -80,17 +83,35 @@ a:hover {
width: 1.1rem;
}
.footer__settings {
.spacer {
flex-grow:1;
}
.footer__icon {
color: var(--color-primary);
cursor: pointer;
height: 1.1rem;
margin-left: 1rem;
vertical-align: middle;
width: 1.1rem;
}
.footer__switch {
height: 1.5rem;
width: 1.5rem;
}
.footer__switch--hidden {
display: none;
}
.footer__switch--disabled {
color: var(--color-text);
}
.detections {
columns: 2;
column-gap: 1.5rem;
column-gap: 3rem;
padding: 1.5rem 1.5rem .5rem 1.5rem;
}
@ -100,7 +121,7 @@ a:hover {
.empty {
opacity: .3;
padding: 3rem 1.5rem .5rem 1.5rem;
padding: 3rem 1.5rem 2.5rem 1.5rem;
text-align: center;
}
@ -114,6 +135,10 @@ a:hover {
padding-bottom: 1rem;
}
.category__heading {
white-space: nowrap;
}
.category__link {
font-weight: bold;
line-height: 2rem;
@ -159,6 +184,7 @@ a:hover {
display: flex;
align-items: center;
margin-bottom: .2rem;
white-space: nowrap;
}
.technology__icon {
@ -246,6 +272,10 @@ a:hover {
margin-bottom: .5rem;
}
.options__cache {
margin-top: 1rem;
}
@media (prefers-color-scheme: dark) {
body.theme-mode {
background: var(--color-primary-darken);

@ -42,6 +42,8 @@
<span data-i18n="optionThemeMode">&nbsp;</span>
</label>
<button data-i18n="clearCache" class="options__cache"></button>
</div>
</body>
</html>

@ -72,7 +72,20 @@
<a class="alerts__link" href="https://www.wappalyzer.com/alerts" data-i18n="createAlert"></a>
</div>
<svg class="footer__settings" viewBox="0 0 24 24">
<div class="spacer"></div>
<svg class="footer__switch footer__switch--enabled footer__icon" viewBox="0 0 24 24">
<title data-i18n="disableOnDomain"></title>
<path fill="currentColor" d="M17,7H7A5,5 0 0,0 2,12A5,5 0 0,0 7,17H17A5,5 0 0,0 22,12A5,5 0 0,0 17,7M17,15A3,3 0 0,1 14,12A3,3 0 0,1 17,9A3,3 0 0,1 20,12A3,3 0 0,1 17,15Z" />
</svg>
<svg class="footer__switch footer__switch--disabled footer__icon" viewBox="0 0 24 24">
<title data-i18n="disableOnDomain"></title>
<path fill="currentColor" d="M17,7H7A5,5 0 0,0 2,12A5,5 0 0,0 7,17H17A5,5 0 0,0 22,12A5,5 0 0,0 17,7M7,15A3,3 0 0,1 4,12A3,3 0 0,1 7,9A3,3 0 0,1 10,12A3,3 0 0,1 7,15Z" />
</svg>
<svg class="footer__settings footer__icon" viewBox="0 0 24 24">
<title data-i18n="options"></title>
<path fill="currentColor" d="M12,15.5A3.5,3.5 0 0,1 8.5,12A3.5,3.5 0 0,1 12,8.5A3.5,3.5 0 0,1 15.5,12A3.5,3.5 0 0,1 12,15.5M19.43,12.97C19.47,12.65 19.5,12.33 19.5,12C19.5,11.67 19.47,11.34 19.43,11L21.54,9.37C21.73,9.22 21.78,8.95 21.66,8.73L19.66,5.27C19.54,5.05 19.27,4.96 19.05,5.05L16.56,6.05C16.04,5.66 15.5,5.32 14.87,5.07L14.5,2.42C14.46,2.18 14.25,2 14,2H10C9.75,2 9.54,2.18 9.5,2.42L9.13,5.07C8.5,5.32 7.96,5.66 7.44,6.05L4.95,5.05C4.73,4.96 4.46,5.05 4.34,5.27L2.34,8.73C2.21,8.95 2.27,9.22 2.46,9.37L4.57,11C4.53,11.34 4.5,11.67 4.5,12C4.5,12.33 4.53,12.65 4.57,12.97L2.46,14.63C2.27,14.78 2.21,15.05 2.34,15.27L4.34,18.73C4.46,18.95 4.73,19.03 4.95,18.95L7.44,17.94C7.96,18.34 8.5,18.68 9.13,18.93L9.5,21.58C9.54,21.82 9.75,22 10,22H14C14.25,22 14.46,21.82 14.5,21.58L14.87,18.93C15.5,18.67 16.04,18.34 16.56,17.94L19.05,18.95C19.27,19.03 19.54,18.95 19.66,18.73L21.66,15.27C21.78,15.05 21.73,14.78 21.54,14.63L19.43,12.97Z" />
</svg>
</div>

@ -7,6 +7,10 @@ const Content = {
* Initialise content script
*/
async init() {
if (await Content.driver('isDisabledDomain', [location])) {
return
}
await new Promise((resolve) => setTimeout(resolve, 1000))
try {

@ -185,6 +185,10 @@ const Driver = {
* @param {Object} request
*/
async onWebRequestComplete(request) {
if (await Driver.isDisabledDomain(request.url)) {
return
}
if (request.responseHeaders) {
const headers = {}
@ -252,6 +256,19 @@ const Driver = {
return Wappalyzer.technologies
},
/**
* Check if Wappalyzer has been disabled for the domain
*/
async isDisabledDomain(url) {
try {
const { hostname } = new URL(url)
return (await getOption('disabledDomains', [])).includes(hostname)
} catch (error) {
return false
}
},
/**
* Callback for detections
* @param {String} url
@ -363,7 +380,7 @@ const Driver = {
* @param {String} url
* @param {Object} technologies
*/
async setIcon(url, technologies) {
async setIcon(url, technologies = []) {
const dynamicIcon = await getOption('dynamicIcon', false)
const badge = await getOption('badge', true)
@ -384,7 +401,8 @@ const Driver = {
chrome.browserAction.setBadgeText(
{
tabId,
text: badge ? technologies.length.toString() : ''
text:
badge && technologies.length ? technologies.length.toString() : ''
},
() => {}
)
@ -410,12 +428,22 @@ const Driver = {
* Get the detected technologies for the current tab
*/
async getDetections() {
const [{ id }] = await promisify(chrome.tabs, 'query', {
const [{ id, url }] = await promisify(chrome.tabs, 'query', {
active: true,
currentWindow: true
})
return Driver.cache.tabs[id]
if (await Driver.isDisabledDomain(url)) {
await Driver.setIcon(url, [])
return
}
const resolved = Driver.cache.tabs[id]
await Driver.setIcon(url, resolved)
return resolved
},
/**
@ -511,6 +539,16 @@ const Driver = {
}
},
/**
* Clear caches
*/
async clearCache() {
Driver.cache.hostnames = {}
Driver.cache.tabs = {}
await setOption('hostnames', {})
},
/**
* Anonymously send identified technologies to wappalyzer.com
* This function can be disabled in the extension settings

@ -1,6 +1,6 @@
'use strict'
/* eslint-env browser */
/* globals Utils */
/* globals Utils, chrome */
const { i18n, getOption, setOption } = Utils
@ -37,7 +37,28 @@ const Options = {
})
})
document
.querySelector('.options__cache')
.addEventListener('click', () => Options.driver('clearCache'))
i18n()
},
driver(func, args, callback) {
return new Promise((resolve, reject) => {
chrome.runtime.sendMessage(
{
source: 'content.js',
func,
args: args ? (Array.isArray(args) ? args : [args]) : []
},
(response) => {
chrome.runtime.lastError
? reject(new Error(chrome.runtime.lastError.message))
: resolve(response)
}
)
})
}
}

@ -12,6 +12,24 @@ const {
sendMessage
} = Utils
function setDisabledDomain(enabled) {
if (enabled) {
document
.querySelector('.footer__switch--enabled')
.classList.add('footer__switch--hidden')
document
.querySelector('.footer__switch--disabled')
.classList.remove('footer__switch--hidden')
} else {
document
.querySelector('.footer__switch--enabled')
.classList.remove('footer__switch--hidden')
document
.querySelector('.footer__switch--disabled')
.classList.add('footer__switch--hidden')
}
}
const Popup = {
/**
* Initialise popup
@ -28,6 +46,9 @@ const Popup = {
return templates
}, {})
// Disabled domains
let disabledDomains = await getOption('disabledDomains', [])
// Theme mode
const themeMode = await getOption('themeMode', false)
@ -55,7 +76,7 @@ const Popup = {
document.querySelector('.terms').classList.add('terms--hidden')
document.querySelector('.empty').classList.remove('empty--hidden')
chrome.runtime.sendMessage('getDetections', Popup.onGetDetections)
Popup.onGetDetections(await Popup.driver('getDetections'))
})
}
@ -76,7 +97,40 @@ const Popup = {
).href = `https://www.wappalyzer.com/alerts?url=${encodeURIComponent(
`${url}`
)}`
const { hostname } = new URL(url)
setDisabledDomain(disabledDomains.includes(hostname))
document
.querySelector('.footer__switch--disabled')
.addEventListener('click', async () => {
disabledDomains = disabledDomains.filter(
(_hostname) => _hostname !== hostname
)
await setOption('disabledDomains', disabledDomains)
setDisabledDomain(false)
Popup.onGetDetections(await Popup.driver('getDetections'))
})
document
.querySelector('.footer__switch--enabled')
.addEventListener('click', async () => {
disabledDomains.push(hostname)
await setOption('disabledDomains', disabledDomains)
setDisabledDomain(true)
Popup.onGetDetections(await Popup.driver('getDetections'))
})
} else {
for (const el of document.querySelectorAll('.footer__switch')) {
el.classList.add('footer__switch--hidden')
}
document.querySelector('.alerts').classList.add('alerts--hidden')
}
}
@ -128,11 +182,14 @@ const Popup = {
*/
async onGetDetections(detections = []) {
if (!detections || !detections.length) {
document.querySelector('.empty').classList.remove('empty--hidden')
document.querySelector('.detections').classList.add('detections--hidden')
return
}
document.querySelector('.empty').classList.add('empty--hidden')
document.querySelector('.detections').classList.remove('empty--hidden')
document.querySelector('.detections').classList.remove('detections--hidden')
const pinnedCategory = await getOption('pinnedCategory')