Add errors collecting

This commit is contained in:
Ilya Ig. Petrov 2017-05-28 22:27:11 +05:00
parent 0028c77f0d
commit a328fa88d9
8 changed files with 216 additions and 42 deletions

View File

@ -0,0 +1,58 @@
<!DOCTYPE html>
<html style="display: none; will-change: contents, display">
<head>
<meta charset="utf-8">
<title>Последние ошибки</title>
<style>
html {
display: flex;
}
body {
display: inline-block;
margin: 0 auto;
}
table {
border-collapse: collapse;
background-color: #f3f5f6;
margin-bottom: 1em;
}
td, th {
border-style: solid;
border-width: 1px;
padding: 0.5em;
}
a:not(:hover) {
text-decoration: none;
}
tr > td:first-child {
text-align: center;
}
main {
display: block-inline;
margin: 0 auto;
}
h1,h2,h3,h4 {
text-align: center;
}
#addBtn {
float: right;
}
</style>
</head>
<body>
<h3>Список последних ошибок</h3>
<table>
<thead>
<tr>
<th>Индекс</th>
<th>Хост</th>
<th>Ошибка</th>
<th><a href id="allBtn">Все</a></th>
</tr>
</thead>
<tbody id="errorsTable"></tbody>
</table>
<button id="addBtn">Добавить в исключения</button>
<script src="./index.js"></script>
</body>
</html>

View File

@ -0,0 +1,75 @@
'use strict';
chrome.runtime.getBackgroundPage( (bgWindow) =>
bgWindow.apis.errorHandlers.installListenersOn(
window, 'LERR', () => {
const tbody = document.getElementById('errorsTable');
const errors = bgWindow.apis.lastErrors.get().map(
({url, error}, index) => ({ message: error, hostname: new URL(url).hostname, ifChecked: false })
);
const renderTbody = () => {
const exc = bgWindow.apis.pacKitchen.getPacMods().exceptions || {};
tbody.innerHTML = '';
errors.forEach((err, index) => {
const ifProxy = exc[err.hostname];
let style = '';
if (ifProxy !== undefined) {
style = `style="color: ${ifProxy ? 'green' : 'red' }"`;
}
const tr = document.createElement('tr');
tr.innerHTML = `
<td>${index}</td>
<td ${style}>${err.hostname}</td>
<td>${err.message}</td>
<td><input type="checkbox" ${ err.ifChecked ? 'checked' : '' }></td>
`;
tr.querySelector('input').onchange = function() {
errors[index].ifChecked = this.checked;
return false;
};
tbody.appendChild(tr);
});
};
document.getElementById('allBtn').onclick = () => {
const ifAllChecked = errors.every((err) => err.ifChecked);
if (ifAllChecked) {
errors.forEach((err) => { err.ifChecked = false; })
} else {
errors.forEach((err) => { err.ifChecked = true; })
}
renderTbody();
return false;
};
document.getElementById('addBtn').onclick = () => {
const mutatedMods = bgWindow.apis.pacKitchen.getPacMods();
const exc = mutatedMods.exceptions || {};
mutatedMods.exceptions = errors.reduce((acc, err) => {
if (err.ifChecked) {
acc[err.hostname] = true;
}
return acc;
}, exc);
bgWindow.apis.pacKitchen.keepCookedNowAsync(mutatedMods, (err) => alert(err || 'Сделано!'));
};
renderTbody();
document.documentElement.style.display = '';
})
);

View File

@ -62,7 +62,21 @@ export default function getExceptions(theState) {
})
}
<li><input type="checkbox" style="visibility: hidden"/><a href>Смотреть последние ошибки</a></li>
<InfoLi
type="checkbox"
conf={{
key: 'lookupLastErrors',
desc: 'Собирать последние ошибки в запросах, чтобы вручную добавлять избранные из них в исключения.',
value: props.bgWindow.apis.lastErrors.ifCollecting
}}
onChange={(event) => {
props.bgWindow.apis.lastErrors.ifCollecting = event.target.checked;
props.funs.setStatusTo('Сделано.');
}}
nodeAfterLabel={(<span>Собирать <a href="../errors-to-exc/index.html">последние ошибки</a> сайтов</span>)}
/>
</ul>
</div>
);

View File

@ -1,4 +1,5 @@
import Inferno from 'inferno';
import createElement from 'inferno-create-element';
import css from 'csjs-inject';
export default function getInfoLi() {
@ -119,18 +120,10 @@ export default function getInfoLi() {
const iddy = props.idPrefix + ( props.ifDashify ? camelToDash(props.conf.key) : props.conf.key );
return (
<li class={scopedCss.infoRow + ' horFlex'} style={ props.children && 'flex-wrap: wrap'}>
<input
type={props.type}
name={props.name}
checked={props.checked}
id={iddy}
onClick={props.onClick}
onChange={props.onChange}
disabled={props.disabled}
/>
{ createElement('input', Object.assign({}, props, {id: iddy})) }
<div class={scopedCss.labelContainer}>
<label for={iddy} dangerouslySetInnerHTML={{__html: props.conf.label}}></label>
&nbsp;{props.nodeAfterLabel}
{props.nodeAfterLabel}
</div>
{props.conf.desc
? (

View File

@ -28,6 +28,7 @@ export default function getPacChooser(theState) {
.updateButton {
visibility: hidden;
margin-left: 0.5em;
}
input:checked + div .updateButton {
visibility: inherit;

View File

@ -1,10 +1,6 @@
'use strict';
/*
window.chrome.browserAction.setBadgeBackgroundColor({
color: '#db4b2f',
});
*/
{
chrome.webNavigation.onErrorOccurred.addListener((details) => {
@ -36,3 +32,4 @@ chrome.webNavigation.onErrorOccurred.addListener((details) => {
});
}

View File

@ -0,0 +1,36 @@
'use strict';
{
const lastErrors = [];
const lastErrorsLength = 20;
const that = window.apis.lastErrors = {
ifCollecting: false,
get: () => lastErrors,
}
chrome.webRequest.onErrorOccurred.addListener((details) => {
if (!that.ifCollecting || [
'net::ERR_BLOCKED_BY_CLIENT',
'net::ERR_ABORTED',
].includes(details.error) ) {
return;
}
const last = lastErrors[0];
if (last && details.error === last.error && details.url === last.url) {
// Dup.
return;
}
lastErrors.unshift(details);
if (lastErrors.length > lastErrorsLenght) {
lastErrors.pop();
}
},
{urls: ['<all_urls>']}
);
}

View File

@ -13,7 +13,7 @@ exports.contexts.full = Object.assign({}, commonContext, {
extra_permissions: ', "webRequest", "webNavigation"',
persistent: '',
scripts_2x: ', "20-ip-to-host-api.js"',
scripts_8x: ', "80-error-menu.js", "85-block-informer.js"',
scripts_8x: ', "80-error-menu.js", "83-last-errors.js", "85-block-informer.js"',
});
exports.contexts.mini = Object.assign({}, commonContext, {