mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-17 14:25:49 +00:00
Bug 1863022 - Render message from browser-siteProtections.js, replace messaging system telemetry, and migrate strings r=pdahiya,omc-reviewers,pbz,fluent-reviewers,flod
The protections panel message should show once when the panel is first opened; after that it will be collapsed by default and can be shown again by clicking the "info" button on the panel Messaging system previously sent the following pings on message show, and when the "learn more" link was clicked: ``` {“message_id”:“PROTECTIONS_PANEL_1",“event”:“IMPRESSION”,“addon_version”:“20231106094018",“locale”:“en-US”,“client_id”:“6fabd2de-3d0a-4b11-be4c-86b0ea1a1144",“browser_session_id”:“4b0f34b1-75ef-4704-907e-18d84e5187c3",“pingType”:“whats-new-panel”} ``` and ``` {“message_id”:“PROTECTIONS_PANEL_1",“event”:“CLICK”,“addon_version”:“20231106094018",“locale”:“en-US”,“client_id”:“6fabd2de-3d0a-4b11-be4c-86b0ea1a1144",“browser_session_id”:“4b0f34b1-75ef-4704-907e-18d84e5187c3",“pingType”:“whats-new-panel”} ``` This patch replaces these pings with 'RecordEvents' telemetry on the `protectionsPopup` object: ``` 33153 security.ui.protectionspopup open protectionspopup_cfr impression {"message": "PROTECTIONS_PANEL_1"} ``` and ``` 34932 security.ui.protectionspopup click protectionspopup_cfr ``` Differential Revision: https://phabricator.services.mozilla.com/D192968
This commit is contained in:
parent
5a73b57894
commit
a240571a59
@ -7,10 +7,8 @@
|
||||
ChromeUtils.defineESModuleGetters(this, {
|
||||
ContentBlockingAllowList:
|
||||
"resource://gre/modules/ContentBlockingAllowList.sys.mjs",
|
||||
});
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetters(this, {
|
||||
ToolbarPanelHub: "resource://activity-stream/lib/ToolbarPanelHub.jsm",
|
||||
SpecialMessageActions:
|
||||
"resource://messaging-system/lib/SpecialMessageActions.sys.mjs",
|
||||
});
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(
|
||||
@ -1657,6 +1655,13 @@ var gProtectionsHandler = {
|
||||
() => this.maybeSetMilestoneCounterText()
|
||||
);
|
||||
|
||||
XPCOMUtils.defineLazyPreferenceGetter(
|
||||
this,
|
||||
"protectionsPanelMessageSeen",
|
||||
"browser.protections_panel.infoMessage.seen",
|
||||
false
|
||||
);
|
||||
|
||||
for (let blocker of Object.values(this.blockers)) {
|
||||
if (blocker.init) {
|
||||
blocker.init();
|
||||
@ -1813,7 +1818,7 @@ var gProtectionsHandler = {
|
||||
|
||||
// Insert the info message if needed. This will be shown once and then
|
||||
// remain collapsed.
|
||||
ToolbarPanelHub.insertProtectionPanelMessage(event);
|
||||
this._insertProtectionsPanelInfoMessage(event);
|
||||
|
||||
if (!event.target.hasAttribute("toast")) {
|
||||
Services.telemetry.recordEvent(
|
||||
@ -2693,4 +2698,188 @@ var gProtectionsHandler = {
|
||||
this._earliestRecordedDate = date;
|
||||
}
|
||||
},
|
||||
|
||||
_sendUserEventTelemetry(event, value = null, options = {}) {
|
||||
// Only send telemetry for non private browsing windows
|
||||
if (!PrivateBrowsingUtils.isWindowPrivate(window)) {
|
||||
Services.telemetry.recordEvent(
|
||||
"security.ui.protectionspopup",
|
||||
event,
|
||||
"protectionspopup_cfr",
|
||||
value,
|
||||
options
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Dispatch the action defined in the message and user telemetry event.
|
||||
*/
|
||||
_dispatchUserAction(message) {
|
||||
let url;
|
||||
try {
|
||||
// Set platform specific path variables for SUMO articles
|
||||
url = Services.urlFormatter.formatURL(message.content.cta_url);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
url = message.content.cta_url;
|
||||
}
|
||||
SpecialMessageActions.handleAction(
|
||||
{
|
||||
type: message.content.cta_type,
|
||||
data: {
|
||||
args: url,
|
||||
where: message.content.cta_where || "tabshifted",
|
||||
},
|
||||
},
|
||||
window.browser
|
||||
);
|
||||
|
||||
this._sendUserEventTelemetry("click", "learn_more_link", {
|
||||
message: message.id,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Attach event listener to dispatch message defined action.
|
||||
*/
|
||||
_attachCommandListener(element, message) {
|
||||
// Add event listener for `mouseup` not to overlap with the
|
||||
// `mousedown` & `click` events dispatched from PanelMultiView.sys.mjs
|
||||
// https://searchfox.org/mozilla-central/rev/7531325c8660cfa61bf71725f83501028178cbb9/browser/components/customizableui/PanelMultiView.jsm#1830-1837
|
||||
element.addEventListener("mouseup", () => {
|
||||
this._dispatchUserAction(message);
|
||||
});
|
||||
element.addEventListener("keyup", e => {
|
||||
if (e.key === "Enter" || e.key === " ") {
|
||||
this._dispatchUserAction(message);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Inserts a message into the Protections Panel. The message is visible once
|
||||
* and afterwards set in a collapsed state. It can be shown again using the
|
||||
* info button in the panel header.
|
||||
*/
|
||||
_insertProtectionsPanelInfoMessage(event) {
|
||||
// const PROTECTIONS_PANEL_INFOMSG_PREF =
|
||||
// "browser.protections_panel.infoMessage.seen";
|
||||
const message = {
|
||||
id: "PROTECTIONS_PANEL_1",
|
||||
content: {
|
||||
title: { string_id: "cfr-protections-panel-header" },
|
||||
body: { string_id: "cfr-protections-panel-body" },
|
||||
link_text: { string_id: "cfr-protections-panel-link-text" },
|
||||
cta_url: `${Services.urlFormatter.formatURLPref(
|
||||
"app.support.baseURL"
|
||||
)}etp-promotions?as=u&utm_source=inproduct`,
|
||||
cta_type: "OPEN_URL",
|
||||
},
|
||||
};
|
||||
|
||||
const doc = event.target.ownerDocument;
|
||||
const container = doc.getElementById("messaging-system-message-container");
|
||||
const infoButton = doc.getElementById("protections-popup-info-button");
|
||||
const panelContainer = doc.getElementById("protections-popup");
|
||||
const toggleMessage = () => {
|
||||
const learnMoreLink = doc.querySelector(
|
||||
"#messaging-system-message-container .text-link"
|
||||
);
|
||||
if (learnMoreLink) {
|
||||
container.toggleAttribute("disabled");
|
||||
infoButton.toggleAttribute("checked");
|
||||
panelContainer.toggleAttribute("infoMessageShowing");
|
||||
learnMoreLink.disabled = !learnMoreLink.disabled;
|
||||
}
|
||||
// If the message panel is opened, send impression telemetry
|
||||
if (panelContainer.hasAttribute("infoMessageShowing")) {
|
||||
this._sendUserEventTelemetry("open", "impression", {
|
||||
message: message.id,
|
||||
});
|
||||
}
|
||||
};
|
||||
if (!container.childElementCount) {
|
||||
const messageEl = this._createHeroElement(doc, message);
|
||||
container.appendChild(messageEl);
|
||||
infoButton.addEventListener("click", toggleMessage);
|
||||
}
|
||||
// Message is collapsed by default. If it was never shown before we want
|
||||
// to expand it
|
||||
if (
|
||||
!this.protectionsPanelMessageSeen &&
|
||||
container.hasAttribute("disabled")
|
||||
) {
|
||||
toggleMessage(message);
|
||||
}
|
||||
// Save state that we displayed the message
|
||||
if (!this.protectionsPanelMessageSeen) {
|
||||
Services.prefs.setBoolPref(
|
||||
"browser.protections_panel.infoMessage.seen",
|
||||
true
|
||||
);
|
||||
}
|
||||
// Collapse the message after the panel is hidden so we don't get the
|
||||
// animation when opening the panel
|
||||
panelContainer.addEventListener(
|
||||
"popuphidden",
|
||||
() => {
|
||||
if (
|
||||
this.protectionsPanelMessageSeen &&
|
||||
!container.hasAttribute("disabled")
|
||||
) {
|
||||
toggleMessage(message);
|
||||
}
|
||||
},
|
||||
{
|
||||
once: true,
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
_createElement(doc, elem, options = {}) {
|
||||
const node = doc.createElementNS("http://www.w3.org/1999/xhtml", elem);
|
||||
if (options.classList) {
|
||||
node.classList.add(options.classList);
|
||||
}
|
||||
if (options.content) {
|
||||
doc.l10n.setAttributes(node, options.content.string_id);
|
||||
}
|
||||
return node;
|
||||
},
|
||||
|
||||
_createHeroElement(doc, message) {
|
||||
const messageEl = this._createElement(doc, "div");
|
||||
messageEl.setAttribute("id", "protections-popup-message");
|
||||
messageEl.classList.add("whatsNew-hero-message");
|
||||
const wrapperEl = this._createElement(doc, "div");
|
||||
wrapperEl.classList.add("whatsNew-message-body");
|
||||
messageEl.appendChild(wrapperEl);
|
||||
|
||||
wrapperEl.appendChild(
|
||||
this._createElement(doc, "h2", {
|
||||
classList: "whatsNew-message-title",
|
||||
content: message.content.title,
|
||||
})
|
||||
);
|
||||
|
||||
wrapperEl.appendChild(
|
||||
this._createElement(doc, "p", { content: message.content.body })
|
||||
);
|
||||
|
||||
if (message.content.link_text) {
|
||||
let linkEl = this._createElement(doc, "a", {
|
||||
classList: "text-link",
|
||||
content: message.content.link_text,
|
||||
});
|
||||
|
||||
linkEl.disabled = true;
|
||||
wrapperEl.appendChild(linkEl);
|
||||
this._attachCommandListener(linkEl, message);
|
||||
} else {
|
||||
this._attachCommandListener(wrapperEl, message);
|
||||
}
|
||||
|
||||
return messageEl;
|
||||
},
|
||||
};
|
||||
|
@ -47,6 +47,65 @@ async function clickToggle(toggle) {
|
||||
await changed;
|
||||
}
|
||||
|
||||
add_task(async function testPanelInfoMessage() {
|
||||
const PROTECTIONS_PANEL_INFOMSG_PREF =
|
||||
"browser.protections_panel.infoMessage.seen";
|
||||
|
||||
let tab = await BrowserTestUtils.openNewForegroundTab(
|
||||
gBrowser,
|
||||
TRACKING_PAGE
|
||||
);
|
||||
// Set the infomessage pref to ensure the message is displayed every time
|
||||
Services.prefs.setBoolPref(PROTECTIONS_PANEL_INFOMSG_PREF, false);
|
||||
|
||||
await openProtectionsPanel();
|
||||
|
||||
await BrowserTestUtils.waitForMutationCondition(
|
||||
gProtectionsHandler._protectionsPopup,
|
||||
{ attributes: true, attributeFilter: ["infoMessageShowing"] },
|
||||
() =>
|
||||
!gProtectionsHandler._protectionsPopup.hasAttribute("infoMessageShowing")
|
||||
);
|
||||
|
||||
// Test that the info message is displayed when the panel opens
|
||||
let container = document.getElementById("messaging-system-message-container");
|
||||
let message = document.getElementById("protections-popup-message");
|
||||
let learnMoreLink = document.querySelector(
|
||||
"#messaging-system-message-container .text-link"
|
||||
);
|
||||
|
||||
// Check the visibility of the info message.
|
||||
ok(
|
||||
BrowserTestUtils.is_visible(container),
|
||||
"The message container should exist."
|
||||
);
|
||||
|
||||
ok(BrowserTestUtils.is_visible(message), "The message should be visible.");
|
||||
|
||||
ok(BrowserTestUtils.is_visible(learnMoreLink), "The link should be visible.");
|
||||
|
||||
// Check telemetry for the info message
|
||||
let events = Services.telemetry.snapshotEvents(
|
||||
Ci.nsITelemetry.DATASET_PRERELEASE_CHANNELS,
|
||||
false
|
||||
).parent;
|
||||
let messageEvents = events.filter(
|
||||
e =>
|
||||
e[1] == "security.ui.protectionspopup" &&
|
||||
e[2] == "open" &&
|
||||
e[3] == "protectionspopup_cfr" &&
|
||||
e[4] == "impression"
|
||||
);
|
||||
is(
|
||||
messageEvents.length,
|
||||
1,
|
||||
"recorded telemetry for showing the info message"
|
||||
);
|
||||
|
||||
Services.telemetry.clearEvents();
|
||||
BrowserTestUtils.removeTab(tab);
|
||||
});
|
||||
|
||||
add_task(async function testToggleSwitch() {
|
||||
let tab = await BrowserTestUtils.openNewForegroundTab(
|
||||
gBrowser,
|
||||
|
@ -170,6 +170,12 @@ module.exports = function (config) {
|
||||
functions: 0,
|
||||
branches: 0,
|
||||
},
|
||||
"lib/ToolbarPanelHub.jsm": {
|
||||
statements: 88,
|
||||
lines: 88,
|
||||
functions: 94,
|
||||
branches: 84,
|
||||
},
|
||||
"lib/*.jsm": {
|
||||
statements: 100,
|
||||
lines: 100,
|
||||
|
@ -50,8 +50,6 @@ class _ToolbarPanelHub {
|
||||
this._hideAppmenuButton = this._hideAppmenuButton.bind(this);
|
||||
this._showToolbarButton = this._showToolbarButton.bind(this);
|
||||
this._hideToolbarButton = this._hideToolbarButton.bind(this);
|
||||
this.insertProtectionPanelMessage =
|
||||
this.insertProtectionPanelMessage.bind(this);
|
||||
|
||||
this.state = {};
|
||||
this._initialized = false;
|
||||
@ -511,73 +509,6 @@ class _ToolbarPanelHub {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts a message into the Protections Panel. The message is visible once
|
||||
* and afterwards set in a collapsed state. It can be shown again using the
|
||||
* info button in the panel header.
|
||||
*/
|
||||
async insertProtectionPanelMessage(event) {
|
||||
const win = event.target.ownerGlobal;
|
||||
this.maybeInsertFTL(win);
|
||||
|
||||
const doc = event.target.ownerDocument;
|
||||
const container = doc.getElementById("messaging-system-message-container");
|
||||
const infoButton = doc.getElementById("protections-popup-info-button");
|
||||
const panelContainer = doc.getElementById("protections-popup");
|
||||
const toggleMessage = () => {
|
||||
const learnMoreLink = doc.querySelector(
|
||||
"#messaging-system-message-container .text-link"
|
||||
);
|
||||
if (learnMoreLink) {
|
||||
container.toggleAttribute("disabled");
|
||||
infoButton.toggleAttribute("checked");
|
||||
panelContainer.toggleAttribute("infoMessageShowing");
|
||||
learnMoreLink.disabled = !learnMoreLink.disabled;
|
||||
}
|
||||
};
|
||||
if (!container.childElementCount) {
|
||||
const message = await this._getMessages({
|
||||
template: "protections_panel",
|
||||
triggerId: "protectionsPanelOpen",
|
||||
});
|
||||
if (message) {
|
||||
const messageEl = this._createHeroElement(win, doc, message);
|
||||
container.appendChild(messageEl);
|
||||
infoButton.addEventListener("click", toggleMessage);
|
||||
this.sendUserEventTelemetry(win, "IMPRESSION", message);
|
||||
}
|
||||
}
|
||||
// Message is collapsed by default. If it was never shown before we want
|
||||
// to expand it
|
||||
if (
|
||||
!this.state.protectionPanelMessageSeen &&
|
||||
container.hasAttribute("disabled")
|
||||
) {
|
||||
toggleMessage();
|
||||
}
|
||||
// Save state that we displayed the message
|
||||
if (!this.state.protectionPanelMessageSeen) {
|
||||
Services.prefs.setBoolPref(PROTECTIONS_PANEL_INFOMSG_PREF, true);
|
||||
this.state.protectionPanelMessageSeen = true;
|
||||
}
|
||||
// Collapse the message after the panel is hidden so we don't get the
|
||||
// animation when opening the panel
|
||||
panelContainer.addEventListener(
|
||||
"popuphidden",
|
||||
() => {
|
||||
if (
|
||||
this.state.protectionPanelMessageSeen &&
|
||||
!container.hasAttribute("disabled")
|
||||
) {
|
||||
toggleMessage();
|
||||
}
|
||||
},
|
||||
{
|
||||
once: true,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {object} [browser] MessageChannel target argument as a response to a
|
||||
* user action. No message is shown if undefined.
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { _ToolbarPanelHub } from "lib/ToolbarPanelHub.jsm";
|
||||
import { GlobalOverrider } from "test/unit/utils";
|
||||
import { OnboardingMessageProvider } from "lib/OnboardingMessageProvider.jsm";
|
||||
import { PanelTestProvider } from "lib/PanelTestProvider.sys.mjs";
|
||||
|
||||
describe("ToolbarPanelHub", () => {
|
||||
@ -760,169 +759,4 @@ describe("ToolbarPanelHub", () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
describe("#insertProtectionPanelMessage", () => {
|
||||
const fakeInsert = () =>
|
||||
instance.insertProtectionPanelMessage({
|
||||
target: { ownerGlobal: fakeWindow, ownerDocument: fakeDocument },
|
||||
});
|
||||
let getMessagesStub;
|
||||
beforeEach(async () => {
|
||||
const onboardingMsgs =
|
||||
await OnboardingMessageProvider.getUntranslatedMessages();
|
||||
getMessagesStub = sandbox
|
||||
.stub()
|
||||
.resolves(
|
||||
onboardingMsgs.find(msg => msg.template === "protections_panel")
|
||||
);
|
||||
await instance.init(waitForInitializedStub, {
|
||||
sendTelemetry: fakeSendTelemetry,
|
||||
getMessages: getMessagesStub,
|
||||
});
|
||||
});
|
||||
it("should remember it showed", async () => {
|
||||
await fakeInsert();
|
||||
|
||||
assert.calledWithExactly(
|
||||
setBoolPrefStub,
|
||||
"browser.protections_panel.infoMessage.seen",
|
||||
true
|
||||
);
|
||||
});
|
||||
it("should toggle/expand when default collapsed/disabled", async () => {
|
||||
fakeElementById.hasAttribute.returns(true);
|
||||
|
||||
await fakeInsert();
|
||||
|
||||
assert.calledThrice(fakeElementById.toggleAttribute);
|
||||
});
|
||||
it("should toggle again when popup hides", async () => {
|
||||
fakeElementById.addEventListener.callsArg(1);
|
||||
|
||||
await fakeInsert();
|
||||
|
||||
assert.callCount(fakeElementById.toggleAttribute, 6);
|
||||
});
|
||||
it("should open link on click (separate link element)", async () => {
|
||||
const sendTelemetryStub = sandbox.stub(
|
||||
instance,
|
||||
"sendUserEventTelemetry"
|
||||
);
|
||||
const onboardingMsgs =
|
||||
await OnboardingMessageProvider.getUntranslatedMessages();
|
||||
const msg = onboardingMsgs.find(m => m.template === "protections_panel");
|
||||
|
||||
await fakeInsert();
|
||||
|
||||
assert.calledOnce(sendTelemetryStub);
|
||||
assert.calledWithExactly(
|
||||
sendTelemetryStub,
|
||||
fakeWindow,
|
||||
"IMPRESSION",
|
||||
msg
|
||||
);
|
||||
|
||||
eventListeners.mouseup();
|
||||
|
||||
assert.calledOnce(global.SpecialMessageActions.handleAction);
|
||||
assert.calledWithExactly(
|
||||
global.SpecialMessageActions.handleAction,
|
||||
{
|
||||
type: "OPEN_URL",
|
||||
data: {
|
||||
args: sinon.match.string,
|
||||
where: "tabshifted",
|
||||
},
|
||||
},
|
||||
fakeWindow.browser
|
||||
);
|
||||
});
|
||||
it("should format the url", async () => {
|
||||
const stub = sandbox
|
||||
.stub(global.Services.urlFormatter, "formatURL")
|
||||
.returns("formattedURL");
|
||||
const onboardingMsgs =
|
||||
await OnboardingMessageProvider.getUntranslatedMessages();
|
||||
const msg = onboardingMsgs.find(m => m.template === "protections_panel");
|
||||
|
||||
await fakeInsert();
|
||||
|
||||
eventListeners.mouseup();
|
||||
|
||||
assert.calledOnce(stub);
|
||||
assert.calledWithExactly(stub, msg.content.cta_url);
|
||||
assert.calledOnce(global.SpecialMessageActions.handleAction);
|
||||
assert.calledWithExactly(
|
||||
global.SpecialMessageActions.handleAction,
|
||||
{
|
||||
type: "OPEN_URL",
|
||||
data: {
|
||||
args: "formattedURL",
|
||||
where: "tabshifted",
|
||||
},
|
||||
},
|
||||
fakeWindow.browser
|
||||
);
|
||||
});
|
||||
it("should report format url errors", async () => {
|
||||
const stub = sandbox
|
||||
.stub(global.Services.urlFormatter, "formatURL")
|
||||
.throws();
|
||||
const onboardingMsgs =
|
||||
await OnboardingMessageProvider.getUntranslatedMessages();
|
||||
const msg = onboardingMsgs.find(m => m.template === "protections_panel");
|
||||
sandbox.spy(global.console, "error");
|
||||
|
||||
await fakeInsert();
|
||||
|
||||
eventListeners.mouseup();
|
||||
|
||||
assert.calledOnce(stub);
|
||||
assert.calledOnce(global.console.error);
|
||||
assert.calledOnce(global.SpecialMessageActions.handleAction);
|
||||
assert.calledWithExactly(
|
||||
global.SpecialMessageActions.handleAction,
|
||||
{
|
||||
type: "OPEN_URL",
|
||||
data: {
|
||||
args: msg.content.cta_url,
|
||||
where: "tabshifted",
|
||||
},
|
||||
},
|
||||
fakeWindow.browser
|
||||
);
|
||||
});
|
||||
it("should open link on click (directly attached to the message)", async () => {
|
||||
const onboardingMsgs =
|
||||
await OnboardingMessageProvider.getUntranslatedMessages();
|
||||
const msg = onboardingMsgs.find(m => m.template === "protections_panel");
|
||||
getMessagesStub.resolves({
|
||||
...msg,
|
||||
content: { ...msg.content, link_text: null },
|
||||
});
|
||||
await fakeInsert();
|
||||
|
||||
eventListeners.mouseup();
|
||||
|
||||
assert.calledOnce(global.SpecialMessageActions.handleAction);
|
||||
assert.calledWithExactly(
|
||||
global.SpecialMessageActions.handleAction,
|
||||
{
|
||||
type: "OPEN_URL",
|
||||
data: {
|
||||
args: sinon.match.string,
|
||||
where: "tabshifted",
|
||||
},
|
||||
},
|
||||
fakeWindow.browser
|
||||
);
|
||||
});
|
||||
it("should handle user actions from mouseup and keyup", async () => {
|
||||
await fakeInsert();
|
||||
|
||||
eventListeners.mouseup();
|
||||
eventListeners.keyup({ key: "Enter" });
|
||||
eventListeners.keyup({ key: " " });
|
||||
assert.calledThrice(global.SpecialMessageActions.handleAction);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -75,12 +75,6 @@ cfr-doorhanger-bookmark-fxa-close-btn-tooltip =
|
||||
.aria-label = Close button
|
||||
.title = Close
|
||||
|
||||
## Protections panel
|
||||
|
||||
cfr-protections-panel-header = Browse without being followed
|
||||
cfr-protections-panel-body = Keep your data to yourself. { -brand-short-name } protects you from many of the most common trackers that follow what you do online.
|
||||
cfr-protections-panel-link-text = Learn more
|
||||
|
||||
## What's New toolbar button and panel
|
||||
|
||||
# This string is used by screen readers to offer a text based alternative for
|
||||
|
@ -153,3 +153,9 @@ protections-panel-cookie-banner-view-turn-on-label =
|
||||
protections-panel-report-broken-site =
|
||||
.label = Report broken site
|
||||
.title = Report broken site
|
||||
|
||||
## Protections panel info message
|
||||
|
||||
cfr-protections-panel-header = Browse without being followed
|
||||
cfr-protections-panel-body = Keep your data to yourself. { -brand-short-name } protects you from many of the most common trackers that follow what you do online.
|
||||
cfr-protections-panel-link-text = Learn more
|
||||
|
@ -0,0 +1,24 @@
|
||||
# Any copyright is dedicated to the Public Domain.
|
||||
# http://creativecommons.org/publicdomain/zero/1.0/
|
||||
|
||||
from fluent.migrate.helpers import transforms_from
|
||||
|
||||
|
||||
def migrate(ctx):
|
||||
"""Bug 1863022 - Move Protection Panel Message to calling code, part {index}"""
|
||||
|
||||
source = "browser/browser/newtab/asrouter.ftl"
|
||||
target = "browser/browser/protectionsPanel.ftl"
|
||||
|
||||
ctx.add_transforms(
|
||||
target,
|
||||
target,
|
||||
transforms_from(
|
||||
"""
|
||||
cfr-protections-panel-header = {COPY_PATTERN(from_path, "cfr-protections-panel-header")}
|
||||
cfr-protections-panel-body = {COPY_PATTERN(from_path, "cfr-protections-panel-body")}
|
||||
cfr-protections-panel-link-text = {COPY_PATTERN(from_path, "cfr-protections-panel-link-text")}
|
||||
""",
|
||||
from_path=source,
|
||||
),
|
||||
)
|
@ -2497,7 +2497,10 @@ security.ui.app_menu:
|
||||
|
||||
security.ui.protectionspopup:
|
||||
open:
|
||||
objects: ["protections_popup"]
|
||||
objects: ["protections_popup", "protectionspopup_cfr",]
|
||||
extra_keys:
|
||||
message: >
|
||||
For protectionspopup_cfr, the message ID.
|
||||
bug_numbers:
|
||||
- 1560327
|
||||
- 1607488
|
||||
@ -2534,7 +2537,11 @@ security.ui.protectionspopup:
|
||||
"milestone_message",
|
||||
"cookieb_toggle_on",
|
||||
"cookieb_toggle_off",
|
||||
"protectionspopup_cfr",
|
||||
]
|
||||
extra_keys:
|
||||
message: >
|
||||
For protectionspopup_cfr, the message ID.
|
||||
bug_numbers:
|
||||
- 1560327
|
||||
- 1602015
|
||||
|
Loading…
x
Reference in New Issue
Block a user