Functional ES6 code

main
Elbert Alias 8 years ago
parent b38abb793c
commit a00319a3a8

8
bin/node_modules/.yarn-integrity generated vendored

@ -1,8 +0,0 @@
{
"flags": [],
"linkedModules": [],
"topLevelPatters": [],
"lockfileEntries": {},
"files": [],
"artifacts": {}
}

@ -3,20 +3,6 @@
cd "$(dirname $0)" cd "$(dirname $0)"
if [[ -f "$1" ]]; then if [[ -f "$1" ]]; then
yarn install
pushd ../src/drivers/webextension
yarn install
popd
pushd ../src/drivers/npm
yarn install
popd
./$1 $@ ./$1 $@
else else
./help ./help

@ -1,4 +0,0 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1

@ -1,147 +0,0 @@
/******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, {
/******/ configurable: false,
/******/ enumerable: true,
/******/ get: getter
/******/ });
/******/ }
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports) {
/** global: browser */
(function () {
var c = {
init: function () {
var html = document.documentElement.outerHTML;
c.log('Function call: init()');
if (html.length > 50000) {
html = html.substring(0, 25000) + html.substring(html.length - 25000, html.length);
}
browser.runtime.sendMessage({
id: 'analyze',
subject: { html: html },
source: 'content.js'
});
c.getEnvironmentVars();
},
log: function (message) {
browser.runtime.sendMessage({
id: 'log',
message: message,
source: 'content.js'
});
},
getEnvironmentVars: function () {
var container, script;
c.log('Function call: getEnvironmentVars()');
if (typeof document.body === 'undefined') {
return;
}
try {
container = document.createElement('wappalyzerData');
container.setAttribute('id', 'wappalyzerData');
container.setAttribute('style', 'display: none');
script = document.createElement('script');
script.setAttribute('id', 'wappalyzerEnvDetection');
script.setAttribute('src', browser.extension.getURL('js/inject.js'));
container.addEventListener('wappalyzerEvent', function (event) {
var environmentVars = event.target.childNodes[0].nodeValue;
document.documentElement.removeChild(container);
document.documentElement.removeChild(script);
environmentVars = environmentVars.split(' ').slice(0, 500);
browser.runtime.sendMessage({
id: 'analyze',
subject: { env: environmentVars },
source: 'content.js'
});
}, true);
document.documentElement.appendChild(container);
document.documentElement.appendChild(script);
} catch (e) {
c.log('Error: ' + e);
}
}
};
c.init();
})();
/***/ })
/******/ ]);

File diff suppressed because it is too large Load Diff

@ -1,144 +0,0 @@
/******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, {
/******/ configurable: false,
/******/ enumerable: true,
/******/ get: getter
/******/ });
/******/ }
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports) {
/** global: browser */
/** global: wappalyzer */
document.addEventListener('DOMContentLoaded', function () {
var d = document;
var options = {
init: function () {
options.load();
d.querySelector('#github').addEventListener('click', function () {
open(wappalyzer.config.githubURL);
});
d.querySelector('#twitter').addEventListener('click', function () {
open(wappalyzer.config.twitterURL);
});
d.querySelector('#wappalyzer').addEventListener('click', function () {
open(wappalyzer.config.websiteURL);
});
},
get: function (name, defaultValue, callback) {
browser.storage.local.get(name).then(function (item) {
callback(item.hasOwnProperty(name) ? item[name] : defaultValue);
});
},
set: function (name, value) {
var option = {};
option[name] = value;
browser.storage.local.set(option);
},
load: function () {
options.get('upgradeMessage', true, function (value) {
var el = d.querySelector('#option-upgrade-message');
el.checked = value;
el.addEventListener('change', function () {
options.set('upgradeMessage', el.checked);
});
});
options.get('dynamicIcon', true, function (value) {
var el = d.querySelector('#option-dynamic-icon');
el.checked = value;
el.addEventListener('change', function () {
options.set('dynamicIcon', el.checked);
});
});
options.get('tracking', true, function (value) {
var el = d.querySelector('#option-tracking');
el.checked = value;
el.addEventListener('change', function () {
options.set('tracking', el.checked);
});
});
}
};
options.init();
});
/***/ })
/******/ ]);

@ -1,16 +0,0 @@
{
"devDependencies": {
"file-type": "3.8.*",
"is-svg": "2.0.*",
"read-chunk": "2.0.*",
"svg2png-many": "*",
"webpack": "^3.0.0"
},
"scripts": {
"dev": "webpack --progress --colors --watch"
},
"dependencies": {
"babel-preset-es2015": "^6.24.1",
"glob": "^7.1.2"
}
}

@ -1,168 +0,0 @@
/******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, {
/******/ configurable: false,
/******/ enumerable: true,
/******/ get: getter
/******/ });
/******/ }
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports) {
/** global: chrome */
/** global: browser */
(function () {
var popup = {
init: function () {
popup.update(['p', {}, ' '], document, {});
var func = function (tabs) {
(chrome || browser).runtime.sendMessage({ id: 'get_apps', tab: tabs[0], source: 'popup.js' }, function (response) {
popup.update(popup.appsToDomTemplate(response));
});
};
try {
// Chrome, Firefox
browser.tabs.query({ active: true, currentWindow: true }).then(func);
} catch (e) {
// Edge
browser.tabs.query({ active: true, currentWindow: true }, func);
}
},
update: function (dom) {
if (/complete|interactive|loaded/.test(document.readyState)) {
popup.replaceDom(dom);
} else {
document.addEventListener('DOMContentLoaded', function () {
popup.replaceDom(dom);
});
}
},
replaceDom: function (domTemplate) {
var body = document.body;
while (body.firstChild) {
body.removeChild(body.firstChild);
}
body.appendChild(jsonToDOM(domTemplate, document, {}));
},
appsToDomTemplate: function (response) {
var appName,
confidence,
version,
categories = [],
template = [];
if (response.tabCache && response.tabCache.count > 0) {
for (appName in response.tabCache.appsDetected) {
confidence = response.tabCache.appsDetected[appName].confidenceTotal;
version = response.tabCache.appsDetected[appName].version;
categories = [];
response.apps[appName].cats.forEach(function (cat) {
categories.push(['a', {
target: '_blank',
href: 'https://wappalyzer.com/categories/' + popup.slugify(response.categories[cat].name)
}, ['span', {
class: 'category'
}, ['span', {
class: 'name'
}, browser.i18n.getMessage('categoryName' + cat)]]]);
});
template.push(['div', {
class: 'detected-app'
}, ['a', {
target: '_blank',
href: 'https://wappalyzer.com/applications/' + popup.slugify(appName)
}, ['img', {
src: 'images/icons/' + (response.apps[appName].icon || 'default.svg')
}], ['span', {
class: 'label'
}, ['span', {
class: 'name'
}, appName], (version ? ' ' + version : '') + (confidence < 100 ? ' (' + confidence + '% sure)' : '')]], categories]);
}
} else {
template = ['div', {
class: 'empty'
}, browser.i18n.getMessage('noAppsDetected')];
}
return template;
},
slugify: function (string) {
return string.toLowerCase().replace(/[^a-z0-9-]/g, '-').replace(/--+/g, '-').replace(/(?:^-|-$)/, '');
}
};
popup.init();
})();
/***/ })
/******/ ]);

5
run

@ -8,4 +8,7 @@ if [[ -z "$(which docker)" ]]; then
exit 1 exit 1
fi fi
docker run --rm -v "$(pwd):/opt/wappalyzer" -it wappalyzer/dev ./bin/run $@ cmd="docker run --rm -v "$(pwd):/opt/wappalyzer" -it wappalyzer/dev ./bin/run"
$cmd links
$cmd $@

@ -1,15 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="js/wappalyzer.js"></script>
<script src="js/driver.js"></script>
<!--
<script src="js/network.js"></script>
-->
</head>
<body>
</body>
</html>

@ -0,0 +1,14 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="../node_modules/webextension-polyfill/dist/browser-polyfill.js"></script>
<script src="../js/wappalyzer.js"></script>
<script src="../js/driver.js"></script>
<script src="../js/network.js"></script>
</head>
<body>
</body>
</html>

@ -6,17 +6,18 @@
<title data-i18n="options">Wappalyzer options</title> <title data-i18n="options">Wappalyzer options</title>
<link rel="icon" href="images/icon_32.png"> <link rel="icon" href="../images/icon_32.png">
<link rel="stylesheet" href="css/options.css"> <link rel="stylesheet" href="../css/options.css">
<script src="js/wappalyzer.js"></script> <script src="../node_modules/webextension-polyfill/dist/browser-polyfill.js"></script>
<script src="js/options.js"></script> <script src="../js/wappalyzer.js"></script>
<script src="../js/options.js"></script>
</head> </head>
<body> <body>
<div class="hero"> <div class="hero">
<div class="container"> <div class="container">
<img src="images/logo-white.svg"> <img src="../images/logo-white.svg">
</div> </div>
</div> </div>
@ -32,9 +33,9 @@
<div id="about"> <div id="about">
<p> <p>
<button id="github"><img src="images/github.png" width="16" height="16" alt=""/> <span data-i18n="github" >Fork Wappalyzer on GitHub!</span></button><!-- <button id="github"><img src="../images/github.png" width="16" height="16" alt=""/> <span data-i18n="github" >Fork Wappalyzer on GitHub!</span></button><!--
--><button id="twitter"><img src="images/twitter.png" width="16" height="16" alt=""/> <span data-i18n="twitter">Follow Wappalyzer on Twitter</span></button><!-- --><button id="twitter"><img src="../images/twitter.png" width="16" height="16" alt=""/> <span data-i18n="twitter">Follow Wappalyzer on Twitter</span></button><!--
--><button id="wappalyzer"><img src="images/icon_16.png" width="16" height="16" alt=""/> <span data-i18n="website">Go to wappalyzer.com</span></button> --><button id="wappalyzer"><img src="../images/icon_16.png" width="16" height="16" alt=""/> <span data-i18n="website">Go to wappalyzer.com</span></button>
</p> </p>
</div> </div>
</div> </div>

@ -0,0 +1,15 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="../css/popup.css">
<script src="../node_modules/webextension-polyfill/dist/browser-polyfill.js"></script>
<script src="../js/jsontodom.js"></script>
<script src="../js/popup.js"></script>
</head>
<body>
</body>
</html>

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

@ -1,73 +0,0 @@
/******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, {
/******/ configurable: false,
/******/ enumerable: true,
/******/ get: getter
/******/ });
/******/ }
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports) {
throw new Error("Module build failed: Error: ENOENT: no such file or directory, open '/opt/wappalyzer/src/drivers/webextension/src/i18n.js'\n at Error (native)");
/***/ })
/******/ ]);

File diff suppressed because it is too large Load Diff

@ -1,90 +1,16 @@
/******/ (function(modules) { // webpackBootstrap (function() {
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, {
/******/ configurable: false,
/******/ enumerable: true,
/******/ get: getter
/******/ });
/******/ }
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports) {
(function () {
try { try {
var i, var i, environmentVars = '', e = document.createEvent('Events');
environmentVars = '',
e = document.createEvent('Events');
e.initEvent('wappalyzerEvent', true, false); e.initEvent('wappalyzerEvent', true, false);
for (i in window) { for ( i in window ) {
environmentVars += i + ' '; environmentVars += i + ' ';
} }
document.getElementById('wappalyzerData').appendChild(document.createComment(environmentVars)); document.getElementById('wappalyzerData').appendChild(document.createComment(environmentVars));
document.getElementById('wappalyzerData').dispatchEvent(e); document.getElementById('wappalyzerData').dispatchEvent(e);
} catch (e) { } catch(e) {
// Fail quietly // Fail quietly
} }
})(); }());
/***/ })
/******/ ]);

File diff suppressed because it is too large Load Diff

@ -1,83 +1,13 @@
/******/ (function(modules) { // webpackBootstrap 'use strict';
/******/ // The module cache (function() {
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, {
/******/ configurable: false,
/******/ enumerable: true,
/******/ get: getter
/******/ });
/******/ }
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
(function () {
function isChrome() { function isChrome() {
return typeof chrome !== 'undefined' && window.navigator.userAgent.match(/Chrom(?:e|ium)\/([0-9\.]+)/); return (typeof chrome !== 'undefined' &&
window.navigator.userAgent.match(/Chrom(?:e|ium)\/([0-9\.]+)/));
} }
var browserProxy; var browserProxy;
if (isChrome()) { if ( isChrome() ) {
browserProxy = chrome; browserProxy = chrome;
} else { } else {
browserProxy = browser; browserProxy = browser;
@ -85,7 +15,12 @@
var MIN_FF_MAJOR_VERSION = 51; var MIN_FF_MAJOR_VERSION = 51;
var requiredBrowserApis = [browserProxy.webNavigation, browserProxy.tabs, browserProxy.webRequest, browserProxy.runtime]; var requiredBrowserApis = [
browserProxy.webNavigation,
browserProxy.tabs,
browserProxy.webRequest,
browserProxy.runtime
];
var areListenersRegistered = false; var areListenersRegistered = false;
var secBefore = 2000; var secBefore = 2000;
var secAfter = 5000; var secAfter = 5000;
@ -93,21 +28,49 @@
var minVidSize = 500e3; var minVidSize = 500e3;
var maxVidSize = 25e6; var maxVidSize = 25e6;
var maxContentRange = 25e6; var maxContentRange = 25e6;
var videoExtensions = ['af', '3gp', 'asf', 'avchd', 'avi', 'cam', 'dsh', 'flv', 'm1v', 'm2v', 'fla', 'flr', 'sol', 'm4v', 'mkv', 'wrap', 'mng', 'mov', 'mpeg', 'mpg', 'mpe', 'mp4', 'mxf', 'nsv', 'ogg', 'rm', 'svi', 'smi', 'wmv', 'webm']; var videoExtensions = [
'af', '3gp', 'asf', 'avchd', 'avi', 'cam', 'dsh', 'flv', 'm1v', 'm2v',
'fla', 'flr', 'sol', 'm4v', 'mkv', 'wrap', 'mng', 'mov', 'mpeg', 'mpg',
'mpe', 'mp4', 'mxf', 'nsv', 'ogg', 'rm', 'svi', 'smi', 'wmv', 'webm'
];
var extensionsReg = new RegExp('\\.' + videoExtensions.join('$|\\.') + '$'); var extensionsReg = new RegExp('\\.' + videoExtensions.join('$|\\.') + '$');
var videoContentTypesPrefixes = ['binary/octet-stream', 'video/', 'flv-application/', 'media']; var videoContentTypesPrefixes = ['binary/octet-stream', 'video/', 'flv-application/', 'media'];
var bannedContentTypes = ['video/mp2t', 'video/f4m', 'video/f4f']; var bannedContentTypes = ['video/mp2t','video/f4m','video/f4f'];
var bannedFiletypes = ['ts']; var bannedFiletypes = ['ts'];
var bannedFiletypesReg = new RegExp('\\.' + bannedFiletypes.join('$|\\.') + '$'); var bannedFiletypesReg = new RegExp('\\.' + bannedFiletypes.join('$|\\.') + '$');
var whitelistReqTypes = ['object', 'xmlhttprequest', 'other']; var whitelistReqTypes = ['object', 'xmlhttprequest', 'other'];
var topVideoAssetDomains = ['2mdn.net', 'adap.tv', 'adnxs.com', 'adsrvr.org', 'btrll.com', 'celtra.com', 'flashtalking.com', 'flite.com', 'innovid.com', 'jivox.com', 'mixpo.com', 'nytimes.com', 'playwire.com', 'selectmedia.asia', 'serving-sys.com', 'solvemedia.com', 'spotible.com', 'teads.tv', 'tribalfusion.com', 'tubemogul.com', 'videologygroup.com', 'washingtonpost.com']; var topVideoAssetDomains = [
'2mdn.net',
if (!String.prototype.endsWith) { 'adap.tv',
String.prototype.endsWith = function (searchString, position) { 'adnxs.com',
'adsrvr.org',
'btrll.com',
'celtra.com',
'flashtalking.com',
'flite.com',
'innovid.com',
'jivox.com',
'mixpo.com',
'nytimes.com',
'playwire.com',
'selectmedia.asia',
'serving-sys.com',
'solvemedia.com',
'spotible.com',
'teads.tv',
'tribalfusion.com',
'tubemogul.com',
'videologygroup.com',
'washingtonpost.com'
];
if ( !String.prototype.endsWith ) {
String.prototype.endsWith = function(searchString, position) {
var subjectString = this.toString(); var subjectString = this.toString();
if (typeof position !== 'number' || !isFinite(position) || Math.floor(position) !== position || position > subjectString.length) { if ( typeof position !== 'number' || !isFinite(position) ||
Math.floor(position) !== position || position > subjectString.length) {
position = subjectString.length; position = subjectString.length;
} }
position -= searchString.length; position -= searchString.length;
@ -117,25 +80,26 @@
} }
function getFrame(getFrameDetails, callback) { function getFrame(getFrameDetails, callback) {
if (typeof chrome !== 'undefined') { if ( typeof chrome !== 'undefined' ) {
chrome.webNavigation.getFrame(getFrameDetails, callback); chrome.webNavigation.getFrame(getFrameDetails, callback);
} else if (typeof browser !== 'undefined') { } else if ( typeof browser !== 'undefined' ) {
var gettingFrame = browser.webNavigation.getFrame(getFrameDetails); var gettingFrame = browser.webNavigation.getFrame(getFrameDetails);
gettingFrame.then(callback); gettingFrame.then(callback);
} }
} }
function ifBrowserValid(callback, elseCallback) { function ifBrowserValid(callback, elseCallback) {
if (isChrome()) { if ( isChrome() ) {
callback(); callback();
} else if (typeof browser !== 'undefined') { } else if ( typeof browser !== 'undefined' ) {
try { try {
var gettingInfo = browser.runtime.getBrowserInfo(); var gettingInfo = browser.runtime.getBrowserInfo();
gettingInfo.then(function (browserInfo) { gettingInfo.then(function(browserInfo) {
var browserVersion = parseInt(browserInfo.version.split('.')[0]); var browserVersion = parseInt(browserInfo.version.split('.')[0]);
if (browserInfo.name === 'Firefox' && browserVersion >= MIN_FF_MAJOR_VERSION) { if ( browserInfo.name === 'Firefox' &&
browserVersion >= MIN_FF_MAJOR_VERSION) {
callback(); callback();
} else { } else {
elseCallback(); elseCallback();
@ -152,10 +116,10 @@
function ifTrackingEnabled(ifCallback, elseCallback) { function ifTrackingEnabled(ifCallback, elseCallback) {
browser.storage.local.get('tracking').then(function (item) { browser.storage.local.get('tracking').then(function(item) {
if (item.hasOwnProperty('tracking')) { if ( item.hasOwnProperty('tracking') ) {
if (item.tracking) { if ( item.tracking ) {
ifCallback(); ifCallback();
} else { } else {
elseCallback(); elseCallback();
@ -164,10 +128,12 @@
ifCallback(); ifCallback();
} }
}); });
} }
function isPixelRequest(request) { function isPixelRequest(request) {
return (request.type === 'image' || request.responseStatus === 204) && request.size <= 1000; return (request.type === 'image' || request.responseStatus === 204) &&
request.size <= 1000;
} }
function isVpaidOrVastRequest(request) { function isVpaidOrVastRequest(request) {
@ -195,9 +161,9 @@
function findHeader(headers, key) { function findHeader(headers, key) {
var header; var header;
for (var i = 0; i < headers.length; i += 1) { for ( var i = 0; i < headers.length; i += 1 ) {
header = headers[i]; header = headers[i];
if (header.name.toLowerCase() === key) { if ( header.name.toLowerCase() === key ) {
return header; return header;
} }
} }
@ -205,7 +171,7 @@
} }
function validVideoType(vtype) { function validVideoType(vtype) {
var goodType = videoContentTypesPrefixes.some(function (prefix) { var goodType = videoContentTypesPrefixes.some(function(prefix) {
return vtype.indexOf(prefix) === 0; return vtype.indexOf(prefix) === 0;
}); });
return goodType; return goodType;
@ -217,7 +183,7 @@
return key; return key;
} }
var PageNetworkTrafficCollector = function (tabId) { var PageNetworkTrafficCollector = function(tabId) {
this.tabId = tabId; this.tabId = tabId;
this.displayAdFound = false; this.displayAdFound = false;
this.requests = {}; this.requests = {};
@ -230,84 +196,89 @@
collectors: {}, collectors: {},
dyingCollectors: {}, dyingCollectors: {},
cleanupCollector: function (tabId) { cleanupCollector: function(tabId) {
if (tabId in this.collectors) { if ( tabId in this.collectors ) {
delete globalPageContainer.collectors[tabId]; delete globalPageContainer.collectors[tabId];
} }
}, },
onNewNavigation: function (details) { onNewNavigation: function(details) {
var tabId = details.tabId; var tabId = details.tabId;
this.cleanupCollector(tabId); this.cleanupCollector(tabId);
ifTrackingEnabled(function () { ifTrackingEnabled(
if (!areListenersRegistered) { function() {
if ( !areListenersRegistered ) {
registerListeners(); registerListeners();
} }
this.collectors[tabId] = new PageNetworkTrafficCollector(tabId); this.collectors[tabId] = new PageNetworkTrafficCollector(tabId);
}.bind(this), function () { }.bind(this),
if (areListenersRegistered) { function() {
if ( areListenersRegistered ) {
unregisterListeners(); unregisterListeners();
} }
}); }
);
}, },
onNavigationCommitted: function (details) {}, onNavigationCommitted: function(details) {
onNavigationCompleted: function (details) {}, },
onNavigationCompleted: function(details) {
},
onTabClose: function (tabId, closeInfo) { onTabClose: function(tabId, closeInfo) {
this.cleanupCollector(tabId); this.cleanupCollector(tabId);
delete this.collectors[tabId]; delete this.collectors[tabId];
}, },
onDisplayAdFound: function (tabId) { onDisplayAdFound: function(tabId) {
this.collectors[tabId].displayAdFound = true; this.collectors[tabId].displayAdFound = true;
}, },
getRandId: function () { getRandId: function() {
return String(Math.floor(Math.random() * 1e9)); return String(Math.floor(Math.random() * 1e9));
}, },
getCollector: function (tabId) { getCollector: function(tabId) {
if (this.collectors.hasOwnProperty(tabId)) { if ( this.collectors.hasOwnProperty(tabId) ) {
return this.collectors[tabId]; return this.collectors[tabId];
} }
return null; return null;
}, },
forwardCall: function (details, collectorMemberFunction) { forwardCall: function(details, collectorMemberFunction) {
var collector = this.getCollector(details.tabId); var collector = this.getCollector(details.tabId);
if (collector !== null) { if ( collector !== null ) {
collectorMemberFunction.apply(collector, [details]); collectorMemberFunction.apply(collector, [details]);
} }
} }
}; };
PageNetworkTrafficCollector.prototype.sendLogMessageToTabConsole = function () { PageNetworkTrafficCollector.prototype.sendLogMessageToTabConsole = function() {
var logMessage = Array.from(arguments).join(' '); var logMessage = Array.from(arguments).join(' ');
var message = { message: logMessage, event: 'console-log-message' }; var message = {message: logMessage, event: 'console-log-message'};
browserProxy.tabs.sendMessage(this.tabId, message); browserProxy.tabs.sendMessage(this.tabId, message);
}; };
PageNetworkTrafficCollector.prototype.sendToTab = function (assetReq, reqs, curPageUrl, isValidAd) { PageNetworkTrafficCollector.prototype.sendToTab = function(assetReq, reqs, curPageUrl, isValidAd) {
var msg = {}; var msg = {};
msg.assets = []; msg.assets = [];
msg.event_data = {}; msg.event_data = {};
if (isValidAd) { if ( isValidAd ) {
msg.event = 'new-video-ad'; msg.event = 'new-video-ad';
msg.requests = reqs; msg.requests = reqs;
msg.requests.sort(function (reqA, reqB) { msg.requests.sort(function(reqA, reqB) {return reqA.requestTimestamp - reqB.requestTimestamp;});
return reqA.requestTimestamp - reqB.requestTimestamp; if ( assetReq ) {
});
if (assetReq) {
msg.assets = [assetReq]; msg.assets = [assetReq];
} }
} else { } else {
msg.requests = reqs.map(function (request) { msg.requests = reqs.map(function(request) {
return parseHostnameFromUrl(request.url); return parseHostnameFromUrl(request.url);
}); });
msg.assets = [{ msg.assets = [{
@ -325,96 +296,97 @@
browserProxy.tabs.sendMessage(this.tabId, msg); browserProxy.tabs.sendMessage(this.tabId, msg);
}; };
PageNetworkTrafficCollector.prototype.getRedirKey = function (url, frameId) { PageNetworkTrafficCollector.prototype.getRedirKey = function(url, frameId) {
return url + ':' + frameId; return url + ':' + frameId;
}; };
PageNetworkTrafficCollector.prototype.seenBefore = function (request) { PageNetworkTrafficCollector.prototype.seenBefore = function(request) {
var oldTime = this.assetsSeen[assetMsgKey(request)]; var oldTime = this.assetsSeen[assetMsgKey(request)];
if (oldTime && request.requestTimestamp - oldTime < secBetweenDupAssets) { if ( oldTime && (request.requestTimestamp-oldTime < secBetweenDupAssets)){
return true; return true;
} }
return false; return false;
}; };
PageNetworkTrafficCollector.prototype.recordSeenAsset = function (request) { PageNetworkTrafficCollector.prototype.recordSeenAsset = function(request) {
this.assetsSeen[assetMsgKey(request)] = request.requestTimestamp; this.assetsSeen[assetMsgKey(request)] = request.requestTimestamp;
}; };
PageNetworkTrafficCollector.prototype.onBeforeRequest = function (details) { PageNetworkTrafficCollector.prototype.onBeforeRequest = function(details) {
var req = { var req = {
url: details.url, url: details.url,
type: details.type, type: details.type,
httpMethod: details.method, httpMethod: details.method,
frameId: details.frameId, frameId: details.frameId,
parentFrameId: details.parentFrameId, parentFrameId: details.parentFrameId,
requestTimestamp: details.timeStamp requestTimestamp: details.timeStamp,
}; };
this.requests[details.requestId] = req; this.requests[details.requestId] = req;
}; };
PageNetworkTrafficCollector.prototype.onSendHeaders = function (details) { PageNetworkTrafficCollector.prototype.onSendHeaders = function(details) {
var request, header; var request, header;
request = this.requests[details.requestId]; request = this.requests[details.requestId];
header = request && findHeader(details.requestHeaders, 'x-requested-with'); header = request && findHeader(details.requestHeaders, 'x-requested-with');
if (header && header.value.toLowerCase().indexOf('flash') > -1) { if ( header && header.value.toLowerCase().indexOf('flash') > -1 ) {
request.from_flash = true; request.from_flash = true;
} }
}; };
PageNetworkTrafficCollector.prototype.onHeadersReceived = function (details) { PageNetworkTrafficCollector.prototype.onHeadersReceived = function(details) {
var getFrameDetails = { var getFrameDetails = {
tabId: details.tabId, tabId: details.tabId,
processId: null, processId: null,
frameId: details.frameId frameId: details.frameId
}; };
var pageNetworkTrafficController = this; var pageNetworkTrafficController = this;
getFrame(getFrameDetails, function (frameDetails) { getFrame(getFrameDetails, function(frameDetails) {
if (frameDetails && frameDetails.url) { if ( frameDetails && frameDetails.url ) {
pageNetworkTrafficController._onHeadersReceived(details, frameDetails); pageNetworkTrafficController._onHeadersReceived(details, frameDetails);
} }
}); });
}; };
PageNetworkTrafficCollector.prototype._onHeadersReceived = function (details, frameDetails) { PageNetworkTrafficCollector.prototype._onHeadersReceived = function(details, frameDetails) {
var contentSize, contentRange; var contentSize, contentRange;
var request = this.requests[details.requestId]; var request = this.requests[details.requestId];
if (request) { if ( request ) {
var redirParent = this.allRedirects[this.getRedirKey(details.url, details.frameId)]; var redirParent = this.allRedirects[this.getRedirKey(details.url, details.frameId)];
var header = request && findHeader(details.responseHeaders, 'content-type'); var header = request && findHeader(details.responseHeaders, 'content-type');
var contentType = header && header.value.toLowerCase(); var contentType = header && header.value.toLowerCase();
if (contentType) { if ( contentType){
request.contentType = contentType; request.contentType = contentType;
} }
header = request && findHeader(details.responseHeaders, 'content-length'); header = request && findHeader(details.responseHeaders, 'content-length');
contentSize = header && header.value; contentSize = header && header.value;
if (contentSize) { if ( contentSize ) {
request.size = request.size || 0; request.size = request.size || 0;
request.size += parseInt(contentSize); request.size += parseInt(contentSize);
} }
header = request && findHeader(details.responseHeaders, 'content-range'); header = request && findHeader(details.responseHeaders, 'content-range');
contentRange = header && header.value; contentRange = header && header.value;
if (contentRange) { if ( contentRange ) {
request.contentRange = parseInt(contentRange.split('/')[1]); request.contentRange = parseInt(contentRange.split('/')[1]);
} }
var frameUrl = null; var frameUrl = null;
if (frameDetails && frameDetails.url) { if ( frameDetails && frameDetails.url ) {
frameUrl = frameDetails.url; frameUrl = frameDetails.url;
} }
if (!this.bannedRequest(request) && (this.isVideoReq(frameUrl, request) || redirParent && redirParent.isVideo)) { if ( !this.bannedRequest(request) &&
(this.isVideoReq(frameUrl, request) || (redirParent && redirParent.isVideo))) {
request.isVideo = true; request.isVideo = true;
} }
} }
}; };
PageNetworkTrafficCollector.prototype.onBeforeRedirect = function (details) { PageNetworkTrafficCollector.prototype.onBeforeRedirect = function(details) {
var request = this.requests[details.requestId]; var request = this.requests[details.requestId];
if (request) { if ( request ) {
if (request.redirects) { if ( request.redirects ) {
request.redirects.push(details.redirectUrl); request.redirects.push(details.redirectUrl);
} else { } else {
request.redirects = [details.redirectUrl]; request.redirects = [details.redirectUrl];
@ -423,52 +395,53 @@
} }
}; };
PageNetworkTrafficCollector.prototype.isYoutubeMastheadRequest = function (url) { PageNetworkTrafficCollector.prototype.isYoutubeMastheadRequest = function(url) {
var re = /video_masthead/; var re = /video_masthead/;
return this.hasYoutubeDomain(url) && re.test(url); return this.hasYoutubeDomain(url) && re.test(url);
}; };
PageNetworkTrafficCollector.prototype.isYoutubeVideoRequest = function (srcUrl, destUrl) { PageNetworkTrafficCollector.prototype.isYoutubeVideoRequest = function(srcUrl, destUrl) {
if (!this.hasYoutubeDomain(srcUrl)) { if ( !this.hasYoutubeDomain(srcUrl) ) {
return false; return false;
} }
var re = /https?:\/\/r.*?\.googlevideo\.com\/videoplayback\?/; var re = /https?:\/\/r.*?\.googlevideo\.com\/videoplayback\?/;
return re.test(destUrl); return re.test(destUrl);
}; };
PageNetworkTrafficCollector.prototype.processResponse = function (requestDetails, frameDetails) { PageNetworkTrafficCollector.prototype.processResponse = function(requestDetails, frameDetails) {
var request; var request;
if (requestDetails) { if ( requestDetails ) {
request = this.requests[requestDetails.requestId]; request = this.requests[requestDetails.requestId];
if (request) { if ( request ) {
request.responseStatus = requestDetails.statusCode; request.responseStatus = requestDetails.statusCode;
request.responseTimestamp = requestDetails.timeStamp; request.responseTimestamp = requestDetails.timeStamp;
var frameUrl = null; var frameUrl = null;
if (frameDetails && frameDetails.url) { if ( frameDetails && frameDetails.url ) {
frameUrl = frameDetails.url; frameUrl = frameDetails.url;
} }
var requestUrl = null; var requestUrl = null;
if (request.url) { if ( request.url ) {
requestUrl = request.url; requestUrl = request.url;
} }
if (this.isYoutubeAdReq(frameUrl, requestUrl)) { if ( this.isYoutubeAdReq(frameUrl, requestUrl) ) {
var videoId = this.parseYoutubeVideoIdFromUrl(requestUrl); var videoId = this.parseYoutubeVideoIdFromUrl(requestUrl);
if (videoId) { if ( videoId ) {
request.isYoutubeAd = true; request.isYoutubeAd = true;
request.isVideo = true; request.isVideo = true;
request.url = 'https://www.youtube.com/watch?v=' + this.parseYoutubeVideoIdFromUrl(requestUrl); request.url = 'https://www.youtube.com/watch?v=' + this.parseYoutubeVideoIdFromUrl(requestUrl);
} }
} else if (!this.bannedRequest(request) && (this.isVideo || this.isVideoReq(frameUrl, request))) { } else if ( !this.bannedRequest(request) &&
(this.isVideo || this.isVideoReq(frameUrl, request))) {
request.isVideo = true; request.isVideo = true;
} }
if (request.isVideo) { if ( request.isVideo ) {
var msgKey = assetMsgKey(request); var msgKey = assetMsgKey(request);
this.msgsBeingSent[msgKey] = request; this.msgsBeingSent[msgKey] = request;
if (!this.seenBefore(request)) { if ( !this.seenBefore(request) ) {
this.sendMsgWhenQuiet(msgKey); this.sendMsgWhenQuiet(msgKey);
} }
this.recordSeenAsset(request); this.recordSeenAsset(request);
@ -477,9 +450,10 @@
} }
}; };
PageNetworkTrafficCollector.prototype.onResponseStarted = function (responseDetails) { PageNetworkTrafficCollector.prototype.onResponseStarted = function(responseDetails) {
if (responseDetails.frameId < 0) { if ( responseDetails.frameId < 0 ) {
responseDetails.frameId = 99999; responseDetails.frameId = 99999;
} }
var getFrameDetails = { var getFrameDetails = {
tabId: responseDetails.tabId, tabId: responseDetails.tabId,
@ -487,171 +461,179 @@
frameId: responseDetails.frameId frameId: responseDetails.frameId
}; };
var pageNetworkTrafficController = this; var pageNetworkTrafficController = this;
getFrame(getFrameDetails, function (frameDetails) { getFrame(getFrameDetails, function(frameDetails) {
if (frameDetails && frameDetails.url) { if ( frameDetails && frameDetails.url ) {
pageNetworkTrafficController.processResponse(responseDetails, frameDetails); pageNetworkTrafficController.processResponse(responseDetails, frameDetails);
} }
}); });
}; };
PageNetworkTrafficCollector.prototype.hasBannedFiletype = function (request) { PageNetworkTrafficCollector.prototype.hasBannedFiletype = function(request) {
var url = stripQueryParams(request.url); var url = stripQueryParams(request.url);
if (bannedFiletypesReg.exec(url)) { if ( bannedFiletypesReg.exec(url) ) {
return true; return true;
} else { } else {
return false; return false;
} }
}; };
PageNetworkTrafficCollector.prototype.checkContentHeaders = function (request) { PageNetworkTrafficCollector.prototype.checkContentHeaders = function(request) {
if (request.contentType && validVideoType(request.contentType)) { if ( request.contentType && validVideoType(request.contentType) ) {
return true; return true;
} }
return false; return false;
}; };
PageNetworkTrafficCollector.prototype.checkUrlExtension = function (request) { PageNetworkTrafficCollector.prototype.checkUrlExtension = function(request) {
var url = stripQueryParams(request.url); var url = stripQueryParams(request.url);
if (extensionsReg.exec(url)) { if ( extensionsReg.exec(url) ) {
return true; return true;
} else { } else {
return false; return false;
} }
}; };
PageNetworkTrafficCollector.prototype.isVideoReq = function (srcUrl, request) { PageNetworkTrafficCollector.prototype.isVideoReq = function(srcUrl, request) {
if (this.isYoutubeVideoRequest(srcUrl, request.url)) { if ( this.isYoutubeVideoRequest(srcUrl, request.url) ) {
return false; return false;
} }
return this.checkUrlExtension(request) || this.checkContentHeaders(request); return this.checkUrlExtension(request) || this.checkContentHeaders(request);
}; };
PageNetworkTrafficCollector.prototype.hasYoutubeDomain = function (url) { PageNetworkTrafficCollector.prototype.hasYoutubeDomain = function(url) {
var hostname = parseHostnameFromUrl(url); var hostname = parseHostnameFromUrl(url) ;
if (hostname === 'www.youtube.com') { if ( hostname === 'www.youtube.com' ) {
return true; return true;
} }
return false; return false;
}; };
PageNetworkTrafficCollector.prototype.parseYoutubeVideoIdFromUrl = function (url) { PageNetworkTrafficCollector.prototype.parseYoutubeVideoIdFromUrl = function(url) {
var re = /^https?:\/\/www\.youtube\.com\/get_video_info.*(?:\?|&)video_id=(.*?)(?:$|&)/; var re = /^https?:\/\/www\.youtube\.com\/get_video_info.*(?:\?|&)video_id=(.*?)(?:$|&)/;
var match = re.exec(url); var match = re.exec(url);
if (match && match.length > 1) { if ( match && match.length > 1 ) {
return match[1]; return match[1];
} }
re = /^https?:\/\/www\.youtube\.com\/embed\/(.*?)(?:$|\?)/; re = /^https?:\/\/www\.youtube\.com\/embed\/(.*?)(?:$|\?)/;
match = re.exec(url); match = re.exec(url);
if (match && match.length > 1) { if ( match && match.length > 1 ) {
return match[1]; return match[1];
} }
re = /^https?:\/\/www\.youtube\.com\/watch\?v=(.*$)/; re = /^https?:\/\/www\.youtube\.com\/watch\?v=(.*$)/;
match = re.exec(url); match = re.exec(url);
if (match && match.length > 1) { if ( match && match.length > 1 ) {
return match[1]; return match[1];
} }
return null; return null;
}; };
PageNetworkTrafficCollector.prototype.isYoutubeGetVideoInfoReq = function (url) { PageNetworkTrafficCollector.prototype.isYoutubeGetVideoInfoReq = function(url) {
var re = /^https?:\/\/www\.youtube\.com\/get_video_info\?/; var re = /^https?:\/\/www\.youtube\.com\/get_video_info\?/;
return re.test(url); return re.test(url);
}; };
PageNetworkTrafficCollector.prototype.isYoutubeAdReq = function (srcUrl, destUrl) { PageNetworkTrafficCollector.prototype.isYoutubeAdReq = function(srcUrl, destUrl) {
if (!this.hasYoutubeDomain(srcUrl) || !this.isYoutubeGetVideoInfoReq(destUrl)) { if ( !this.hasYoutubeDomain(srcUrl) ||
!this.isYoutubeGetVideoInfoReq(destUrl)) {
return false; return false;
} }
if (this.parseYoutubeVideoIdFromUrl(srcUrl) === this.parseYoutubeVideoIdFromUrl(destUrl) && !this.isYoutubeMastheadRequest(destUrl)) { if ( this.parseYoutubeVideoIdFromUrl(srcUrl) ===
this.parseYoutubeVideoIdFromUrl(destUrl) &&
!this.isYoutubeMastheadRequest(destUrl)) {
return false; return false;
} }
return true; return true;
}; };
PageNetworkTrafficCollector.prototype.bannedRequest = function (request) { PageNetworkTrafficCollector.prototype.bannedRequest = function(request) {
return this.bannedVideoType(request) || this.hasBannedFiletype(request) || this.bannedVideoSize(request); return this.bannedVideoType(request) || this.hasBannedFiletype(request) || this.bannedVideoSize(request);
}; };
PageNetworkTrafficCollector.prototype.bannedVideoType = function (request) { PageNetworkTrafficCollector.prototype.bannedVideoType = function(request) {
var badType = false; var badType = false;
if (request.contentType) { if ( request.contentType ) {
badType = bannedContentTypes.some(function (prefix) { badType = bannedContentTypes.some(function(prefix) {
return request.contentType.indexOf(prefix) >= 0; return request.contentType.indexOf(prefix) >= 0;
}); });
} }
return badType; return badType;
}; };
PageNetworkTrafficCollector.prototype.bannedVideoSize = function (request) { PageNetworkTrafficCollector.prototype.bannedVideoSize = function(request) {
if (request.size !== null) { if ( request.size !== null ) {
if (request.size < minVidSize || request.size > maxVidSize || request.contentRange > maxContentRange) { if ( request.size < minVidSize || request.size > maxVidSize || request.contentRange > maxContentRange ) {
return true; return true;
} }
} }
return false; return false;
}; };
PageNetworkTrafficCollector.prototype.grabTagReqs = function (tabRequests, assetRequest) { PageNetworkTrafficCollector.prototype.grabTagReqs = function(tabRequests, assetRequest) {
var minTimestamp, maxTimestamp; var minTimestamp, maxTimestamp;
minTimestamp = assetRequest.requestTimestamp - secBefore; minTimestamp = assetRequest.requestTimestamp - secBefore;
maxTimestamp = assetRequest.requestTimestamp + secAfter; maxTimestamp = assetRequest.requestTimestamp + secAfter;
var filteredRequests = tabRequests.filter(function (request) { var filteredRequests = tabRequests.filter(function(request) {
return request.requestTimestamp > minTimestamp && request.requestTimestamp < maxTimestamp && request.frameId === assetRequest.frameId && request.url !== assetRequest.url && (hasValidRequestType(request) || isPixelRequest(request)); return (request.requestTimestamp > minTimestamp &&
request.requestTimestamp < maxTimestamp &&
request.frameId === assetRequest.frameId &&
request.url !== assetRequest.url &&
(hasValidRequestType(request) ||
isPixelRequest(request)));
}); });
return filteredRequests; return filteredRequests;
}; };
PageNetworkTrafficCollector.prototype.isValidVideoAd = function (assetRequest, tagRequests) { PageNetworkTrafficCollector.prototype.isValidVideoAd = function(assetRequest, tagRequests) {
var hasVpaidOrVastRequest = tagRequests.some(function (tagRequest) { var hasVpaidOrVastRequest = tagRequests.some(function(tagRequest) {
return isVpaidOrVastRequest(tagRequest); return isVpaidOrVastRequest(tagRequest);
}); });
if (assetRequest.isYoutubeAd) { if ( assetRequest.isYoutubeAd ) {
return true; return true;
} }
if (hasVpaidOrVastRequest) { if ( hasVpaidOrVastRequest ) {
return true; return true;
} }
var hasTopVideoAssetDomain = topVideoAssetDomains.some(function (assetDomain) { var hasTopVideoAssetDomain = topVideoAssetDomains.some(function(assetDomain) {
return hasDomain(assetRequest.url, assetDomain); return hasDomain(assetRequest.url, assetDomain);
}); });
return hasTopVideoAssetDomain; return hasTopVideoAssetDomain;
}; };
PageNetworkTrafficCollector.prototype.sendMsgWhenQuiet = function (msgKey) { PageNetworkTrafficCollector.prototype.sendMsgWhenQuiet = function(msgKey) {
var _this = this, var _this = this,
origPageUrl, origPageUrl, msgAssetReq;
msgAssetReq;
msgAssetReq = this.msgsBeingSent[msgKey]; msgAssetReq = this.msgsBeingSent[msgKey];
browserProxy.tabs.get(this.tabId, function (tab) { browserProxy.tabs.get(this.tabId, function(tab) {origPageUrl = tab.url;});
origPageUrl = tab.url;
});
setTimeout(function () { setTimeout(function() {
var rawRequests = []; var rawRequests = [];
if (globalPageContainer.collectors[_this.tabId] === _this) { if ( globalPageContainer.collectors[_this.tabId] === _this ) {
for (var reqId in _this.requests) { for ( var reqId in _this.requests ) {
rawRequests.push(_this.requests[reqId]); rawRequests.push(_this.requests[reqId]);
} }
var tagReqs = _this.grabTagReqs(rawRequests, msgAssetReq); var tagReqs = _this.grabTagReqs(rawRequests, msgAssetReq);
if (_this.isValidVideoAd(msgAssetReq, tagReqs)) { if ( _this.isValidVideoAd(msgAssetReq, tagReqs) ) {
_this.sendToTab(msgAssetReq, tagReqs, origPageUrl, true); _this.sendToTab(msgAssetReq, tagReqs, origPageUrl, true);
} else { } else {
_this.sendToTab(msgAssetReq, tagReqs, origPageUrl, false); _this.sendToTab(msgAssetReq, tagReqs, origPageUrl, false);
} }
} else {}
} else {
}
delete _this.msgsBeingSent[msgKey]; delete _this.msgsBeingSent[msgKey];
}, secAfter + secBefore); }, secAfter+secBefore);
}; };
PageNetworkTrafficCollector.prototype.existingMessage = function (candidateRequest) { PageNetworkTrafficCollector.prototype.existingMessage = function(candidateRequest) {
var frameMsg = this.msgsBeingSent[candidateRequest.frameId]; var frameMsg = this.msgsBeingSent[candidateRequest.frameId];
if (frameMsg) { if ( frameMsg ) {
return frameMsg; return frameMsg;
} else { } else {
return null; return null;
@ -679,13 +661,13 @@
} }
function onCommittedListener(details) { function onCommittedListener(details) {
if (details.frameId === 0) { if ( details.frameId === 0 ) {
globalPageContainer.onNavigationCommitted(details); globalPageContainer.onNavigationCommitted(details);
} }
} }
function onCompletedListener(details) { function onCompletedListener(details) {
if (details.frameId === 0) { if ( details.frameId === 0 ) {
globalPageContainer.onNavigationCompleted(details); globalPageContainer.onNavigationCompleted(details);
} }
} }
@ -695,9 +677,9 @@
} }
function onMessageListener(message, sender, sendResponse) { function onMessageListener(message, sender, sendResponse) {
if (message.event === 'new-ad' && message.data.event === 'ad') { if ( message.event === 'new-ad' && message.data.event === 'ad' ) {
var tabId = sender.tab.id; var tabId = sender.tab.id;
if (tabId) { if ( tabId ) {
globalPageContainer.onDisplayAdFound(tabId); globalPageContainer.onDisplayAdFound(tabId);
} }
} }
@ -705,15 +687,35 @@
function registerListeners() { function registerListeners() {
browserProxy.webRequest.onBeforeRequest.addListener(onBeforeRequestListener, { urls: ['http://*/*', 'https://*/*'] }, []); browserProxy.webRequest.onBeforeRequest.addListener(
onBeforeRequestListener,
browserProxy.webRequest.onSendHeaders.addListener(onSendHeadersListener, { urls: ['http://*/*', 'https://*/*'] }, ['requestHeaders']); {urls: ['http://*/*', 'https://*/*']},
[]
browserProxy.webRequest.onHeadersReceived.addListener(onHeadersReceivedListener, { urls: ['http://*/*', 'https://*/*'] }, ['responseHeaders']); );
browserProxy.webRequest.onBeforeRedirect.addListener(onBeforeRedirectListener, { urls: ['http://*/*', 'https://*/*'] }, []); browserProxy.webRequest.onSendHeaders.addListener(
onSendHeadersListener,
browserProxy.webRequest.onResponseStarted.addListener(onResponseStartedListener, { urls: ['http://*/*', 'https://*/*'] }, ['responseHeaders']); {urls: ['http://*/*', 'https://*/*']},
['requestHeaders']
);
browserProxy.webRequest.onHeadersReceived.addListener(
onHeadersReceivedListener,
{urls: ['http://*/*', 'https://*/*']},
['responseHeaders']
);
browserProxy.webRequest.onBeforeRedirect.addListener(
onBeforeRedirectListener,
{urls: ['http://*/*', 'https://*/*']},
[]
);
browserProxy.webRequest.onResponseStarted.addListener(
onResponseStartedListener,
{urls: ['http://*/*', 'https://*/*']},
['responseHeaders']
);
browserProxy.webNavigation.onCommitted.addListener(onCommittedListener); browserProxy.webNavigation.onCommitted.addListener(onCommittedListener);
browserProxy.webNavigation.onCompleted.addListener(onCompletedListener); browserProxy.webNavigation.onCompleted.addListener(onCompletedListener);
@ -725,15 +727,25 @@
function unregisterListeners() { function unregisterListeners() {
browserProxy.webRequest.onBeforeRequest.removeListener(onBeforeRequestListener); browserProxy.webRequest.onBeforeRequest.removeListener(
onBeforeRequestListener
);
browserProxy.webRequest.onSendHeaders.removeListener(onSendHeadersListener); browserProxy.webRequest.onSendHeaders.removeListener(
onSendHeadersListener
);
browserProxy.webRequest.onHeadersReceived.removeListener(onHeadersReceivedListener); browserProxy.webRequest.onHeadersReceived.removeListener(
onHeadersReceivedListener
);
browserProxy.webRequest.onBeforeRedirect.removeListener(onBeforeRedirectListener); browserProxy.webRequest.onBeforeRedirect.removeListener(
onBeforeRedirectListener
);
browserProxy.webRequest.onResponseStarted.removeListener(onResponseStartedListener); browserProxy.webRequest.onResponseStarted.removeListener(
onResponseStartedListener
);
browserProxy.webNavigation.onCommitted.removeListener(onCommittedListener); browserProxy.webNavigation.onCommitted.removeListener(onCommittedListener);
browserProxy.webNavigation.onCompleted.removeListener(onCompletedListener); browserProxy.webNavigation.onCompleted.removeListener(onCompletedListener);
@ -744,40 +756,51 @@
} }
function areRequiredBrowserApisAvailable() { function areRequiredBrowserApisAvailable() {
return requiredBrowserApis.every(function (api) { return requiredBrowserApis.every(function(api) {
return typeof api !== 'undefined'; return typeof api !== 'undefined';
}); });
} }
if (areRequiredBrowserApisAvailable()) { if ( areRequiredBrowserApisAvailable() ) {
ifBrowserValid(function () { ifBrowserValid(
browserProxy.webNavigation.onBeforeNavigate.addListener(function (details) { function() {
if (details.frameId === 0) { browserProxy.webNavigation.onBeforeNavigate.addListener(
function(details) {
if ( details.frameId === 0 ) {
globalPageContainer.onNewNavigation(details); globalPageContainer.onNewNavigation(details);
} }
}, { },
url: [{ urlMatches: 'http://*/*' }, { urlMatches: 'https://*/*' }] {
}); url: [{urlMatches: 'http://*/*'}, {urlMatches: 'https://*/*'}]
}, function () {});
} }
);
}, function() {
browserProxy.runtime.onMessage.addListener(function (request, sender, sendResponse) {
if (request === 'is_browser_valid') {
ifBrowserValid(sendResponse({ 'browser_valid': true }), sendResponse({ 'browser_valid': false }));
} }
}); );
}
browserProxy.runtime.onMessage.addListener(function (request, sender, sendResponse) { browserProxy.runtime.onMessage.addListener(function(request, sender, sendResponse) {
if (request === 'is_tracking_enabled') { if ( request === 'is_browser_valid' ) {
ifTrackingEnabled(function () { ifBrowserValid(
sendResponse({ 'tracking_enabled': true }); sendResponse({'browser_valid': true}),
}, function () { sendResponse({'browser_valid': false})
sendResponse({ 'tracking_enabled': false }); );
}
}); });
browserProxy.runtime.onMessage.addListener(function(request, sender, sendResponse) {
if ( request === 'is_tracking_enabled' ) {
ifTrackingEnabled(
function() {
sendResponse({'tracking_enabled': true});
},
function() {
sendResponse({'tracking_enabled': false});
}
);
} }
return true; return true;
}); });
})();
/***/ }) })();
/******/ ]);

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -23,10 +23,10 @@
"128": "images/icon_128.png" "128": "images/icon_128.png"
}, },
"default_title": "Wappalyzer", "default_title": "Wappalyzer",
"default_popup": "popup.html" "default_popup": "html/popup.html"
}, },
"background": { "background": {
"page": "background.html", "page": "html/background.html",
"persistent": true "persistent": true
}, },
"content_scripts": [ "content_scripts": [
@ -36,7 +36,7 @@
"https://*/*" "https://*/*"
], ],
"js": [ "js": [
"js/browser-polyfill.js", "node_modules/webextension-polyfill/dist/browser-polyfill.js",
"js/content.js" "js/content.js"
], ],
"run_at": "document_idle" "run_at": "document_idle"
@ -57,7 +57,7 @@
"web_accessible_resources": [ "web_accessible_resources": [
"js/inject.js" "js/inject.js"
], ],
"options_page": "options.html", "options_page": "html/options.html",
"permissions": [ "permissions": [
"storage", "storage",
"tabs", "tabs",

@ -23,10 +23,10 @@
"128": "images/icon_128.png" "128": "images/icon_128.png"
}, },
"default_title": "Wappalyzer", "default_title": "Wappalyzer",
"default_popup": "popup.html" "default_popup": "html/popup.html"
}, },
"background": { "background": {
"page": "background.html" "page": "html/background.html"
}, },
"content_scripts": [ "content_scripts": [
@ -36,6 +36,7 @@
"https://*/*" "https://*/*"
], ],
"js": [ "js": [
"node_modules/webextension-polyfill/dist/browser-polyfill.js",
"js/content.js" "js/content.js"
], ],
"run_at": "document_idle" "run_at": "document_idle"
@ -55,9 +56,9 @@
"web_accessible_resources": [ "web_accessible_resources": [
"js/inject.js" "js/inject.js"
], ],
"options_page": "options.html", "options_page": "html/options.html",
"options_ui": { "options_ui": {
"page": "options.html", "page": "html/options.html",
"open_in_tab": false "open_in_tab": false
}, },
"permissions": [ "permissions": [

@ -1,12 +1,5 @@
{ {
"devDependencies": {
"babel-core": "^6.25.0",
"babel-loader": "^7.1.1",
"babel-preset-react": "^6.24.1",
"babelify": "^7.3.0"
},
"dependencies": { "dependencies": {
"request": "^2.81.0",
"webextension-polyfill": "^0.1.1" "webextension-polyfill": "^0.1.1"
} }
} }

@ -1,14 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="css/popup.css">
<script src="js/jsontodom.js"></script>
<script src="js/popup.js"></script>
</head>
<body>
</body>
</html>

@ -1,77 +0,0 @@
/** global: browser */
import browser from 'webextension-polyfill'
(function() {
var c = {
init: function() {
var html = document.documentElement.outerHTML;
c.log('Function call: init()');
if ( html.length > 50000 ) {
html = html.substring(0, 25000) + html.substring(html.length - 25000, html.length);
}
browser.runtime.sendMessage({
id: 'analyze',
subject: { html: html },
source: 'content.js'
});
c.getEnvironmentVars();
},
log: function(message) {
browser.runtime.sendMessage({
id: 'log',
message: message,
source: 'content.js'
});
},
getEnvironmentVars: function() {
var container, script;
c.log('Function call: getEnvironmentVars()');
if ( typeof document.body === 'undefined' ) {
return;
}
try {
container = document.createElement('wappalyzerData');
container.setAttribute('id', 'wappalyzerData');
container.setAttribute('style', 'display: none');
script = document.createElement('script');
script.setAttribute('id', 'wappalyzerEnvDetection');
script.setAttribute('src', browser.extension.getURL('js/inject.js'));
container.addEventListener('wappalyzerEvent', (function(event) {
var environmentVars = event.target.childNodes[0].nodeValue;
document.documentElement.removeChild(container);
document.documentElement.removeChild(script);
environmentVars = environmentVars.split(' ').slice(0, 500);
browser.runtime.sendMessage({
id: 'analyze',
subject: { env: environmentVars },
source: 'content.js'
});
}), true);
document.documentElement.appendChild(container);
document.documentElement.appendChild(script);
} catch(e) {
c.log('Error: ' + e);
}
}
}
c.init();
}());

@ -1,244 +0,0 @@
/**
* WebExtension driver
*/
import wappalyzer from '../../../wappalyzer';
import browser from 'webextension-polyfill';
import request from 'request';
var tabCache = {};
var headersCache = {};
browser.tabs.onRemoved.addListener(function(tabId) {
tabCache[tabId] = null;
});
/**
* Get a value from localStorage
*/
function getOption(name, defaultValue, callback) {
const func = item => {
callback(item.hasOwnProperty(name) ? item[name] : defaultValue);
};
try {
// Chrome, Firefox
browser.storage.local.get(name).then(func);
} catch ( e ) {
// Edge
browser.storage.local.get(name, func);
}
}
/**
* Set a value in localStorage
*/
function setOption(name, value) {
var option = {};
option[name] = value;
browser.storage.local.set(option);
}
/**
* Open a tab
*/
function openTab(args) {
browser.tabs.create({
url: args.url,
active: args.background === undefined || !args.background
});
}
/**
* Make a POST request
*/
function post(url, body) {
request.post({ url, body, json: true }, (error, response) => {
wappalyzer.log('Post request: ' + ( error || response.statusCode ), 'driver');
});
}
//
var categoryOrder = Object.keys(wappalyzer.categories).sort(function(a, b) {
return wappalyzer.categories[a].priority - wappalyzer.categories[b].priority;
});
// Version check
var version = browser.runtime.getManifest().version;
getOption('version', null, function(previousVersion) {
if ( previousVersion === null ) {
openTab({
url: wappalyzer.config.websiteURL + 'installed'
});
} else if ( version !== previousVersion ) {
getOption('upgradeMessage', true, function(upgradeMessage) {
if ( upgradeMessage ) {
openTab({
url: wappalyzer.config.websiteURL + 'upgraded',
background: true
});
}
});
}
setOption('version', version);
});
// Run content script
var callback = function(tabs) {
tabs.forEach(function(tab) {
if ( tab.url.match(/^https?:\/\//) ) {
browser.tabs.executeScript(tab.id, { file: 'js/content.js' });
}
})
};
try {
browser.tabs.query({}).then(callback);
} catch ( e ) {
browser.tabs.query({}, callback);
}
// Capture response headers
browser.webRequest.onCompleted.addListener(request => {
var responseHeaders = {};
if ( request.responseHeaders ) {
var uri = request.url.replace(/#.*$/, ''); // Remove hash
request.responseHeaders.forEach(header => {
responseHeaders[header.name.toLowerCase()] = header.value || '' + header.binaryValue;
});
if ( headersCache.length > 50 ) {
headersCache = {};
}
if ( /text\/html/.test(responseHeaders['content-type']) ) {
if ( headersCache[uri] === undefined ) {
headersCache[uri] = {};
}
Object.keys(responseHeaders).forEach(header => {
headersCache[uri][header] = responseHeaders[header];
});
}
}
}, { urls: [ 'http://*/*', 'https://*/*' ], types: [ 'main_frame' ] }, [ 'responseHeaders' ]);
// Listen for messages
( chrome || browser ).runtime.onMessage.addListener((message, sender, sendResponse) => {
if ( typeof message.id != 'undefined' ) {
if ( message.id !== 'log' ) {
wappalyzer.log('Message received from ' + message.source + ': ' + message.id, 'driver');
}
switch ( message.id ) {
case 'log':
wappalyzer.log(message.message, message.source);
break;
case 'analyze':
var a = document.createElement('a');
a.href = sender.tab.url.replace(/#.*$/, '');
if ( headersCache[a.href] !== undefined ) {
message.subject.headers = headersCache[a.href];
}
wappalyzer.analyze(a.hostname, a.href, message.subject, { tab: sender.tab });
break;
case 'ad_log':
wappalyzer.cacheDetectedAds(message.subject);
break;
case 'get_apps':
var response = {
tabCache: tabCache[message.tab.id],
apps: wappalyzer.apps,
categories: wappalyzer.categories
};
break;
default:
}
sendResponse(response);
}
});
/**
* Log messages to console
*/
wappalyzer.driver.log = (message, source, type) => {
console.log('[wappalyzer ' + type + ']', '[' + source + ']', message);
}
/**
* Display apps
*/
wappalyzer.driver.displayApps = (detected, context) => {
var tab = context.tab;
tabCache[tab.id] = tabCache[tab.id] || { detected: [] };
tabCache[tab.id].detected = detected;
if ( Object.keys(detected).length ) {
getOption('dynamicIcon', true, function(dynamicIcon) {
var appName, found = false;
// Find the main application to display
categoryOrder.forEach(match => {
Object.keys(detected).forEach(appName => {
var app = detected[appName];
app.props.cats.forEach(function(category) {
var icon = app.icon || 'default.svg';
if ( !dynamicIcon ) {
icon = 'default.svg';
}
if ( category === match && !found ) {
if ( /\.svg$/i.test(icon) ) {
icon = 'converted/' + icon.replace(/\.svg$/, '.png');
}
browser.pageAction.setIcon({
tabId: tab.id,
path: 'images/icons/' + icon
});
found = true;
}
});
});
});
if ( typeof chrome !== 'undefined' ) {
// Browser polyfill doesn't seem to work here
chrome.pageAction.show(tab.id);
} else {
browser.pageAction.show(tab.id);
}
});
};
}
/**
* Anonymously track detected applications for research purposes
*/
wappalyzer.driver.ping = (ping, adCache) => {
getOption('tracking', true, tracking => {
if ( tracking ) {
post('http://ping.wappalyzer.com/v2/', ping);
post('https://ad.wappalyzer.com/log/wp/', adCache);
}
});
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -1,16 +0,0 @@
(function() {
try {
var i, environmentVars = '', e = document.createEvent('Events');
e.initEvent('wappalyzerEvent', true, false);
for ( i in window ) {
environmentVars += i + ' ';
}
document.getElementById('wappalyzerData').appendChild(document.createComment(environmentVars));
document.getElementById('wappalyzerData').dispatchEvent(e);
} catch(e) {
// Fail quietly
}
}());

@ -1,65 +0,0 @@
jsonToDOM.namespaces = {
html: "http://www.w3.org/1999/xhtml",
xul: "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
};
jsonToDOM.defaultNamespace = jsonToDOM.namespaces.html;
function jsonToDOM(jsonTemplate, doc, nodes) {
function namespace(name) {
var reElemNameParts = /^(?:(.*):)?(.*)$/.exec(name);
return { namespace: jsonToDOM.namespaces[reElemNameParts[1]], shortName: reElemNameParts[2] };
}
// Note that 'elemNameOrArray' is: either the full element name (eg. [html:]div) or an array of elements in JSON notation
function tag(elemNameOrArray, elemAttr) {
// Array of elements? Parse each one...
if (Array.isArray(elemNameOrArray)) {
var frag = doc.createDocumentFragment();
Array.prototype.forEach.call(arguments, function(thisElem) {
frag.appendChild(tag.apply(null, thisElem));
});
return frag;
}
// Single element? Parse element namespace prefix (if none exists, default to defaultNamespace), and create element
var elemNs = namespace(elemNameOrArray);
var elem = doc.createElementNS(elemNs.namespace || jsonToDOM.defaultNamespace, elemNs.shortName);
// Set element's attributes and/or callback functions (eg. onclick)
for (var key in elemAttr) {
var val = elemAttr[key];
if (nodes && key == "key") {
nodes[val] = elem;
continue;
}
var attrNs = namespace(key);
if (typeof val == "function") {
// Special case for function attributes; don't just add them as 'on...' attributes, but as events, using addEventListener
elem.addEventListener(key.replace(/^on/, ""), val, false);
}
else {
// Note that the default namespace for XML attributes is, and should be, blank (ie. they're not in any namespace)
elem.setAttributeNS(attrNs.namespace || "", attrNs.shortName, val);
}
}
// Create and append this element's children
var childElems = Array.prototype.slice.call(arguments, 2);
childElems.forEach(function(childElem) {
if (childElem != null) {
elem.appendChild(
childElem instanceof doc.defaultView.Node ? childElem :
Array.isArray(childElem) ? tag.apply(null, childElem) :
doc.createTextNode(childElem));
}
});
return elem;
}
return tag.apply(null, jsonTemplate);
}
export default jsonToDOM;

@ -1,846 +0,0 @@
if (!Range.prototype["intersectsNode"]) {
Range.prototype["intersectsNode"] = function (node) {
let range = document.createRange();
range.selectNode(node);
return 0 > this.compareBoundaryPoints(Range.END_TO_START, range)
&& 0 < this.compareBoundaryPoints(Range.START_TO_END, range);
};
}
var getExtensionProtocol = function () {
if (typeof browser == "undefined") {
if (typeof chrome !== "undefined")
return "chrome-extension://";
}
else {
return "ms-browser-extension://";
}
};
class FakeEvent {
addListener(callback) { }
addRules(rules, callback) { }
getRules(ruleIdentifiers, callback) { }
hasListener(callback) { return false; }
hasListeners() { return false; }
removeRules(ruleIdentifiers, callback) { }
removeListener(callback) { }
}
class EdgeBridgeHelper {
constructor() {
this.fakeEvent = new FakeEvent();
}
toAbsolutePath(relativePath) {
if (relativePath.indexOf("ms-browser-extension://") == 0) {
return relativePath.replace(myBrowser.runtime.getURL(""), "");
}
else if (relativePath.indexOf("/") != 0) {
var absolutePath = "";
var documentPath = document.location.pathname;
absolutePath = documentPath.substring(0, documentPath.lastIndexOf("/") + 1);
absolutePath += relativePath;
return absolutePath;
}
return relativePath;
}
}
var bridgeHelper = new EdgeBridgeHelper();
class EdgeBridgeDebugLog {
constructor() {
this.CatchOnException = true;
this.VerboseLogging = true;
this.FailedCalls = {};
this.SuccededCalls = {};
this.DeprecatedCalls = {};
this.BridgedCalls = {};
this.UnavailableApis = {};
this.EdgeIssues = {};
}
log(message) {
try {
if (this.VerboseLogging) {
console.log(message);
}
}
catch (e) {
}
}
info(message) {
try {
if (this.VerboseLogging) {
console.info(message);
}
}
catch (e) {
}
}
warn(message) {
try {
if (this.VerboseLogging) {
console.warn(message);
}
}
catch (e) {
}
}
error(message) {
try {
if (this.VerboseLogging) {
console.error(message);
}
}
catch (e) {
}
}
DoActionAndLog(action, name, deprecatedTo, bridgedTo) {
var result;
try {
result = action();
this.AddToCalledDictionary(this.SuccededCalls, name);
if (typeof deprecatedTo !== "undefined" && typeof deprecatedTo !== "null") {
this.warn("API Call Deprecated - Name: " + name + ", Please use " + deprecatedTo + " instead!");
this.AddToCalledDictionary(this.DeprecatedCalls, name);
}
if (typeof bridgedTo !== "undefined" && typeof bridgedTo !== "null") {
this.info("API Call '" + name + "' has been bridged to another Edge API: " + bridgedTo);
this.AddToCalledDictionary(this.BridgedCalls, name);
}
return result;
}
catch (ex) {
this.AddToCalledDictionary(this.FailedCalls, name);
if (this.CatchOnException)
this.error("API Call Failed: " + name + " - " + ex);
else
throw ex;
}
}
LogEdgeIssue(name, message) {
this.warn(message);
this.AddToCalledDictionary(this.EdgeIssues, name);
}
LogUnavailbleApi(name, deprecatedTo) {
this.warn("API Call '" + name + "' is not supported in Edge");
this.AddToCalledDictionary(this.UnavailableApis, name);
if (typeof deprecatedTo !== "undefined" && typeof deprecatedTo !== "null") {
this.warn("API Call Deprecated - Name: " + name + ", Please use " + deprecatedTo + " instead!");
this.AddToCalledDictionary(this.DeprecatedCalls, name);
}
}
AddToCalledDictionary(dictionary, name) {
if (typeof dictionary[name] !== "undefined") {
dictionary[name]++;
}
else {
dictionary[name] = 1;
}
}
}
var bridgeLog = new EdgeBridgeDebugLog();
class EdgeChromeAppBridge {
getDetails() {
return bridgeLog.DoActionAndLog(() => {
return EdgeChromeRuntimeBridge.prototype.getManifest();
}, "app.getManifest", undefined, "runtime.getManifest");
}
get isInstalled() { return bridgeLog.DoActionAndLog(() => { throw "app.isInstalled is not available in Edge"; }, "app.isInstalled"); }
getIsInstalled() { return bridgeLog.DoActionAndLog(() => { throw "app.getIsInstalled is not available in the Edge"; }, "app.getIsInstalled"); }
installState() { return bridgeLog.DoActionAndLog(() => { throw "app.installState is not available in Edge"; }, "app.installState"); }
runningState() { return bridgeLog.DoActionAndLog(() => { throw "app.runningState is not available in Edge"; }, "app.runningState"); }
}
class EdgeBrowserActionBridge {
get onClicked() { return bridgeLog.DoActionAndLog(() => { return myBrowser.browserAction.onClicked; }, "browserAction.onClicked"); }
disable(tabId) {
bridgeLog.DoActionAndLog(() => {
myBrowser.browserAction.disable(tabId);
}, "browserAction.disable");
}
enable(tabId) {
bridgeLog.DoActionAndLog(() => {
if (typeof tabId !== "undefined" && typeof tabId !== "null") {
myBrowser.browserAction.enable(tabId);
}
else {
myBrowser.browserAction.enable();
}
}, "browserAction.Enable");
}
getBadgeBackgroundColor(details, callback) {
bridgeLog.DoActionAndLog(() => {
myBrowser.browserAction.getBadgeBackgroundColor(details, callback);
}, "browserAction.getBadgeBackgroundColor");
}
getBadgeText(details, callback) {
bridgeLog.DoActionAndLog(() => {
myBrowser.browserAction.getBadgeText(details, callback);
}, "browserAction.getBadgeText");
}
setBadgeBackgroundColor(details) {
bridgeLog.DoActionAndLog(() => {
myBrowser.browserAction.setBadgeBackgroundColor(details);
}, "browserAction.setBadgeBackgroundColor");
}
setBadgeText(details) {
bridgeLog.DoActionAndLog(() => {
myBrowser.browserAction.setBadgeText(details);
}, "browserAction.setBadgeText");
}
setIcon(details, callback) {
bridgeLog.DoActionAndLog(() => {
if (typeof details.path !== "undefined") {
if (typeof details.path === "object") {
for (var key in details.path) {
if (details.path.hasOwnProperty(key)) {
details.path[key] = bridgeHelper.toAbsolutePath(details.path[key]);
}
}
}
else {
details.path = bridgeHelper.toAbsolutePath(details.path);
}
}
if (typeof callback !== "undefined" && typeof callback !== "null") {
myBrowser.browserAction.setIcon(details, callback);
}
else {
myBrowser.browserAction.setIcon(details);
}
}, "browserAction.setIcon", undefined, "browserAction.setIcon with absolute path");
}
setPopup(details) {
bridgeLog.DoActionAndLog(() => {
myBrowser.browserAction.setPopup(details);
}, "browserAction.setPopup");
}
}
class EdgeChromeBrowserActionBridge extends EdgeBrowserActionBridge {
getPopup(details, callback) {
bridgeLog.LogUnavailbleApi("browserAction.getPopup");
}
getTitle(details, callback) {
bridgeLog.LogUnavailbleApi("browserAction.getTitle");
}
setTitle(details) {
bridgeLog.LogUnavailbleApi("browserAction.setTitle");
}
}
class EdgeContextMenusBridge {
get ACTION_MENU_TOP_LEVEL_LIMIT() { return bridgeLog.DoActionAndLog(() => { return myBrowser.contextMenus.ACTION_MENU_TOP_LEVEL_LIMIT; }, "contextMenus.ACTION_MENU_TOP_LEVEL_LIMIT"); }
get onClicked() { return bridgeLog.DoActionAndLog(() => { return myBrowser.contextMenus.onClicked; }, "contextMenus.onClicked"); }
create(createProperties, callback) {
bridgeLog.DoActionAndLog(() => {
if (typeof callback !== "undefined" && typeof callback !== "null") {
myBrowser.contextMenus.create(createProperties, callback);
}
else {
myBrowser.contextMenus.create(createProperties);
}
}, "contextMenus.create");
}
remove(menuItemId, callback) {
bridgeLog.DoActionAndLog(() => {
if (typeof callback !== "undefined" && typeof callback !== "null") {
myBrowser.contextMenus.remove(menuItemId, callback);
}
else {
myBrowser.contextMenus.remove(menuItemId);
}
}, "contextMenus.remove");
}
removeAll(callback) {
bridgeLog.DoActionAndLog(() => {
if (typeof callback !== "undefined" && typeof callback !== "null") {
myBrowser.contextMenus.removeAll(callback);
}
else {
myBrowser.contextMenus.removeAll();
}
}, "contextMenus.removeAll");
}
update(id, updateProperties, callback) {
bridgeLog.DoActionAndLog(() => {
if (typeof callback !== "undefined" && typeof callback !== "null") {
myBrowser.contextMenus.update(id, updateProperties, callback);
}
else {
myBrowser.contextMenus.update(id, updateProperties);
}
}, "contextMenus.update");
}
}
class EdgeCookiesBridge {
get(details, callback) {
bridgeLog.DoActionAndLog(() => {
myBrowser.cookies.get(details, callback);
}, "cookies.get");
}
getAll(details, callback) {
bridgeLog.DoActionAndLog(() => {
myBrowser.cookies.getAll(details, callback);
}, "cookies.getAll");
}
remove(details, callback) {
bridgeLog.DoActionAndLog(() => {
if (typeof callback !== "undefined" && typeof callback !== "null") {
myBrowser.cookies.remove(details, callback);
}
else {
myBrowser.cookies.remove(details);
}
}, "cookies.remove");
}
set(details, callback) {
bridgeLog.DoActionAndLog(() => {
if (typeof callback !== "undefined" && typeof callback !== "null") {
myBrowser.cookies.set(details, callback);
}
else {
myBrowser.cookies.set(details);
}
}, "cookies.set");
}
}
class EdgeChromeCookiesBridge extends EdgeCookiesBridge {
get onChanged() { bridgeLog.LogUnavailbleApi("cookies.onChanged"); return bridgeHelper.fakeEvent; }
}
class EdgeExtensionBridge {
getBackgroundPage() {
return bridgeLog.DoActionAndLog(() => {
return myBrowser.extension.getBackgroundPage();
}, "extension.getBackgroundPage");
}
getURL(path) {
return bridgeLog.DoActionAndLog(() => {
return myBrowser.extension.getURL(path);
}, "extension.getURL");
}
getViews(fetchProperties) {
return bridgeLog.DoActionAndLog(() => {
return myBrowser.extension.getViews(fetchProperties);
}, "extension.getViews");
}
}
class EdgeChromeExtensionBridge extends EdgeExtensionBridge {
get onConnect() { return bridgeLog.DoActionAndLog(() => { return EdgeRuntimeBridge.prototype.onConnect; }, "extension.onConnect", "runtime.onConnect", "runtime.onConnect"); }
get onMessage() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.onMessage; }, "extension.onMessage", "runtime.onMessage", "runtime.onMessage"); }
get onRequest() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.onMessage; }, "extension.onRequest", "runtime.onMessage", "runtime.onMessage"); }
get onRequestExternal() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.onMessageExternal; }, "extension.onRequestExternal", "runtime.onMessageExternal", "runtime.onMessageExternal"); }
get inIncognitoContext() { return bridgeLog.DoActionAndLog(() => { return myBrowser.extension["inPrivateContext"]; }, "extension.inIncognitoContext", undefined, "extension.inPrivateContext"); }
get lastError() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.lastError; }, "extension.lastError", undefined, "runtime.lastError"); }
connect(extensionId, connectInfo) {
return bridgeLog.DoActionAndLog(() => {
return EdgeRuntimeBridge.prototype.connect(extensionId, connectInfo);
}, "extension.connect", "runtime.connect", "runtime.connect");
}
sendMessage(message, responseCallback) {
return bridgeLog.DoActionAndLog(() => {
return EdgeRuntimeBridge.prototype.sendMessage(message, responseCallback, undefined, undefined);
}, "extension.sendMessage", "runtime.sendMessage", "runtime.sendMessage");
}
sendRequest(extensionId, message, options, responseCallback) {
return bridgeLog.DoActionAndLog(() => {
return EdgeRuntimeBridge.prototype.sendMessage(extensionId, message, options, responseCallback);
}, "extension.sendRequest", "runtime.sendMessage", "runtime.sendMessage");
}
isAllowedFileSchemeAccess(callback) {
bridgeLog.LogUnavailbleApi("extension.isAllowedFileSchemeAccess");
}
isAllowedIncognitoAccess(callback) {
bridgeLog.LogUnavailbleApi("extension.isAllowedIncognitoAccess");
}
setUpdateUrlData(data) {
bridgeLog.LogUnavailbleApi("extension.setUpdateUrlData");
}
}
class EdgeHistoryBridge {
get onVisited() { bridgeLog.LogUnavailbleApi("history.onVisited"); return bridgeHelper.fakeEvent; }
get onVisitRemoved() { bridgeLog.LogUnavailbleApi("history.onVisitRemoved"); return bridgeHelper.fakeEvent; }
addUrl(details, callback) {
bridgeLog.LogUnavailbleApi("history.addUrl");
}
deleteAll(callback) {
bridgeLog.LogUnavailbleApi("history.deleteAll");
}
deleteRange(range, callback) {
bridgeLog.LogUnavailbleApi("history.deleteRange");
}
deleteUrl(details, callback) {
bridgeLog.LogUnavailbleApi("history.deleteUrl");
}
getVisits(details, callback) {
bridgeLog.LogUnavailbleApi("history.getVisits");
}
search(query, callback) {
bridgeLog.LogUnavailbleApi("history.search");
}
}
class EdgeI18nBridge {
getAcceptLanguages(callback) {
return bridgeLog.DoActionAndLog(() => {
return myBrowser.i18n.getAcceptLanguages(callback);
}, "i18n.getAcceptLanguages");
}
getMessage(messageName, substitutions) {
return bridgeLog.DoActionAndLog(() => {
if (messageName.indexOf("@@extension_id") > -1) {
return myBrowser.runtime.id;
}
if (typeof substitutions !== "undefined" && typeof substitutions !== "null") {
return myBrowser.i18n.getMessage(messageName, substitutions);
}
else {
return myBrowser.i18n.getMessage(messageName);
}
}, "i18n.getMessage");
}
getUILanguage() {
return bridgeLog.DoActionAndLog(() => {
return myBrowser.i18n.getUILanguage();
}, "i18n.getUILanguage");
}
}
class EdgeNotificationBridge {
get onButtonClicked() { bridgeLog.LogUnavailbleApi("notifications.onButtonClicked"); return bridgeHelper.fakeEvent; }
get onClicked() { bridgeLog.LogUnavailbleApi("notifications.onClicked"); return bridgeHelper.fakeEvent; }
get onClosed() { bridgeLog.LogUnavailbleApi("notifications.onClosed"); return bridgeHelper.fakeEvent; }
get onPermissionLevelChanged() { bridgeLog.LogUnavailbleApi("notifications.onPermissionLevelChanged"); return bridgeHelper.fakeEvent; }
get onShowSettings() { bridgeLog.LogUnavailbleApi("notifications.onShowSettings"); return bridgeHelper.fakeEvent; }
clear(notificationId, callback) {
bridgeLog.LogUnavailbleApi("notifications.clear");
}
create(notificationId, options, callback) {
bridgeLog.LogUnavailbleApi("notifications.create");
}
getAll(callback) {
bridgeLog.LogUnavailbleApi("notifications.getAll");
}
getPermissionLevel(callback) {
bridgeLog.LogUnavailbleApi("notifications.getPermissionLevel");
}
update(notificationId, options, callback) {
bridgeLog.LogUnavailbleApi("notifications.update");
}
}
class EdgePageActionBridge {
get onClicked() { return bridgeLog.DoActionAndLog(() => { return myBrowser.pageAction.onClicked; }, "pageAction.onClicked"); }
getPopup(details, callback) {
bridgeLog.DoActionAndLog(() => {
myBrowser.pageAction.getPopup(details, callback);
}, "pageAction.getPopup");
}
getTitle(details, callback) {
bridgeLog.DoActionAndLog(() => {
myBrowser.pageAction.getTitle(details, callback);
}, "pageAction.getTitle");
}
hide(tabId) {
bridgeLog.DoActionAndLog(() => {
myBrowser.pageAction.hide(tabId);
}, "pageAction.hide");
}
setTitle(details) {
bridgeLog.DoActionAndLog(() => {
myBrowser.pageAction.setTitle(details);
}, "pageAction.setTitle");
}
setIcon(details, callback) {
bridgeLog.DoActionAndLog(() => {
if (typeof callback !== "undefined" && typeof callback !== "null") {
myBrowser.pageAction.setIcon(details, callback);
}
else {
myBrowser.pageAction.setIcon(details, callback);
}
}, "pageAction.setIcon");
}
setPopup(details) {
bridgeLog.DoActionAndLog(() => {
myBrowser.pageAction.setPopup(details);
}, "pageAction.setPopup");
}
show(tabId) {
bridgeLog.DoActionAndLog(() => {
myBrowser.pageAction.show(tabId);
}, "pageAction.show");
}
}
class EdgePermissionsBridge {
get onAdded() { bridgeLog.LogUnavailbleApi("permissions.onAdded"); return bridgeHelper.fakeEvent; }
get onRemoved() { bridgeLog.LogUnavailbleApi("permissions.onRemoved"); return bridgeHelper.fakeEvent; }
contains(permissions, callback) {
bridgeLog.LogUnavailbleApi("permissions.contains");
}
getAll(callback) {
bridgeLog.LogUnavailbleApi("permissions.getAll");
}
remove(permissions, callback) {
bridgeLog.LogUnavailbleApi("permissions.remove");
}
request(permissions, callback) {
bridgeLog.LogUnavailbleApi("permissions.request");
}
}
class EdgeRuntimeBridge {
get id() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.id; }, "runtime.id"); }
get lastError() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.lastError; }, "runtime.lastError"); }
get onConnect() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.onConnect; }, "runtime.onConnect"); }
get onInstalled() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.onInstalled; }, "runtime.onInstalled"); }
get onMessage() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.onMessage; }, "runtime.onMessage"); }
get onMessageExternal() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.onMessageExternal; }, "runtime.onMessageExternal"); }
connect(extensionId, connectInfo) {
return bridgeLog.DoActionAndLog(() => {
if (typeof connectInfo !== "undefined" && typeof connectInfo !== "null") {
return myBrowser.runtime.connect(extensionId, connectInfo);
}
else {
return myBrowser.runtime.connect(extensionId);
}
}, "runtime.connect");
}
getBackgroundPage(callback) {
bridgeLog.DoActionAndLog(() => {
myBrowser.runtime.getBackgroundPage(callback);
}, "runtime.getBackgroundPage");
}
getManifest() {
return bridgeLog.DoActionAndLog(() => {
return myBrowser.runtime.getManifest();
}, "runtime.getManifest");
}
getURL(path) {
return bridgeLog.DoActionAndLog(() => {
return myBrowser.runtime.getURL(path);
}, "runtime.getURL");
}
sendMessage(extensionId, message, options, responseCallback) {
bridgeLog.DoActionAndLog(() => {
if (typeof responseCallback !== "undefined" && typeof responseCallback !== "null") {
myBrowser.runtime.sendMessage(extensionId, message, options, responseCallback);
}
else if (typeof options !== "undefined" && typeof options !== "null") {
myBrowser.runtime.sendMessage(extensionId, message, options);
}
else if (typeof message !== "undefined" && typeof message !== "null") {
myBrowser.runtime.sendMessage(extensionId, message);
}
else {
myBrowser.runtime.sendMessage(undefined, extensionId);
}
}, "runtime.sendMessage");
}
}
class EdgeChromeRuntimeBridge extends EdgeRuntimeBridge {
get onConnectExternal() { bridgeLog.LogUnavailbleApi("runtime.onConnectExternal"); return bridgeHelper.fakeEvent; }
get onRestartRequired() { bridgeLog.LogUnavailbleApi("runtime.onRestartRequired"); return bridgeHelper.fakeEvent; }
get onStartup() { bridgeLog.LogUnavailbleApi("runtime.onStartup"); return bridgeHelper.fakeEvent; }
get onSuspend() { bridgeLog.LogUnavailbleApi("runtime.onSuspend"); return bridgeHelper.fakeEvent; }
get onSuspendCanceled() { bridgeLog.LogUnavailbleApi("runtime.onSuspendCanceled"); return bridgeHelper.fakeEvent; }
get onUpdateAvailable() { bridgeLog.LogUnavailbleApi("runtime.onUpdateAvailable"); return bridgeHelper.fakeEvent; }
openOptionsPage(callback) {
bridgeLog.DoActionAndLog(() => {
var optionsPage = myBrowser.runtime.getManifest()["options_page"];
var optionsPageUrl = myBrowser.runtime.getURL(optionsPage);
if (typeof callback !== "undefined" && typeof callback !== "null") {
myBrowser.tabs.create({ url: optionsPageUrl }, callback);
}
else {
myBrowser.tabs.create({ url: optionsPageUrl });
}
}, "runtime.openOptionsPage", undefined, "tabs.create({ url: optionsPageUrl })");
}
connectNative(application) {
bridgeLog.LogUnavailbleApi("runtime.connectNative");
return null;
}
getPackageDirectoryEntry(callback) {
bridgeLog.LogUnavailbleApi("runtime.getPackageDirectoryEntry");
}
getPlatformInfo(callback) {
bridgeLog.LogUnavailbleApi("runtime.getPlatformInfo");
}
reload() {
bridgeLog.LogUnavailbleApi("runtime.reload");
}
requestUpdateCheck(callback) {
bridgeLog.LogUnavailbleApi("runtime.requestUpdateCheck");
}
restart() {
bridgeLog.LogUnavailbleApi("runtime.restart");
}
setUninstallURL(url, callback) {
bridgeLog.LogUnavailbleApi("runtime.setUninstallURL");
}
sendNativeMessage(application, message, responseCallback) {
bridgeLog.LogUnavailbleApi("runtime.sendNativeMessage");
}
}
class EdgeStorageBridge {
get local() { return bridgeLog.DoActionAndLog(() => { return myBrowser.storage.local; }, "storage.local"); }
get onChanged() { return bridgeLog.DoActionAndLog(() => { return myBrowser.storage.onChanged; }, "storage.onChanged"); }
}
class EdgeChromeStorageBridge extends EdgeStorageBridge {
get managed() { return bridgeLog.DoActionAndLog(() => { return myBrowser.storage.local; }, "storage.managed", undefined, "storage.local"); }
get sync() { return bridgeLog.DoActionAndLog(() => { return myBrowser.storage.local; }, "storage.sync", undefined, "storage.local"); }
}
class EdgeTabsBridge {
get onActivated() { return bridgeLog.DoActionAndLog(() => { return myBrowser.tabs.onActivated; }, "tabs.onActivated"); }
get onCreated() { return bridgeLog.DoActionAndLog(() => { return myBrowser.tabs.onCreated; }, "tabs.onCreated"); }
get onRemoved() { return bridgeLog.DoActionAndLog(() => { return myBrowser.tabs.onRemoved; }, "tabs.onRemoved"); }
get onReplaced() { return bridgeLog.DoActionAndLog(() => { return myBrowser.tabs.onReplaced; }, "tabs.onReplaced"); }
get onUpdated() { return bridgeLog.DoActionAndLog(() => { return myBrowser.tabs.onUpdated; }, "tabs.onUpdated"); }
create(createProperties, callback) {
bridgeLog.DoActionAndLog(() => {
if (typeof callback !== "undefined" && typeof callback !== "null") {
myBrowser.tabs.create(createProperties, callback);
}
else {
myBrowser.tabs.create(createProperties);
}
}, "tabs.create");
}
detectLanguage(tabId, callback) {
bridgeLog.DoActionAndLog(() => {
myBrowser.tabs.detectLanguage(tabId, callback);
}, "tabs.detectLanguage");
}
executeScript(tabId, details, callback) {
bridgeLog.DoActionAndLog(() => {
if (typeof callback !== "undefined" && typeof callback !== "null") {
myBrowser.tabs.executeScript(tabId, details, callback);
}
else {
myBrowser.tabs.executeScript(tabId, details);
}
}, "tabs.executeScript");
}
get(tabId, callback) {
bridgeLog.DoActionAndLog(() => {
myBrowser.tabs.get(tabId, callback);
}, "tabs.get");
}
getCurrent(callback) {
bridgeLog.DoActionAndLog(() => {
myBrowser.tabs.getCurrent(callback);
}, "tabs.getCurrent");
}
insertCSS(tabId, details, callback) {
bridgeLog.DoActionAndLog(() => {
if (typeof callback !== "undefined" && typeof callback !== "null") {
myBrowser.tabs.insertCSS(tabId, details, callback);
}
else {
myBrowser.tabs.insertCSS(tabId, details);
}
}, "tabs.insertCSS");
}
query(queryInfo, callback) {
bridgeLog.DoActionAndLog(() => {
myBrowser.tabs.query(queryInfo, callback);
}, "tabs.query");
}
remove(tabId, callback) {
bridgeLog.DoActionAndLog(() => {
if (typeof callback !== "undefined" && typeof callback !== "null") {
myBrowser.tabs.remove(tabId, callback);
}
else {
myBrowser.tabs.remove(tabId);
}
}, "tabs.remove");
}
sendMessage(tabId, message, responseCallback) {
bridgeLog.DoActionAndLog(() => {
if (typeof responseCallback !== "undefined" && typeof responseCallback !== "null") {
myBrowser.tabs.sendMessage(tabId, message, responseCallback);
}
else {
myBrowser.tabs.sendMessage(tabId, message);
}
}, "tabs.sendMessage");
}
update(tabId, updateProperties, callback) {
bridgeLog.DoActionAndLog(() => {
if (typeof callback !== "undefined" && typeof callback !== "null") {
myBrowser.tabs.update(tabId, updateProperties, callback);
}
else {
myBrowser.tabs.update(tabId, updateProperties);
}
}, "tabs.update");
}
}
class EdgeChromeTabsBridge extends EdgeTabsBridge {
get onAttached() { bridgeLog.LogUnavailbleApi("tabs.onAttached"); return bridgeHelper.fakeEvent; }
get onDetached() { bridgeLog.LogUnavailbleApi("tabs.onDetached"); return bridgeHelper.fakeEvent; }
get onHighlighted() { bridgeLog.LogUnavailbleApi("tabs.onHighlighted"); return bridgeHelper.fakeEvent; }
get onMoved() { bridgeLog.LogUnavailbleApi("tabs.onMoved"); return bridgeHelper.fakeEvent; }
get onSelectionChanged() {
return bridgeLog.DoActionAndLog(() => {
var fakeEvent = bridgeHelper.fakeEvent;
fakeEvent.addListener = (callback) => {
myBrowser.tabs.onActivated.addListener((activeInfo) => {
callback(activeInfo.tabId, { windowId: activeInfo.windowId });
});
};
return fakeEvent;
}, "tabs.onSelectionChanged", "tabs.onActivated", "tabs.onActivated");
}
duplicate(tabId, callback) {
bridgeLog.DoActionAndLog(() => {
this.get(tabId, function (tab) {
if (typeof callback !== "undefined" && typeof callback !== "null") {
myBrowser.tabs.create({ url: tab.url }, callback);
}
else {
myBrowser.tabs.create({ url: tab.url });
}
});
}, "tabs.duplicate", undefined, "tabs.create");
}
getAllInWindow(windowId, callback) {
bridgeLog.DoActionAndLog(() => {
this.query({ windowId: windowId }, callback);
}, "tabs.getAllInWindow", "tabs.query", "tabs.query");
}
getSelected(windowId, callback) {
bridgeLog.DoActionAndLog(() => {
this.query({ active: true }, (tabs) => callback(tabs[0]));
}, "tabs.getSelected", "tabs.query", "tabs.query");
}
sendRequest(tabId, request, responseCallback) {
bridgeLog.DoActionAndLog(() => {
this.sendMessage(tabId, request, responseCallback);
}, "tabs.sendRequest", "tabs.sendMessage", "tabs.sendMessage");
}
captureVisibleTab(windowId, options, callback) {
bridgeLog.LogUnavailbleApi("tabs.captureVisibleTab");
}
connect(tabId, connectInfo) {
bridgeLog.LogUnavailbleApi("tabs.connect");
return null;
}
highlight(highlightInfo, callback) {
bridgeLog.LogUnavailbleApi("tabs.highlight");
}
move(tabId, moveProperties, callback) {
bridgeLog.LogUnavailbleApi("tabs.move");
}
reload(tabId, reloadProperties, callback) {
bridgeLog.LogUnavailbleApi("tabs.reload");
}
}
class EdgeWebNavigationBridge {
get onBeforeNavigate() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webNavigation.onBeforeNavigate; }, "webNavigation.onBeforeNavigate"); }
get onCommitted() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webNavigation.onCommitted; }, "webNavigation.onCommitted"); }
get onCompleted() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webNavigation.onCompleted; }, "webNavigation.onCompleted"); }
get onCreatedNavigationTarget() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webNavigation.onCreatedNavigationTarget; }, "webNavigation.onCreatedNavigationTarget"); }
get onDOMContentLoaded() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webNavigation.onDOMContentLoaded; }, "webNavigation.onDOMContentLoaded"); }
get onErrorOccurred() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webNavigation.onErrorOccurred; }, "webNavigation.onErrorOccurred"); }
get onHistoryStateUpdated() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webNavigation.onHistoryStateUpdated; }, "webNavigation.onHistoryStateUpdated"); }
get onReferenceFragmentUpdated() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webNavigation.onReferenceFragmentUpdated; }, "webNavigation.onReferenceFragmentUpdated"); }
get onTabReplaced() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webNavigation.onTabReplaced; }, "webNavigation.onTabReplaced"); }
getAllFrames(details, callback) {
bridgeLog.DoActionAndLog(() => {
myBrowser.webNavigation.getAllFrames(details, callback);
}, "webNavigation.getAllFrames");
}
getFrame(details, callback) {
bridgeLog.DoActionAndLog(() => {
myBrowser.webNavigation.getFrame(details, callback);
}, "webNavigation.getFrame");
}
}
class EdgeWebRequestBridge {
get MAX_HANDLER_BEHAVIOR_CHANGED_CALLS_PER_10_MINUTES() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webRequest.MAX_HANDLER_BEHAVIOR_CHANGED_CALLS_PER_10_MINUTES; }, "webNavigation.MAX_HANDLER_BEHAVIOR_CHANGED_CALLS_PER_10_MINUTES"); }
get onAuthRequired() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webRequest.onAuthRequired; }, "webNavigation.onAuthRequired"); }
get onBeforeRedirect() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webRequest.onBeforeRedirect; }, "webNavigation.onBeforeRedirect"); }
get onBeforeRequest() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webRequest.onBeforeRequest; }, "webNavigation.onBeforeRequest"); }
get onBeforeSendHeaders() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webRequest.onBeforeSendHeaders; }, "webNavigation.onBeforeSendHeaders"); }
get onCompleted() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webRequest.onCompleted; }, "webNavigation.onCompleted"); }
get onErrorOccurred() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webRequest.onErrorOccurred; }, "webNavigation.onErrorOccurred"); }
get onHeadersReceived() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webRequest.onHeadersReceived; }, "webNavigation.onHeadersReceived"); }
get onResponseStarted() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webRequest.onResponseStarted; }, "webNavigation.onResponseStarted"); }
get onSendHeaders() { return bridgeLog.DoActionAndLog(() => { return myBrowser.webRequest.onSendHeaders; }, "webNavigation.onSendHeaders"); }
handlerBehaviorChanged(callback) {
bridgeLog.DoActionAndLog(() => {
if (typeof callback !== "undefined" && typeof callback !== "null") {
myBrowser.webRequest.handlerBehaviorChanged(callback);
}
else {
myBrowser.webRequest.handlerBehaviorChanged();
}
}, "webRequest.handlerBehaviorChanged");
}
}
class EdgeWindowsBridge {
get WINDOW_ID_CURRENT() { return bridgeLog.DoActionAndLog(() => { return myBrowser.windows.WINDOW_ID_CURRENT; }, "windows.WINDOW_ID_CURRENT"); }
get WINDOW_ID_NONE() { return bridgeLog.DoActionAndLog(() => { return myBrowser.windows.WINDOW_ID_NONE; }, "windows.WINDOW_ID_NONE"); }
get onCreated() { return bridgeLog.DoActionAndLog(() => { return myBrowser.windows.onCreated; }, "windows.onCreated"); }
get onFocusChanged() { return bridgeLog.DoActionAndLog(() => { return myBrowser.windows.onFocusChanged; }, "windows.onFocusChanged"); }
get onRemoved() { return bridgeLog.DoActionAndLog(() => { return myBrowser.windows.onRemoved; }, "windows.onRemoved"); }
create(createData, callback) {
bridgeLog.DoActionAndLog(() => {
if (typeof callback !== "undefined" && typeof callback !== "null") {
myBrowser.windows.create(createData, callback);
}
else {
myBrowser.windows.create(createData);
}
}, "windows.create");
}
get(windowId, getInfo, callback) {
bridgeLog.DoActionAndLog(() => {
myBrowser.windows.get(windowId, getInfo, callback);
}, "windows.get");
}
getAll(getInfo, callback) {
bridgeLog.DoActionAndLog(() => {
myBrowser.windows.getAll(getInfo, callback);
}, "windows.getAll");
}
getCurrent(getInfo, callback) {
bridgeLog.DoActionAndLog(() => {
myBrowser.windows.getCurrent(getInfo, callback);
}, "windows.getCurrent");
}
getLastFocused(getInfo, callback) {
bridgeLog.DoActionAndLog(() => {
myBrowser.windows.getLastFocused(getInfo, callback);
}, "windows.getLastFocused");
}
update(windowId, updateInfo, callback) {
bridgeLog.DoActionAndLog(() => {
if (typeof callback !== "undefined" && typeof callback !== "null") {
myBrowser.windows.update(windowId, updateInfo, callback);
}
else {
myBrowser.windows.update(windowId, updateInfo);
}
}, "windows.update");
}
}
class EdgeChromeWindowsBridge extends EdgeWindowsBridge {
remove(windowId, callback) {
bridgeLog.LogUnavailbleApi("windows.remove");
}
}
class EdgeBackgroundBridge {
constructor() {
this.app = new EdgeChromeAppBridge();
this.browserAction = typeof browser.browserAction !== "undefined" ? new EdgeChromeBrowserActionBridge() : undefined;
this.contextMenus = typeof browser.contextMenus !== "undefined" ? new EdgeContextMenusBridge() : undefined;
this.cookies = typeof browser.cookies !== "undefined" ? new EdgeChromeCookiesBridge() : undefined;
this.extension = typeof browser.extension !== "undefined" ? new EdgeChromeExtensionBridge() : undefined;
this.history = typeof browser.history !== "undefined" ? new EdgeHistoryBridge() : undefined;
this.i18n = typeof browser.i18n !== "undefined" ? new EdgeI18nBridge() : undefined;
this.notifications = typeof browser.notifications !== "undefined" ? new EdgeNotificationBridge() : undefined;
this.pageAction = typeof browser.pageAction !== "undefined" ? new EdgePageActionBridge() : undefined;
this.permissions = typeof browser.permissions !== "undefined" ? new EdgePermissionsBridge() : undefined;
this.runtime = typeof browser.runtime !== "undefined" ? new EdgeChromeRuntimeBridge() : undefined;
this.storage = typeof browser.storage !== "undefined" ? new EdgeChromeStorageBridge() : undefined;
this.tabs = typeof browser.tabs !== "undefined" ? new EdgeChromeTabsBridge() : undefined;
this.webNavigation = typeof browser.webNavigation !== "undefined" ? new EdgeWebNavigationBridge() : undefined;
this.webRequest = typeof browser.webRequest !== "undefined" ? new EdgeWebRequestBridge() : undefined;
this.windows = typeof browser.windows !== "undefined" ? new EdgeChromeWindowsBridge() : undefined;
}
}
var myBrowser = browser;
var chrome = new EdgeBackgroundBridge();

@ -1,323 +0,0 @@
if (!Range.prototype["intersectsNode"]) {
Range.prototype["intersectsNode"] = function (node) {
let range = document.createRange();
range.selectNode(node);
return 0 > this.compareBoundaryPoints(Range.END_TO_START, range)
&& 0 < this.compareBoundaryPoints(Range.START_TO_END, range);
};
}
var getExtensionProtocol = function () {
if (typeof browser == "undefined") {
if (typeof chrome !== "undefined")
return "chrome-extension://";
}
else {
return "ms-browser-extension://";
}
};
class FakeEvent {
addListener(callback) { }
addRules(rules, callback) { }
getRules(ruleIdentifiers, callback) { }
hasListener(callback) { return false; }
hasListeners() { return false; }
removeRules(ruleIdentifiers, callback) { }
removeListener(callback) { }
}
class EdgeBridgeHelper {
constructor() {
this.fakeEvent = new FakeEvent();
}
toAbsolutePath(relativePath) {
if (relativePath.indexOf("ms-browser-extension://") == 0) {
return relativePath.replace(myBrowser.runtime.getURL(""), "");
}
else if (relativePath.indexOf("/") != 0) {
var absolutePath = "";
var documentPath = document.location.pathname;
absolutePath = documentPath.substring(0, documentPath.lastIndexOf("/") + 1);
absolutePath += relativePath;
return absolutePath;
}
return relativePath;
}
}
var bridgeHelper = new EdgeBridgeHelper();
class EdgeBridgeDebugLog {
constructor() {
this.CatchOnException = true;
this.VerboseLogging = true;
this.FailedCalls = {};
this.SuccededCalls = {};
this.DeprecatedCalls = {};
this.BridgedCalls = {};
this.UnavailableApis = {};
this.EdgeIssues = {};
}
log(message) {
try {
if (this.VerboseLogging) {
console.log(message);
}
}
catch (e) {
}
}
info(message) {
try {
if (this.VerboseLogging) {
console.info(message);
}
}
catch (e) {
}
}
warn(message) {
try {
if (this.VerboseLogging) {
console.warn(message);
}
}
catch (e) {
}
}
error(message) {
try {
if (this.VerboseLogging) {
console.error(message);
}
}
catch (e) {
}
}
DoActionAndLog(action, name, deprecatedTo, bridgedTo) {
var result;
try {
result = action();
this.AddToCalledDictionary(this.SuccededCalls, name);
if (typeof deprecatedTo !== "undefined" && typeof deprecatedTo !== "null") {
this.warn("API Call Deprecated - Name: " + name + ", Please use " + deprecatedTo + " instead!");
this.AddToCalledDictionary(this.DeprecatedCalls, name);
}
if (typeof bridgedTo !== "undefined" && typeof bridgedTo !== "null") {
this.info("API Call '" + name + "' has been bridged to another Edge API: " + bridgedTo);
this.AddToCalledDictionary(this.BridgedCalls, name);
}
return result;
}
catch (ex) {
this.AddToCalledDictionary(this.FailedCalls, name);
if (this.CatchOnException)
this.error("API Call Failed: " + name + " - " + ex);
else
throw ex;
}
}
LogEdgeIssue(name, message) {
this.warn(message);
this.AddToCalledDictionary(this.EdgeIssues, name);
}
LogUnavailbleApi(name, deprecatedTo) {
this.warn("API Call '" + name + "' is not supported in Edge");
this.AddToCalledDictionary(this.UnavailableApis, name);
if (typeof deprecatedTo !== "undefined" && typeof deprecatedTo !== "null") {
this.warn("API Call Deprecated - Name: " + name + ", Please use " + deprecatedTo + " instead!");
this.AddToCalledDictionary(this.DeprecatedCalls, name);
}
}
AddToCalledDictionary(dictionary, name) {
if (typeof dictionary[name] !== "undefined") {
dictionary[name]++;
}
else {
dictionary[name] = 1;
}
}
}
var bridgeLog = new EdgeBridgeDebugLog();
class EdgeExtensionBridge {
getBackgroundPage() {
return bridgeLog.DoActionAndLog(() => {
return myBrowser.extension.getBackgroundPage();
}, "extension.getBackgroundPage");
}
getURL(path) {
return bridgeLog.DoActionAndLog(() => {
return myBrowser.extension.getURL(path);
}, "extension.getURL");
}
getViews(fetchProperties) {
return bridgeLog.DoActionAndLog(() => {
return myBrowser.extension.getViews(fetchProperties);
}, "extension.getViews");
}
}
class EdgeChromeExtensionBridge extends EdgeExtensionBridge {
get onConnect() { return bridgeLog.DoActionAndLog(() => { return EdgeRuntimeBridge.prototype.onConnect; }, "extension.onConnect", "runtime.onConnect", "runtime.onConnect"); }
get onMessage() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.onMessage; }, "extension.onMessage", "runtime.onMessage", "runtime.onMessage"); }
get onRequest() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.onMessage; }, "extension.onRequest", "runtime.onMessage", "runtime.onMessage"); }
get onRequestExternal() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.onMessageExternal; }, "extension.onRequestExternal", "runtime.onMessageExternal", "runtime.onMessageExternal"); }
get inIncognitoContext() { return bridgeLog.DoActionAndLog(() => { return myBrowser.extension["inPrivateContext"]; }, "extension.inIncognitoContext", undefined, "extension.inPrivateContext"); }
get lastError() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.lastError; }, "extension.lastError", undefined, "runtime.lastError"); }
connect(extensionId, connectInfo) {
return bridgeLog.DoActionAndLog(() => {
return EdgeRuntimeBridge.prototype.connect(extensionId, connectInfo);
}, "extension.connect", "runtime.connect", "runtime.connect");
}
sendMessage(message, responseCallback) {
return bridgeLog.DoActionAndLog(() => {
return EdgeRuntimeBridge.prototype.sendMessage(message, responseCallback, undefined, undefined);
}, "extension.sendMessage", "runtime.sendMessage", "runtime.sendMessage");
}
sendRequest(extensionId, message, options, responseCallback) {
return bridgeLog.DoActionAndLog(() => {
return EdgeRuntimeBridge.prototype.sendMessage(extensionId, message, options, responseCallback);
}, "extension.sendRequest", "runtime.sendMessage", "runtime.sendMessage");
}
isAllowedFileSchemeAccess(callback) {
bridgeLog.LogUnavailbleApi("extension.isAllowedFileSchemeAccess");
}
isAllowedIncognitoAccess(callback) {
bridgeLog.LogUnavailbleApi("extension.isAllowedIncognitoAccess");
}
setUpdateUrlData(data) {
bridgeLog.LogUnavailbleApi("extension.setUpdateUrlData");
}
}
class EdgeI18nBridge {
getAcceptLanguages(callback) {
return bridgeLog.DoActionAndLog(() => {
return myBrowser.i18n.getAcceptLanguages(callback);
}, "i18n.getAcceptLanguages");
}
getMessage(messageName, substitutions) {
return bridgeLog.DoActionAndLog(() => {
if (messageName.indexOf("@@extension_id") > -1) {
return myBrowser.runtime.id;
}
if (typeof substitutions !== "undefined" && typeof substitutions !== "null") {
return myBrowser.i18n.getMessage(messageName, substitutions);
}
else {
return myBrowser.i18n.getMessage(messageName);
}
}, "i18n.getMessage");
}
getUILanguage() {
return bridgeLog.DoActionAndLog(() => {
return myBrowser.i18n.getUILanguage();
}, "i18n.getUILanguage");
}
}
class EdgeRuntimeBridge {
get id() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.id; }, "runtime.id"); }
get lastError() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.lastError; }, "runtime.lastError"); }
get onConnect() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.onConnect; }, "runtime.onConnect"); }
get onInstalled() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.onInstalled; }, "runtime.onInstalled"); }
get onMessage() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.onMessage; }, "runtime.onMessage"); }
get onMessageExternal() { return bridgeLog.DoActionAndLog(() => { return myBrowser.runtime.onMessageExternal; }, "runtime.onMessageExternal"); }
connect(extensionId, connectInfo) {
return bridgeLog.DoActionAndLog(() => {
if (typeof connectInfo !== "undefined" && typeof connectInfo !== "null") {
return myBrowser.runtime.connect(extensionId, connectInfo);
}
else {
return myBrowser.runtime.connect(extensionId);
}
}, "runtime.connect");
}
getBackgroundPage(callback) {
bridgeLog.DoActionAndLog(() => {
myBrowser.runtime.getBackgroundPage(callback);
}, "runtime.getBackgroundPage");
}
getManifest() {
return bridgeLog.DoActionAndLog(() => {
return myBrowser.runtime.getManifest();
}, "runtime.getManifest");
}
getURL(path) {
return bridgeLog.DoActionAndLog(() => {
return myBrowser.runtime.getURL(path);
}, "runtime.getURL");
}
sendMessage(extensionId, message, options, responseCallback) {
bridgeLog.DoActionAndLog(() => {
if (typeof responseCallback !== "undefined" && typeof responseCallback !== "null") {
myBrowser.runtime.sendMessage(extensionId, message, options, responseCallback);
}
else if (typeof options !== "undefined" && typeof options !== "null") {
myBrowser.runtime.sendMessage(extensionId, message, options);
}
else if (typeof message !== "undefined" && typeof message !== "null") {
myBrowser.runtime.sendMessage(extensionId, message);
}
else {
myBrowser.runtime.sendMessage(undefined, extensionId);
}
}, "runtime.sendMessage");
}
}
class EdgeChromeRuntimeBridge extends EdgeRuntimeBridge {
get onConnectExternal() { bridgeLog.LogUnavailbleApi("runtime.onConnectExternal"); return bridgeHelper.fakeEvent; }
get onRestartRequired() { bridgeLog.LogUnavailbleApi("runtime.onRestartRequired"); return bridgeHelper.fakeEvent; }
get onStartup() { bridgeLog.LogUnavailbleApi("runtime.onStartup"); return bridgeHelper.fakeEvent; }
get onSuspend() { bridgeLog.LogUnavailbleApi("runtime.onSuspend"); return bridgeHelper.fakeEvent; }
get onSuspendCanceled() { bridgeLog.LogUnavailbleApi("runtime.onSuspendCanceled"); return bridgeHelper.fakeEvent; }
get onUpdateAvailable() { bridgeLog.LogUnavailbleApi("runtime.onUpdateAvailable"); return bridgeHelper.fakeEvent; }
openOptionsPage(callback) {
bridgeLog.DoActionAndLog(() => {
var optionsPage = myBrowser.runtime.getManifest()["options_page"];
var optionsPageUrl = myBrowser.runtime.getURL(optionsPage);
if (typeof callback !== "undefined" && typeof callback !== "null") {
myBrowser.tabs.create({ url: optionsPageUrl }, callback);
}
else {
myBrowser.tabs.create({ url: optionsPageUrl });
}
}, "runtime.openOptionsPage", undefined, "tabs.create({ url: optionsPageUrl })");
}
connectNative(application) {
bridgeLog.LogUnavailbleApi("runtime.connectNative");
return null;
}
getPackageDirectoryEntry(callback) {
bridgeLog.LogUnavailbleApi("runtime.getPackageDirectoryEntry");
}
getPlatformInfo(callback) {
bridgeLog.LogUnavailbleApi("runtime.getPlatformInfo");
}
reload() {
bridgeLog.LogUnavailbleApi("runtime.reload");
}
requestUpdateCheck(callback) {
bridgeLog.LogUnavailbleApi("runtime.requestUpdateCheck");
}
restart() {
bridgeLog.LogUnavailbleApi("runtime.restart");
}
setUninstallURL(url, callback) {
bridgeLog.LogUnavailbleApi("runtime.setUninstallURL");
}
sendNativeMessage(application, message, responseCallback) {
bridgeLog.LogUnavailbleApi("runtime.sendNativeMessage");
}
}
class EdgeStorageBridge {
get local() { return bridgeLog.DoActionAndLog(() => { return myBrowser.storage.local; }, "storage.local"); }
get onChanged() { return bridgeLog.DoActionAndLog(() => { return myBrowser.storage.onChanged; }, "storage.onChanged"); }
}
class EdgeChromeStorageBridge extends EdgeStorageBridge {
get managed() { return bridgeLog.DoActionAndLog(() => { return myBrowser.storage.local; }, "storage.managed", undefined, "storage.local"); }
get sync() { return bridgeLog.DoActionAndLog(() => { return myBrowser.storage.local; }, "storage.sync", undefined, "storage.local"); }
}
class EdgeContentBridge {
constructor() {
this.extension = typeof browser.extension !== "undefined" ? new EdgeChromeExtensionBridge() : undefined;
this.i18n = typeof browser.i18n !== "undefined" ? new EdgeI18nBridge() : undefined;
this.runtime = typeof browser.runtime !== "undefined" ? new EdgeChromeRuntimeBridge() : undefined;
this.storage = typeof browser.storage !== "undefined" ? new EdgeChromeStorageBridge() : undefined;
}
}
var myBrowser = browser;
var chrome = new EdgeContentBridge();

@ -1,806 +0,0 @@
'use strict';
(function() {
function isChrome() {
return (typeof chrome !== 'undefined' &&
window.navigator.userAgent.match(/Chrom(?:e|ium)\/([0-9\.]+)/));
}
var browserProxy;
if ( isChrome() ) {
browserProxy = chrome;
} else {
browserProxy = browser;
}
var MIN_FF_MAJOR_VERSION = 51;
var requiredBrowserApis = [
browserProxy.webNavigation,
browserProxy.tabs,
browserProxy.webRequest,
browserProxy.runtime
];
var areListenersRegistered = false;
var secBefore = 2000;
var secAfter = 5000;
var secBetweenDupAssets = 10e3;
var minVidSize = 500e3;
var maxVidSize = 25e6;
var maxContentRange = 25e6;
var videoExtensions = [
'af', '3gp', 'asf', 'avchd', 'avi', 'cam', 'dsh', 'flv', 'm1v', 'm2v',
'fla', 'flr', 'sol', 'm4v', 'mkv', 'wrap', 'mng', 'mov', 'mpeg', 'mpg',
'mpe', 'mp4', 'mxf', 'nsv', 'ogg', 'rm', 'svi', 'smi', 'wmv', 'webm'
];
var extensionsReg = new RegExp('\\.' + videoExtensions.join('$|\\.') + '$');
var videoContentTypesPrefixes = ['binary/octet-stream', 'video/', 'flv-application/', 'media'];
var bannedContentTypes = ['video/mp2t','video/f4m','video/f4f'];
var bannedFiletypes = ['ts'];
var bannedFiletypesReg = new RegExp('\\.' + bannedFiletypes.join('$|\\.') + '$');
var whitelistReqTypes = ['object', 'xmlhttprequest', 'other'];
var topVideoAssetDomains = [
'2mdn.net',
'adap.tv',
'adnxs.com',
'adsrvr.org',
'btrll.com',
'celtra.com',
'flashtalking.com',
'flite.com',
'innovid.com',
'jivox.com',
'mixpo.com',
'nytimes.com',
'playwire.com',
'selectmedia.asia',
'serving-sys.com',
'solvemedia.com',
'spotible.com',
'teads.tv',
'tribalfusion.com',
'tubemogul.com',
'videologygroup.com',
'washingtonpost.com'
];
if ( !String.prototype.endsWith ) {
String.prototype.endsWith = function(searchString, position) {
var subjectString = this.toString();
if ( typeof position !== 'number' || !isFinite(position) ||
Math.floor(position) !== position || position > subjectString.length) {
position = subjectString.length;
}
position -= searchString.length;
var lastIndex = subjectString.indexOf(searchString, position);
return lastIndex !== -1 && lastIndex === position;
};
}
function getFrame(getFrameDetails, callback) {
if ( typeof chrome !== 'undefined' ) {
chrome.webNavigation.getFrame(getFrameDetails, callback);
} else if ( typeof browser !== 'undefined' ) {
var gettingFrame = browser.webNavigation.getFrame(getFrameDetails);
gettingFrame.then(callback);
}
}
function ifBrowserValid(callback, elseCallback) {
if ( isChrome() ) {
callback();
} else if ( typeof browser !== 'undefined' ) {
try {
var gettingInfo = browser.runtime.getBrowserInfo();
gettingInfo.then(function(browserInfo) {
var browserVersion = parseInt(browserInfo.version.split('.')[0]);
if ( browserInfo.name === 'Firefox' &&
browserVersion >= MIN_FF_MAJOR_VERSION) {
callback();
} else {
elseCallback();
}
});
} catch (err) {
elseCallback();
}
} else {
elseCallback();
}
}
function ifTrackingEnabled(ifCallback, elseCallback) {
browser.storage.local.get('tracking').then(function(item) {
if ( item.hasOwnProperty('tracking') ) {
if ( item.tracking ) {
ifCallback();
} else {
elseCallback();
}
} else {
ifCallback();
}
});
}
function isPixelRequest(request) {
return (request.type === 'image' || request.responseStatus === 204) &&
request.size <= 1000;
}
function isVpaidOrVastRequest(request) {
var lowerCaseUrl = request.url.toLowerCase();
return lowerCaseUrl.indexOf('vpaid') !== -1 || lowerCaseUrl.indexOf('vast') !== -1;
}
function hasValidRequestType(request) {
return whitelistReqTypes.indexOf(request.type) >= 0;
}
function stripQueryParams(url) {
return url.split('?', 1)[0];
}
function parseHostnameFromUrl(url) {
var parser = document.createElement('a');
parser.href = url;
return parser.hostname;
}
function hasDomain(url, domain) {
return parseHostnameFromUrl(url).endsWith(domain);
}
function findHeader(headers, key) {
var header;
for ( var i = 0; i < headers.length; i += 1 ) {
header = headers[i];
if ( header.name.toLowerCase() === key ) {
return header;
}
}
return null;
}
function validVideoType(vtype) {
var goodType = videoContentTypesPrefixes.some(function(prefix) {
return vtype.indexOf(prefix) === 0;
});
return goodType;
}
function assetMsgKey(assetReq) {
var url = stripQueryParams(assetReq.url);
var key = assetReq.frameId + '-' + url;
return key;
}
var PageNetworkTrafficCollector = function(tabId) {
this.tabId = tabId;
this.displayAdFound = false;
this.requests = {};
this.msgsBeingSent = {};
this.assetsSeen = {};
this.allRedirects = {};
};
var globalPageContainer = {
collectors: {},
dyingCollectors: {},
cleanupCollector: function(tabId) {
if ( tabId in this.collectors ) {
delete globalPageContainer.collectors[tabId];
}
},
onNewNavigation: function(details) {
var tabId = details.tabId;
this.cleanupCollector(tabId);
ifTrackingEnabled(
function() {
if ( !areListenersRegistered ) {
registerListeners();
}
this.collectors[tabId] = new PageNetworkTrafficCollector(tabId);
}.bind(this),
function() {
if ( areListenersRegistered ) {
unregisterListeners();
}
}
);
},
onNavigationCommitted: function(details) {
},
onNavigationCompleted: function(details) {
},
onTabClose: function(tabId, closeInfo) {
this.cleanupCollector(tabId);
delete this.collectors[tabId];
},
onDisplayAdFound: function(tabId) {
this.collectors[tabId].displayAdFound = true;
},
getRandId: function() {
return String(Math.floor(Math.random() * 1e9));
},
getCollector: function(tabId) {
if ( this.collectors.hasOwnProperty(tabId) ) {
return this.collectors[tabId];
}
return null;
},
forwardCall: function(details, collectorMemberFunction) {
var collector = this.getCollector(details.tabId);
if ( collector !== null ) {
collectorMemberFunction.apply(collector, [details]);
}
}
};
PageNetworkTrafficCollector.prototype.sendLogMessageToTabConsole = function() {
var logMessage = Array.from(arguments).join(' ');
var message = {message: logMessage, event: 'console-log-message'};
browserProxy.tabs.sendMessage(this.tabId, message);
};
PageNetworkTrafficCollector.prototype.sendToTab = function(assetReq, reqs, curPageUrl, isValidAd) {
var msg = {};
msg.assets = [];
msg.event_data = {};
if ( isValidAd ) {
msg.event = 'new-video-ad';
msg.requests = reqs;
msg.requests.sort(function(reqA, reqB) {return reqA.requestTimestamp - reqB.requestTimestamp;});
if ( assetReq ) {
msg.assets = [assetReq];
}
} else {
msg.requests = reqs.map(function(request) {
return parseHostnameFromUrl(request.url);
});
msg.assets = [{
url: parseHostnameFromUrl(assetReq.url),
contentType: assetReq.contentType,
size: assetReq.size
}];
msg.event = 'new-invalid-video-ad';
}
msg.origUrl = curPageUrl;
msg.displayAdFound = this.displayAdFound;
browserProxy.tabs.sendMessage(this.tabId, msg);
};
PageNetworkTrafficCollector.prototype.getRedirKey = function(url, frameId) {
return url + ':' + frameId;
};
PageNetworkTrafficCollector.prototype.seenBefore = function(request) {
var oldTime = this.assetsSeen[assetMsgKey(request)];
if ( oldTime && (request.requestTimestamp-oldTime < secBetweenDupAssets)){
return true;
}
return false;
};
PageNetworkTrafficCollector.prototype.recordSeenAsset = function(request) {
this.assetsSeen[assetMsgKey(request)] = request.requestTimestamp;
};
PageNetworkTrafficCollector.prototype.onBeforeRequest = function(details) {
var req = {
url: details.url,
type: details.type,
httpMethod: details.method,
frameId: details.frameId,
parentFrameId: details.parentFrameId,
requestTimestamp: details.timeStamp,
};
this.requests[details.requestId] = req;
};
PageNetworkTrafficCollector.prototype.onSendHeaders = function(details) {
var request, header;
request = this.requests[details.requestId];
header = request && findHeader(details.requestHeaders, 'x-requested-with');
if ( header && header.value.toLowerCase().indexOf('flash') > -1 ) {
request.from_flash = true;
}
};
PageNetworkTrafficCollector.prototype.onHeadersReceived = function(details) {
var getFrameDetails = {
tabId: details.tabId,
processId: null,
frameId: details.frameId
};
var pageNetworkTrafficController = this;
getFrame(getFrameDetails, function(frameDetails) {
if ( frameDetails && frameDetails.url ) {
pageNetworkTrafficController._onHeadersReceived(details, frameDetails);
}
});
};
PageNetworkTrafficCollector.prototype._onHeadersReceived = function(details, frameDetails) {
var contentSize, contentRange;
var request = this.requests[details.requestId];
if ( request ) {
var redirParent = this.allRedirects[this.getRedirKey(details.url, details.frameId)];
var header = request && findHeader(details.responseHeaders, 'content-type');
var contentType = header && header.value.toLowerCase();
if ( contentType){
request.contentType = contentType;
}
header = request && findHeader(details.responseHeaders, 'content-length');
contentSize = header && header.value;
if ( contentSize ) {
request.size = request.size || 0;
request.size += parseInt(contentSize);
}
header = request && findHeader(details.responseHeaders, 'content-range');
contentRange = header && header.value;
if ( contentRange ) {
request.contentRange = parseInt(contentRange.split('/')[1]);
}
var frameUrl = null;
if ( frameDetails && frameDetails.url ) {
frameUrl = frameDetails.url;
}
if ( !this.bannedRequest(request) &&
(this.isVideoReq(frameUrl, request) || (redirParent && redirParent.isVideo))) {
request.isVideo = true;
}
}
};
PageNetworkTrafficCollector.prototype.onBeforeRedirect = function(details) {
var request = this.requests[details.requestId];
if ( request ) {
if ( request.redirects ) {
request.redirects.push(details.redirectUrl);
} else {
request.redirects = [details.redirectUrl];
}
this.allRedirects[this.getRedirKey(details.redirectUrl, details.frameId)] = request;
}
};
PageNetworkTrafficCollector.prototype.isYoutubeMastheadRequest = function(url) {
var re = /video_masthead/;
return this.hasYoutubeDomain(url) && re.test(url);
};
PageNetworkTrafficCollector.prototype.isYoutubeVideoRequest = function(srcUrl, destUrl) {
if ( !this.hasYoutubeDomain(srcUrl) ) {
return false;
}
var re = /https?:\/\/r.*?\.googlevideo\.com\/videoplayback\?/;
return re.test(destUrl);
};
PageNetworkTrafficCollector.prototype.processResponse = function(requestDetails, frameDetails) {
var request;
if ( requestDetails ) {
request = this.requests[requestDetails.requestId];
if ( request ) {
request.responseStatus = requestDetails.statusCode;
request.responseTimestamp = requestDetails.timeStamp;
var frameUrl = null;
if ( frameDetails && frameDetails.url ) {
frameUrl = frameDetails.url;
}
var requestUrl = null;
if ( request.url ) {
requestUrl = request.url;
}
if ( this.isYoutubeAdReq(frameUrl, requestUrl) ) {
var videoId = this.parseYoutubeVideoIdFromUrl(requestUrl);
if ( videoId ) {
request.isYoutubeAd = true;
request.isVideo = true;
request.url = 'https://www.youtube.com/watch?v=' + this.parseYoutubeVideoIdFromUrl(requestUrl);
}
} else if ( !this.bannedRequest(request) &&
(this.isVideo || this.isVideoReq(frameUrl, request))) {
request.isVideo = true;
}
if ( request.isVideo ) {
var msgKey = assetMsgKey(request);
this.msgsBeingSent[msgKey] = request;
if ( !this.seenBefore(request) ) {
this.sendMsgWhenQuiet(msgKey);
}
this.recordSeenAsset(request);
}
}
}
};
PageNetworkTrafficCollector.prototype.onResponseStarted = function(responseDetails) {
if ( responseDetails.frameId < 0 ) {
responseDetails.frameId = 99999;
}
var getFrameDetails = {
tabId: responseDetails.tabId,
processId: null,
frameId: responseDetails.frameId
};
var pageNetworkTrafficController = this;
getFrame(getFrameDetails, function(frameDetails) {
if ( frameDetails && frameDetails.url ) {
pageNetworkTrafficController.processResponse(responseDetails, frameDetails);
}
});
};
PageNetworkTrafficCollector.prototype.hasBannedFiletype = function(request) {
var url = stripQueryParams(request.url);
if ( bannedFiletypesReg.exec(url) ) {
return true;
} else {
return false;
}
};
PageNetworkTrafficCollector.prototype.checkContentHeaders = function(request) {
if ( request.contentType && validVideoType(request.contentType) ) {
return true;
}
return false;
};
PageNetworkTrafficCollector.prototype.checkUrlExtension = function(request) {
var url = stripQueryParams(request.url);
if ( extensionsReg.exec(url) ) {
return true;
} else {
return false;
}
};
PageNetworkTrafficCollector.prototype.isVideoReq = function(srcUrl, request) {
if ( this.isYoutubeVideoRequest(srcUrl, request.url) ) {
return false;
}
return this.checkUrlExtension(request) || this.checkContentHeaders(request);
};
PageNetworkTrafficCollector.prototype.hasYoutubeDomain = function(url) {
var hostname = parseHostnameFromUrl(url) ;
if ( hostname === 'www.youtube.com' ) {
return true;
}
return false;
};
PageNetworkTrafficCollector.prototype.parseYoutubeVideoIdFromUrl = function(url) {
var re = /^https?:\/\/www\.youtube\.com\/get_video_info.*(?:\?|&)video_id=(.*?)(?:$|&)/;
var match = re.exec(url);
if ( match && match.length > 1 ) {
return match[1];
}
re = /^https?:\/\/www\.youtube\.com\/embed\/(.*?)(?:$|\?)/;
match = re.exec(url);
if ( match && match.length > 1 ) {
return match[1];
}
re = /^https?:\/\/www\.youtube\.com\/watch\?v=(.*$)/;
match = re.exec(url);
if ( match && match.length > 1 ) {
return match[1];
}
return null;
};
PageNetworkTrafficCollector.prototype.isYoutubeGetVideoInfoReq = function(url) {
var re = /^https?:\/\/www\.youtube\.com\/get_video_info\?/;
return re.test(url);
};
PageNetworkTrafficCollector.prototype.isYoutubeAdReq = function(srcUrl, destUrl) {
if ( !this.hasYoutubeDomain(srcUrl) ||
!this.isYoutubeGetVideoInfoReq(destUrl)) {
return false;
}
if ( this.parseYoutubeVideoIdFromUrl(srcUrl) ===
this.parseYoutubeVideoIdFromUrl(destUrl) &&
!this.isYoutubeMastheadRequest(destUrl)) {
return false;
}
return true;
};
PageNetworkTrafficCollector.prototype.bannedRequest = function(request) {
return this.bannedVideoType(request) || this.hasBannedFiletype(request) || this.bannedVideoSize(request);
};
PageNetworkTrafficCollector.prototype.bannedVideoType = function(request) {
var badType = false;
if ( request.contentType ) {
badType = bannedContentTypes.some(function(prefix) {
return request.contentType.indexOf(prefix) >= 0;
});
}
return badType;
};
PageNetworkTrafficCollector.prototype.bannedVideoSize = function(request) {
if ( request.size !== null ) {
if ( request.size < minVidSize || request.size > maxVidSize || request.contentRange > maxContentRange ) {
return true;
}
}
return false;
};
PageNetworkTrafficCollector.prototype.grabTagReqs = function(tabRequests, assetRequest) {
var minTimestamp, maxTimestamp;
minTimestamp = assetRequest.requestTimestamp - secBefore;
maxTimestamp = assetRequest.requestTimestamp + secAfter;
var filteredRequests = tabRequests.filter(function(request) {
return (request.requestTimestamp > minTimestamp &&
request.requestTimestamp < maxTimestamp &&
request.frameId === assetRequest.frameId &&
request.url !== assetRequest.url &&
(hasValidRequestType(request) ||
isPixelRequest(request)));
});
return filteredRequests;
};
PageNetworkTrafficCollector.prototype.isValidVideoAd = function(assetRequest, tagRequests) {
var hasVpaidOrVastRequest = tagRequests.some(function(tagRequest) {
return isVpaidOrVastRequest(tagRequest);
});
if ( assetRequest.isYoutubeAd ) {
return true;
}
if ( hasVpaidOrVastRequest ) {
return true;
}
var hasTopVideoAssetDomain = topVideoAssetDomains.some(function(assetDomain) {
return hasDomain(assetRequest.url, assetDomain);
});
return hasTopVideoAssetDomain;
};
PageNetworkTrafficCollector.prototype.sendMsgWhenQuiet = function(msgKey) {
var _this = this,
origPageUrl, msgAssetReq;
msgAssetReq = this.msgsBeingSent[msgKey];
browserProxy.tabs.get(this.tabId, function(tab) {origPageUrl = tab.url;});
setTimeout(function() {
var rawRequests = [];
if ( globalPageContainer.collectors[_this.tabId] === _this ) {
for ( var reqId in _this.requests ) {
rawRequests.push(_this.requests[reqId]);
}
var tagReqs = _this.grabTagReqs(rawRequests, msgAssetReq);
if ( _this.isValidVideoAd(msgAssetReq, tagReqs) ) {
_this.sendToTab(msgAssetReq, tagReqs, origPageUrl, true);
} else {
_this.sendToTab(msgAssetReq, tagReqs, origPageUrl, false);
}
} else {
}
delete _this.msgsBeingSent[msgKey];
}, secAfter+secBefore);
};
PageNetworkTrafficCollector.prototype.existingMessage = function(candidateRequest) {
var frameMsg = this.msgsBeingSent[candidateRequest.frameId];
if ( frameMsg ) {
return frameMsg;
} else {
return null;
}
};
function onBeforeRequestListener(details) {
globalPageContainer.forwardCall(details, PageNetworkTrafficCollector.prototype.onBeforeRequest);
}
function onSendHeadersListener(details) {
globalPageContainer.forwardCall(details, PageNetworkTrafficCollector.prototype.onSendHeaders);
}
function onHeadersReceivedListener(details) {
globalPageContainer.forwardCall(details, PageNetworkTrafficCollector.prototype.onHeadersReceived);
}
function onBeforeRedirectListener(details) {
globalPageContainer.forwardCall(details, PageNetworkTrafficCollector.prototype.onBeforeRedirect);
}
function onResponseStartedListener(details) {
globalPageContainer.forwardCall(details, PageNetworkTrafficCollector.prototype.onResponseStarted);
}
function onCommittedListener(details) {
if ( details.frameId === 0 ) {
globalPageContainer.onNavigationCommitted(details);
}
}
function onCompletedListener(details) {
if ( details.frameId === 0 ) {
globalPageContainer.onNavigationCompleted(details);
}
}
function onRemovedListener(tabId, closeInfo) {
globalPageContainer.onTabClose(tabId, closeInfo);
}
function onMessageListener(message, sender, sendResponse) {
if ( message.event === 'new-ad' && message.data.event === 'ad' ) {
var tabId = sender.tab.id;
if ( tabId ) {
globalPageContainer.onDisplayAdFound(tabId);
}
}
}
function registerListeners() {
browserProxy.webRequest.onBeforeRequest.addListener(
onBeforeRequestListener,
{urls: ['http://*/*', 'https://*/*']},
[]
);
browserProxy.webRequest.onSendHeaders.addListener(
onSendHeadersListener,
{urls: ['http://*/*', 'https://*/*']},
['requestHeaders']
);
browserProxy.webRequest.onHeadersReceived.addListener(
onHeadersReceivedListener,
{urls: ['http://*/*', 'https://*/*']},
['responseHeaders']
);
browserProxy.webRequest.onBeforeRedirect.addListener(
onBeforeRedirectListener,
{urls: ['http://*/*', 'https://*/*']},
[]
);
browserProxy.webRequest.onResponseStarted.addListener(
onResponseStartedListener,
{urls: ['http://*/*', 'https://*/*']},
['responseHeaders']
);
browserProxy.webNavigation.onCommitted.addListener(onCommittedListener);
browserProxy.webNavigation.onCompleted.addListener(onCompletedListener);
browserProxy.tabs.onRemoved.addListener(onRemovedListener);
browserProxy.runtime.onMessage.addListener(onMessageListener);
areListenersRegistered = true;
}
function unregisterListeners() {
browserProxy.webRequest.onBeforeRequest.removeListener(
onBeforeRequestListener
);
browserProxy.webRequest.onSendHeaders.removeListener(
onSendHeadersListener
);
browserProxy.webRequest.onHeadersReceived.removeListener(
onHeadersReceivedListener
);
browserProxy.webRequest.onBeforeRedirect.removeListener(
onBeforeRedirectListener
);
browserProxy.webRequest.onResponseStarted.removeListener(
onResponseStartedListener
);
browserProxy.webNavigation.onCommitted.removeListener(onCommittedListener);
browserProxy.webNavigation.onCompleted.removeListener(onCompletedListener);
browserProxy.tabs.onRemoved.removeListener(onRemovedListener);
browserProxy.runtime.onMessage.removeListener(onMessageListener);
areListenersRegistered = false;
}
function areRequiredBrowserApisAvailable() {
return requiredBrowserApis.every(function(api) {
return typeof api !== 'undefined';
});
}
if ( areRequiredBrowserApisAvailable() ) {
ifBrowserValid(
function() {
browserProxy.webNavigation.onBeforeNavigate.addListener(
function(details) {
if ( details.frameId === 0 ) {
globalPageContainer.onNewNavigation(details);
}
},
{
url: [{urlMatches: 'http://*/*'}, {urlMatches: 'https://*/*'}]
}
);
}, function() {
}
);
}
browserProxy.runtime.onMessage.addListener(function(request, sender, sendResponse) {
if ( request === 'is_browser_valid' ) {
ifBrowserValid(
sendResponse({'browser_valid': true}),
sendResponse({'browser_valid': false})
);
}
});
browserProxy.runtime.onMessage.addListener(function(request, sender, sendResponse) {
if ( request === 'is_tracking_enabled' ) {
ifTrackingEnabled(
function() {
sendResponse({'tracking_enabled': true});
},
function() {
sendResponse({'tracking_enabled': false});
}
);
}
return true;
});
})();

@ -1,67 +0,0 @@
import wappalyzer from '../../../wappalyzer';
import browser from 'webextension-polyfill';
function getOption(name, defaultValue, callback) {
browser.storage.local.get(name)
.then(item => {
callback(item.hasOwnProperty(name) ? item[name] : defaultValue);
});
}
function setOption(name, value) {
var option = {};
option[name] = value;
browser.storage.local.set(option);
}
document.addEventListener('DOMContentLoaded', () => {
var nodes = document.querySelectorAll('[data-i18n]');
Array.prototype.forEach.call(nodes, node => {
node.childNodes[0].nodeValue = browser.i18n.getMessage(node.dataset.i18n);
});
document.querySelector('#github').addEventListener('click', () => {
open(wappalyzer.config.githubURL);
});
document.querySelector('#twitter').addEventListener('click', () => {
open(wappalyzer.config.twitterURL);
});
document.querySelector('#wappalyzer').addEventListener('click', () => {
open(wappalyzer.config.websiteURL);
});
getOption('upgradeMessage', true, value => {
const el = d.querySelector('#option-upgrade-message');
el.checked = value;
el.addEventListener('change', () => {
setOption('upgradeMessage', el.checked);
});
});
getOption('dynamicIcon', true, value => {
const el = d.querySelector('#option-dynamic-icon');
el.checked = value;
el.addEventListener('change', () => {
setOption('dynamicIcon', el.checked);
});
});
getOption('tracking', true, value => {
const el = d.querySelector('#option-tracking');
el.checked = value;
el.addEventListener('change', function() {
setOption('tracking', el.checked);
});
});
});

@ -1,131 +0,0 @@
/** global: chrome */
/** global: browser */
import browser from 'webextension-polyfill';
import jsonToDOM from './modules/jsontodom.js';
(function() {
var popup = {
init: function() {
popup.update([ 'p', {}, ' ' ], document, {});
var func = function(tabs) {
( chrome || browser ).runtime.sendMessage({ id: 'get_apps', tab: tabs[0], source: 'popup.js' }, function(response) {
popup.update(popup.appsToDomTemplate(response));
});
};
try {
// Chrome, Firefox
browser.tabs.query({ active: true, currentWindow: true }).then(func);
} catch ( e ) {
// Edge
browser.tabs.query({ active: true, currentWindow: true }, func);
}
},
update: function(dom) {
if ( /complete|interactive|loaded/.test(document.readyState) ) {
popup.replaceDom(dom);
} else {
document.addEventListener('DOMContentLoaded', function() {
popup.replaceDom(dom);
});
}
},
replaceDom: function(domTemplate) {
var body = document.body;
while ( body.firstChild ) {
body.removeChild(body.firstChild);
}
body.appendChild(jsonToDOM(domTemplate, document, {}));
var nodes = document.querySelectorAll('[data-i18n]');
Array.prototype.forEach.call(nodes, node => {
node.childNodes[0].nodeValue = browser.i18n.getMessage(node.dataset.i18n);
});
},
appsToDomTemplate: function(response) {
var
appName, confidence, version,
categories = [],
template = [];
if ( response.tabCache && response.tabCache.count > 0 ) {
for ( appName in response.tabCache.appsDetected ) {
confidence = response.tabCache.appsDetected[appName].confidenceTotal;
version = response.tabCache.appsDetected[appName].version;
categories = [];
response.apps[appName].cats.forEach(function(cat) {
categories.push(
[
'a', {
target: '_blank',
href: 'https://wappalyzer.com/categories/' + popup.slugify(response.categories[cat].name)
}, [
'span', {
class: 'category'
}, [
'span', {
class: 'name'
},
browser.i18n.getMessage('categoryName' + cat)
]
]
]
);
});
template.push(
[
'div', {
class: 'detected-app'
}, [
'a', {
target: '_blank',
href: 'https://wappalyzer.com/applications/' + popup.slugify(appName)
}, [
'img', {
src: 'images/icons/' + ( response.apps[appName].icon || 'default.svg' )
}
], [
'span', {
class: 'label'
}, [
'span', {
class: 'name'
},
appName
],
( version ? ' ' + version : '' ) + ( confidence < 100 ? ' (' + confidence + '% sure)' : '' )
]
],
categories
]
);
}
} else {
template = [
'div', {
class: 'empty'
},
browser.i18n.getMessage('noAppsDetected')
];
}
return template;
},
slugify: function(string) {
return string.toLowerCase().replace(/[^a-z0-9-]/g, '-').replace(/--+/g, '-').replace(/(?:^-|-$)/, '');
}
};
popup.init();
}());

@ -2,755 +2,6 @@
# yarn lockfile v1 # yarn lockfile v1
ajv@^4.9.1:
version "4.11.8"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536"
dependencies:
co "^4.6.0"
json-stable-stringify "^1.0.1"
ansi-regex@^2.0.0:
version "2.1.1"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
ansi-styles@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
asn1@~0.2.3:
version "0.2.3"
resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86"
assert-plus@1.0.0, assert-plus@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525"
assert-plus@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234"
asynckit@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
aws-sign2@~0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f"
aws4@^1.2.1:
version "1.6.0"
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e"
babel-code-frame@^6.22.0:
version "6.22.0"
resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.22.0.tgz#027620bee567a88c32561574e7fd0801d33118e4"
dependencies:
chalk "^1.1.0"
esutils "^2.0.2"
js-tokens "^3.0.0"
babel-core@^6.0.14, babel-core@^6.24.1, babel-core@^6.25.0:
version "6.25.0"
resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.25.0.tgz#7dd42b0463c742e9d5296deb3ec67a9322dad729"
dependencies:
babel-code-frame "^6.22.0"
babel-generator "^6.25.0"
babel-helpers "^6.24.1"
babel-messages "^6.23.0"
babel-register "^6.24.1"
babel-runtime "^6.22.0"
babel-template "^6.25.0"
babel-traverse "^6.25.0"
babel-types "^6.25.0"
babylon "^6.17.2"
convert-source-map "^1.1.0"
debug "^2.1.1"
json5 "^0.5.0"
lodash "^4.2.0"
minimatch "^3.0.2"
path-is-absolute "^1.0.0"
private "^0.1.6"
slash "^1.0.0"
source-map "^0.5.0"
babel-generator@^6.25.0:
version "6.25.0"
resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.25.0.tgz#33a1af70d5f2890aeb465a4a7793c1df6a9ea9fc"
dependencies:
babel-messages "^6.23.0"
babel-runtime "^6.22.0"
babel-types "^6.25.0"
detect-indent "^4.0.0"
jsesc "^1.3.0"
lodash "^4.2.0"
source-map "^0.5.0"
trim-right "^1.0.1"
babel-helper-builder-react-jsx@^6.24.1:
version "6.24.1"
resolved "https://registry.yarnpkg.com/babel-helper-builder-react-jsx/-/babel-helper-builder-react-jsx-6.24.1.tgz#0ad7917e33c8d751e646daca4e77cc19377d2cbc"
dependencies:
babel-runtime "^6.22.0"
babel-types "^6.24.1"
esutils "^2.0.0"
babel-helpers@^6.24.1:
version "6.24.1"
resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2"
dependencies:
babel-runtime "^6.22.0"
babel-template "^6.24.1"
babel-loader@^7.1.1:
version "7.1.1"
resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-7.1.1.tgz#b87134c8b12e3e4c2a94e0546085bc680a2b8488"
dependencies:
find-cache-dir "^1.0.0"
loader-utils "^1.0.2"
mkdirp "^0.5.1"
babel-messages@^6.23.0:
version "6.23.0"
resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e"
dependencies:
babel-runtime "^6.22.0"
babel-plugin-syntax-flow@^6.18.0:
version "6.18.0"
resolved "https://registry.yarnpkg.com/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz#4c3ab20a2af26aa20cd25995c398c4eb70310c8d"
babel-plugin-syntax-jsx@^6.3.13, babel-plugin-syntax-jsx@^6.8.0:
version "6.18.0"
resolved "https://registry.yarnpkg.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946"
babel-plugin-transform-flow-strip-types@^6.22.0:
version "6.22.0"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-flow-strip-types/-/babel-plugin-transform-flow-strip-types-6.22.0.tgz#84cb672935d43714fdc32bce84568d87441cf7cf"
dependencies:
babel-plugin-syntax-flow "^6.18.0"
babel-runtime "^6.22.0"
babel-plugin-transform-react-display-name@^6.23.0:
version "6.25.0"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-display-name/-/babel-plugin-transform-react-display-name-6.25.0.tgz#67e2bf1f1e9c93ab08db96792e05392bf2cc28d1"
dependencies:
babel-runtime "^6.22.0"
babel-plugin-transform-react-jsx-self@^6.22.0:
version "6.22.0"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx-self/-/babel-plugin-transform-react-jsx-self-6.22.0.tgz#df6d80a9da2612a121e6ddd7558bcbecf06e636e"
dependencies:
babel-plugin-syntax-jsx "^6.8.0"
babel-runtime "^6.22.0"
babel-plugin-transform-react-jsx-source@^6.22.0:
version "6.22.0"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx-source/-/babel-plugin-transform-react-jsx-source-6.22.0.tgz#66ac12153f5cd2d17b3c19268f4bf0197f44ecd6"
dependencies:
babel-plugin-syntax-jsx "^6.8.0"
babel-runtime "^6.22.0"
babel-plugin-transform-react-jsx@^6.24.1:
version "6.24.1"
resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx/-/babel-plugin-transform-react-jsx-6.24.1.tgz#840a028e7df460dfc3a2d29f0c0d91f6376e66a3"
dependencies:
babel-helper-builder-react-jsx "^6.24.1"
babel-plugin-syntax-jsx "^6.8.0"
babel-runtime "^6.22.0"
babel-preset-flow@^6.23.0:
version "6.23.0"
resolved "https://registry.yarnpkg.com/babel-preset-flow/-/babel-preset-flow-6.23.0.tgz#e71218887085ae9a24b5be4169affb599816c49d"
dependencies:
babel-plugin-transform-flow-strip-types "^6.22.0"
babel-preset-react@^6.24.1:
version "6.24.1"
resolved "https://registry.yarnpkg.com/babel-preset-react/-/babel-preset-react-6.24.1.tgz#ba69dfaea45fc3ec639b6a4ecea6e17702c91380"
dependencies:
babel-plugin-syntax-jsx "^6.3.13"
babel-plugin-transform-react-display-name "^6.23.0"
babel-plugin-transform-react-jsx "^6.24.1"
babel-plugin-transform-react-jsx-self "^6.22.0"
babel-plugin-transform-react-jsx-source "^6.22.0"
babel-preset-flow "^6.23.0"
babel-register@^6.24.1:
version "6.24.1"
resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.24.1.tgz#7e10e13a2f71065bdfad5a1787ba45bca6ded75f"
dependencies:
babel-core "^6.24.1"
babel-runtime "^6.22.0"
core-js "^2.4.0"
home-or-tmp "^2.0.0"
lodash "^4.2.0"
mkdirp "^0.5.1"
source-map-support "^0.4.2"
babel-runtime@^6.22.0:
version "6.23.0"
resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.23.0.tgz#0a9489f144de70efb3ce4300accdb329e2fc543b"
dependencies:
core-js "^2.4.0"
regenerator-runtime "^0.10.0"
babel-template@^6.24.1, babel-template@^6.25.0:
version "6.25.0"
resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.25.0.tgz#665241166b7c2aa4c619d71e192969552b10c071"
dependencies:
babel-runtime "^6.22.0"
babel-traverse "^6.25.0"
babel-types "^6.25.0"
babylon "^6.17.2"
lodash "^4.2.0"
babel-traverse@^6.25.0:
version "6.25.0"
resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.25.0.tgz#2257497e2fcd19b89edc13c4c91381f9512496f1"
dependencies:
babel-code-frame "^6.22.0"
babel-messages "^6.23.0"
babel-runtime "^6.22.0"
babel-types "^6.25.0"
babylon "^6.17.2"
debug "^2.2.0"
globals "^9.0.0"
invariant "^2.2.0"
lodash "^4.2.0"
babel-types@^6.24.1, babel-types@^6.25.0:
version "6.25.0"
resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.25.0.tgz#70afb248d5660e5d18f811d91c8303b54134a18e"
dependencies:
babel-runtime "^6.22.0"
esutils "^2.0.2"
lodash "^4.2.0"
to-fast-properties "^1.0.1"
babelify@^7.3.0:
version "7.3.0"
resolved "https://registry.yarnpkg.com/babelify/-/babelify-7.3.0.tgz#aa56aede7067fd7bd549666ee16dc285087e88e5"
dependencies:
babel-core "^6.0.14"
object-assign "^4.0.0"
babylon@^6.17.2:
version "6.17.4"
resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.17.4.tgz#3e8b7402b88d22c3423e137a1577883b15ff869a"
balanced-match@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
bcrypt-pbkdf@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz#63bc5dcb61331b92bc05fd528953c33462a06f8d"
dependencies:
tweetnacl "^0.14.3"
big.js@^3.1.3:
version "3.1.3"
resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.1.3.tgz#4cada2193652eb3ca9ec8e55c9015669c9806978"
boom@2.x.x:
version "2.10.1"
resolved "https://registry.yarnpkg.com/boom/-/boom-2.10.1.tgz#39c8918ceff5799f83f9492a848f625add0c766f"
dependencies:
hoek "2.x.x"
brace-expansion@^1.1.7:
version "1.1.8"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292"
dependencies:
balanced-match "^1.0.0"
concat-map "0.0.1"
caseless@~0.12.0:
version "0.12.0"
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
chalk@^1.1.0:
version "1.1.3"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
dependencies:
ansi-styles "^2.2.1"
escape-string-regexp "^1.0.2"
has-ansi "^2.0.0"
strip-ansi "^3.0.0"
supports-color "^2.0.0"
co@^4.6.0:
version "4.6.0"
resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
combined-stream@^1.0.5, combined-stream@~1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009"
dependencies:
delayed-stream "~1.0.0"
commondir@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b"
concat-map@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
convert-source-map@^1.1.0:
version "1.5.0"
resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.0.tgz#9acd70851c6d5dfdd93d9282e5edf94a03ff46b5"
core-js@^2.4.0:
version "2.4.1"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.4.1.tgz#4de911e667b0eae9124e34254b53aea6fc618d3e"
cryptiles@2.x.x:
version "2.0.5"
resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8"
dependencies:
boom "2.x.x"
dashdash@^1.12.0:
version "1.14.1"
resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0"
dependencies:
assert-plus "^1.0.0"
debug@^2.1.1, debug@^2.2.0:
version "2.6.8"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc"
dependencies:
ms "2.0.0"
delayed-stream@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
detect-indent@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208"
dependencies:
repeating "^2.0.0"
ecc-jsbn@~0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505"
dependencies:
jsbn "~0.1.0"
emojis-list@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389"
escape-string-regexp@^1.0.2:
version "1.0.5"
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
esutils@^2.0.0, esutils@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b"
extend@~3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444"
extsprintf@1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.0.2.tgz#e1080e0658e300b06294990cc70e1502235fd550"
find-cache-dir@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-1.0.0.tgz#9288e3e9e3cc3748717d39eade17cf71fc30ee6f"
dependencies:
commondir "^1.0.1"
make-dir "^1.0.0"
pkg-dir "^2.0.0"
find-up@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7"
dependencies:
locate-path "^2.0.0"
forever-agent@~0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
form-data@~2.1.1:
version "2.1.4"
resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.1.4.tgz#33c183acf193276ecaa98143a69e94bfee1750d1"
dependencies:
asynckit "^0.4.0"
combined-stream "^1.0.5"
mime-types "^2.1.12"
getpass@^0.1.1:
version "0.1.7"
resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa"
dependencies:
assert-plus "^1.0.0"
globals@^9.0.0:
version "9.18.0"
resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a"
har-schema@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-1.0.5.tgz#d263135f43307c02c602afc8fe95970c0151369e"
har-validator@~4.2.1:
version "4.2.1"
resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-4.2.1.tgz#33481d0f1bbff600dd203d75812a6a5fba002e2a"
dependencies:
ajv "^4.9.1"
har-schema "^1.0.5"
has-ansi@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91"
dependencies:
ansi-regex "^2.0.0"
hawk@~3.1.3:
version "3.1.3"
resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4"
dependencies:
boom "2.x.x"
cryptiles "2.x.x"
hoek "2.x.x"
sntp "1.x.x"
hoek@2.x.x:
version "2.16.3"
resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed"
home-or-tmp@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8"
dependencies:
os-homedir "^1.0.0"
os-tmpdir "^1.0.1"
http-signature@~1.1.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.1.1.tgz#df72e267066cd0ac67fb76adf8e134a8fbcf91bf"
dependencies:
assert-plus "^0.2.0"
jsprim "^1.2.2"
sshpk "^1.7.0"
invariant@^2.2.0:
version "2.2.2"
resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.2.tgz#9e1f56ac0acdb6bf303306f338be3b204ae60360"
dependencies:
loose-envify "^1.0.0"
is-finite@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa"
dependencies:
number-is-nan "^1.0.0"
is-typedarray@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
isstream@~0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
js-tokens@^3.0.0:
version "3.0.2"
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b"
jsbn@~0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
jsesc@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b"
json-schema@0.2.3:
version "0.2.3"
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
json-stable-stringify@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af"
dependencies:
jsonify "~0.0.0"
json-stringify-safe@~5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
json5@^0.5.0:
version "0.5.1"
resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821"
jsonify@~0.0.0:
version "0.0.0"
resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73"
jsprim@^1.2.2:
version "1.4.0"
resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.0.tgz#a3b87e40298d8c380552d8cc7628a0bb95a22918"
dependencies:
assert-plus "1.0.0"
extsprintf "1.0.2"
json-schema "0.2.3"
verror "1.3.6"
loader-utils@^1.0.2:
version "1.1.0"
resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.1.0.tgz#c98aef488bcceda2ffb5e2de646d6a754429f5cd"
dependencies:
big.js "^3.1.3"
emojis-list "^2.0.0"
json5 "^0.5.0"
locate-path@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e"
dependencies:
p-locate "^2.0.0"
path-exists "^3.0.0"
lodash@^4.2.0:
version "4.17.4"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae"
loose-envify@^1.0.0:
version "1.3.1"
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848"
dependencies:
js-tokens "^3.0.0"
make-dir@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.0.0.tgz#97a011751e91dd87cfadef58832ebb04936de978"
dependencies:
pify "^2.3.0"
mime-db@~1.27.0:
version "1.27.0"
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.27.0.tgz#820f572296bbd20ec25ed55e5b5de869e5436eb1"
mime-types@^2.1.12, mime-types@~2.1.7:
version "2.1.15"
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.15.tgz#a4ebf5064094569237b8cf70046776d09fc92aed"
dependencies:
mime-db "~1.27.0"
minimatch@^3.0.2:
version "3.0.4"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
dependencies:
brace-expansion "^1.1.7"
minimist@0.0.8:
version "0.0.8"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
mkdirp@^0.5.1:
version "0.5.1"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
dependencies:
minimist "0.0.8"
ms@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
number-is-nan@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d"
oauth-sign@~0.8.1:
version "0.8.2"
resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43"
object-assign@^4.0.0:
version "4.1.1"
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
os-homedir@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3"
os-tmpdir@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
p-limit@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.1.0.tgz#b07ff2d9a5d88bec806035895a2bab66a27988bc"
p-locate@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43"
dependencies:
p-limit "^1.1.0"
path-exists@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515"
path-is-absolute@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
performance-now@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5"
pify@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c"
pkg-dir@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b"
dependencies:
find-up "^2.1.0"
private@^0.1.6:
version "0.1.7"
resolved "https://registry.yarnpkg.com/private/-/private-0.1.7.tgz#68ce5e8a1ef0a23bb570cc28537b5332aba63ef1"
punycode@^1.4.1:
version "1.4.1"
resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"
qs@~6.4.0:
version "6.4.0"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233"
regenerator-runtime@^0.10.0:
version "0.10.5"
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz#336c3efc1220adcedda2c9fab67b5a7955a33658"
repeating@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda"
dependencies:
is-finite "^1.0.0"
request@^2.81.0:
version "2.81.0"
resolved "https://registry.yarnpkg.com/request/-/request-2.81.0.tgz#c6928946a0e06c5f8d6f8a9333469ffda46298a0"
dependencies:
aws-sign2 "~0.6.0"
aws4 "^1.2.1"
caseless "~0.12.0"
combined-stream "~1.0.5"
extend "~3.0.0"
forever-agent "~0.6.1"
form-data "~2.1.1"
har-validator "~4.2.1"
hawk "~3.1.3"
http-signature "~1.1.0"
is-typedarray "~1.0.0"
isstream "~0.1.2"
json-stringify-safe "~5.0.1"
mime-types "~2.1.7"
oauth-sign "~0.8.1"
performance-now "^0.2.0"
qs "~6.4.0"
safe-buffer "^5.0.1"
stringstream "~0.0.4"
tough-cookie "~2.3.0"
tunnel-agent "^0.6.0"
uuid "^3.0.0"
safe-buffer@^5.0.1:
version "5.1.1"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853"
slash@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55"
sntp@1.x.x:
version "1.0.9"
resolved "https://registry.yarnpkg.com/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198"
dependencies:
hoek "2.x.x"
source-map-support@^0.4.2:
version "0.4.15"
resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.15.tgz#03202df65c06d2bd8c7ec2362a193056fef8d3b1"
dependencies:
source-map "^0.5.6"
source-map@^0.5.0, source-map@^0.5.6:
version "0.5.6"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412"
sshpk@^1.7.0:
version "1.13.1"
resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.13.1.tgz#512df6da6287144316dc4c18fe1cf1d940739be3"
dependencies:
asn1 "~0.2.3"
assert-plus "^1.0.0"
dashdash "^1.12.0"
getpass "^0.1.1"
optionalDependencies:
bcrypt-pbkdf "^1.0.0"
ecc-jsbn "~0.1.1"
jsbn "~0.1.0"
tweetnacl "~0.14.0"
stringstream@~0.0.4:
version "0.0.5"
resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878"
strip-ansi@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf"
dependencies:
ansi-regex "^2.0.0"
supports-color@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
to-fast-properties@^1.0.1:
version "1.0.3"
resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47"
tough-cookie@~2.3.0:
version "2.3.2"
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.2.tgz#f081f76e4c85720e6c37a5faced737150d84072a"
dependencies:
punycode "^1.4.1"
trim-right@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003"
tunnel-agent@^0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd"
dependencies:
safe-buffer "^5.0.1"
tweetnacl@^0.14.3, tweetnacl@~0.14.0:
version "0.14.5"
resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
uuid@^3.0.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04"
verror@1.3.6:
version "1.3.6"
resolved "https://registry.yarnpkg.com/verror/-/verror-1.3.6.tgz#cff5df12946d297d2baaefaa2689e25be01c005c"
dependencies:
extsprintf "1.0.2"
webextension-polyfill@^0.1.1: webextension-polyfill@^0.1.1:
version "0.1.1" version "0.1.1"
resolved "https://registry.yarnpkg.com/webextension-polyfill/-/webextension-polyfill-0.1.1.tgz#1d172e59b9ee8706d5ce2c55eebfe0cf23972d70" resolved "https://registry.yarnpkg.com/webextension-polyfill/-/webextension-polyfill-0.1.1.tgz#1d172e59b9ee8706d5ce2c55eebfe0cf23972d70"

@ -1,63 +0,0 @@
class Application {
constructor(name, props, detected) {
this.name = name;
this.props = props;
this.confidence = {};
this.confidenceTotal = 0;
this.detected = Boolean(detected);
this.excludes = [];
this.version = '';
this.versions = [];
}
/**
* Calculate confidence total
*/
getConfidence() {
var total = 0;
for ( var id in this.confidence ) {
total += this.confidence[id];
}
return this.confidenceTotal = Math.min(total, 100);
}
setDetected(pattern, type, value, key) {
this.detected = true;
// Set confidence level
this.confidence[type + ' ' + ( key ? key + ' ' : '' ) + pattern.regex] = pattern.confidence || 100;
// Detect version number
if ( pattern.version ) {
var version = pattern.version;
var matches = pattern.regex.exec(value);
if ( matches ) {
matches.forEach((match, i) => {
// Parse ternary operator
var ternary = new RegExp('\\\\' + i + '\\?([^:]+):(.*)$').exec(version);
if ( ternary && ternary.length === 3 ) {
version = version.replace(ternary[0], match ? ternary[1] : ternary[2]);
}
// Replace back references
version = version.replace(new RegExp('\\\\' + i, 'g'), match || '');
});
if ( version && this.versions.indexOf(version) === -1 ) {
this.versions.push(version);
}
if ( this.versions.length ) {
// Use the longest detected version number
this.version = this.versions.reduce((a, b) => a.length > b.length ? a : b)[0];
}
}
}
}
}
export default Application

@ -8,17 +8,14 @@
'use strict'; 'use strict';
import json from './apps.json';
import Application from './modules/application.js';
const validation = { const validation = {
hostname: /(www.)?((.+?)\.(([a-z]{2,3}\.)?[a-z]{2,6}))$/, hostname: /(www.)?((.+?)\.(([a-z]{2,3}\.)?[a-z]{2,6}))$/,
hostnameBlacklist: /((local|dev(elopment)?|stag(e|ing)?|test(ing)?|demo(shop)?|admin|google|cache)\.|\/admin|\.local)/ hostnameBlacklist: /((local|dev(elopment)?|stag(e|ing)?|test(ing)?|demo(shop)?|admin|google|cache)\.|\/admin|\.local)/
}; };
var wappalyzer = { var wappalyzer = {
apps: json.apps, apps: {},
categories: json.categories, categories: {},
driver: {} driver: {}
}; };
@ -79,8 +76,10 @@ wappalyzer.analyze = (hostname, url, data, context) => {
} }
}) })
Object.keys(apps).forEach(app => { Object.keys(apps).forEach(appName => {
if ( !app.detected ) { var app = apps[appName];
if ( !app.detected || !app.getConfidence() ) {
delete apps[app.name]; delete apps[app.name];
} }
}); });
@ -98,6 +97,13 @@ wappalyzer.analyze = (hostname, url, data, context) => {
wappalyzer.driver.displayApps(detected[url], context); wappalyzer.driver.displayApps(detected[url], context);
} }
/**
* Cache detected ads
*/
wappalyzer.cacheDetectedAds = ad => {
adCache.push(ad);
}
/** /**
* Enclose string in array * Enclose string in array
*/ */
@ -234,13 +240,6 @@ function cacheDetectedApps(apps, url) {
}) })
} }
/**
* Cache detected ads
*/
function cacheDetectedAds(ad) {
adCache.push(ad);
}
/** /**
* Track detected applications * Track detected applications
*/ */
@ -298,7 +297,7 @@ function analyzeUrl(app, url) {
if ( patterns.length ) { if ( patterns.length ) {
patterns.forEach(pattern => { patterns.forEach(pattern => {
if ( pattern.regex.test(url) ) { if ( pattern.regex.test(url) ) {
app.setDetected(pattern, 'url', url); addDetected(app, pattern, 'url', url);
} }
}); });
} }
@ -313,7 +312,7 @@ function analyzeHtml(app, html) {
if ( patterns.length ) { if ( patterns.length ) {
patterns.forEach(pattern => { patterns.forEach(pattern => {
if ( pattern.regex.test(html) ) { if ( pattern.regex.test(html) ) {
app.setDetected(pattern, 'html', html); addDetected(app, pattern, 'html', html);
} }
}); });
} }
@ -332,7 +331,7 @@ function analyzeScript(app, html) {
while ( ( match = regex.exec(html) ) ) { while ( ( match = regex.exec(html) ) ) {
if ( pattern.regex.test(match[2]) ) { if ( pattern.regex.test(match[2]) ) {
app.setDetected(pattern, 'script', match[2]); addDetected(app, pattern, 'script', match[2]);
} }
} }
}); });
@ -355,7 +354,7 @@ function analyzeMeta(app, html) {
patterns[meta].forEach(pattern => { patterns[meta].forEach(pattern => {
if ( content && content.length === 4 && pattern.regex.test(content[2]) ) { if ( content && content.length === 4 && pattern.regex.test(content[2]) ) {
app.setDetected(pattern, 'meta', content[2], meta); addDetected(app, pattern, 'meta', content[2], meta);
} }
}); });
} }
@ -375,7 +374,7 @@ function analyzeHeaders(app, headers) {
header = header.toLowerCase(); header = header.toLowerCase();
if ( headers.hasOwnProperty(header) && pattern.regex.test(headers[header]) ) { if ( headers.hasOwnProperty(header) && pattern.regex.test(headers[header]) ) {
app.setDetected(pattern, 'headers', headers[header], header); addDetected(app, pattern, 'headers', headers[header], header);
} }
}); });
}); });
@ -392,11 +391,81 @@ function analyzeEnv(app, envs) {
patterns.forEach(pattern => { patterns.forEach(pattern => {
Object.keys(envs).forEach(env => { Object.keys(envs).forEach(env => {
if ( pattern.regex.test(envs[env]) ) { if ( pattern.regex.test(envs[env]) ) {
app.setDetected(pattern, 'env', envs[env]); addDetected(app, pattern, 'env', envs[env]);
} }
}) })
}); });
} }
} }
export default wappalyzer; /**
* Mark application as detected, set confidence and version
*/
function addDetected(app, pattern, type, value, key) {
app.detected = true;
// Set confidence level
app.confidence[type + ' ' + ( key ? key + ' ' : '' ) + pattern.regex] = pattern.confidence || 100;
// Detect version number
if ( pattern.version ) {
var versions = [];
var version = pattern.version;
var matches = pattern.regex.exec(value);
if ( matches ) {
matches.forEach((match, i) => {
// Parse ternary operator
var ternary = new RegExp('\\\\' + i + '\\?([^:]+):(.*)$').exec(version);
if ( ternary && ternary.length === 3 ) {
version = version.replace(ternary[0], match ? ternary[1] : ternary[2]);
}
// Replace back references
version = version.replace(new RegExp('\\\\' + i, 'g'), match || '');
});
if ( version && versions.indexOf(version) === -1 ) {
versions.push(version);
}
if ( versions.length ) {
// Use the longest detected version number
app.version = versions.reduce((a, b) => a.length > b.length ? a : b)[0];
}
}
}
}
/**
* Application class
*/
class Application {
constructor(name, props, detected) {
this.confidence = {};
this.confidenceTotal = 0;
this.detected = Boolean(detected);
this.excludes = [];
this.name = name;
this.props = props;
this.version = '';
}
/**
* Calculate confidence total
*/
getConfidence() {
var total = 0;
for ( var id in this.confidence ) {
total += this.confidence[id];
}
return this.confidenceTotal = Math.min(total, 100);
}
}
if ( typeof exports === 'object' ) {
exports.wappalyzer = wappalyzer;
}

@ -1,52 +0,0 @@
const path = require('path');
const glob = require('glob');
var exports = [];
const rootPath = {
webExtension: path.join(__dirname, 'src/drivers/webextension'),
npm: path.join(__dirname, 'src/drivers/npm')
};
const config = {
module: {
loaders: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader'
// query: {
// presets: ['es2015']
// }
}
]
},
node: {
console: true,
child_process: 'empty',
fs: 'empty',
net: 'empty',
tls: 'empty'
}
};
glob.sync(path.join(rootPath.webExtension, 'src/*.js'))
.forEach(file => {
exports.push(Object.assign({}, config, {
context: path.resolve(rootPath.webExtension),
resolve: {
modules: [
rootPath.webExtension,
'node_modules'
]
},
entry: file,
output: {
path: path.join(rootPath.webExtension, 'js'),
filename: path.relative(path.join(rootPath.webExtension, 'src'), file)
}
}))
});
module.exports = exports;

File diff suppressed because it is too large Load Diff