mirror of
https://github.com/gorhill/uBlock.git
synced 2024-11-21 18:02:34 +01:00
[mv3] Add a _chat_ icon in popup panel to report filter issues
Just the same as with uBO, but for uBOL.
This commit is contained in:
parent
dcb86e3667
commit
560def639f
@ -31,6 +31,10 @@
|
||||
"message": "filtering mode",
|
||||
"description": "Label in the popup panel for the current filtering mode"
|
||||
},
|
||||
"popupTipReport": {
|
||||
"message": "Report an issue on this website",
|
||||
"description": "Tooltip used for the 'chat' icon in the panel"
|
||||
},
|
||||
"popupTipDashboard": {
|
||||
"message": "Open the dashboard",
|
||||
"description": "English: Click to open the dashboard"
|
||||
@ -99,6 +103,70 @@
|
||||
"message": "External dependencies (GPLv3-compatible):",
|
||||
"description": "Shown in the About pane"
|
||||
},
|
||||
"supportS6H": {
|
||||
"message": "Report a filter issue",
|
||||
"description": "Header of 'Report a filter issue' section in Support pane"
|
||||
},
|
||||
"supportS3P1": {
|
||||
"message": "Report filter issues with specific websites to the <span data-url=\"https://github.com/uBlockOrigin/uAssets/issues?q=is%3Aissue\"><code>uBlockOrigin/uAssets</code> issue tracker</span>. <u>Requires a GitHub account.</u>",
|
||||
"description": "First paragraph of 'Filter issues' section in Support pane"
|
||||
},
|
||||
"supportS6P1S1": {
|
||||
"message": "To avoid burdening volunteers with duplicate reports, please verify that the issue has not already been reported.",
|
||||
"description": "A paragraph in the filter issue reporter section"
|
||||
},
|
||||
"supportFindSpecificButton": {
|
||||
"message": "Find similar reports",
|
||||
"description": "A clickable link in the filter issue reporter section"
|
||||
},
|
||||
"supportS6URL": {
|
||||
"message": "Address of the webpage:",
|
||||
"description": "Label for the URL of the page"
|
||||
},
|
||||
"supportS6Select1": {
|
||||
"message": "The webpage…",
|
||||
"description": "Label for widget to select type of issue"
|
||||
},
|
||||
"supportS6Select1Option0": {
|
||||
"message": "-- Pick an entry --",
|
||||
"description": "An entry in the widget used to select the type of issue"
|
||||
},
|
||||
"supportS6Select1Option1": {
|
||||
"message": "Shows ads or ad leftovers",
|
||||
"description": "An entry in the widget used to select the type of issue"
|
||||
},
|
||||
"supportS6Select1Option2": {
|
||||
"message": "Has overlays or other nuisances",
|
||||
"description": "An entry in the widget used to select the type of issue"
|
||||
},
|
||||
"supportS6Select1Option3": {
|
||||
"message": "Detects uBO Lite",
|
||||
"description": "An entry in the widget used to select the type of issue"
|
||||
},
|
||||
"supportS6Select1Option4": {
|
||||
"message": "Has privacy-related issues",
|
||||
"description": "An entry in the widget used to select the type of issue"
|
||||
},
|
||||
"supportS6Select1Option5": {
|
||||
"message": "Malfunctions when uBO Lite is enabled",
|
||||
"description": "An entry in the widget used to select the type of issue"
|
||||
},
|
||||
"supportS6Select1Option6": {
|
||||
"message": "Opens unwanted tabs or windows",
|
||||
"description": "An entry in the widget used to select the type of issue"
|
||||
},
|
||||
"supportS6Select1Option7": {
|
||||
"message": "Leads to badware, phishing",
|
||||
"description": "An entry in the widget used to select the type of issue"
|
||||
},
|
||||
"supportS6Checkbox1": {
|
||||
"message": "Label the webpage as “NSFW” (<a href=\"https://wikipedia.org/wiki/Not_safe_for_work\">“Not Safe For Work”</a>)",
|
||||
"description": "A checkbox to use for NSFW sites"
|
||||
},
|
||||
"supportReportSpecificButton": {
|
||||
"message": "Create new report",
|
||||
"description": "Text for button which open an external webpage in Support pane"
|
||||
},
|
||||
"firstRunSectionLabel": {
|
||||
"message": "Welcome",
|
||||
"description": "The header text for the welcome message section"
|
||||
|
@ -1,3 +1,14 @@
|
||||
body {
|
||||
align-items: center;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 0 var(--default-gap-xxsmall);
|
||||
}
|
||||
body > * {
|
||||
width: min(640px, 100%);
|
||||
}
|
||||
|
||||
h2, h3 {
|
||||
margin: 1em 0;
|
||||
}
|
||||
@ -7,9 +18,11 @@ h2 {
|
||||
h3 {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.fa-icon.info {
|
||||
color: var(--info0-ink);
|
||||
fill: var(--info0-ink);
|
||||
|
@ -1,12 +1,3 @@
|
||||
body {
|
||||
align-items: center;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
body > * {
|
||||
width: min(640px, 100%);
|
||||
}
|
||||
#dashboard-nav {
|
||||
background-color: var(--surface-1);
|
||||
border: 0;
|
||||
|
@ -22,10 +22,6 @@ p {
|
||||
white-space: pre-line;
|
||||
}
|
||||
|
||||
section > div {
|
||||
padding: 0 var(--default-gap-xxsmall);
|
||||
}
|
||||
|
||||
#showBlockedCount:has(input[type="checkbox"][disabled]) {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
@ -145,6 +145,36 @@ async function onPermissionsRemoved() {
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
async function gotoURL(url, type) {
|
||||
const pageURL = new URL(url, runtime.getURL('/'));
|
||||
const tabs = await browser.tabs.query({
|
||||
url: pageURL.href,
|
||||
windowType: type !== 'popup' ? 'normal' : 'popup'
|
||||
});
|
||||
|
||||
if ( Array.isArray(tabs) && tabs.length !== 0 ) {
|
||||
const { windowId, id } = tabs[0];
|
||||
return Promise.all([
|
||||
browser.windows.update(windowId, { focused: true }),
|
||||
browser.tabs.update(id, { active: true }),
|
||||
]);
|
||||
}
|
||||
|
||||
if ( type === 'popup' ) {
|
||||
return windows.create({
|
||||
type: 'popup',
|
||||
url: pageURL.href,
|
||||
});
|
||||
}
|
||||
|
||||
return browser.tabs.create({
|
||||
active: true,
|
||||
url: pageURL.href,
|
||||
});
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
function onMessage(request, sender, callback) {
|
||||
|
||||
// Does not require trusted origin.
|
||||
@ -265,6 +295,10 @@ function onMessage(request, sender, callback) {
|
||||
return true;
|
||||
}
|
||||
|
||||
case 'gotoURL':
|
||||
gotoURL(request.url, request.type);
|
||||
break;
|
||||
|
||||
case 'setFilteringMode': {
|
||||
getFilteringMode(request.hostname).then(actualLevel => {
|
||||
if ( request.level === actualLevel ) { return actualLevel; }
|
||||
@ -276,6 +310,13 @@ function onMessage(request, sender, callback) {
|
||||
return true;
|
||||
}
|
||||
|
||||
case 'getDefaultFilteringMode': {
|
||||
getDefaultFilteringMode().then(level => {
|
||||
callback(level);
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
case 'setDefaultFilteringMode': {
|
||||
getDefaultFilteringMode().then(beforeLevel =>
|
||||
setDefaultFilteringMode(request.level).then(afterLevel =>
|
||||
|
@ -261,12 +261,6 @@ dom.on('#lessButton', 'click', ( ) => {
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
dom.on('[data-i18n-title="popupTipDashboard"]', 'click', ev => {
|
||||
if ( ev.isTrusted !== true ) { return; }
|
||||
if ( ev.button !== 0 ) { return; }
|
||||
runtime.openOptionsPage();
|
||||
});
|
||||
|
||||
dom.on('#showMatchedRules', 'click', ev => {
|
||||
if ( ev.isTrusted !== true ) { return; }
|
||||
if ( ev.button !== 0 ) { return; }
|
||||
@ -278,6 +272,33 @@ dom.on('#showMatchedRules', 'click', ev => {
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
dom.on('[data-i18n-title="popupTipReport"]', 'click', ev => {
|
||||
if ( ev.isTrusted !== true ) { return; }
|
||||
let url;
|
||||
try {
|
||||
url = new URL(currentTab.url);
|
||||
} catch(_) {
|
||||
}
|
||||
if ( url === undefined ) { return; }
|
||||
const reportURL = new URL(runtime.getURL('/report.html'));
|
||||
reportURL.searchParams.set('url', url.href);
|
||||
reportURL.searchParams.set('mode', popupPanelData.level);
|
||||
sendMessage({
|
||||
what: 'gotoURL',
|
||||
url: `${reportURL.pathname}${reportURL.search}`,
|
||||
});
|
||||
});
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
dom.on('[data-i18n-title="popupTipDashboard"]', 'click', ev => {
|
||||
if ( ev.isTrusted !== true ) { return; }
|
||||
if ( ev.button !== 0 ) { return; }
|
||||
runtime.openOptionsPage();
|
||||
});
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
async function init() {
|
||||
const [ tab ] = await browser.tabs.query({
|
||||
active: true,
|
||||
@ -314,6 +335,10 @@ async function init() {
|
||||
isNaN(currentTab.id) === false
|
||||
);
|
||||
|
||||
dom.cl.toggle('#reportFilterIssue', 'enabled',
|
||||
/^https?:\/\//.test(url?.href)
|
||||
);
|
||||
|
||||
const parent = qs$('#rulesetStats');
|
||||
for ( const details of popupPanelData.rulesetDetails || [] ) {
|
||||
const div = dom.clone('#templates .rulesetDetails');
|
||||
|
155
platform/mv3/extension/js/report.js
Normal file
155
platform/mv3/extension/js/report.js
Normal file
@ -0,0 +1,155 @@
|
||||
/*******************************************************************************
|
||||
|
||||
uBlock Origin - a comprehensive, efficient content blocker
|
||||
Copyright (C) 2024-present Raymond Hill
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||
|
||||
Home: https://github.com/gorhill/uBlock
|
||||
*/
|
||||
|
||||
import { dnr, runtime } from './ext.js';
|
||||
import { dom, qs$ } from './dom.js';
|
||||
import { sendMessage } from './ext.js';
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
const reportedPage = (( ) => {
|
||||
const url = new URL(window.location.href);
|
||||
try {
|
||||
const pageURL = url.searchParams.get('url');
|
||||
if ( pageURL === null ) { return null; }
|
||||
const parsedURL = new URL(pageURL);
|
||||
parsedURL.username = '';
|
||||
parsedURL.password = '';
|
||||
parsedURL.hash = '';
|
||||
const select = qs$('select[name="url"]');
|
||||
dom.text(select.options[0], parsedURL.href);
|
||||
if ( parsedURL.search !== '' ) {
|
||||
const option = dom.create('option');
|
||||
parsedURL.search = '';
|
||||
dom.text(option, parsedURL.href);
|
||||
select.append(option);
|
||||
}
|
||||
if ( parsedURL.pathname !== '/' ) {
|
||||
const option = dom.create('option');
|
||||
parsedURL.pathname = '';
|
||||
dom.text(option, parsedURL.href);
|
||||
select.append(option);
|
||||
}
|
||||
return {
|
||||
hostname: parsedURL.hostname.replace(/^(m|mobile|www)\./, ''),
|
||||
mode: url.searchParams.get('mode'),
|
||||
};
|
||||
} catch(ex) {
|
||||
}
|
||||
return null;
|
||||
})();
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
function reportSpecificFilterType() {
|
||||
return qs$('select[name="type"]').value;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
function renderData(data, depth = 0) {
|
||||
const indent = ' '.repeat(depth);
|
||||
if ( Array.isArray(data) ) {
|
||||
const out = [];
|
||||
for ( const value of data ) {
|
||||
out.push(renderData(value, depth));
|
||||
}
|
||||
return out.join('\n');
|
||||
}
|
||||
if ( typeof data !== 'object' || data === null ) {
|
||||
return `${indent}${data}`;
|
||||
}
|
||||
const out = [];
|
||||
for ( const [ name, value ] of Object.entries(data) ) {
|
||||
if ( typeof value === 'object' && value !== null ) {
|
||||
out.push(`${indent}${name}:`);
|
||||
out.push(renderData(value, depth + 1));
|
||||
continue;
|
||||
}
|
||||
out.push(`${indent}${name}: ${value}`);
|
||||
}
|
||||
return out.join('\n');
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
async function reportSpecificFilterIssue() {
|
||||
const githubURL = new URL(
|
||||
'https://github.com/uBlockOrigin/uAssets/issues/new?template=specific_report_from_ubol.yml'
|
||||
);
|
||||
const issueType = reportSpecificFilterType();
|
||||
let title = `${reportedPage.hostname}: ${issueType}`;
|
||||
if ( qs$('#isNSFW').checked ) {
|
||||
title = `[nsfw] ${title}`;
|
||||
}
|
||||
githubURL.searchParams.set('title', title);
|
||||
githubURL.searchParams.set(
|
||||
'url_address_of_the_web_page',
|
||||
'`' + qs$('select[name="url"]').value + '`'
|
||||
);
|
||||
githubURL.searchParams.set('category', issueType);
|
||||
githubURL.searchParams.set('labels', 'uBOL');
|
||||
|
||||
const manifest = runtime.getManifest();
|
||||
const rulesets = await dnr.getEnabledRulesets();
|
||||
const defaultMode = await sendMessage({ what: 'getDefaultFilteringMode' });
|
||||
const modes = [ 'no filtering', 'basic', 'optimal', 'complete' ];
|
||||
const config = {
|
||||
version: `uBOL ${manifest.version}`,
|
||||
mode: `${modes[reportedPage.mode]} / ${modes[defaultMode]}`,
|
||||
rulesets,
|
||||
};
|
||||
const configBody = [
|
||||
'```yaml',
|
||||
renderData(config),
|
||||
'```',
|
||||
'',
|
||||
].join('\n');
|
||||
githubURL.searchParams.set('configuration', configBody);
|
||||
sendMessage({ what: 'gotoURL', url: githubURL.href });
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
(async ( ) => {
|
||||
dom.on('[data-url]', 'click', ev => {
|
||||
const elem = ev.target.closest('[data-url]');
|
||||
const url = dom.attr(elem, 'data-url');
|
||||
if ( typeof url !== 'string' || url === '' ) { return; }
|
||||
sendMessage({ what: 'gotoURL', url });
|
||||
ev.preventDefault();
|
||||
});
|
||||
|
||||
if ( reportedPage !== null ) {
|
||||
dom.on('[data-i18n="supportReportSpecificButton"]', 'click', ev => {
|
||||
reportSpecificFilterIssue();
|
||||
ev.preventDefault();
|
||||
});
|
||||
|
||||
dom.on('[data-i18n="supportFindSpecificButton"]', 'click', ev => {
|
||||
const url = new URL('https://github.com/uBlockOrigin/uAssets/issues');
|
||||
url.searchParams.set('q', `is:issue sort:updated-desc "${reportedPage.hostname}" in:title`);
|
||||
sendMessage({ what: 'gotoURL', url: url.href });
|
||||
ev.preventDefault();
|
||||
});
|
||||
}
|
||||
|
||||
})();
|
@ -7,7 +7,6 @@
|
||||
<link rel="stylesheet" href="css/default.css">
|
||||
<link rel="stylesheet" href="css/common.css">
|
||||
<link rel="stylesheet" href="css/fa-icons.css">
|
||||
<link rel="stylesheet" href="css/dashboard-common.css">
|
||||
<link rel="stylesheet" href="css/matched-rules.css">
|
||||
|
||||
<link rel="shortcut icon" type="image/png" href="img/icon_64.png"/>
|
||||
|
@ -13,6 +13,7 @@
|
||||
</head>
|
||||
|
||||
<body class="loading" data-section="">
|
||||
|
||||
<div id="main">
|
||||
<div id="hostname"><span></span>­<span></span></div>
|
||||
<!-- -------- -->
|
||||
@ -30,6 +31,7 @@
|
||||
<span></span>
|
||||
<span></span>
|
||||
<span id="showMatchedRules" class="fa-icon tool" tabindex="0" title="Show matched rules">list-alt<span class="caption">Show matched rules</span></span>
|
||||
<span id="reportFilterIssue" class="fa-icon tool enabled" data-i18n-title="popupTipReport">comment-alt<span class="caption" data-i18n="popupTipReport"></span></span>
|
||||
<span class="fa-icon tool enabled" tabindex="0" data-i18n-title="popupTipDashboard">cogs<span class="caption" data-i18n="popupTipDashboard"></span></span>
|
||||
</div>
|
||||
<!-- -------- -->
|
||||
|
61
platform/mv3/extension/report.html
Normal file
61
platform/mv3/extension/report.html
Normal file
@ -0,0 +1,61 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>uBO Lite — Report</title>
|
||||
|
||||
<link rel="stylesheet" href="css/default.css">
|
||||
<link rel="stylesheet" href="css/common.css">
|
||||
<link rel="stylesheet" href="css/dashboard-common.css">
|
||||
<link rel="stylesheet" href="css/fa-icons.css">
|
||||
<link rel="shortcut icon" type="image/png" href="img/icon_64.png">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<section>
|
||||
|
||||
<h3 data-i18n="supportS6H"></h3>
|
||||
<p data-i18n="supportS3P1"></p>
|
||||
<div class="supportEntry">
|
||||
<hr>
|
||||
<p data-i18n="supportS6P1S1"></p>
|
||||
<button type="button" data-i18n="supportFindSpecificButton">_<span class="hover"></span></button>
|
||||
</div>
|
||||
<div class="supportEntry createEntry">
|
||||
<hr>
|
||||
<p>
|
||||
<label data-i18n="supportS6URL"></label><br>
|
||||
<select name="url">
|
||||
<option></option>
|
||||
</select>
|
||||
</p>
|
||||
<p>
|
||||
<label data-i18n="supportS6Select1"></label><br>
|
||||
<select name="type">
|
||||
<option value="[unknown]" data-i18n="supportS6Select1Option0" selected disabled></option>
|
||||
<option value="ads" data-i18n="supportS6Select1Option1"></option>
|
||||
<option value="detection" data-i18n="supportS6Select1Option3"></option>
|
||||
<option value="popups" data-i18n="supportS6Select1Option6"></option>
|
||||
<option value="nuisance" data-i18n="supportS6Select1Option2"></option>
|
||||
<option value="breakage" data-i18n="supportS6Select1Option5"></option>
|
||||
<option value="privacy" data-i18n="supportS6Select1Option4"></option>
|
||||
<option value="badware" data-i18n="supportS6Select1Option7"></option>
|
||||
</select>
|
||||
</p>
|
||||
<p>
|
||||
<label><span class="input checkbox"><input id="isNSFW" type="checkbox"><svg viewBox="0 0 24 24"><path d="M1.73,12.91 8.1,19.28 22.79,4.59"/></svg></span><span data-i18n="supportS6Checkbox1"></span></label>
|
||||
</p>
|
||||
<button type="button" data-i18n="supportReportSpecificButton" class="preferred">_<span class="hover"></span></button>
|
||||
</div>
|
||||
|
||||
</section>
|
||||
|
||||
<script src="js/theme.js" type="module"></script>
|
||||
<script src="js/fa-icons.js" type="module"></script>
|
||||
<script src="js/i18n.js" type="module"></script>
|
||||
<script src="js/report.js" type="module"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user