You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
323 lines
8.9 KiB
323 lines
8.9 KiB
'use strict'
|
|
/* eslint-env browser */
|
|
/* globals chrome, Utils */
|
|
|
|
const {
|
|
agent,
|
|
open,
|
|
i18n,
|
|
getOption,
|
|
setOption,
|
|
promisify,
|
|
sendMessage,
|
|
} = Utils
|
|
|
|
function setDisabledDomain(enabled) {
|
|
if (enabled) {
|
|
document
|
|
.querySelector('.header__switch--enabled')
|
|
.classList.add('header__switch--hidden')
|
|
document
|
|
.querySelector('.header__switch--disabled')
|
|
.classList.remove('header__switch--hidden')
|
|
} else {
|
|
document
|
|
.querySelector('.header__switch--enabled')
|
|
.classList.remove('header__switch--hidden')
|
|
document
|
|
.querySelector('.header__switch--disabled')
|
|
.classList.add('header__switch--hidden')
|
|
}
|
|
}
|
|
|
|
const Popup = {
|
|
/**
|
|
* Initialise popup
|
|
*/
|
|
async init() {
|
|
// Templates
|
|
Popup.templates = Array.from(
|
|
document.querySelectorAll('[data-template]')
|
|
).reduce((templates, template) => {
|
|
templates[template.dataset.template] = template.cloneNode(true)
|
|
|
|
template.remove()
|
|
|
|
return templates
|
|
}, {})
|
|
|
|
// Disabled domains
|
|
const dynamicIcon = await getOption('dynamicIcon', false)
|
|
|
|
if (dynamicIcon) {
|
|
document.querySelector('body').classList.add('dynamic-icon')
|
|
}
|
|
|
|
// Disabled domains
|
|
let disabledDomains = await getOption('disabledDomains', [])
|
|
|
|
// Theme mode
|
|
const themeMode = await getOption('themeMode', false)
|
|
|
|
if (themeMode) {
|
|
document.querySelector('body').classList.add('theme-mode')
|
|
}
|
|
|
|
// Terms
|
|
const termsAccepted =
|
|
agent === 'chrome' || (await getOption('termsAccepted', false))
|
|
|
|
if (termsAccepted) {
|
|
document.querySelector('.terms').classList.add('terms--hidden')
|
|
document.querySelector('.empty').classList.remove('empty--hidden')
|
|
|
|
Popup.onGetDetections(await Popup.driver('getDetections'))
|
|
} else {
|
|
document.querySelector('.terms').classList.remove('terms--hidden')
|
|
document.querySelector('.detections').classList.add('detections--hidden')
|
|
document.querySelector('.empty').classList.add('empty--hidden')
|
|
|
|
document
|
|
.querySelector('.terms__button--accept')
|
|
.addEventListener('click', async () => {
|
|
await setOption('termsAccepted', true)
|
|
await setOption('tracking', true)
|
|
|
|
document.querySelector('.terms').classList.add('terms--hidden')
|
|
document.querySelector('.empty').classList.remove('empty--hidden')
|
|
|
|
Popup.onGetDetections(await Popup.driver('getDetections'))
|
|
})
|
|
|
|
document
|
|
.querySelector('.terms__button--decline')
|
|
.addEventListener('click', async () => {
|
|
await setOption('termsAccepted', true)
|
|
await setOption('tracking', false)
|
|
|
|
document.querySelector('.terms').classList.add('terms--hidden')
|
|
document.querySelector('.empty').classList.remove('empty--hidden')
|
|
|
|
Popup.onGetDetections(await Popup.driver('getDetections'))
|
|
})
|
|
}
|
|
|
|
const tabs = await promisify(chrome.tabs, 'query', {
|
|
active: true,
|
|
currentWindow: true,
|
|
})
|
|
|
|
if (tabs && tabs.length) {
|
|
const [{ url }] = tabs
|
|
|
|
if (url.startsWith('http')) {
|
|
const { hostname } = new URL(url)
|
|
|
|
setDisabledDomain(disabledDomains.includes(hostname))
|
|
|
|
document
|
|
.querySelector('.header__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('.header__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('.header__switch')) {
|
|
el.classList.add('header__switch--hidden')
|
|
}
|
|
}
|
|
}
|
|
|
|
document
|
|
.querySelector('.header__settings')
|
|
.addEventListener('click', () => chrome.runtime.openOptionsPage())
|
|
|
|
// Apply internationalization
|
|
i18n()
|
|
},
|
|
|
|
driver(func, args) {
|
|
return sendMessage('popup.js', func, args)
|
|
},
|
|
|
|
/**
|
|
* Log debug messages to the console
|
|
* @param {String} message
|
|
*/
|
|
log(message) {
|
|
Popup.driver('log', message)
|
|
},
|
|
|
|
/**
|
|
* Group technologies into categories
|
|
* @param {Object} technologies
|
|
*/
|
|
categorise(technologies) {
|
|
return Object.values(
|
|
technologies
|
|
.filter(({ confidence }) => confidence >= 50)
|
|
.reduce((categories, technology) => {
|
|
technology.categories.forEach((category) => {
|
|
categories[category.id] = categories[category.id] || {
|
|
...category,
|
|
technologies: [],
|
|
}
|
|
|
|
categories[category.id].technologies.push(technology)
|
|
})
|
|
|
|
return categories
|
|
}, {})
|
|
)
|
|
},
|
|
|
|
/**
|
|
* Callback for getDetection listener
|
|
* @param {Array} detections
|
|
*/
|
|
async onGetDetections(detections = []) {
|
|
detections = detections
|
|
.filter(({ confidence }) => confidence >= 50)
|
|
.filter(({ slug }) => slug !== 'cart-functionality')
|
|
|
|
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')
|
|
|
|
const el = document.querySelector('.detections')
|
|
|
|
el.classList.remove('detections--hidden')
|
|
|
|
while (el.firstChild) {
|
|
el.removeChild(detections.lastChild)
|
|
}
|
|
|
|
const pinnedCategory = await getOption('pinnedCategory')
|
|
|
|
const categorised = Popup.categorise(detections)
|
|
|
|
categorised.forEach(({ id, name, slug: categorySlug, technologies }) => {
|
|
const categoryNode = Popup.templates.category.cloneNode(true)
|
|
|
|
const link = categoryNode.querySelector('.category__link')
|
|
|
|
link.href = `https://www.wappalyzer.com/technologies/${categorySlug}/?utm_source=popup&utm_medium=extension&utm_campaign=wappalyzer`
|
|
link.dataset.i18n = `categoryName${id}`
|
|
|
|
const pins = categoryNode.querySelectorAll('.category__pin')
|
|
|
|
if (pinnedCategory === id) {
|
|
pins.forEach((pin) => pin.classList.add('category__pin--active'))
|
|
}
|
|
|
|
pins.forEach((pin) =>
|
|
pin.addEventListener('click', async () => {
|
|
const pinnedCategory = await getOption('pinnedCategory')
|
|
|
|
Array.from(
|
|
document.querySelectorAll('.category__pin--active')
|
|
).forEach((pin) => pin.classList.remove('category__pin--active'))
|
|
|
|
if (pinnedCategory === id) {
|
|
await setOption('pinnedCategory', null)
|
|
} else {
|
|
await setOption('pinnedCategory', id)
|
|
|
|
pins.forEach((pin) => pin.classList.add('category__pin--active'))
|
|
}
|
|
})
|
|
)
|
|
|
|
technologies.forEach(
|
|
({ name, slug, confidence, version, icon, website }) => {
|
|
const technologyNode = Popup.templates.technology.cloneNode(true)
|
|
|
|
const image = technologyNode.querySelector('.technology__icon img')
|
|
|
|
image.src = `../images/icons/${icon}`
|
|
|
|
const link = technologyNode.querySelector('.technology__link')
|
|
const linkText = technologyNode.querySelector('.technology__name')
|
|
|
|
link.href = `https://www.wappalyzer.com/technologies/${categorySlug}/${slug}/?utm_source=popup&utm_medium=extension&utm_campaign=wappalyzer`
|
|
linkText.textContent = name
|
|
|
|
const confidenceNode = technologyNode.querySelector(
|
|
'.technology__confidence'
|
|
)
|
|
|
|
if (confidence < 100) {
|
|
confidenceNode.textContent = `${confidence}% sure`
|
|
} else {
|
|
confidenceNode.remove()
|
|
}
|
|
|
|
const versionNode = technologyNode.querySelector(
|
|
'.technology__version'
|
|
)
|
|
|
|
if (version) {
|
|
versionNode.textContent = version
|
|
} else {
|
|
versionNode.remove()
|
|
}
|
|
|
|
categoryNode
|
|
.querySelector('.technologies')
|
|
.appendChild(technologyNode)
|
|
}
|
|
)
|
|
|
|
document.querySelector('.detections').appendChild(categoryNode)
|
|
})
|
|
|
|
if (categorised.length === 1) {
|
|
document
|
|
.querySelector('.detections')
|
|
.appendChild(Popup.templates.category.cloneNode(true))
|
|
}
|
|
|
|
Array.from(document.querySelectorAll('a')).forEach((a) =>
|
|
a.addEventListener('click', (event) => {
|
|
event.preventDefault()
|
|
|
|
open(a.href)
|
|
|
|
return false
|
|
})
|
|
)
|
|
|
|
i18n()
|
|
},
|
|
}
|
|
|
|
if (/complete|interactive|loaded/.test(document.readyState)) {
|
|
Popup.init()
|
|
} else {
|
|
document.addEventListener('DOMContentLoaded', Popup.init)
|
|
}
|