parent
b38abb793c
commit
a00319a3a8
@ -1,8 +0,0 @@
|
|||||||
{
|
|
||||||
"flags": [],
|
|
||||||
"linkedModules": [],
|
|
||||||
"topLevelPatters": [],
|
|
||||||
"lockfileEntries": {},
|
|
||||||
"files": [],
|
|
||||||
"artifacts": {}
|
|
||||||
}
|
|
@ -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();
|
|
||||||
})();
|
|
||||||
|
|
||||||
/***/ })
|
|
||||||
/******/ ]);
|
|
@ -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();
|
|
||||||
})();
|
|
||||||
|
|
||||||
/***/ })
|
|
||||||
/******/ ]);
|
|
@ -0,0 +1 @@
|
|||||||
|
../../apps.json
|
@ -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>
|
@ -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
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -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();
|
|
||||||
}());
|
|
@ -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
|
|
@ -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;
|
|
Reference in new issue