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.
247 lines
6.1 KiB
247 lines
6.1 KiB
/* eslint-env browser */
|
|
/* global browser, jsonToDOM */
|
|
|
|
/** global: browser */
|
|
/** global: jsonToDOM */
|
|
|
|
let pinnedCategory = null;
|
|
let termsAccepted = false;
|
|
|
|
const port = browser.runtime.connect({
|
|
name: 'popup.js',
|
|
});
|
|
|
|
function slugify(string) {
|
|
return string.toLowerCase().replace(/[^a-z0-9-]/g, '-').replace(/--+/g, '-').replace(/(?:^-|-$)/, '');
|
|
}
|
|
|
|
function i18n() {
|
|
const nodes = document.querySelectorAll('[data-i18n]');
|
|
|
|
Array.prototype.forEach.call(nodes, (node) => {
|
|
node.innerHTML = browser.i18n.getMessage(node.dataset.i18n);
|
|
});
|
|
}
|
|
|
|
function replaceDom(domTemplate) {
|
|
const container = document.getElementsByClassName('container')[0];
|
|
|
|
while (container.firstChild) {
|
|
container.removeChild(container.firstChild);
|
|
}
|
|
|
|
container.appendChild(jsonToDOM(domTemplate, document, {}));
|
|
|
|
i18n();
|
|
|
|
Array.from(document.querySelectorAll('.detected__category-pin-wrapper')).forEach((pin) => {
|
|
pin.addEventListener('click', () => {
|
|
const categoryId = parseInt(pin.dataset.categoryId, 10);
|
|
|
|
if (categoryId === pinnedCategory) {
|
|
pin.className = 'detected__category-pin-wrapper';
|
|
|
|
pinnedCategory = null;
|
|
} else {
|
|
const active = document.querySelector('.detected__category-pin-wrapper--active');
|
|
|
|
if (active) {
|
|
active.className = 'detected__category-pin-wrapper';
|
|
}
|
|
|
|
pin.className = 'detected__category-pin-wrapper detected__category-pin-wrapper--active';
|
|
|
|
pinnedCategory = categoryId;
|
|
}
|
|
|
|
port.postMessage({
|
|
id: 'set_option',
|
|
key: 'pinnedCategory',
|
|
value: pinnedCategory,
|
|
});
|
|
});
|
|
});
|
|
}
|
|
|
|
function replaceDomWhenReady(dom) {
|
|
if (/complete|interactive|loaded/.test(document.readyState)) {
|
|
replaceDom(dom);
|
|
} else {
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
replaceDom(dom);
|
|
});
|
|
}
|
|
}
|
|
|
|
function appsToDomTemplate(response) {
|
|
let template = [];
|
|
|
|
if (response.tabCache && Object.keys(response.tabCache.detected).length > 0) {
|
|
const categories = {};
|
|
|
|
// Group apps by category
|
|
for (const appName in response.tabCache.detected) {
|
|
response.apps[appName].cats.forEach((cat) => {
|
|
categories[cat] = categories[cat] || { apps: [] };
|
|
|
|
categories[cat].apps[appName] = appName;
|
|
});
|
|
}
|
|
|
|
for (const cat in categories) {
|
|
const apps = [];
|
|
|
|
for (const appName in categories[cat].apps) {
|
|
const { confidence, version } = response.tabCache.detected[appName];
|
|
|
|
apps.push(
|
|
[
|
|
'a', {
|
|
class: 'detected__app',
|
|
target: '_blank',
|
|
href: `https://www.wappalyzer.com/technologies/${slugify(appName)}`,
|
|
}, [
|
|
'img', {
|
|
class: 'detected__app-icon',
|
|
src: `../images/icons/${response.apps[appName].icon || 'default.svg'}`,
|
|
},
|
|
], [
|
|
'span', {
|
|
class: 'detected__app-name',
|
|
},
|
|
appName,
|
|
], version ? [
|
|
'span', {
|
|
class: 'detected__app-version',
|
|
},
|
|
version,
|
|
] : null, confidence < 100 ? [
|
|
'span', {
|
|
class: 'detected__app-confidence',
|
|
},
|
|
`${confidence}% sure`,
|
|
] : null,
|
|
],
|
|
);
|
|
}
|
|
|
|
template.push(
|
|
[
|
|
'div', {
|
|
class: 'detected__category',
|
|
}, [
|
|
'div', {
|
|
class: 'detected__category-name',
|
|
}, [
|
|
'a', {
|
|
class: 'detected__category-link',
|
|
target: '_blank',
|
|
href: `https://www.wappalyzer.com/categories/${slugify(response.categories[cat].name)}`,
|
|
},
|
|
browser.i18n.getMessage(`categoryName${cat}`),
|
|
], [
|
|
'span', {
|
|
class: `detected__category-pin-wrapper${pinnedCategory == cat ? ' detected__category-pin-wrapper--active' : ''}`,
|
|
'data-category-id': cat,
|
|
title: browser.i18n.getMessage('categoryPin'),
|
|
}, [
|
|
'img', {
|
|
class: 'detected__category-pin detected__category-pin--active',
|
|
src: '../images/pin-active.svg',
|
|
},
|
|
], [
|
|
'img', {
|
|
class: 'detected__category-pin detected__category-pin--inactive',
|
|
src: '../images/pin.svg',
|
|
},
|
|
],
|
|
],
|
|
], [
|
|
'div', {
|
|
class: 'detected__apps',
|
|
},
|
|
apps,
|
|
],
|
|
],
|
|
);
|
|
}
|
|
|
|
template = [
|
|
'div', {
|
|
class: 'detected',
|
|
},
|
|
template,
|
|
];
|
|
} else {
|
|
template = [
|
|
'div', {
|
|
class: 'empty',
|
|
},
|
|
[
|
|
'span', {
|
|
class: 'empty__text',
|
|
},
|
|
browser.i18n.getMessage('noAppsDetected'),
|
|
],
|
|
];
|
|
}
|
|
|
|
return template;
|
|
}
|
|
|
|
async function getApps() {
|
|
try {
|
|
const tabs = await browser.tabs.query({
|
|
active: true,
|
|
currentWindow: true,
|
|
});
|
|
|
|
port.postMessage({
|
|
id: 'get_apps',
|
|
tab: tabs[0],
|
|
});
|
|
} catch (error) {
|
|
console.error(error); // eslint-disable-line no-console
|
|
}
|
|
}
|
|
|
|
function displayApps(response) {
|
|
pinnedCategory = response.pinnedCategory; // eslint-disable-line prefer-destructuring
|
|
termsAccepted = response.termsAccepted; // eslint-disable-line prefer-destructuring
|
|
|
|
if (termsAccepted) {
|
|
replaceDomWhenReady(appsToDomTemplate(response));
|
|
} else {
|
|
i18n();
|
|
|
|
const wrapper = document.querySelector('.terms__wrapper');
|
|
|
|
document.querySelector('.terms__accept').addEventListener('click', () => {
|
|
port.postMessage({
|
|
id: 'set_option',
|
|
key: 'termsAccepted',
|
|
value: true,
|
|
});
|
|
|
|
wrapper.classList.remove('terms__wrapper--active');
|
|
|
|
getApps();
|
|
});
|
|
|
|
wrapper.classList.add('terms__wrapper--active');
|
|
}
|
|
}
|
|
|
|
port.onMessage.addListener((message) => {
|
|
switch (message.id) {
|
|
case 'get_apps':
|
|
displayApps(message.response);
|
|
|
|
break;
|
|
default:
|
|
// Do nothing
|
|
}
|
|
});
|
|
|
|
getApps();
|