2020-08-08 07:27:02 +02:00
|
|
|
/**
|
|
|
|
* Statistic
|
|
|
|
* Belongs to LocalCDN (since 2020-02-26)
|
|
|
|
*
|
|
|
|
* @author nobody
|
|
|
|
* @since 2020-02-26
|
|
|
|
*
|
|
|
|
* @license MPL 2.0
|
|
|
|
*
|
|
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
|
|
|
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
*/
|
|
|
|
|
|
|
|
'use strict';
|
|
|
|
|
2021-02-17 07:01:08 +01:00
|
|
|
|
2020-08-08 07:27:02 +02:00
|
|
|
/**
|
|
|
|
* Statistic
|
|
|
|
*/
|
2021-02-17 07:01:08 +01:00
|
|
|
|
2020-08-08 07:27:02 +02:00
|
|
|
var statistics = {};
|
|
|
|
|
2021-02-17 07:01:08 +01:00
|
|
|
|
2020-08-08 07:27:02 +02:00
|
|
|
/**
|
|
|
|
* Private Methods
|
|
|
|
*/
|
2021-02-17 07:01:08 +01:00
|
|
|
|
2020-08-08 07:27:02 +02:00
|
|
|
statistics._onDocumentLoaded = function () {
|
2020-08-09 08:34:11 +02:00
|
|
|
helpers.insertI18nContentIntoDocument(document);
|
|
|
|
helpers.insertI18nTitlesIntoDocument(document);
|
|
|
|
|
2021-03-07 08:01:22 +01:00
|
|
|
chrome.storage.local.get([Setting.DEFAULT_RANGE_STATISTIC], function (items) {
|
2021-03-21 08:07:30 +01:00
|
|
|
statistics._dateUnit = items.defaultRangeStatistic || 'week';
|
|
|
|
document.getElementById('date-range').value = statistics._dateUnit;
|
|
|
|
|
|
|
|
statistics._setDateRange();
|
2021-03-07 08:01:22 +01:00
|
|
|
statistics._registerListener();
|
|
|
|
statistics._getStatistics().then(statistics._renderContents);
|
|
|
|
});
|
2020-08-08 07:27:02 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
statistics._renderContents = function () {
|
|
|
|
statistics._filterAndSortData();
|
|
|
|
statistics._determineInjections();
|
|
|
|
|
|
|
|
statistics._clearTables();
|
2020-08-09 08:34:11 +02:00
|
|
|
statistics._determineInjections();
|
2020-08-08 07:27:02 +02:00
|
|
|
statistics._generateTable(statistics._dataSortedCDNs, 'cdns');
|
|
|
|
statistics._generateTable(statistics._dataSortedFrameworks, 'frameworks');
|
|
|
|
};
|
|
|
|
|
|
|
|
statistics._generateTable = function (data, type) {
|
|
|
|
let arr = Object.values(data);
|
|
|
|
if (arr.length === 0) {
|
|
|
|
arr = [['no data', '-']];
|
|
|
|
}
|
|
|
|
|
|
|
|
for (const value of arr) {
|
2020-08-10 17:59:46 +02:00
|
|
|
let row, keyColumn, valueColumn;
|
2020-08-08 07:27:02 +02:00
|
|
|
|
2020-08-10 17:59:46 +02:00
|
|
|
row = document.createElement('tr');
|
|
|
|
|
|
|
|
keyColumn = document.createElement('td');
|
|
|
|
keyColumn.appendChild(statistics._displayNameOfFramework(value[0], type));
|
2020-08-08 07:27:02 +02:00
|
|
|
row.appendChild(keyColumn);
|
|
|
|
|
2020-08-10 17:59:46 +02:00
|
|
|
valueColumn = document.createElement('td');
|
2020-08-08 07:27:02 +02:00
|
|
|
valueColumn.appendChild(document.createTextNode(value[1]));
|
|
|
|
row.appendChild(valueColumn);
|
|
|
|
|
2021-02-17 07:01:08 +01:00
|
|
|
document.getElementById(`tbody-${type}`).appendChild(row);
|
2020-08-08 07:27:02 +02:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
statistics._filterAndSortData = function () {
|
2020-08-10 18:04:50 +02:00
|
|
|
let tmpCDNs, tmpFrameworks;
|
|
|
|
|
|
|
|
tmpCDNs = {};
|
|
|
|
tmpFrameworks = {};
|
|
|
|
|
2020-08-08 07:27:02 +02:00
|
|
|
// Purge
|
|
|
|
statistics._dataSortedCDNs = {};
|
|
|
|
statistics._dataSortedFrameworks = {};
|
|
|
|
|
|
|
|
statistics._dateRange.forEach(function (entry) {
|
|
|
|
if (entry in statistics._data) {
|
2020-08-10 18:04:50 +02:00
|
|
|
statistics._mergeObjects(statistics._data[entry]['cdns'], tmpCDNs);
|
|
|
|
statistics._mergeObjects(statistics._data[entry]['frameworks'], tmpFrameworks);
|
2020-08-08 07:27:02 +02:00
|
|
|
}
|
|
|
|
});
|
2020-08-10 18:04:50 +02:00
|
|
|
statistics._dataSortedCDNs = Object.entries(tmpCDNs).sort((a, b) => b[1] - a[1]);
|
|
|
|
statistics._dataSortedFrameworks = Object.entries(tmpFrameworks).sort((a, b) => b[1] - a[1]);
|
|
|
|
};
|
|
|
|
|
|
|
|
statistics._mergeObjects = function (obj, arr) {
|
|
|
|
for (let [key, value] of Object.entries(obj)) {
|
2021-02-07 08:09:45 +01:00
|
|
|
let bundle = targets.determineBundle(key);
|
|
|
|
if (bundle !== '') {
|
|
|
|
bundle = key.split('/');
|
2021-02-17 07:01:08 +01:00
|
|
|
key = `${bundle[0]}/${bundle[1]}/${bundle[2]}/`;
|
2021-02-07 08:09:45 +01:00
|
|
|
}
|
2020-08-10 18:04:50 +02:00
|
|
|
// If CDN/Framework exists, add it, otherwise create new one
|
|
|
|
if (arr[key]) {
|
|
|
|
arr[key] += value;
|
|
|
|
} else {
|
|
|
|
arr[key] = value;
|
|
|
|
}
|
|
|
|
}
|
2020-08-08 07:27:02 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
statistics._setDateRange = function () {
|
2020-08-10 18:04:50 +02:00
|
|
|
let today, from, days, type;
|
|
|
|
|
|
|
|
today = new Date();
|
|
|
|
from = new Date();
|
|
|
|
type = statistics._dateUnit;
|
2020-08-08 07:27:02 +02:00
|
|
|
|
|
|
|
// Purge
|
|
|
|
statistics._dateRange = [];
|
|
|
|
|
|
|
|
if (type === 'week') {
|
|
|
|
days = 7;
|
|
|
|
} else if (type === 'month') {
|
|
|
|
days = 30;
|
|
|
|
} else if (type === 'year') {
|
|
|
|
days = 365;
|
|
|
|
} else {
|
|
|
|
statistics._dateRange = [new Date().toISOString().slice(0, 10)];
|
|
|
|
}
|
|
|
|
|
|
|
|
if (days > 1) {
|
|
|
|
for (let i = 0; i < days; i++) {
|
2021-02-17 07:01:08 +01:00
|
|
|
let diff, day;
|
|
|
|
|
2020-08-08 07:27:02 +02:00
|
|
|
// NOTE: setDate/getDate is buggy over day/month/year boundaries
|
2021-02-17 07:01:08 +01:00
|
|
|
diff = 24 * 3600000 * i;
|
|
|
|
day = from.setTime(today.getTime() - diff);
|
2020-08-08 07:27:02 +02:00
|
|
|
statistics._dateRange.push(new Date(day).toISOString().slice(0, 10));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
statistics._renderContents();
|
|
|
|
};
|
|
|
|
|
|
|
|
statistics._determineInjections = function () {
|
|
|
|
// NOTE: Differences between CDNs and frameworks possible.
|
|
|
|
// CDN can be contacted without loading a framework.
|
2020-08-10 18:04:50 +02:00
|
|
|
let sum, days, avg;
|
|
|
|
|
|
|
|
sum = 0;
|
|
|
|
days = 0;
|
2020-11-15 12:31:18 +01:00
|
|
|
|
2020-08-08 07:27:02 +02:00
|
|
|
statistics._dataOverview = [];
|
|
|
|
|
|
|
|
statistics._dateRange.forEach(function (entry) {
|
|
|
|
if (entry in statistics._data) {
|
|
|
|
for (const value of Object.values(statistics._data[entry]['frameworks'])) {
|
|
|
|
sum += parseFloat(value);
|
|
|
|
}
|
|
|
|
days++;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
avg = sum / days > 0 ? sum / days : 0;
|
2020-08-09 08:34:11 +02:00
|
|
|
avg = Math.round((avg + Number.EPSILON) * 100) / 100;
|
2020-08-08 07:27:02 +02:00
|
|
|
|
2020-08-12 16:11:06 +02:00
|
|
|
document.getElementById('avg-quantity').textContent = isNaN(avg) ? '-' : helpers.formatNumber(avg);
|
2020-08-09 08:34:11 +02:00
|
|
|
document.getElementById('quantity-injected-frameworks').textContent = isNaN(sum) ? '-' : sum;
|
2020-08-08 07:27:02 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
statistics._getStatistics = function () {
|
|
|
|
return new Promise((resolve) => {
|
|
|
|
chrome.storage.local.get([Setting.INTERNAL_STATISTICS_DATA], function (items) {
|
|
|
|
statistics._data = items.internalStatisticsData;
|
|
|
|
resolve();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
statistics._clearTables = function () {
|
|
|
|
const tbody = document.querySelectorAll('tbody');
|
|
|
|
|
|
|
|
tbody.forEach((table) => {
|
|
|
|
while (table.hasChildNodes()) {
|
|
|
|
table.removeChild(table.firstChild);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
statistics._displayNameOfFramework = function (str, type) {
|
|
|
|
// Is used in generateTable(), but should only be used for frameworks
|
|
|
|
if (type === 'frameworks' && str !== 'no data') {
|
2020-08-10 17:59:46 +02:00
|
|
|
let filename, line, lbName, lbVersion, version;
|
2020-08-08 07:27:02 +02:00
|
|
|
|
2020-08-10 17:59:46 +02:00
|
|
|
// Create elements
|
|
|
|
line = document.createElement('p');
|
|
|
|
lbName = document.createElement('span');
|
|
|
|
lbVersion = document.createElement('span');
|
2020-08-08 07:27:02 +02:00
|
|
|
|
2020-08-10 17:59:46 +02:00
|
|
|
filename = helpers.extractFilenameFromPath(str);
|
2020-11-05 07:07:29 +01:00
|
|
|
filename = targets.determineResourceName(filename);
|
2020-08-10 17:59:46 +02:00
|
|
|
|
2020-10-25 00:09:15 +02:00
|
|
|
if (filename === 'Unknown') {
|
2020-11-12 06:57:19 +01:00
|
|
|
filename = targets.determineBundle(str);
|
2021-02-02 05:48:41 +01:00
|
|
|
if (filename === '' && str.startsWith('resources/font-awesome/')) {
|
2021-02-17 07:01:08 +01:00
|
|
|
filename = 'Font Awesome (Fonts)';
|
2021-02-21 20:03:16 +01:00
|
|
|
} else if (str === 'resources/google-charts/loader.jsm') {
|
|
|
|
filename = 'Google Charts';
|
|
|
|
} else if (str === 'resources/fontawesome/5.15.1/css/v4-shims.css') {
|
|
|
|
filename = 'Font Awesome (Shim)';
|
2021-04-16 06:44:15 +02:00
|
|
|
} else if (str === 'resources/bootstrap/fonts/') {
|
|
|
|
filename = 'Bootstrap (Fonts)';
|
|
|
|
} else {
|
|
|
|
console.warn(`[LocalCDN] Missing path: ${str}`);
|
2020-11-12 06:57:19 +01:00
|
|
|
}
|
2020-10-25 00:09:15 +02:00
|
|
|
}
|
2021-04-16 06:44:15 +02:00
|
|
|
|
2020-08-10 17:59:46 +02:00
|
|
|
version = str.match(Resource.VERSION_EXPRESSION);
|
2020-08-08 07:27:02 +02:00
|
|
|
if (version !== null && version.length > 0) {
|
2021-02-17 07:01:08 +01:00
|
|
|
version = version[0] === 'latest' ? version[0] : `v${version[0]}`;
|
2020-08-08 07:27:02 +02:00
|
|
|
} else {
|
|
|
|
version = '';
|
2021-04-16 06:44:15 +02:00
|
|
|
console.log(`[LocalCDN] Missing version: ${str}`);
|
2020-08-08 07:27:02 +02:00
|
|
|
}
|
2020-08-10 17:59:46 +02:00
|
|
|
|
|
|
|
lbName.appendChild(document.createTextNode(filename));
|
|
|
|
lbVersion.appendChild(document.createTextNode(version));
|
|
|
|
lbVersion.classList.add('version');
|
|
|
|
line.appendChild(lbName);
|
|
|
|
line.appendChild(lbVersion);
|
2021-04-16 06:44:15 +02:00
|
|
|
|
2020-08-10 17:59:46 +02:00
|
|
|
return line;
|
2020-08-08 07:27:02 +02:00
|
|
|
}
|
|
|
|
// If type is CDN
|
2020-08-10 17:59:46 +02:00
|
|
|
return document.createTextNode(str);
|
2020-08-08 07:27:02 +02:00
|
|
|
};
|
|
|
|
|
2021-02-17 07:01:08 +01:00
|
|
|
statistics._handlerDateRange = function ({target}) {
|
2020-08-09 08:34:11 +02:00
|
|
|
let type = target.value;
|
|
|
|
if (type === 'day' || type === 'week' || type === 'month' || type === 'year') {
|
|
|
|
statistics._dateUnit = type;
|
2021-03-07 08:01:22 +01:00
|
|
|
statistics._saveDefaultRange(type);
|
2020-08-09 08:34:11 +02:00
|
|
|
} else if (type === 'delete') {
|
2020-08-08 07:27:02 +02:00
|
|
|
statistics._deleteStatistic();
|
|
|
|
}
|
2020-08-12 07:23:33 +02:00
|
|
|
statistics._getStatistics().then(statistics._setDateRange);
|
2020-08-08 07:27:02 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
statistics._deleteStatistic = function () {
|
2020-08-09 11:16:53 +02:00
|
|
|
let text = chrome.i18n.getMessage('dialogConfirmDeleteStatistics');
|
2020-08-09 11:01:33 +02:00
|
|
|
if (confirm(text)) {
|
2020-08-08 07:27:02 +02:00
|
|
|
chrome.storage.local.set({
|
2020-08-13 08:07:04 +02:00
|
|
|
[Setting.INTERNAL_STATISTICS_DATA]: {}
|
2020-08-08 07:27:02 +02:00
|
|
|
});
|
2021-03-21 08:07:30 +01:00
|
|
|
chrome.runtime.sendMessage({'topic': 'statistic:delete'});
|
2020-08-08 07:27:02 +02:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2021-03-07 08:01:22 +01:00
|
|
|
statistics._saveDefaultRange = function (value) {
|
|
|
|
chrome.storage.local.set({
|
|
|
|
[Setting.DEFAULT_RANGE_STATISTIC]: value
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2020-08-08 07:27:02 +02:00
|
|
|
statistics._registerListener = function () {
|
2020-08-09 08:34:11 +02:00
|
|
|
document.getElementById('date-range').addEventListener('change', statistics._handlerDateRange);
|
|
|
|
document.getElementById('btn-delete').addEventListener('click', function () {
|
2021-02-17 07:01:08 +01:00
|
|
|
statistics._handlerDateRange({'target': {'value': 'delete'}});
|
2020-08-09 08:34:11 +02:00
|
|
|
});
|
2020-08-08 07:27:02 +02:00
|
|
|
};
|
|
|
|
|
2021-02-17 07:01:08 +01:00
|
|
|
|
2020-08-08 07:27:02 +02:00
|
|
|
/**
|
|
|
|
* Initializations
|
|
|
|
*/
|
2021-02-17 07:01:08 +01:00
|
|
|
|
2020-08-08 07:27:02 +02:00
|
|
|
statistics._data = {};
|
|
|
|
statistics._dataSortedCDNs = {};
|
|
|
|
statistics._dataSortedFrameworks = {};
|
|
|
|
statistics._dataOverview = [];
|
|
|
|
statistics._dateRange = [];
|
2021-03-07 08:01:22 +01:00
|
|
|
statistics._dateUnit = 'week';
|
2020-08-08 07:27:02 +02:00
|
|
|
|
|
|
|
document.addEventListener('DOMContentLoaded', statistics._onDocumentLoaded);
|