Backed out changeset 0f21091f77ec (bug 1952334) for causing bc failures @browser_all_files_referenced.js. CLOSED TREE
This commit is contained in:
@@ -455,6 +455,7 @@ const rollouts = [
|
||||
"browser/extensions/formautofill/**",
|
||||
"browser/extensions/newtab/**",
|
||||
"browser/extensions/pictureinpicture/**",
|
||||
"browser/extensions/report-site-issue/test/browser/head.js",
|
||||
"browser/extensions/search-detection/extension/background.js",
|
||||
"browser/extensions/webcompat/**",
|
||||
"browser/fxr/content/permissions.js",
|
||||
@@ -1076,6 +1077,10 @@ const rollouts = [
|
||||
"browser/components/urlbar/tests/quicksuggest/browser/browser_quicksuggest_indexes.js",
|
||||
"browser/extensions/formautofill/test/browser/browser_dropdown_layout.js",
|
||||
"browser/extensions/formautofill/test/browser/creditCard/browser_anti_clickjacking.js",
|
||||
"browser/extensions/report-site-issue/test/browser/browser_button_state.js",
|
||||
"browser/extensions/report-site-issue/test/browser/browser_disabled_cleanup.js",
|
||||
"browser/extensions/report-site-issue/test/browser/browser_report_site_issue.js",
|
||||
"browser/extensions/report-site-issue/test/browser/head.js",
|
||||
"browser/extensions/webcompat/tests/browser/head.js",
|
||||
"browser/modules/test/browser/browser_PageActions.js",
|
||||
"browser/modules/test/browser/browser_PageActions_contextMenus.js",
|
||||
|
||||
@@ -131,6 +131,7 @@ const extraBrowserTestPaths = [
|
||||
"browser/components/shell/test/",
|
||||
"browser/components/touchbar/tests/",
|
||||
"browser/components/uitour/test/",
|
||||
"browser/extensions/report-site-issue/test/browser/",
|
||||
"browser/tools/mozscreenshots/",
|
||||
"caps/tests/mochitest/",
|
||||
"devtools/client/debugger/test/mochitest/",
|
||||
|
||||
@@ -142,7 +142,7 @@
|
||||
class="subviewbutton subviewbutton-nav"
|
||||
data-l10n-id="appmenuitem-report-broken-site"
|
||||
closemenu="none"
|
||||
disabled="true"
|
||||
hidden="true"
|
||||
command="cmd_reportBrokenSite"/>
|
||||
<toolbarbutton id="appMenu-help-button2"
|
||||
class="subviewbutton subviewbutton-nav"
|
||||
|
||||
@@ -426,7 +426,7 @@
|
||||
<menuitem id="help_reportBrokenSite"
|
||||
command="cmd_reportBrokenSite"
|
||||
data-l10n-id="menu-report-broken-site"
|
||||
disabled="true"
|
||||
hidden="true"
|
||||
appmenu-data-l10n-id="menu-report-broken-site"/>
|
||||
<menuitem id="feedbackPage"
|
||||
data-l10n-id="menu-help-share-ideas"
|
||||
@@ -437,6 +437,10 @@
|
||||
<menuitem id="troubleShooting"
|
||||
data-l10n-id="menu-help-more-troubleshooting-info"
|
||||
appmenu-data-l10n-id="appmenu-help-more-troubleshooting-info"/>
|
||||
<menuitem id="help_reportSiteIssue"
|
||||
data-l10n-id="menu-help-report-site-issue"
|
||||
appmenu-data-l10n-id="appmenu-help-report-site-issue"
|
||||
hidden="true"/>
|
||||
<menuitem id="menu_HelpPopup_reportPhishingtoolmenu"
|
||||
disabled="true"
|
||||
hidden="true"
|
||||
|
||||
@@ -85,6 +85,9 @@ document.addEventListener(
|
||||
case "troubleShooting":
|
||||
openTroubleshootingPage();
|
||||
break;
|
||||
case "help_reportSiteIssue":
|
||||
ReportSiteIssue();
|
||||
break;
|
||||
case "menu_HelpPopup_reportPhishingtoolmenu":
|
||||
openUILink(gSafeBrowsing.getReportURL("Phish"), event, {
|
||||
triggeringPrincipal:
|
||||
|
||||
@@ -4951,6 +4951,22 @@ function undoCloseWindow(aIndex) {
|
||||
return window;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a temporary hack to connect a Help menu item for reporting
|
||||
* site issues to the WebCompat team's Site Compatability Reporter
|
||||
* WebExtension, which ships by default and is enabled on pre-release
|
||||
* channels.
|
||||
*
|
||||
* Once we determine if Help is the right place for it, we'll do something
|
||||
* slightly better than this.
|
||||
*
|
||||
* See bug 1690573.
|
||||
*/
|
||||
function ReportSiteIssue() {
|
||||
let subject = { wrappedJSObject: gBrowser.selectedTab };
|
||||
Services.obs.notifyObservers(subject, "report-site-issue");
|
||||
}
|
||||
|
||||
/**
|
||||
* When the browser is being controlled from out-of-process,
|
||||
* e.g. when Marionette or the remote debugging protocol is used,
|
||||
|
||||
@@ -85,6 +85,7 @@
|
||||
"restoreLastClosedTabOrWindowOrSession",
|
||||
"undoCloseTab",
|
||||
"undoCloseWindow",
|
||||
"ReportSiteIssue",
|
||||
"gRemoteControl",
|
||||
"gPrivateBrowsingUI",
|
||||
"switchToTabHavingURI",
|
||||
|
||||
@@ -479,7 +479,14 @@ function parseManifest(manifestUri) {
|
||||
let [type, ...argv] = line.split(/\s+/);
|
||||
if (type == "content" || type == "skin" || type == "locale") {
|
||||
let chromeUri = `chrome://${argv[0]}/${type}/`;
|
||||
// The webcompat reporter's locale directory may not exist if
|
||||
// the addon is preffed-off, and since it's a hack until we
|
||||
// get bz1425104 landed, we'll just skip it for now.
|
||||
if (chromeUri === "chrome://report-site-issue/locale/") {
|
||||
gChromeMap.set("chrome://report-site-issue/locale/", true);
|
||||
} else {
|
||||
trackChromeUri(chromeUri);
|
||||
}
|
||||
} else if (type == "override" || type == "overlay") {
|
||||
// Overlays aren't really overrides, but behave the same in
|
||||
// that the overlay is only referenced if the original xul
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
command="cmd_reportBrokenSite"
|
||||
class="subviewbutton subviewbutton-nav"
|
||||
data-l10n-id="protections-panel-report-broken-site"
|
||||
disabled="true"
|
||||
hidden="true"
|
||||
closemenu="none"/>
|
||||
|
||||
<!-- Tracking Protection Section -->
|
||||
|
||||
@@ -745,6 +745,9 @@ const PanelUI = {
|
||||
case "appMenu_troubleShooting":
|
||||
openTroubleshootingPage();
|
||||
break;
|
||||
case "appMenu_help_reportSiteIssue":
|
||||
ReportSiteIssue();
|
||||
break;
|
||||
case "appMenu_menu_HelpPopup_reportPhishingtoolmenu":
|
||||
openUILink(gSafeBrowsing.getReportURL("Phish"), aEvent, {
|
||||
triggeringPrincipal:
|
||||
|
||||
@@ -294,6 +294,7 @@ export var ReportBrokenSite = new (class ReportBrokenSite {
|
||||
static SEND_MORE_INFO_PREF = "ui.new-webcompat-reporter.send-more-info-link";
|
||||
static NEW_REPORT_ENDPOINT_PREF =
|
||||
"ui.new-webcompat-reporter.new-report-endpoint";
|
||||
static REPORT_SITE_ISSUE_PREF = "extensions.webcompat-reporter.enabled";
|
||||
|
||||
static MAIN_PANELVIEW_ID = "report-broken-site-popup-mainView";
|
||||
static SENT_PANELVIEW_ID = "report-broken-site-popup-reportSentView";
|
||||
@@ -336,6 +337,10 @@ export var ReportBrokenSite = new (class ReportBrokenSite {
|
||||
DEFAULT_NEW_REPORT_ENDPOINT,
|
||||
],
|
||||
enabledPref: [ReportBrokenSite.REPORTER_ENABLED_PREF, true],
|
||||
reportSiteIssueEnabledPref: [
|
||||
ReportBrokenSite.REPORT_SITE_ISSUE_PREF,
|
||||
false,
|
||||
],
|
||||
})) {
|
||||
XPCOMUtils.defineLazyPreferenceGetter(
|
||||
this,
|
||||
@@ -358,8 +363,9 @@ export var ReportBrokenSite = new (class ReportBrokenSite {
|
||||
|
||||
updateParentMenu(event) {
|
||||
// We need to make sure that the Report Broken Site menu item
|
||||
// is disabled if the tab's location changes to a non-reportable
|
||||
// one while the menu is open.
|
||||
// is disabled and/or hidden depending on the prefs/active tab URL
|
||||
// when our parent popups are shown, and if their tab's location
|
||||
// changes while they are open.
|
||||
const tabbrowser = event.target.ownerGlobal.gBrowser;
|
||||
this.enableOrDisableMenuitems(tabbrowser.selectedBrowser);
|
||||
|
||||
@@ -420,63 +426,48 @@ export var ReportBrokenSite = new (class ReportBrokenSite {
|
||||
win.document
|
||||
.getElementById("cmd_reportBrokenSite")
|
||||
.addEventListener("command", e => {
|
||||
if (this.enabled) {
|
||||
this.open(e);
|
||||
} else {
|
||||
const tabbrowser = e.target.ownerGlobal.gBrowser;
|
||||
state.resetURLToCurrentTab();
|
||||
state.currentTabWebcompatDetailsPromise = this.#queryActor(
|
||||
"GetWebCompatInfo",
|
||||
undefined,
|
||||
tabbrowser.selectedBrowser
|
||||
);
|
||||
this.#openWebCompatTab(tabbrowser)
|
||||
.catch(err => {
|
||||
console.error("Report Broken Site: unexpected error", err);
|
||||
})
|
||||
.finally(() => {
|
||||
state.reset();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
enableOrDisableMenuitems(selectedbrowser) {
|
||||
// Ensures that the various Report Broken Site menu items and
|
||||
// toolbar buttons are disabled when appropriate.
|
||||
// toolbar buttons are enabled/hidden when appropriate (and
|
||||
// also the Help menu's Report Site Issue item)/
|
||||
|
||||
const canReportUrl = this.canReportURI(selectedbrowser.currentURI);
|
||||
|
||||
const { document } = selectedbrowser.ownerGlobal;
|
||||
|
||||
// Altering the disabled attribute on the command does not propagate
|
||||
// the change to the related menuitems (see bug 805653), so we change them all.
|
||||
const cmd = document.getElementById("cmd_reportBrokenSite");
|
||||
const app = document.ownerGlobal.PanelMultiView.getViewNode(
|
||||
document,
|
||||
"appMenu-report-broken-site-button"
|
||||
);
|
||||
// Note that this element does not exist until the protections popup is actually opened.
|
||||
const prot = document.getElementById(
|
||||
"protections-popup-report-broken-site-button"
|
||||
);
|
||||
if (this.enabled) {
|
||||
cmd.setAttribute("hidden", "false"); // see bug 805653
|
||||
} else {
|
||||
cmd.setAttribute("hidden", "true");
|
||||
}
|
||||
if (canReportUrl) {
|
||||
cmd.removeAttribute("disabled");
|
||||
app.removeAttribute("disabled");
|
||||
prot?.removeAttribute("disabled");
|
||||
} else {
|
||||
cmd.setAttribute("disabled", "true");
|
||||
app.setAttribute("disabled", "true");
|
||||
prot?.setAttribute("disabled", "true");
|
||||
}
|
||||
|
||||
// Changes to the "disabled" state of the command aren't reliably
|
||||
// Changes to the "hidden" and "disabled" state of the command aren't reliably
|
||||
// reflected on the main menu unless we open it twice, or do it manually.
|
||||
// (See bug 1864953).
|
||||
const mainmenuItem = document.getElementById("help_reportBrokenSite");
|
||||
if (mainmenuItem) {
|
||||
mainmenuItem.hidden = !this.enabled;
|
||||
mainmenuItem.disabled = !canReportUrl;
|
||||
}
|
||||
|
||||
// Report Site Issue is our older issue reporter, shown in the Help
|
||||
// menu on pre-release channels. We should hide it unless we're
|
||||
// disabled, at which point we should show it when available.
|
||||
const reportSiteIssue = document.getElementById("help_reportSiteIssue");
|
||||
if (reportSiteIssue) {
|
||||
reportSiteIssue.hidden = this.enabled || !this.reportSiteIssueEnabledPref;
|
||||
reportSiteIssue.disabled = !canReportUrl;
|
||||
}
|
||||
}
|
||||
|
||||
#checkPrefs(whichChanged) {
|
||||
|
||||
@@ -24,6 +24,8 @@ support-files = [ "send_more_info.js" ]
|
||||
["browser_report_send.js"]
|
||||
support-files = [ "send.js" ]
|
||||
|
||||
["browser_report_site_issue_fallback.js"]
|
||||
|
||||
["browser_send_more_info.js"]
|
||||
support-files = [
|
||||
"send_more_info.js",
|
||||
@@ -33,9 +35,3 @@ support-files = [
|
||||
["browser_tab_key_order.js"]
|
||||
|
||||
["browser_tab_switch_handling.js"]
|
||||
|
||||
["browser_webcompat.com_fallback.js"]
|
||||
support-files = [
|
||||
"send_more_info.js",
|
||||
"../../../../../toolkit/components/gfx/content/videotest.mp4",
|
||||
]
|
||||
|
||||
@@ -12,7 +12,31 @@
|
||||
|
||||
add_common_setup();
|
||||
|
||||
add_task(async function testMenus() {
|
||||
add_task(async function testAppMenuHelpSubmenuItemIsHidden() {
|
||||
ensureReportBrokenSitePreffedOn();
|
||||
const menu = AppMenuHelpSubmenu();
|
||||
await menu.open();
|
||||
isMenuItemHidden(menu.reportBrokenSite);
|
||||
await menu.close();
|
||||
|
||||
ensureReportBrokenSitePreffedOff();
|
||||
await menu.open();
|
||||
isMenuItemHidden(menu.reportBrokenSite);
|
||||
await menu.close();
|
||||
|
||||
await BrowserTestUtils.withNewTab(REPORTABLE_PAGE_URL, async function () {
|
||||
await menu.open();
|
||||
isMenuItemHidden(menu.reportBrokenSite);
|
||||
await menu.close();
|
||||
|
||||
ensureReportBrokenSitePreffedOn();
|
||||
await menu.open();
|
||||
isMenuItemHidden(menu.reportBrokenSite);
|
||||
await menu.close();
|
||||
});
|
||||
});
|
||||
|
||||
add_task(async function testOtherMenus() {
|
||||
ensureReportBrokenSitePreffedOff();
|
||||
|
||||
const appMenu = AppMenu();
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/* Tests that when Report Broken Site is active,
|
||||
* Report Site Issue is hidden.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
add_common_setup();
|
||||
|
||||
async function testDisabledByReportBrokenSite(menu) {
|
||||
ensureReportBrokenSitePreffedOn();
|
||||
ensureReportSiteIssuePreffedOn();
|
||||
|
||||
await menu.open();
|
||||
menu.isReportSiteIssueHidden();
|
||||
await menu.close();
|
||||
}
|
||||
|
||||
async function testDisabledByPref(menu) {
|
||||
ensureReportBrokenSitePreffedOff();
|
||||
ensureReportSiteIssuePreffedOff();
|
||||
|
||||
await menu.open();
|
||||
menu.isReportSiteIssueHidden();
|
||||
await menu.close();
|
||||
}
|
||||
|
||||
async function testDisabledForInvalidURLs(menu) {
|
||||
ensureReportBrokenSitePreffedOff();
|
||||
ensureReportSiteIssuePreffedOn();
|
||||
|
||||
await menu.open();
|
||||
menu.isReportSiteIssueDisabled();
|
||||
await menu.close();
|
||||
}
|
||||
|
||||
async function testEnabledForValidURLs(menu) {
|
||||
ensureReportBrokenSitePreffedOff();
|
||||
ensureReportSiteIssuePreffedOn();
|
||||
|
||||
await BrowserTestUtils.withNewTab(REPORTABLE_PAGE_URL, async function () {
|
||||
await menu.open();
|
||||
menu.isReportSiteIssueEnabled();
|
||||
await menu.close();
|
||||
});
|
||||
}
|
||||
|
||||
// AppMenu help sub-menu
|
||||
|
||||
add_task(async function testDisabledByReportBrokenSiteAppMenuHelpSubmenu() {
|
||||
await testDisabledByReportBrokenSite(AppMenuHelpSubmenu());
|
||||
});
|
||||
|
||||
// disabled for now due to bug 1775402
|
||||
//add_task(async function testDisabledByPrefAppMenuHelpSubmenu() {
|
||||
// await testDisabledByPref(AppMenuHelpSubmenu());
|
||||
//});
|
||||
|
||||
add_task(async function testDisabledForInvalidURLsAppMenuHelpSubmenu() {
|
||||
await testDisabledForInvalidURLs(AppMenuHelpSubmenu());
|
||||
});
|
||||
|
||||
add_task(async function testEnabledForValidURLsAppMenuHelpSubmenu() {
|
||||
await testEnabledForValidURLs(AppMenuHelpSubmenu());
|
||||
});
|
||||
|
||||
// Help menu
|
||||
|
||||
add_task(async function testDisabledByReportBrokenSiteHelpMenu() {
|
||||
await testDisabledByReportBrokenSite(HelpMenu());
|
||||
});
|
||||
|
||||
// disabled for now due to bug 1775402
|
||||
//add_task(async function testDisabledByPrefHelpMenu() {
|
||||
// await testDisabledByPref(HelpMenu());
|
||||
//});
|
||||
|
||||
add_task(async function testDisabledForInvalidURLsHelpMenu() {
|
||||
await testDisabledForInvalidURLs(HelpMenu());
|
||||
});
|
||||
|
||||
add_task(async function testEnabledForValidURLsHelpMenu() {
|
||||
await testEnabledForValidURLs(HelpMenu());
|
||||
});
|
||||
@@ -1,69 +0,0 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/* Tests that when Report Broken Site is disabled, it will
|
||||
* send the user to webcompat.com when clicked and it the
|
||||
* relevant tab's report data.
|
||||
*/
|
||||
|
||||
/* import-globals-from send_more_info.js */
|
||||
|
||||
"use strict";
|
||||
|
||||
Services.scriptloader.loadSubScript(
|
||||
getRootDirectory(gTestPath) + "send_more_info.js",
|
||||
this
|
||||
);
|
||||
|
||||
add_common_setup();
|
||||
|
||||
const VIDEO_URL = `${BASE_URL}/videotest.mp4`;
|
||||
|
||||
add_task(async function testWebcompatComFallbacks() {
|
||||
ensureReportBrokenSitePreffedOff();
|
||||
|
||||
const tab = await openTab(REPORTABLE_PAGE_URL);
|
||||
|
||||
await testWebcompatComFallback(tab, AppMenu());
|
||||
|
||||
await changeTab(tab, REPORTABLE_PAGE_URL2);
|
||||
await testWebcompatComFallback(tab, ProtectionsPanel());
|
||||
|
||||
// also load a video to ensure system codec
|
||||
// information is loaded and properly sent
|
||||
const tab2 = await openTab(VIDEO_URL);
|
||||
await testWebcompatComFallback(tab2, HelpMenu());
|
||||
closeTab(tab2);
|
||||
|
||||
closeTab(tab);
|
||||
});
|
||||
|
||||
async function testMenuDisabledForInvalidURLs(menu) {
|
||||
ensureReportBrokenSitePreffedOff();
|
||||
|
||||
await menu.open();
|
||||
menu.isReportBrokenSiteDisabled();
|
||||
await menu.close();
|
||||
}
|
||||
|
||||
async function testMenuEnabledForValidURLs(menu) {
|
||||
ensureReportBrokenSitePreffedOff();
|
||||
|
||||
await BrowserTestUtils.withNewTab(REPORTABLE_PAGE_URL, async function () {
|
||||
await menu.open();
|
||||
menu.isReportBrokenSiteEnabled();
|
||||
await menu.close();
|
||||
});
|
||||
}
|
||||
|
||||
add_task(async function testDisabledForInvalidURLsHelpMenu() {
|
||||
await testMenuDisabledForInvalidURLs(AppMenu());
|
||||
await testMenuDisabledForInvalidURLs(HelpMenu());
|
||||
await testMenuDisabledForInvalidURLs(ProtectionsPanel());
|
||||
});
|
||||
|
||||
add_task(async function testEnabledForValidURLs() {
|
||||
await testMenuEnabledForValidURLs(AppMenu());
|
||||
await testMenuEnabledForValidURLs(HelpMenu());
|
||||
await testMenuEnabledForValidURLs(ProtectionsPanel());
|
||||
});
|
||||
@@ -30,6 +30,7 @@ const PREFS = {
|
||||
REASON: "ui.new-webcompat-reporter.reason-dropdown",
|
||||
SEND_MORE_INFO: "ui.new-webcompat-reporter.send-more-info-link",
|
||||
NEW_REPORT_ENDPOINT: "ui.new-webcompat-reporter.new-report-endpoint",
|
||||
REPORT_SITE_ISSUE_ENABLED: "extensions.webcompat-reporter.enabled",
|
||||
TOUCH_EVENTS: "dom.w3c_touch_events.enabled",
|
||||
USE_ACCESSIBILITY_THEME: "ui.useAccessibilityTheme",
|
||||
};
|
||||
@@ -156,6 +157,14 @@ function ensureReportBrokenSitePreffedOff() {
|
||||
Services.prefs.setBoolPref(PREFS.REPORTER_ENABLED, false);
|
||||
}
|
||||
|
||||
function ensureReportSiteIssuePreffedOn() {
|
||||
Services.prefs.setBoolPref(PREFS.REPORT_SITE_ISSUE_ENABLED, true);
|
||||
}
|
||||
|
||||
function ensureReportSiteIssuePreffedOff() {
|
||||
Services.prefs.setBoolPref(PREFS.REPORT_SITE_ISSUE_ENABLED, false);
|
||||
}
|
||||
|
||||
function ensureSendMoreInfoEnabled() {
|
||||
Services.prefs.setBoolPref(PREFS.SEND_MORE_INFO, true);
|
||||
}
|
||||
@@ -193,10 +202,6 @@ function isMenuItemDisabled(menuItem, itemDesc) {
|
||||
ok(menuItem.disabled, `${itemDesc} menu item is disabled`);
|
||||
}
|
||||
|
||||
function waitForWebcompatComTab(gBrowser) {
|
||||
return BrowserTestUtils.waitForNewTab(gBrowser, NEW_REPORT_ENDPOINT_TEST_URL);
|
||||
}
|
||||
|
||||
class ReportBrokenSiteHelper {
|
||||
sourceMenu = undefined;
|
||||
win = undefined;
|
||||
@@ -226,18 +231,14 @@ class ReportBrokenSiteHelper {
|
||||
return this.openPanel?.hasAttribute("panelopen");
|
||||
}
|
||||
|
||||
async click(triggerMenuItem) {
|
||||
const window = triggerMenuItem.ownerGlobal;
|
||||
await EventUtils.synthesizeMouseAtCenter(triggerMenuItem, {}, window);
|
||||
}
|
||||
|
||||
async open(triggerMenuItem) {
|
||||
const window = triggerMenuItem.ownerGlobal;
|
||||
const shownPromise = BrowserTestUtils.waitForEvent(
|
||||
this.mainView,
|
||||
"ViewShown"
|
||||
);
|
||||
const focusPromise = BrowserTestUtils.waitForEvent(this.URLInput, "focus");
|
||||
await this.click(triggerMenuItem);
|
||||
await EventUtils.synthesizeMouseAtCenter(triggerMenuItem, {}, window);
|
||||
await shownPromise;
|
||||
await focusPromise;
|
||||
}
|
||||
@@ -287,7 +288,7 @@ class ReportBrokenSiteHelper {
|
||||
}
|
||||
|
||||
async clickSendMoreInfo() {
|
||||
const newTabPromise = waitForWebcompatComTab(this.win.gBrowser);
|
||||
const newTabPromise = this.waitForSendMoreInfoTab();
|
||||
EventUtils.synthesizeMouseAtCenter(this.sendMoreInfoLink, {}, this.win);
|
||||
const newTab = await newTabPromise;
|
||||
const receivedData = await SpecialPowers.spawn(
|
||||
@@ -564,6 +565,10 @@ class MenuHelper {
|
||||
throw new Error("Should be defined in derived class");
|
||||
}
|
||||
|
||||
get reportSiteIssue() {
|
||||
throw new Error("Should be defined in derived class");
|
||||
}
|
||||
|
||||
get popup() {
|
||||
throw new Error("Should be defined in derived class");
|
||||
}
|
||||
@@ -588,31 +593,16 @@ class MenuHelper {
|
||||
return isMenuItemHidden(this.reportBrokenSite, this.menuDescription);
|
||||
}
|
||||
|
||||
async clickReportBrokenSiteAndAwaitWebCompatTabData() {
|
||||
const newTabPromise = waitForWebcompatComTab(this.win.gBrowser);
|
||||
await this.clickReportBrokenSite();
|
||||
const newTab = await newTabPromise;
|
||||
const receivedData = await SpecialPowers.spawn(
|
||||
newTab.linkedBrowser,
|
||||
[],
|
||||
async function () {
|
||||
await content.wrappedJSObject.messageArrived;
|
||||
return content.wrappedJSObject.message;
|
||||
}
|
||||
);
|
||||
|
||||
this.win.gBrowser.removeCurrentTab();
|
||||
return receivedData;
|
||||
isReportSiteIssueDisabled() {
|
||||
return isMenuItemDisabled(this.reportSiteIssue, this.menuDescription);
|
||||
}
|
||||
|
||||
async clickReportBrokenSite() {
|
||||
if (!this.opened) {
|
||||
await this.open();
|
||||
isReportSiteIssueEnabled() {
|
||||
return isMenuItemEnabled(this.reportSiteIssue, this.menuDescription);
|
||||
}
|
||||
isMenuItemEnabled(this.reportBrokenSite, this.menuDescription);
|
||||
const rbs = new ReportBrokenSiteHelper(this);
|
||||
await rbs.click(this.reportBrokenSite);
|
||||
return rbs;
|
||||
|
||||
isReportSiteIssueHidden() {
|
||||
return isMenuItemHidden(this.reportSiteIssue, this.menuDescription);
|
||||
}
|
||||
|
||||
async openReportBrokenSite() {
|
||||
@@ -645,6 +635,10 @@ class AppMenuHelper extends MenuHelper {
|
||||
return this.getViewNode("appMenu-report-broken-site-button");
|
||||
}
|
||||
|
||||
get reportSiteIssue() {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
get popup() {
|
||||
return this.win.document.getElementById("appMenu-popup");
|
||||
}
|
||||
@@ -660,6 +654,38 @@ class AppMenuHelper extends MenuHelper {
|
||||
}
|
||||
}
|
||||
|
||||
class AppMenuHelpSubmenuHelper extends MenuHelper {
|
||||
menuDescription = "AppMenu help sub-menu";
|
||||
|
||||
get reportBrokenSite() {
|
||||
return this.getViewNode("appMenu_help_reportBrokenSite");
|
||||
}
|
||||
|
||||
get reportSiteIssue() {
|
||||
return this.getViewNode("appMenu_help_reportSiteIssue");
|
||||
}
|
||||
|
||||
get popup() {
|
||||
return this.win.document.getElementById("appMenu-popup");
|
||||
}
|
||||
|
||||
async open() {
|
||||
await new CustomizableUITestUtils(this.win).openMainMenu();
|
||||
|
||||
const anchor = this.win.document.getElementById("PanelUI-menu-button");
|
||||
this.win.PanelUI.showHelpView(anchor);
|
||||
|
||||
const appMenuHelpSubview = this.getViewNode("PanelUI-helpView");
|
||||
await BrowserTestUtils.waitForEvent(appMenuHelpSubview, "ViewShown");
|
||||
}
|
||||
|
||||
async close() {
|
||||
if (this.opened) {
|
||||
await new CustomizableUITestUtils(this.win).hideMainMenu();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class HelpMenuHelper extends MenuHelper {
|
||||
menuDescription = "Help Menu";
|
||||
|
||||
@@ -671,6 +697,10 @@ class HelpMenuHelper extends MenuHelper {
|
||||
return this.win.document.getElementById("help_reportBrokenSite");
|
||||
}
|
||||
|
||||
get reportSiteIssue() {
|
||||
return this.win.document.getElementById("help_reportSiteIssue");
|
||||
}
|
||||
|
||||
get popup() {
|
||||
return this.getViewNode("PanelUI-helpView");
|
||||
}
|
||||
@@ -695,12 +725,6 @@ class HelpMenuHelper extends MenuHelper {
|
||||
return new ReportBrokenSiteHelper(this);
|
||||
}
|
||||
|
||||
async clickReportBrokenSite() {
|
||||
await this.open();
|
||||
this.reportBrokenSite.click();
|
||||
return new ReportBrokenSiteHelper(this);
|
||||
}
|
||||
|
||||
async open() {
|
||||
const { helpMenu } = this;
|
||||
const promise = BrowserTestUtils.waitForEvent(helpMenu, "popupshown");
|
||||
@@ -736,6 +760,10 @@ class ProtectionsPanelHelper extends MenuHelper {
|
||||
return this.getViewNode("protections-popup-report-broken-site-button");
|
||||
}
|
||||
|
||||
get reportSiteIssue() {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
get popup() {
|
||||
this.win.gProtectionsHandler._initializePopup();
|
||||
return this.win.document.getElementById("protections-popup");
|
||||
@@ -766,6 +794,10 @@ function AppMenu(win = window) {
|
||||
return new AppMenuHelper(win);
|
||||
}
|
||||
|
||||
function AppMenuHelpSubmenu(win = window) {
|
||||
return new AppMenuHelpSubmenuHelper(win);
|
||||
}
|
||||
|
||||
function HelpMenu(win = window) {
|
||||
return new HelpMenuHelper(win);
|
||||
}
|
||||
|
||||
@@ -223,41 +223,13 @@ async function testSendMoreInfo(tab, menu, expectedOverrides = {}) {
|
||||
let rbs = await menu.openAndPrefillReportBrokenSite(url, description);
|
||||
|
||||
const receivedData = await rbs.clickSendMoreInfo();
|
||||
await checkWebcompatComPayload(
|
||||
tab,
|
||||
url,
|
||||
description,
|
||||
expectedOverrides,
|
||||
receivedData
|
||||
);
|
||||
const { message } = receivedData;
|
||||
|
||||
// re-opening the panel, the url and description should be reset
|
||||
rbs = await menu.openReportBrokenSite();
|
||||
rbs.isMainViewResetToCurrentTab();
|
||||
rbs.close();
|
||||
}
|
||||
|
||||
async function testWebcompatComFallback(tab, menu) {
|
||||
const url = menu.win.gBrowser.currentURI.spec;
|
||||
const receivedData =
|
||||
await menu.clickReportBrokenSiteAndAwaitWebCompatTabData();
|
||||
await checkWebcompatComPayload(tab, url, "", {}, receivedData);
|
||||
menu.close();
|
||||
}
|
||||
|
||||
async function checkWebcompatComPayload(
|
||||
tab,
|
||||
url,
|
||||
description,
|
||||
expectedOverrides,
|
||||
receivedData
|
||||
) {
|
||||
const expected = await reformatExpectedWebCompatInfo(tab, expectedOverrides);
|
||||
expected.url = url;
|
||||
expected.description = description;
|
||||
|
||||
// sanity checks
|
||||
const { message } = receivedData;
|
||||
const { details } = message;
|
||||
const { additionalData } = details;
|
||||
ok(message.url?.length, "Got a URL");
|
||||
@@ -284,4 +256,9 @@ async function checkWebcompatComPayload(
|
||||
}
|
||||
|
||||
ok(areObjectsEqual(message, expected), "sent info matches expectations");
|
||||
|
||||
// re-opening the panel, the url and description should be reset
|
||||
rbs = await menu.openReportBrokenSite();
|
||||
rbs.isMainViewResetToCurrentTab();
|
||||
rbs.close();
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
DIRS += [
|
||||
"formautofill",
|
||||
"webcompat",
|
||||
"report-site-issue",
|
||||
"pictureinpicture",
|
||||
"search-detection",
|
||||
"newtab",
|
||||
|
||||
52
browser/extensions/report-site-issue/.eslintrc.js
Normal file
52
browser/extensions/report-site-issue/.eslintrc.js
Normal file
@@ -0,0 +1,52 @@
|
||||
/* 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";
|
||||
|
||||
module.exports = {
|
||||
rules: {
|
||||
// Rules from the mozilla plugin
|
||||
"mozilla/balanced-listeners": "error",
|
||||
"mozilla/no-aArgs": "error",
|
||||
"mozilla/var-only-at-top-level": "error",
|
||||
|
||||
// No expressions where a statement is expected
|
||||
"no-unused-expressions": "error",
|
||||
|
||||
// No declaring variables that are never used
|
||||
"no-unused-vars": "error",
|
||||
|
||||
// Disallow using variables outside the blocks they are defined (especially
|
||||
// since only let and const are used, see "no-var").
|
||||
"block-scoped-var": "error",
|
||||
|
||||
// Warn about cyclomatic complexity in functions.
|
||||
complexity: ["error", { max: 26 }],
|
||||
|
||||
// Maximum depth callbacks can be nested.
|
||||
"max-nested-callbacks": ["error", 4],
|
||||
|
||||
// Disallow use of multiline strings (use template strings instead).
|
||||
"no-multi-str": "error",
|
||||
|
||||
// Disallow usage of __proto__ property.
|
||||
"no-proto": "error",
|
||||
|
||||
// Disallow use of assignment in return statement. It is preferable for a
|
||||
// single line of code to have only one easily predictable effect.
|
||||
"no-return-assign": "error",
|
||||
|
||||
// Require use of the second argument for parseInt().
|
||||
radix: "error",
|
||||
|
||||
// Require "use strict" to be defined globally in the script.
|
||||
strict: ["error", "global"],
|
||||
|
||||
// Disallow Yoda conditions (where literal value comes first).
|
||||
yoda: "error",
|
||||
|
||||
// Disallow function or variable declarations in nested blocks
|
||||
"no-inner-declarations": "error",
|
||||
},
|
||||
};
|
||||
96
browser/extensions/report-site-issue/background.js
Normal file
96
browser/extensions/report-site-issue/background.js
Normal file
@@ -0,0 +1,96 @@
|
||||
/* 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";
|
||||
|
||||
/* globals browser */
|
||||
|
||||
const desktopReporterConfig = {
|
||||
src: "desktop-reporter",
|
||||
utm_campaign: "report-site-issue-button",
|
||||
utm_source: "desktop-reporter",
|
||||
};
|
||||
|
||||
const androidReporterConfig = {
|
||||
src: "android-components-reporter",
|
||||
utm_campaign: "report-site-issue-button",
|
||||
utm_source: "android-components-reporter",
|
||||
};
|
||||
|
||||
const getReporterConfig = (() => {
|
||||
let promise;
|
||||
return async () => {
|
||||
promise ??= new Promise(resolve => {
|
||||
browser.permissions
|
||||
.contains({ permissions: ["nativeMessaging"] })
|
||||
.then(needProductName => {
|
||||
if (needProductName) {
|
||||
const port = browser.runtime.connectNative(
|
||||
"mozacWebcompatReporter"
|
||||
);
|
||||
port.onMessage.addListener(message => {
|
||||
if ("productName" in message) {
|
||||
androidReporterConfig.productName = message.productName;
|
||||
androidReporterConfig.extra_labels = [
|
||||
`browser-${message.productName}`,
|
||||
];
|
||||
resolve(androidReporterConfig);
|
||||
|
||||
// For now, setting the productName and extra_labels is the only use for this port,
|
||||
// and that's only happening once after startup, so let's disconnect the port when we're done.
|
||||
port.disconnect();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
resolve(desktopReporterConfig);
|
||||
}
|
||||
});
|
||||
});
|
||||
return promise;
|
||||
};
|
||||
})();
|
||||
|
||||
async function loadTab(url) {
|
||||
const newTab = await browser.tabs.create({ url });
|
||||
return new Promise(resolve => {
|
||||
const listener = (tabId, changeInfo, tab) => {
|
||||
if (
|
||||
tabId == newTab.id &&
|
||||
tab.url !== "about:blank" &&
|
||||
changeInfo.status == "complete"
|
||||
) {
|
||||
browser.tabs.onUpdated.removeListener(listener);
|
||||
resolve(newTab);
|
||||
}
|
||||
};
|
||||
browser.tabs.onUpdated.addListener(listener);
|
||||
});
|
||||
}
|
||||
|
||||
async function captureAndSendReport(tab) {
|
||||
const { id, url } = tab;
|
||||
try {
|
||||
const { endpointUrl, webcompatInfo } =
|
||||
await browser.tabExtras.getWebcompatInfo(id);
|
||||
const reporterConfig = await getReporterConfig();
|
||||
const dataToSend = {
|
||||
endpointUrl,
|
||||
reportUrl: url,
|
||||
reporterConfig,
|
||||
webcompatInfo,
|
||||
};
|
||||
const newTab = await loadTab(endpointUrl);
|
||||
browser.tabExtras.sendWebcompatInfo(newTab.id, dataToSend);
|
||||
} catch (err) {
|
||||
console.error("WebCompat Reporter: unexpected error", err);
|
||||
}
|
||||
}
|
||||
|
||||
if ("helpMenu" in browser) {
|
||||
// desktop
|
||||
browser.helpMenu.onHelpMenuCommand.addListener(captureAndSendReport);
|
||||
} else {
|
||||
// Android
|
||||
browser.pageAction.onClicked.addListener(captureAndSendReport);
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/* 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";
|
||||
|
||||
/* global ExtensionAPI, ExtensionCommon, Services */
|
||||
|
||||
const TOPIC = "report-site-issue";
|
||||
|
||||
this.helpMenu = class extends ExtensionAPI {
|
||||
getAPI(context) {
|
||||
const { tabManager } = context.extension;
|
||||
let EventManager = ExtensionCommon.EventManager;
|
||||
|
||||
return {
|
||||
helpMenu: {
|
||||
onHelpMenuCommand: new EventManager({
|
||||
context,
|
||||
name: "helpMenu",
|
||||
register: fire => {
|
||||
let observer = subject => {
|
||||
let nativeTab = subject.wrappedJSObject;
|
||||
let tab = tabManager.convert(nativeTab);
|
||||
fire.async(tab);
|
||||
};
|
||||
|
||||
Services.obs.addObserver(observer, TOPIC);
|
||||
|
||||
return () => {
|
||||
Services.obs.removeObserver(observer, TOPIC);
|
||||
};
|
||||
},
|
||||
}).api(),
|
||||
},
|
||||
};
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,28 @@
|
||||
[
|
||||
{
|
||||
"namespace": "helpMenu",
|
||||
"events": [
|
||||
{
|
||||
"name": "onHelpMenuCommand",
|
||||
"type": "function",
|
||||
"async": "callback",
|
||||
"description": "Fired when the command event for the Report Site Issue menuitem in Help is fired.",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "function",
|
||||
"name": "callback",
|
||||
"optional": true,
|
||||
"parameters": [
|
||||
{
|
||||
"name": "tab",
|
||||
"$ref": "tabs.Tab",
|
||||
"optional": true,
|
||||
"description": "Details about the selected tab in the window where the menuitem command fired."
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,53 @@
|
||||
/* 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";
|
||||
|
||||
/* global ExtensionAPI */
|
||||
|
||||
const lazy = {};
|
||||
|
||||
const DEFAULT_NEW_REPORT_ENDPOINT = "https://webcompat.com/issues/new";
|
||||
const NEW_REPORT_ENDPOINT_PREF =
|
||||
"ui.new-webcompat-reporter.new-report-endpoint";
|
||||
|
||||
this.tabExtras = class extends ExtensionAPI {
|
||||
getAPI(context) {
|
||||
const { tabManager } = context.extension;
|
||||
const queryReportBrokenSiteActor = (tabId, name, params) => {
|
||||
const { browser } = tabManager.get(tabId);
|
||||
const windowGlobal = browser.browsingContext.currentWindowGlobal;
|
||||
if (!windowGlobal) {
|
||||
return null;
|
||||
}
|
||||
return windowGlobal.getActor("ReportBrokenSite").sendQuery(name, params);
|
||||
};
|
||||
return {
|
||||
tabExtras: {
|
||||
async getWebcompatInfo(tabId) {
|
||||
const endpointUrl = Services.prefs.getStringPref(
|
||||
NEW_REPORT_ENDPOINT_PREF,
|
||||
DEFAULT_NEW_REPORT_ENDPOINT
|
||||
);
|
||||
const webcompatInfo = await queryReportBrokenSiteActor(
|
||||
tabId,
|
||||
"GetWebCompatInfo"
|
||||
);
|
||||
return {
|
||||
webcompatInfo,
|
||||
endpointUrl,
|
||||
};
|
||||
},
|
||||
async sendWebcompatInfo(tabId, info) {
|
||||
console.error(info);
|
||||
return queryReportBrokenSiteActor(
|
||||
tabId,
|
||||
"SendDataToWebcompatCom",
|
||||
info
|
||||
);
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,37 @@
|
||||
[
|
||||
{
|
||||
"namespace": "tabExtras",
|
||||
"description": "experimental tab API extensions",
|
||||
"functions": [
|
||||
{
|
||||
"name": "getWebcompatInfo",
|
||||
"type": "function",
|
||||
"description": "Gets the content blocking status and script log for a given tab",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "tabId",
|
||||
"minimum": 0
|
||||
}
|
||||
],
|
||||
"async": true
|
||||
},
|
||||
{
|
||||
"name": "sendWebcompatInfo",
|
||||
"type": "function",
|
||||
"description": "Sends the given webcompat info to the given tab",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "integer",
|
||||
"name": "tabId",
|
||||
"minimum": 0
|
||||
},
|
||||
{
|
||||
"type": "any"
|
||||
}
|
||||
],
|
||||
"async": true
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,10 @@
|
||||
# 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/.
|
||||
|
||||
# LOCALIZATION NOTE(wc-reporter.label2): This string will be used in the
|
||||
# Firefox page actions menu. Localized length should be considered.
|
||||
wc-reporter.label2=Report Site Issue…
|
||||
# LOCALIZATION NOTE(wc-reporter.tooltip): A site compatibility issue is
|
||||
# a website bug that exists in one browser (Firefox), but not another.
|
||||
wc-reporter.tooltip=Report a site compatibility issue
|
||||
8
browser/extensions/report-site-issue/locales/jar.mn
Normal file
8
browser/extensions/report-site-issue/locales/jar.mn
Normal file
@@ -0,0 +1,8 @@
|
||||
#filter substitution
|
||||
# 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/.
|
||||
|
||||
[features/webcompat-reporter@mozilla.org] @AB_CD@.jar:
|
||||
% locale report-site-issue @AB_CD@ %locale/@AB_CD@/
|
||||
locale/@AB_CD@/webcompat.properties (%webcompat.properties)
|
||||
7
browser/extensions/report-site-issue/locales/moz.build
Normal file
7
browser/extensions/report-site-issue/locales/moz.build
Normal file
@@ -0,0 +1,7 @@
|
||||
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# 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/.
|
||||
|
||||
JAR_MANIFESTS += ["jar.mn"]
|
||||
44
browser/extensions/report-site-issue/manifest.json
Normal file
44
browser/extensions/report-site-issue/manifest.json
Normal file
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"manifest_version": 2,
|
||||
"name": "WebCompat Reporter",
|
||||
"description": "Report site compatibility issues on webcompat.com",
|
||||
"author": "Thomas Wisniewski <twisniewski@mozilla.com>",
|
||||
"version": "2.1.0",
|
||||
"homepage_url": "https://github.com/mozilla/webcompat-reporter",
|
||||
"browser_specific_settings": {
|
||||
"gecko": {
|
||||
"id": "webcompat-reporter@mozilla.org"
|
||||
}
|
||||
},
|
||||
"experiment_apis": {
|
||||
"helpMenu": {
|
||||
"schema": "experimentalAPIs/helpMenu.json",
|
||||
"parent": {
|
||||
"scopes": ["addon_parent"],
|
||||
"script": "experimentalAPIs/helpMenu.js",
|
||||
"paths": [["helpMenu"]]
|
||||
}
|
||||
},
|
||||
"tabExtras": {
|
||||
"schema": "experimentalAPIs/tabExtras.json",
|
||||
"parent": {
|
||||
"scopes": ["addon_parent"],
|
||||
"script": "experimentalAPIs/tabExtras.js",
|
||||
"paths": [["tabExtras"]]
|
||||
}
|
||||
}
|
||||
},
|
||||
"icons": {
|
||||
"16": "icons/lightbulb.svg",
|
||||
"32": "icons/lightbulb.svg",
|
||||
"48": "icons/lightbulb.svg",
|
||||
"96": "icons/lightbulb.svg",
|
||||
"128": "icons/lightbulb.svg"
|
||||
},
|
||||
"permissions": ["tabs", "<all_urls>"],
|
||||
"background": {
|
||||
"persistent": false,
|
||||
"type": "module",
|
||||
"scripts": ["background.js"]
|
||||
}
|
||||
}
|
||||
31
browser/extensions/report-site-issue/moz.build
Normal file
31
browser/extensions/report-site-issue/moz.build
Normal file
@@ -0,0 +1,31 @@
|
||||
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# 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/.
|
||||
|
||||
DEFINES["MOZ_APP_VERSION"] = CONFIG["MOZ_APP_VERSION"]
|
||||
DEFINES["MOZ_APP_MAXVERSION"] = CONFIG["MOZ_APP_MAXVERSION"]
|
||||
|
||||
DIRS += ["locales"]
|
||||
|
||||
FINAL_TARGET_FILES.features["webcompat-reporter@mozilla.org"] += [
|
||||
"background.js",
|
||||
"manifest.json",
|
||||
]
|
||||
|
||||
FINAL_TARGET_FILES.features["webcompat-reporter@mozilla.org"].experimentalAPIs += [
|
||||
"experimentalAPIs/helpMenu.js",
|
||||
"experimentalAPIs/helpMenu.json",
|
||||
"experimentalAPIs/tabExtras.js",
|
||||
"experimentalAPIs/tabExtras.json",
|
||||
]
|
||||
|
||||
FINAL_TARGET_FILES.features["webcompat-reporter@mozilla.org"].icons += [
|
||||
"../../../toolkit/themes/shared/icons/lightbulb.svg"
|
||||
]
|
||||
|
||||
BROWSER_CHROME_MANIFESTS += ["test/browser/browser.toml"]
|
||||
|
||||
with Files("**"):
|
||||
BUG_COMPONENT = ("Web Compatibility", "Tooling & Investigations")
|
||||
@@ -0,0 +1,17 @@
|
||||
[DEFAULT]
|
||||
support-files = [
|
||||
"frameworks.html",
|
||||
"fastclick.html",
|
||||
"head.js",
|
||||
"test.html",
|
||||
"webcompat.html",
|
||||
]
|
||||
|
||||
["browser_button_state.js"]
|
||||
skip-if = ["true"] # Disabled until we figure out why it is failing in bug 1775526
|
||||
|
||||
["browser_disabled_cleanup.js"]
|
||||
skip-if = ["true"] # Disabled until we figure out why it is failing in bug 1775526
|
||||
|
||||
["browser_report_site_issue.js"]
|
||||
skip-if = ["true"] # Disabled until we figure out why it is failing in bug 1775526
|
||||
@@ -0,0 +1,52 @@
|
||||
"use strict";
|
||||
|
||||
const REPORTABLE_PAGE = "http://example.com/";
|
||||
const REPORTABLE_PAGE2 = "https://example.com/";
|
||||
const NONREPORTABLE_PAGE = "about:mozilla";
|
||||
|
||||
/* Test that the Report Site Issue help menu item is enabled for http and https tabs,
|
||||
on page load, or TabSelect, and disabled for everything else. */
|
||||
add_task(async function test_button_state_disabled() {
|
||||
await SpecialPowers.pushPrefEnv({ set: [[PREF_WC_REPORTER_ENABLED, true]] });
|
||||
|
||||
let tab1 = await BrowserTestUtils.openNewForegroundTab(
|
||||
gBrowser,
|
||||
REPORTABLE_PAGE
|
||||
);
|
||||
const menu = new HelpMenuHelper();
|
||||
await menu.open();
|
||||
is(
|
||||
menu.isItemEnabled(),
|
||||
true,
|
||||
"Check that panel item is enabled for reportable schemes on tab load"
|
||||
);
|
||||
await menu.close();
|
||||
|
||||
let tab2 = await BrowserTestUtils.openNewForegroundTab(
|
||||
gBrowser,
|
||||
NONREPORTABLE_PAGE
|
||||
);
|
||||
await menu.open();
|
||||
is(
|
||||
menu.isItemEnabled(),
|
||||
false,
|
||||
"Check that panel item is disabled for non-reportable schemes on tab load"
|
||||
);
|
||||
await menu.close();
|
||||
|
||||
let tab3 = await BrowserTestUtils.openNewForegroundTab(
|
||||
gBrowser,
|
||||
REPORTABLE_PAGE2
|
||||
);
|
||||
await menu.open();
|
||||
is(
|
||||
menu.isItemEnabled(),
|
||||
true,
|
||||
"Check that panel item is enabled for reportable schemes on tab load"
|
||||
);
|
||||
await menu.close();
|
||||
|
||||
await BrowserTestUtils.removeTab(tab1);
|
||||
await BrowserTestUtils.removeTab(tab2);
|
||||
await BrowserTestUtils.removeTab(tab3);
|
||||
});
|
||||
@@ -0,0 +1,41 @@
|
||||
"use strict";
|
||||
|
||||
// Test the addon is cleaning up after itself when disabled.
|
||||
add_task(async function test_disabled() {
|
||||
await promiseAddonEnabled();
|
||||
|
||||
SpecialPowers.Services.prefs.setBoolPref(PREF_WC_REPORTER_ENABLED, false);
|
||||
|
||||
await BrowserTestUtils.withNewTab(
|
||||
{ gBrowser, url: "http://example.com" },
|
||||
async function () {
|
||||
const menu = new HelpMenuHelper();
|
||||
await menu.open();
|
||||
is(
|
||||
menu.isItemHidden(),
|
||||
true,
|
||||
"Report Site Issue help menu item is hidden."
|
||||
);
|
||||
await menu.close();
|
||||
}
|
||||
);
|
||||
|
||||
await promiseAddonEnabled();
|
||||
|
||||
await BrowserTestUtils.withNewTab(
|
||||
{ gBrowser, url: "http://example.com" },
|
||||
async function () {
|
||||
const menu = new HelpMenuHelper();
|
||||
await menu.open();
|
||||
is(
|
||||
await menu.isItemHidden(),
|
||||
false,
|
||||
"Report Site Issue help menu item is visible."
|
||||
);
|
||||
await menu.close();
|
||||
}
|
||||
);
|
||||
|
||||
// Shut down the addon at the end,or the new instance started when we re-enabled it will "leak".
|
||||
SpecialPowers.Services.prefs.setBoolPref(PREF_WC_REPORTER_ENABLED, false);
|
||||
});
|
||||
@@ -0,0 +1,311 @@
|
||||
"use strict";
|
||||
|
||||
async function clickToReportAndAwaitReportTabLoad() {
|
||||
const helpMenu = new HelpMenuHelper();
|
||||
await helpMenu.open();
|
||||
|
||||
// click on "report site issue" and wait for the new tab to open
|
||||
const tab = await new Promise(resolve => {
|
||||
gBrowser.tabContainer.addEventListener(
|
||||
"TabOpen",
|
||||
event => {
|
||||
resolve(event.target);
|
||||
},
|
||||
{ once: true }
|
||||
);
|
||||
document.getElementById("help_reportSiteIssue").click();
|
||||
});
|
||||
|
||||
// wait for the new tab to acknowledge that it received a screenshot
|
||||
await BrowserTestUtils.waitForContentEvent(
|
||||
gBrowser.selectedBrowser,
|
||||
"ScreenshotReceived",
|
||||
false,
|
||||
null,
|
||||
true
|
||||
);
|
||||
|
||||
await helpMenu.close();
|
||||
|
||||
return tab;
|
||||
}
|
||||
|
||||
add_task(async function start_issue_server() {
|
||||
requestLongerTimeout(2);
|
||||
|
||||
const serverLanding = await startIssueServer();
|
||||
|
||||
// ./head.js sets the value for PREF_WC_REPORTER_ENDPOINT
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
["datareporting.healthreport.uploadEnabled", true],
|
||||
[PREF_WC_REPORTER_ENABLED, true],
|
||||
[PREF_WC_REPORTER_ENDPOINT, serverLanding],
|
||||
],
|
||||
});
|
||||
});
|
||||
|
||||
/* Test that clicking on the Report Site Issue button opens a new tab
|
||||
and sends a postMessaged blob to it. */
|
||||
add_task(async function test_opened_page() {
|
||||
let tab1 = await BrowserTestUtils.openNewForegroundTab(gBrowser, TEST_PAGE);
|
||||
let tab2 = await clickToReportAndAwaitReportTabLoad();
|
||||
|
||||
await SpecialPowers.spawn(
|
||||
tab2.linkedBrowser,
|
||||
[{ TEST_PAGE }],
|
||||
async function (args) {
|
||||
async function isGreen(dataUrl) {
|
||||
const getPixel = await new Promise(resolve => {
|
||||
const myCanvas = content.document.createElement("canvas");
|
||||
const ctx = myCanvas.getContext("2d");
|
||||
const img = new content.Image();
|
||||
img.onload = () => {
|
||||
ctx.drawImage(img, 0, 0);
|
||||
resolve((x, y) => {
|
||||
return ctx.getImageData(x, y, 1, 1).data;
|
||||
});
|
||||
};
|
||||
img.src = dataUrl;
|
||||
});
|
||||
function isPixelGreenFuzzy(p) {
|
||||
// jpeg, so it will be off slightly
|
||||
const fuzz = 4;
|
||||
return p[0] < fuzz && Math.abs(p[1] - 128) < fuzz && p[2] < fuzz;
|
||||
}
|
||||
ok(isPixelGreenFuzzy(getPixel(0, 0)), "The pixels were green");
|
||||
}
|
||||
|
||||
let doc = content.document;
|
||||
let urlParam = doc.getElementById("url").innerText;
|
||||
let preview = doc.getElementById("screenshot-preview");
|
||||
const URL =
|
||||
"http://example.com/browser/browser/extensions/report-site-issue/test/browser/test.html";
|
||||
is(
|
||||
urlParam,
|
||||
args.TEST_PAGE,
|
||||
"Reported page is correctly added to the url param"
|
||||
);
|
||||
|
||||
let docShell = content.docShell;
|
||||
is(
|
||||
typeof docShell.getHasTrackingContentBlocked,
|
||||
"function",
|
||||
"docShell.hasTrackingContentBlocked is available"
|
||||
);
|
||||
|
||||
let detailsParam = doc.getElementById("details").innerText;
|
||||
const details = JSON.parse(detailsParam);
|
||||
Assert.equal(
|
||||
typeof details,
|
||||
"object",
|
||||
"Details param is a stringified JSON object."
|
||||
);
|
||||
ok(Array.isArray(details.consoleLog), "Details has a consoleLog array.");
|
||||
|
||||
const log1 = details.consoleLog[0];
|
||||
is(log1.log[0], null, "Can handle degenerate console logs");
|
||||
is(log1.level, "log", "Reports correct log level");
|
||||
is(log1.uri, URL, "Reports correct url");
|
||||
is(log1.pos, "7:13", "Reports correct line and column");
|
||||
|
||||
const log2 = details.consoleLog[1];
|
||||
is(log2.log[0], "colored message", "Can handle fancy console logs");
|
||||
is(log2.level, "error", "Reports correct log level");
|
||||
is(log2.uri, URL, "Reports correct url");
|
||||
is(log2.pos, "8:13", "Reports correct line and column");
|
||||
|
||||
const log3 = details.consoleLog[2];
|
||||
const loggedObject = log3.log[0];
|
||||
is(loggedObject.testobj, "{...}", "Reports object inside object");
|
||||
is(
|
||||
loggedObject.testSymbol,
|
||||
"Symbol(sym)",
|
||||
"Reports symbol inside object"
|
||||
);
|
||||
is(loggedObject.testnumber, 1, "Reports number inside object");
|
||||
is(loggedObject.testArray, "(4)[...]", "Reports array inside object");
|
||||
is(loggedObject.testUndf, "undefined", "Reports undefined inside object");
|
||||
is(loggedObject.testNull, null, "Reports null inside object");
|
||||
is(
|
||||
loggedObject.testFunc,
|
||||
undefined,
|
||||
"Reports function inside object as undefined due to security reasons"
|
||||
);
|
||||
is(loggedObject.testString, "string", "Reports string inside object");
|
||||
is(loggedObject.c, "{...}", "Reports circular reference inside object");
|
||||
is(
|
||||
Object.keys(loggedObject).length,
|
||||
10,
|
||||
"Preview has 10 keys inside object"
|
||||
);
|
||||
is(log3.level, "log", "Reports correct log level");
|
||||
is(log3.uri, URL, "Reports correct url");
|
||||
is(log3.pos, "24:13", "Reports correct line and column");
|
||||
|
||||
const log4 = details.consoleLog[3];
|
||||
const loggedArray = log4.log[0];
|
||||
is(loggedArray[0], "string", "Reports string inside array");
|
||||
is(loggedArray[1], "{...}", "Reports object inside array");
|
||||
is(loggedArray[2], null, "Reports null inside array");
|
||||
is(loggedArray[3], 90, "Reports number inside array");
|
||||
is(loggedArray[4], "undefined", "Reports undefined inside array");
|
||||
is(
|
||||
loggedArray[5],
|
||||
"undefined",
|
||||
"Reports function inside array as undefined due to security reasons"
|
||||
);
|
||||
is(loggedArray[6], "(4)[...]", "Reports array inside array");
|
||||
is(loggedArray[7], "(8)[...]", "Reports circular array inside array");
|
||||
|
||||
const log5 = details.consoleLog[4];
|
||||
ok(
|
||||
log5.log[0].match(/TypeError: .*document\.access is undefined/),
|
||||
"Script errors are logged"
|
||||
);
|
||||
is(log5.level, "error", "Reports correct log level");
|
||||
is(log5.uri, URL, "Reports correct url");
|
||||
is(log5.pos, "36:5", "Reports correct line and column");
|
||||
|
||||
Assert.equal(
|
||||
typeof details.buildID,
|
||||
"string",
|
||||
"Details has a buildID string."
|
||||
);
|
||||
Assert.equal(
|
||||
typeof details.channel,
|
||||
"string",
|
||||
"Details has a channel string."
|
||||
);
|
||||
Assert.equal(
|
||||
typeof details.hasTouchScreen,
|
||||
"boolean",
|
||||
"Details has a hasTouchScreen flag."
|
||||
);
|
||||
Assert.equal(
|
||||
typeof details.hasFastClick,
|
||||
"undefined",
|
||||
"Details does not have FastClick if not found."
|
||||
);
|
||||
Assert.equal(
|
||||
typeof details.hasMobify,
|
||||
"undefined",
|
||||
"Details does not have Mobify if not found."
|
||||
);
|
||||
Assert.equal(
|
||||
typeof details.hasMarfeel,
|
||||
"undefined",
|
||||
"Details does not have Marfeel if not found."
|
||||
);
|
||||
Assert.equal(
|
||||
typeof details["mixed active content blocked"],
|
||||
"boolean",
|
||||
"Details has a mixed active content blocked flag."
|
||||
);
|
||||
Assert.equal(
|
||||
typeof details["mixed passive content blocked"],
|
||||
"boolean",
|
||||
"Details has a mixed passive content blocked flag."
|
||||
);
|
||||
Assert.equal(
|
||||
typeof details["tracking content blocked"],
|
||||
"string",
|
||||
"Details has a tracking content blocked string."
|
||||
);
|
||||
Assert.equal(
|
||||
typeof details["gfx.webrender.all"],
|
||||
"boolean",
|
||||
"Details has gfx.webrender.all."
|
||||
);
|
||||
|
||||
is(
|
||||
preview.innerText,
|
||||
"Pass",
|
||||
"A Blob object was successfully transferred to the test page."
|
||||
);
|
||||
|
||||
const bgUrl = preview.style.backgroundImage.match(/url\(\"(.*)\"\)/)[1];
|
||||
ok(
|
||||
bgUrl.startsWith("data:image/jpeg;base64,"),
|
||||
"A jpeg screenshot was successfully postMessaged"
|
||||
);
|
||||
await isGreen(bgUrl);
|
||||
}
|
||||
);
|
||||
|
||||
BrowserTestUtils.removeTab(tab2);
|
||||
BrowserTestUtils.removeTab(tab1);
|
||||
});
|
||||
|
||||
add_task(async function test_framework_detection() {
|
||||
let tab1 = await BrowserTestUtils.openNewForegroundTab(
|
||||
gBrowser,
|
||||
FRAMEWORKS_TEST_PAGE
|
||||
);
|
||||
let tab2 = await clickToReportAndAwaitReportTabLoad();
|
||||
|
||||
await SpecialPowers.spawn(tab2.linkedBrowser, [], async function () {
|
||||
let doc = content.document;
|
||||
let detailsParam = doc.getElementById("details").innerText;
|
||||
const details = JSON.parse(detailsParam);
|
||||
Assert.equal(
|
||||
typeof details,
|
||||
"object",
|
||||
"Details param is a stringified JSON object."
|
||||
);
|
||||
is(details.hasFastClick, true, "FastClick was found.");
|
||||
is(details.hasMobify, true, "Mobify was found.");
|
||||
is(details.hasMarfeel, true, "Marfeel was found.");
|
||||
});
|
||||
|
||||
BrowserTestUtils.removeTab(tab2);
|
||||
BrowserTestUtils.removeTab(tab1);
|
||||
});
|
||||
|
||||
add_task(async function test_fastclick_detection() {
|
||||
let tab1 = await BrowserTestUtils.openNewForegroundTab(
|
||||
gBrowser,
|
||||
FASTCLICK_TEST_PAGE
|
||||
);
|
||||
let tab2 = await clickToReportAndAwaitReportTabLoad();
|
||||
|
||||
await SpecialPowers.spawn(tab2.linkedBrowser, [], async function () {
|
||||
let doc = content.document;
|
||||
let detailsParam = doc.getElementById("details").innerText;
|
||||
const details = JSON.parse(detailsParam);
|
||||
Assert.equal(
|
||||
typeof details,
|
||||
"object",
|
||||
"Details param is a stringified JSON object."
|
||||
);
|
||||
is(details.hasFastClick, true, "FastClick was found.");
|
||||
});
|
||||
|
||||
BrowserTestUtils.removeTab(tab2);
|
||||
BrowserTestUtils.removeTab(tab1);
|
||||
});
|
||||
|
||||
add_task(async function test_framework_label() {
|
||||
let tab1 = await BrowserTestUtils.openNewForegroundTab(
|
||||
gBrowser,
|
||||
FRAMEWORKS_TEST_PAGE
|
||||
);
|
||||
let tab2 = await clickToReportAndAwaitReportTabLoad();
|
||||
|
||||
await SpecialPowers.spawn(tab2.linkedBrowser, [], async function () {
|
||||
let doc = content.document;
|
||||
let labelParam = doc.getElementById("label").innerText;
|
||||
const label = JSON.parse(labelParam);
|
||||
Assert.equal(
|
||||
typeof label,
|
||||
"object",
|
||||
"Label param is a stringified JSON object."
|
||||
);
|
||||
is(label.includes("type-fastclick"), true, "FastClick was found.");
|
||||
is(label.includes("type-mobify"), true, "Mobify was found.");
|
||||
is(label.includes("type-marfeel"), true, "Marfeel was found.");
|
||||
});
|
||||
|
||||
BrowserTestUtils.removeTab(tab2);
|
||||
BrowserTestUtils.removeTab(tab1);
|
||||
});
|
||||
@@ -0,0 +1,11 @@
|
||||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<script>
|
||||
"use strict";
|
||||
function ObscuredFastClick() {
|
||||
}
|
||||
ObscuredFastClick.prototype = {
|
||||
needsClick: () => {},
|
||||
};
|
||||
window.someRandomVar = new ObscuredFastClick();
|
||||
</script>
|
||||
@@ -0,0 +1,8 @@
|
||||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<script>
|
||||
"use strict";
|
||||
function FastClick() {}
|
||||
function marfeel() {}
|
||||
var Mobify = {Tag: "something"};
|
||||
</script>
|
||||
117
browser/extensions/report-site-issue/test/browser/head.js
Normal file
117
browser/extensions/report-site-issue/test/browser/head.js
Normal file
@@ -0,0 +1,117 @@
|
||||
"use strict";
|
||||
|
||||
ChromeUtils.defineESModuleGetters(this, {
|
||||
AddonManager: "resource://gre/modules/AddonManager.sys.mjs",
|
||||
});
|
||||
|
||||
const { Management } = ChromeUtils.importESModule(
|
||||
"resource://gre/modules/Extension.sys.mjs"
|
||||
);
|
||||
|
||||
const PREF_WC_REPORTER_ENABLED = "extensions.webcompat-reporter.enabled";
|
||||
const PREF_WC_REPORTER_ENDPOINT =
|
||||
"extensions.webcompat-reporter.newIssueEndpoint";
|
||||
|
||||
const TEST_ROOT = getRootDirectory(gTestPath).replace(
|
||||
"chrome://mochitests/content",
|
||||
"http://example.com"
|
||||
);
|
||||
const TEST_PAGE = TEST_ROOT + "test.html";
|
||||
const FRAMEWORKS_TEST_PAGE = TEST_ROOT + "frameworks.html";
|
||||
const FASTCLICK_TEST_PAGE = TEST_ROOT + "fastclick.html";
|
||||
const NEW_ISSUE_PAGE = TEST_ROOT + "webcompat.html";
|
||||
|
||||
const WC_ADDON_ID = "webcompat-reporter@mozilla.org";
|
||||
|
||||
async function promiseAddonEnabled() {
|
||||
const addon = await AddonManager.getAddonByID(WC_ADDON_ID);
|
||||
if (addon.isActive) {
|
||||
return;
|
||||
}
|
||||
const pref = SpecialPowers.Services.prefs.getBoolPref(
|
||||
PREF_WC_REPORTER_ENABLED,
|
||||
false
|
||||
);
|
||||
if (!pref) {
|
||||
SpecialPowers.Services.prefs.setBoolPref(PREF_WC_REPORTER_ENABLED, true);
|
||||
}
|
||||
}
|
||||
|
||||
class HelpMenuHelper {
|
||||
async open() {
|
||||
this.popup = document.getElementById("menu_HelpPopup");
|
||||
ok(this.popup, "Help menu should exist");
|
||||
|
||||
const menuOpen = BrowserTestUtils.waitForEvent(this.popup, "popupshown");
|
||||
|
||||
// This event-faking method was copied from browser_title_case_menus.js so
|
||||
// this can be tested on MacOS (where the actual menus cannot be opened in
|
||||
// tests, but we only need the help menu to populate itself).
|
||||
this.popup.dispatchEvent(new MouseEvent("popupshowing", { bubbles: true }));
|
||||
this.popup.dispatchEvent(new MouseEvent("popupshown", { bubbles: true }));
|
||||
|
||||
await menuOpen;
|
||||
}
|
||||
|
||||
async close() {
|
||||
if (this.popup) {
|
||||
const menuClose = BrowserTestUtils.waitForEvent(
|
||||
this.popup,
|
||||
"popuphidden"
|
||||
);
|
||||
|
||||
// (Also copied from browser_title_case_menus.js)
|
||||
// Just for good measure, we'll fire the popuphiding/popuphidden events
|
||||
// after we close the menupopups.
|
||||
this.popup.dispatchEvent(
|
||||
new MouseEvent("popuphiding", { bubbles: true })
|
||||
);
|
||||
this.popup.dispatchEvent(
|
||||
new MouseEvent("popuphidden", { bubbles: true })
|
||||
);
|
||||
|
||||
await menuClose;
|
||||
this.popup = null;
|
||||
}
|
||||
}
|
||||
|
||||
isItemHidden() {
|
||||
const item = document.getElementById("help_reportSiteIssue");
|
||||
return item && item.hidden;
|
||||
}
|
||||
|
||||
isItemEnabled() {
|
||||
const item = document.getElementById("help_reportSiteIssue");
|
||||
return item && !item.hidden && !item.disabled;
|
||||
}
|
||||
}
|
||||
|
||||
async function startIssueServer() {
|
||||
const landingTemplate = await new Promise((resolve, reject) => {
|
||||
const xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", NEW_ISSUE_PAGE);
|
||||
xhr.onload = () => {
|
||||
resolve(xhr.responseText);
|
||||
};
|
||||
xhr.onerror = reject;
|
||||
xhr.send();
|
||||
});
|
||||
|
||||
const { HttpServer } = ChromeUtils.importESModule(
|
||||
"resource://testing-common/httpd.sys.mjs"
|
||||
);
|
||||
const server = new HttpServer();
|
||||
|
||||
registerCleanupFunction(async function cleanup() {
|
||||
await new Promise(resolve => server.stop(resolve));
|
||||
});
|
||||
|
||||
server.registerPathHandler("/new", function (request, response) {
|
||||
response.setHeader("Content-Type", "text/html", false);
|
||||
response.setStatusLine(request.httpVersion, 200, "OK");
|
||||
response.write(landingTemplate);
|
||||
});
|
||||
|
||||
server.start(-1);
|
||||
return `http://localhost:${server.identity.primaryPort}/new`;
|
||||
}
|
||||
39
browser/extensions/report-site-issue/test/browser/test.html
Normal file
39
browser/extensions/report-site-issue/test/browser/test.html
Normal file
@@ -0,0 +1,39 @@
|
||||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<script>
|
||||
/* eslint-disable no-unused-expressions */
|
||||
"use strict";
|
||||
console.log(null);
|
||||
console.error("%ccolored message", "background:green; color:white");
|
||||
const obj = {
|
||||
testSymbol: Symbol("sym"),
|
||||
testobj: {},
|
||||
testnumber: 1,
|
||||
testArray: [1, {}, 2, 555],
|
||||
testUndf: undefined,
|
||||
testNull: null,
|
||||
testFunc() {},
|
||||
testString: 'string',
|
||||
prop1: 'prop1',
|
||||
prop2: 'prop2'
|
||||
};
|
||||
obj.c = obj;
|
||||
obj.prop3 = 'prop3';
|
||||
obj.prop4 = 'prop4';
|
||||
console.log(obj);
|
||||
const arr = [
|
||||
'string',
|
||||
{test: 'obj'},
|
||||
null,
|
||||
90,
|
||||
undefined,
|
||||
function() {},
|
||||
[1, {}, 2, 555]
|
||||
];
|
||||
arr.push(arr);
|
||||
console.log(arr);
|
||||
document.access.non.existent.property.to.trigger.error;
|
||||
</script>
|
||||
<style>
|
||||
body {background: rgb(0, 128, 0);}
|
||||
</style>
|
||||
@@ -0,0 +1,85 @@
|
||||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<style>
|
||||
#screenshot-preview {width: 200px; height: 200px;}
|
||||
</style>
|
||||
<div id="url">$$URL$$</div>
|
||||
<div id="details">$$DETAILS$$</div>
|
||||
<div id="label">$$LABEL$$</div>
|
||||
<div id="screenshot-preview">Fail</div>
|
||||
<script>
|
||||
"use strict";
|
||||
let preview = document.getElementById("screenshot-preview");
|
||||
const CONFIG = {
|
||||
url: {
|
||||
element: document.getElementById("url")
|
||||
},
|
||||
details: {
|
||||
element: document.getElementById("details"),
|
||||
toStringify: true
|
||||
},
|
||||
extra_labels: {
|
||||
element: document.getElementById("label"),
|
||||
toStringify: true
|
||||
},
|
||||
};
|
||||
|
||||
function getBlobAsDataURL(blob) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let reader = new FileReader();
|
||||
|
||||
// eslint-disable-next-line mozilla/balanced-listeners
|
||||
reader.addEventListener("error", (e) => {
|
||||
reject(`There was an error reading the blob: ${e.type}`);
|
||||
});
|
||||
|
||||
// eslint-disable-next-line mozilla/balanced-listeners
|
||||
reader.addEventListener("load", (e) => {
|
||||
resolve(e.target.result);
|
||||
});
|
||||
|
||||
reader.readAsDataURL(blob);
|
||||
});
|
||||
}
|
||||
|
||||
function setPreviewBG(backgroundData) {
|
||||
return new Promise((resolve) => {
|
||||
preview.style.background = `url(${backgroundData})`;
|
||||
resolve();
|
||||
});
|
||||
}
|
||||
|
||||
function sendReceivedEvent() {
|
||||
window.dispatchEvent(new CustomEvent("ScreenshotReceived", {bubbles: true}));
|
||||
}
|
||||
|
||||
function prepareContent(toStringify, content) {
|
||||
if (toStringify) {
|
||||
return JSON.stringify(content)
|
||||
}
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
function appendMessage(message) {
|
||||
for (const key in CONFIG) {
|
||||
if (key in message) {
|
||||
const field = CONFIG[key];
|
||||
field.element.innerText = prepareContent(field.toStringify, message[key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line mozilla/balanced-listeners
|
||||
window.addEventListener("message", function(event) {
|
||||
if (event.data.screenshot instanceof Blob) {
|
||||
preview.innerText = "Pass";
|
||||
}
|
||||
|
||||
if (event.data.message) {
|
||||
appendMessage(event.data.message);
|
||||
}
|
||||
|
||||
getBlobAsDataURL(event.data.screenshot).then(setPreviewBG).then(sendReceivedEvent);
|
||||
});
|
||||
</script>
|
||||
@@ -55,6 +55,7 @@ l10n-%:
|
||||
ifneq (,$(wildcard ../extensions/formautofill/locales))
|
||||
@$(MAKE) -C ../extensions/formautofill/locales AB_CD=$* XPI_NAME=locale-$*
|
||||
endif
|
||||
@$(MAKE) -C ../extensions/report-site-issue/locales AB_CD=$* XPI_NAME=locale-$*
|
||||
@$(MAKE) -C ../../devtools/client/locales AB_CD=$* XPI_NAME=locale-$* XPI_ROOT_APPID='$(XPI_ROOT_APPID)'
|
||||
@$(MAKE) -C ../../devtools/startup/locales AB_CD=$* XPI_NAME=locale-$* XPI_ROOT_APPID='$(XPI_ROOT_APPID)'
|
||||
@$(MAKE) l10n AB_CD=$* XPI_NAME=locale-$* PREF_DIR=$(PREF_DIR)
|
||||
@@ -75,6 +76,7 @@ endif
|
||||
@$(MAKE) -C ../../devtools/startup/locales chrome AB_CD=$*
|
||||
@$(MAKE) chrome AB_CD=$*
|
||||
@$(MAKE) -C $(DEPTH)/$(MOZ_BRANDING_DIRECTORY)/locales chrome AB_CD=$*
|
||||
@$(MAKE) -C ../extensions/report-site-issue/locales chrome AB_CD=$*
|
||||
|
||||
package-win32-installer: $(SUBMAKEFILES)
|
||||
$(MAKE) -C ../installer/windows CONFIG_DIR=l10ngen ZIP_IN='$(ZIP_OUT)' installer
|
||||
|
||||
@@ -266,6 +266,8 @@ appmenu-get-help =
|
||||
appmenu-help-more-troubleshooting-info =
|
||||
.label = More troubleshooting information
|
||||
.accesskey = t
|
||||
appmenu-help-report-site-issue =
|
||||
.label = Report site issue…
|
||||
appmenu-help-share-ideas =
|
||||
.label = Share ideas and feedback…
|
||||
.accesskey = S
|
||||
|
||||
@@ -327,6 +327,8 @@ menu-get-help =
|
||||
menu-help-more-troubleshooting-info =
|
||||
.label = More Troubleshooting Information
|
||||
.accesskey = T
|
||||
menu-help-report-site-issue =
|
||||
.label = Report Site Issue…
|
||||
menu-help-share-ideas =
|
||||
.label = Share Ideas and Feedback…
|
||||
.accesskey = S
|
||||
|
||||
@@ -15,6 +15,7 @@ def test(mod, path, entity=None):
|
||||
"devtools/startup",
|
||||
"browser",
|
||||
"browser/extensions/formautofill",
|
||||
"browser/extensions/report-site-issue",
|
||||
"extensions/spellcheck",
|
||||
"other-licenses/branding/firefox",
|
||||
"browser/branding/official",
|
||||
|
||||
@@ -13,6 +13,7 @@ dirs = browser
|
||||
devtools/client
|
||||
devtools/startup
|
||||
browser/extensions/formautofill
|
||||
browser/extensions/report-site-issue
|
||||
|
||||
[includes]
|
||||
# non-central apps might want to use %(topsrcdir)s here, or other vars
|
||||
|
||||
@@ -136,6 +136,10 @@ locales = [
|
||||
reference = "browser/extensions/formautofill/locales/en-US/**"
|
||||
l10n = "{l}browser/extensions/formautofill/**"
|
||||
|
||||
[[paths]]
|
||||
reference = "browser/extensions/report-site-issue/locales/en-US/**"
|
||||
l10n = "{l}browser/extensions/report-site-issue/**"
|
||||
|
||||
|
||||
[[includes]]
|
||||
path = "toolkit/locales/l10n.toml"
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
# documentation and how to modify this file.
|
||||
repo: mozilla-central
|
||||
created_at: '2021-10-14T12:50:40.073465'
|
||||
updated_at: '2025-03-13T19:30:10.326871+00:00'
|
||||
updated_at: '2025-03-07T18:54:25.418364+00:00'
|
||||
export:
|
||||
path: ./docs/mots/index.rst
|
||||
format: rst
|
||||
@@ -4464,6 +4464,7 @@ modules:
|
||||
description: Compatibility interventions (webcompat system addon) and bug
|
||||
reporting capabilities (Report Site Issue addon).
|
||||
includes:
|
||||
- browser/extensions/report-site-issue
|
||||
- browser/extensions/webcompat
|
||||
- mobile/android/android-components/components/feature/webcompat
|
||||
- mobile/android/android-components/components/feature/webcompat-reporter
|
||||
@@ -4574,5 +4575,5 @@ modules:
|
||||
- Ryan Tilder
|
||||
group: dev-platform
|
||||
hashes:
|
||||
config: cc1ba4298fd95273a1290da0ddc890f46201f616
|
||||
export: 875b39a5f851b27790d1afd20ab06b015fefa626
|
||||
config: c50edff26d9ce06c7e7f0855e54c0c98bd169470
|
||||
export: 15298ba93e80b7f56222906aba4f794543bac763
|
||||
|
||||
@@ -798,6 +798,7 @@ _MANIFEST_JSON_DATA = {
|
||||
"devtools": "browser/chrome/fr/locale/fr/devtools/client/",
|
||||
"devtools-shared": "browser/chrome/fr/locale/fr/devtools/shared/",
|
||||
"formautofill": "browser/features/formautofill@mozilla.org/fr/locale/fr/",
|
||||
"report-site-issue": "browser/features/webcompat-reporter@mozilla.org/fr/locale/fr/",
|
||||
"alerts": "chrome/fr/locale/fr/alerts/",
|
||||
"autoconfig": "chrome/fr/locale/fr/autoconfig/",
|
||||
"global": "chrome/fr/locale/fr/global/",
|
||||
|
||||
@@ -337,6 +337,9 @@
|
||||
"test-linux1804-64-tsan/opt-*",
|
||||
"test-windows7-32/debug-*"
|
||||
],
|
||||
"browser/extensions/report-site-issue/test/browser/browser.toml": [
|
||||
"test-windows11-64-2009/opt-*"
|
||||
],
|
||||
"browser/modules/test/browser/browser.toml": [
|
||||
"test-windows11-64-2009/opt-*"
|
||||
],
|
||||
@@ -1969,6 +1972,7 @@
|
||||
"browser/extensions/formautofill/test/mochitest/creditCard/mochitest.toml": 0.62,
|
||||
"browser/extensions/formautofill/test/mochitest/mochitest.toml": 0.77,
|
||||
"browser/extensions/formautofill/test/unit/xpcshell.toml": 0.78,
|
||||
"browser/extensions/report-site-issue/test/browser/browser.toml": 0.53,
|
||||
"browser/modules/test/browser/browser.toml": 0.99,
|
||||
"browser/modules/test/unit/xpcshell.toml": 0.75,
|
||||
"browser/tools/mozscreenshots/controlCenter/browser.toml": 0.69,
|
||||
|
||||
@@ -194,6 +194,7 @@
|
||||
"browser/extensions/newtab/test/browser/abouthomecache/browser.ini": 10.59,
|
||||
"browser/extensions/newtab/test/browser/browser.ini": 74.49,
|
||||
"browser/extensions/pdfjs/test/browser.ini": 19.44,
|
||||
"browser/extensions/report-site-issue/test/browser/browser.ini": 11.62,
|
||||
"browser/modules/test/browser/browser.ini": 147.75,
|
||||
"browser/modules/test/browser/formValidation/browser.ini": 1.36,
|
||||
"caps/tests/mochitest/browser.ini": 2.33,
|
||||
|
||||
@@ -193,6 +193,7 @@
|
||||
"browser/extensions/newtab/test/browser/abouthomecache/browser.ini": 10.38,
|
||||
"browser/extensions/newtab/test/browser/browser.ini": 52.48,
|
||||
"browser/extensions/pdfjs/test/browser.ini": 7.41,
|
||||
"browser/extensions/report-site-issue/test/browser/browser.ini": 10.17,
|
||||
"browser/modules/test/browser/browser.ini": 109.91,
|
||||
"browser/modules/test/browser/formValidation/browser.ini": 0.78,
|
||||
"caps/tests/mochitest/browser.ini": 1.63,
|
||||
|
||||
@@ -12,6 +12,7 @@ codespell:
|
||||
- browser/components/urlbar/docs/
|
||||
- browser/extensions/formautofill/locales/en-US/
|
||||
- browser/extensions/newtab/docs/
|
||||
- browser/extensions/report-site-issue/locales/en-US/
|
||||
- browser/installer/windows/docs/
|
||||
- browser/locales/en-US/
|
||||
- build/docs/
|
||||
|
||||
@@ -6,6 +6,7 @@ l10n:
|
||||
include:
|
||||
- browser/branding/official/locales/en-US
|
||||
- browser/extensions/formautofill/locales/en-US
|
||||
- browser/extensions/report-site-issue/locales/en-US
|
||||
- browser/locales/en-US
|
||||
- devtools/client/locales/en-US
|
||||
- devtools/shared/locales/en-US
|
||||
|
||||
Reference in New Issue
Block a user