Bug 1753746 - PBM messaging devtool integration r=pdahiya,mconley

Differential Revision: https://phabricator.services.mozilla.com/D145808
This commit is contained in:
Punam Dahiya 2022-10-31 15:21:56 +00:00
Родитель a2123f2d55
Коммит 3cfcd785c8
9 изменённых файлов: 447 добавлений и 62 удалений

Просмотреть файл

@ -319,7 +319,7 @@ let JSWINDOWACTORS = {
},
},
matches: ["about:privatebrowsing"],
matches: ["about:privatebrowsing*"],
},
AboutProtections: {
@ -741,7 +741,7 @@ let JSWINDOWACTORS = {
"about:home*",
"about:newtab*",
"about:welcome*",
"about:privatebrowsing",
"about:privatebrowsing*",
],
remoteTypes: ["privilegedabout"],
},

Просмотреть файл

@ -91,6 +91,7 @@ class ASRouterChild extends JSWindowActorChild {
case msg.EXPIRE_QUERY_CACHE:
case msg.FORCE_WHATSNEW_PANEL:
case msg.CLOSE_WHATSNEW_PANEL:
case msg.FORCE_PRIVATE_BROWSING_WINDOW:
case msg.IMPRESSION:
case msg.RESET_PROVIDER_PREF:
case msg.SET_PROVIDER_USER_PREF:

Просмотреть файл

@ -33,6 +33,7 @@ const MESSAGE_TYPE_LIST = [
"EXPIRE_QUERY_CACHE",
"FORCE_ATTRIBUTION",
"FORCE_WHATSNEW_PANEL",
"FORCE_PRIVATE_BROWSING_WINDOW",
"CLOSE_WHATSNEW_PANEL",
"OVERRIDE_MESSAGE",
"MODIFY_MESSAGE_JSON",

Просмотреть файл

@ -494,7 +494,10 @@ export class ASRouterAdminInner extends React.PureComponent {
this.setAttribution = this.setAttribution.bind(this);
this.onCopyTargetingParams = this.onCopyTargetingParams.bind(this);
this.onNewTargetingParams = this.onNewTargetingParams.bind(this);
this.resetPanel = this.resetPanel.bind(this);
this.handleOpenPB = this.handleOpenPB.bind(this);
this.selectPBMessage = this.selectPBMessage.bind(this);
this.resetPBJSON = this.resetPBJSON.bind(this);
this.resetPBMessageState = this.resetPBMessageState.bind(this);
this.toggleJSON = this.toggleJSON.bind(this);
this.toggleAllMessages = this.toggleAllMessages.bind(this);
this.resetGroups = this.resetGroups.bind(this);
@ -506,6 +509,7 @@ export class ASRouterAdminInner extends React.PureComponent {
messageGroupsFilter: "all",
collapsedMessages: [],
modifiedMessages: [],
selectedPBMessage: "",
evaluationStatus: {},
stringTargetingParameters: null,
newStringTargetingParameters: null,
@ -582,30 +586,6 @@ export class ASRouterAdminInner extends React.PureComponent {
}));
}
resetAllJSON() {
let messageCheckboxes = document.querySelectorAll('input[type="checkbox"]');
for (const checkbox of messageCheckboxes) {
let trimmedId = checkbox.id.replace(" checkbox", "");
let message = this.state.messages.filter(msg => msg.id === trimmedId);
let msgId = message[0].id;
document.getElementById(`${msgId}-textarea`).value = JSON.stringify(
message[0],
null,
2
);
}
this.setState({
WNMessages: [],
});
}
resetPanel() {
this.resetAllJSON();
}
handleOverride(id) {
return () =>
ASRouterUtils.overrideMessage(id).then(state => {
@ -616,6 +596,39 @@ export class ASRouterAdminInner extends React.PureComponent {
});
}
resetPBMessageState() {
// Iterate over Private Browsing messages and block/unblock each one to clear impressions
const PBMessages = this.state.messages.filter(
message => message.template === "pb_newtab"
); // messages from state go here
PBMessages.forEach(message => {
if (message?.id) {
ASRouterUtils.blockById(message.id);
ASRouterUtils.unblockById(message.id);
}
});
// Clear the selected messages & radio buttons
document.getElementById("clear radio").checked = true;
this.selectPBMessage("clear");
}
resetPBJSON(msg) {
// reset the displayed JSON for the given message
document.getElementById(`${msg.id}-textarea`).value = JSON.stringify(
msg,
null,
2
);
}
handleOpenPB() {
ASRouterUtils.sendMessage({
type: "FORCE_PRIVATE_BROWSING_WINDOW",
data: { message: { content: this.state.selectedPBMessage } },
});
}
expireCache() {
ASRouterUtils.sendMessage({ type: "EXPIRE_QUERY_CACHE" });
}
@ -919,6 +932,27 @@ export class ASRouterAdminInner extends React.PureComponent {
);
}
selectPBMessage(msgId) {
if (msgId === "clear") {
this.setState({
selectedPBMessage: "",
});
} else {
let selected = document.getElementById(`${msgId} radio`);
let msg = JSON.parse(document.getElementById(`${msgId}-textarea`).value);
if (selected.checked) {
this.setState({
selectedPBMessage: msg?.content,
});
} else {
this.setState({
selectedPBMessage: "",
});
}
}
}
modifyJson(content) {
const message = JSON.parse(
document.getElementById(`${content.id}-textarea`).value
@ -931,6 +965,75 @@ export class ASRouterAdminInner extends React.PureComponent {
});
}
renderPBMessageItem(msg) {
const isBlocked =
this.state.messageBlockList.includes(msg.id) ||
this.state.messageBlockList.includes(msg.campaign);
const impressions = this.state.messageImpressions[msg.id]
? this.state.messageImpressions[msg.id].length
: 0;
const isCollapsed = this.state.collapsedMessages.includes(msg.id);
let itemClassName = "message-item";
if (isBlocked) {
itemClassName += " blocked";
}
return (
<tr className={itemClassName} key={`${msg.id}-${msg.provider}`}>
<td className="message-id">
<span>
{msg.id} <br />
<br />({impressions} impressions)
</span>
</td>
<td>
<ToggleMessageJSON
msgId={`${msg.id}`}
toggleJSON={this.toggleJSON}
isCollapsed={isCollapsed}
/>
</td>
<td>
<input
type="radio"
id={`${msg.id} radio`}
name="PB_message_radio"
style={{ marginBottom: 20 }}
onClick={() => this.selectPBMessage(msg.id)}
disabled={isBlocked}
/>
<button
className={`button ${isBlocked ? "" : " primary"}`}
onClick={
isBlocked ? this.handleUnblock(msg) : this.handleBlock(msg)
}
>
{isBlocked ? "Unblock" : "Block"}
</button>
<button
className="ASRouterButton slim button"
onClick={e => this.resetPBJSON(msg)}
>
Reset JSON
</button>
</td>
<td className={`message-summary`}>
<pre className={isCollapsed ? "collapsed" : "expanded"}>
<textarea
id={`${msg.id}-textarea`}
className="wnp-textarea"
name={msg.id}
>
{JSON.stringify(msg, null, 2)}
</textarea>
</pre>
</td>
</tr>
);
}
toggleAllMessages(messagesToShow) {
if (this.state.collapsedMessages.length) {
this.setState({
@ -953,7 +1056,9 @@ export class ASRouterAdminInner extends React.PureComponent {
this.state.messageFilter === "all"
? this.state.messages
: this.state.messages.filter(
message => message.provider === this.state.messageFilter
message =>
message.provider === this.state.messageFilter &&
message.template !== "pb_newtab"
);
return (
@ -999,6 +1104,22 @@ export class ASRouterAdminInner extends React.PureComponent {
);
}
renderPBMessages() {
if (!this.state.messages) {
return null;
}
const messagesToShow = this.state.messages.filter(
message => message.template === "pb_newtab"
);
return (
<table>
<tbody>
{messagesToShow.map(msg => this.renderPBMessageItem(msg))}
</tbody>
</table>
);
}
renderMessageFilter() {
if (!this.state.providers) {
return null;
@ -1523,9 +1644,78 @@ export class ASRouterAdminInner extends React.PureComponent {
return <p>No errors</p>;
}
renderPBTab() {
if (!this.state.messages) {
return null;
}
let messagesToShow = this.state.messages.filter(
message => message.template === "pb_newtab"
);
return (
<div>
<p className="helpLink">
<span className="icon icon-small-spacer icon-info" />{" "}
<span>
To view an available message, select its radio button and click
"Open a Private Browsing Window".
<br />
To modify a message, make changes to the JSON first, then select the
radio button. (To make new changes, click "Reset Message State",
make your changes, and reselect the radio button.)
<br />
Click "Reset Message State" to clear all message impressions and
view messages in a clean state.
<br />
Note that ContentSearch functions do not work in debug mode.
</span>
</p>
<div>
<button
className="ASRouterButton primary button"
onClick={this.handleOpenPB}
>
Open a Private Browsing Window
</button>
<button
className="ASRouterButton primary button"
style={{ marginInlineStart: 12 }}
onClick={this.resetPBMessageState}
>
Reset Message State
</button>
<br />
<input
type="radio"
id={`clear radio`}
name="PB_message_radio"
value="clearPBMessage"
style={{ display: "none" }}
/>
<h2>Messages</h2>
<button
className="ASRouterButton slim button"
// eslint-disable-next-line react/jsx-no-bind
onClick={e => this.toggleAllMessages(messagesToShow)}
>
Collapse/Expand All
</button>
{this.renderPBMessages()}
</div>
</div>
);
}
getSection() {
const [section] = this.props.location.routes;
switch (section) {
case "private":
return (
<React.Fragment>
<h2>Private Browsing Messages</h2>
{this.renderPBTab()}
</React.Fragment>
);
case "targeting":
return (
<React.Fragment>
@ -1637,6 +1827,9 @@ export class ASRouterAdminInner extends React.PureComponent {
<li>
<a href="#devtools">General</a>
</li>
<li>
<a href="#devtools-private">Private Browsing</a>
</li>
<li>
<a href="#devtools-targeting">Targeting</a>
</li>

Просмотреть файл

@ -425,7 +425,7 @@ const actionUtils = {
const MESSAGE_TYPE_LIST = ["BLOCK_MESSAGE_BY_ID", "USER_ACTION", "IMPRESSION", "TRIGGER", "NEWTAB_MESSAGE_REQUEST", // PB is Private Browsing
"PBNEWTAB_MESSAGE_REQUEST", "DOORHANGER_TELEMETRY", "TOOLBAR_BADGE_TELEMETRY", "TOOLBAR_PANEL_TELEMETRY", "MOMENTS_PAGE_TELEMETRY", "INFOBAR_TELEMETRY", "SPOTLIGHT_TELEMETRY", "TOAST_NOTIFICATION_TELEMETRY", "AS_ROUTER_TELEMETRY_USER_EVENT", // Admin types
"ADMIN_CONNECT_STATE", "UNBLOCK_MESSAGE_BY_ID", "UNBLOCK_ALL", "BLOCK_BUNDLE", "UNBLOCK_BUNDLE", "DISABLE_PROVIDER", "ENABLE_PROVIDER", "EVALUATE_JEXL_EXPRESSION", "EXPIRE_QUERY_CACHE", "FORCE_ATTRIBUTION", "FORCE_WHATSNEW_PANEL", "CLOSE_WHATSNEW_PANEL", "OVERRIDE_MESSAGE", "MODIFY_MESSAGE_JSON", "RESET_PROVIDER_PREF", "SET_PROVIDER_USER_PREF", "RESET_GROUPS_STATE"];
"ADMIN_CONNECT_STATE", "UNBLOCK_MESSAGE_BY_ID", "UNBLOCK_ALL", "BLOCK_BUNDLE", "UNBLOCK_BUNDLE", "DISABLE_PROVIDER", "ENABLE_PROVIDER", "EVALUATE_JEXL_EXPRESSION", "EXPIRE_QUERY_CACHE", "FORCE_ATTRIBUTION", "FORCE_WHATSNEW_PANEL", "FORCE_PRIVATE_BROWSING_WINDOW", "CLOSE_WHATSNEW_PANEL", "OVERRIDE_MESSAGE", "MODIFY_MESSAGE_JSON", "RESET_PROVIDER_PREF", "SET_PROVIDER_USER_PREF", "RESET_GROUPS_STATE"];
const MESSAGE_TYPE_HASH = MESSAGE_TYPE_LIST.reduce((hash, value) => {
hash[value] = value;
return hash;
@ -975,7 +975,10 @@ class ASRouterAdminInner extends (external_React_default()).PureComponent {
this.setAttribution = this.setAttribution.bind(this);
this.onCopyTargetingParams = this.onCopyTargetingParams.bind(this);
this.onNewTargetingParams = this.onNewTargetingParams.bind(this);
this.resetPanel = this.resetPanel.bind(this);
this.handleOpenPB = this.handleOpenPB.bind(this);
this.selectPBMessage = this.selectPBMessage.bind(this);
this.resetPBJSON = this.resetPBJSON.bind(this);
this.resetPBMessageState = this.resetPBMessageState.bind(this);
this.toggleJSON = this.toggleJSON.bind(this);
this.toggleAllMessages = this.toggleAllMessages.bind(this);
this.resetGroups = this.resetGroups.bind(this);
@ -987,6 +990,7 @@ class ASRouterAdminInner extends (external_React_default()).PureComponent {
messageGroupsFilter: "all",
collapsedMessages: [],
modifiedMessages: [],
selectedPBMessage: "",
evaluationStatus: {},
stringTargetingParameters: null,
newStringTargetingParameters: null,
@ -1063,25 +1067,6 @@ class ASRouterAdminInner extends (external_React_default()).PureComponent {
}));
}
resetAllJSON() {
let messageCheckboxes = document.querySelectorAll('input[type="checkbox"]');
for (const checkbox of messageCheckboxes) {
let trimmedId = checkbox.id.replace(" checkbox", "");
let message = this.state.messages.filter(msg => msg.id === trimmedId);
let msgId = message[0].id;
document.getElementById(`${msgId}-textarea`).value = JSON.stringify(message[0], null, 2);
}
this.setState({
WNMessages: []
});
}
resetPanel() {
this.resetAllJSON();
}
handleOverride(id) {
return () => ASRouterUtils.overrideMessage(id).then(state => {
this.setStateFromParent(state);
@ -1091,6 +1076,37 @@ class ASRouterAdminInner extends (external_React_default()).PureComponent {
});
}
resetPBMessageState() {
// Iterate over Private Browsing messages and block/unblock each one to clear impressions
const PBMessages = this.state.messages.filter(message => message.template === "pb_newtab"); // messages from state go here
PBMessages.forEach(message => {
if (message !== null && message !== void 0 && message.id) {
ASRouterUtils.blockById(message.id);
ASRouterUtils.unblockById(message.id);
}
}); // Clear the selected messages & radio buttons
document.getElementById("clear radio").checked = true;
this.selectPBMessage("clear");
}
resetPBJSON(msg) {
// reset the displayed JSON for the given message
document.getElementById(`${msg.id}-textarea`).value = JSON.stringify(msg, null, 2);
}
handleOpenPB() {
ASRouterUtils.sendMessage({
type: "FORCE_PRIVATE_BROWSING_WINDOW",
data: {
message: {
content: this.state.selectedPBMessage
}
}
});
}
expireCache() {
ASRouterUtils.sendMessage({
type: "EXPIRE_QUERY_CACHE"
@ -1377,6 +1393,27 @@ class ASRouterAdminInner extends (external_React_default()).PureComponent {
}, JSON.stringify(msg, null, 2))))));
}
selectPBMessage(msgId) {
if (msgId === "clear") {
this.setState({
selectedPBMessage: ""
});
} else {
let selected = document.getElementById(`${msgId} radio`);
let msg = JSON.parse(document.getElementById(`${msgId}-textarea`).value);
if (selected.checked) {
this.setState({
selectedPBMessage: msg === null || msg === void 0 ? void 0 : msg.content
});
} else {
this.setState({
selectedPBMessage: ""
});
}
}
}
modifyJson(content) {
const message = JSON.parse(document.getElementById(`${content.id}-textarea`).value);
return ASRouterUtils.modifyMessageJson(message).then(state => {
@ -1387,6 +1424,51 @@ class ASRouterAdminInner extends (external_React_default()).PureComponent {
});
}
renderPBMessageItem(msg) {
const isBlocked = this.state.messageBlockList.includes(msg.id) || this.state.messageBlockList.includes(msg.campaign);
const impressions = this.state.messageImpressions[msg.id] ? this.state.messageImpressions[msg.id].length : 0;
const isCollapsed = this.state.collapsedMessages.includes(msg.id);
let itemClassName = "message-item";
if (isBlocked) {
itemClassName += " blocked";
}
return /*#__PURE__*/external_React_default().createElement("tr", {
className: itemClassName,
key: `${msg.id}-${msg.provider}`
}, /*#__PURE__*/external_React_default().createElement("td", {
className: "message-id"
}, /*#__PURE__*/external_React_default().createElement("span", null, msg.id, " ", /*#__PURE__*/external_React_default().createElement("br", null), /*#__PURE__*/external_React_default().createElement("br", null), "(", impressions, " impressions)")), /*#__PURE__*/external_React_default().createElement("td", null, /*#__PURE__*/external_React_default().createElement(ToggleMessageJSON, {
msgId: `${msg.id}`,
toggleJSON: this.toggleJSON,
isCollapsed: isCollapsed
})), /*#__PURE__*/external_React_default().createElement("td", null, /*#__PURE__*/external_React_default().createElement("input", {
type: "radio",
id: `${msg.id} radio`,
name: "PB_message_radio",
style: {
marginBottom: 20
},
onClick: () => this.selectPBMessage(msg.id),
disabled: isBlocked
}), /*#__PURE__*/external_React_default().createElement("button", {
className: `button ${isBlocked ? "" : " primary"}`,
onClick: isBlocked ? this.handleUnblock(msg) : this.handleBlock(msg)
}, isBlocked ? "Unblock" : "Block"), /*#__PURE__*/external_React_default().createElement("button", {
className: "ASRouterButton slim button",
onClick: e => this.resetPBJSON(msg)
}, "Reset JSON")), /*#__PURE__*/external_React_default().createElement("td", {
className: `message-summary`
}, /*#__PURE__*/external_React_default().createElement("pre", {
className: isCollapsed ? "collapsed" : "expanded"
}, /*#__PURE__*/external_React_default().createElement("textarea", {
id: `${msg.id}-textarea`,
className: "wnp-textarea",
name: msg.id
}, JSON.stringify(msg, null, 2)))));
}
toggleAllMessages(messagesToShow) {
if (this.state.collapsedMessages.length) {
this.setState({
@ -1406,7 +1488,7 @@ class ASRouterAdminInner extends (external_React_default()).PureComponent {
return null;
}
const messagesToShow = this.state.messageFilter === "all" ? this.state.messages : this.state.messages.filter(message => message.provider === this.state.messageFilter);
const messagesToShow = this.state.messageFilter === "all" ? this.state.messages : this.state.messages.filter(message => message.provider === this.state.messageFilter && message.template !== "pb_newtab");
return /*#__PURE__*/external_React_default().createElement("div", null, /*#__PURE__*/external_React_default().createElement("button", {
className: "ASRouterButton slim" // eslint-disable-next-line react/jsx-no-bind
,
@ -1427,6 +1509,15 @@ class ASRouterAdminInner extends (external_React_default()).PureComponent {
return /*#__PURE__*/external_React_default().createElement("table", null, /*#__PURE__*/external_React_default().createElement("tbody", null, messagesToShow.map(msg => this.renderMessageItem(msg))));
}
renderPBMessages() {
if (!this.state.messages) {
return null;
}
const messagesToShow = this.state.messages.filter(message => message.template === "pb_newtab");
return /*#__PURE__*/external_React_default().createElement("table", null, /*#__PURE__*/external_React_default().createElement("tbody", null, messagesToShow.map(msg => this.renderPBMessageItem(msg))));
}
renderMessageFilter() {
if (!this.state.providers) {
return null;
@ -1716,10 +1807,47 @@ class ASRouterAdminInner extends (external_React_default()).PureComponent {
return /*#__PURE__*/external_React_default().createElement("p", null, "No errors");
}
renderPBTab() {
if (!this.state.messages) {
return null;
}
let messagesToShow = this.state.messages.filter(message => message.template === "pb_newtab");
return /*#__PURE__*/external_React_default().createElement("div", null, /*#__PURE__*/external_React_default().createElement("p", {
className: "helpLink"
}, /*#__PURE__*/external_React_default().createElement("span", {
className: "icon icon-small-spacer icon-info"
}), " ", /*#__PURE__*/external_React_default().createElement("span", null, "To view an available message, select its radio button and click \"Open a Private Browsing Window\".", /*#__PURE__*/external_React_default().createElement("br", null), "To modify a message, make changes to the JSON first, then select the radio button. (To make new changes, click \"Reset Message State\", make your changes, and reselect the radio button.)", /*#__PURE__*/external_React_default().createElement("br", null), "Click \"Reset Message State\" to clear all message impressions and view messages in a clean state.", /*#__PURE__*/external_React_default().createElement("br", null), "Note that ContentSearch functions do not work in debug mode.")), /*#__PURE__*/external_React_default().createElement("div", null, /*#__PURE__*/external_React_default().createElement("button", {
className: "ASRouterButton primary button",
onClick: this.handleOpenPB
}, "Open a Private Browsing Window"), /*#__PURE__*/external_React_default().createElement("button", {
className: "ASRouterButton primary button",
style: {
marginInlineStart: 12
},
onClick: this.resetPBMessageState
}, "Reset Message State"), /*#__PURE__*/external_React_default().createElement("br", null), /*#__PURE__*/external_React_default().createElement("input", {
type: "radio",
id: `clear radio`,
name: "PB_message_radio",
value: "clearPBMessage",
style: {
display: "none"
}
}), /*#__PURE__*/external_React_default().createElement("h2", null, "Messages"), /*#__PURE__*/external_React_default().createElement("button", {
className: "ASRouterButton slim button" // eslint-disable-next-line react/jsx-no-bind
,
onClick: e => this.toggleAllMessages(messagesToShow)
}, "Collapse/Expand All"), this.renderPBMessages()));
}
getSection() {
const [section] = this.props.location.routes;
switch (section) {
case "private":
return /*#__PURE__*/external_React_default().createElement((external_React_default()).Fragment, null, /*#__PURE__*/external_React_default().createElement("h2", null, "Private Browsing Messages"), this.renderPBTab());
case "targeting":
return /*#__PURE__*/external_React_default().createElement((external_React_default()).Fragment, null, /*#__PURE__*/external_React_default().createElement("h2", null, "Targeting Utilities"), /*#__PURE__*/external_React_default().createElement("button", {
className: "button",
@ -1775,6 +1903,8 @@ class ASRouterAdminInner extends (external_React_default()).PureComponent {
}, /*#__PURE__*/external_React_default().createElement("ul", null, /*#__PURE__*/external_React_default().createElement("li", null, /*#__PURE__*/external_React_default().createElement("a", {
href: "#devtools"
}, "General")), /*#__PURE__*/external_React_default().createElement("li", null, /*#__PURE__*/external_React_default().createElement("a", {
href: "#devtools-private"
}, "Private Browsing")), /*#__PURE__*/external_React_default().createElement("li", null, /*#__PURE__*/external_React_default().createElement("a", {
href: "#devtools-targeting"
}, "Targeting")), /*#__PURE__*/external_React_default().createElement("li", null, /*#__PURE__*/external_React_default().createElement("a", {
href: "#devtools-groups"

Просмотреть файл

@ -32,6 +32,7 @@ XPCOMUtils.defineLazyModuleGetters(lazy, {
RemoteImages: "resource://activity-stream/lib/RemoteImages.jsm",
RemoteL10n: "resource://activity-stream/lib/RemoteL10n.jsm",
ExperimentAPI: "resource://nimbus/ExperimentAPI.jsm",
setTimeout: "resource://gre/modules/Timer.jsm",
NimbusFeatures: "resource://nimbus/ExperimentAPI.jsm",
SpecialMessageActions:
"resource://messaging-system/lib/SpecialMessageActions.jsm",
@ -598,6 +599,7 @@ class _ASRouter {
this._onExperimentForceEnrolled = this._onExperimentForceEnrolled.bind(
this
);
this.forcePBWindow = this.forcePBWindow.bind(this);
Services.telemetry.setEventRecordingEnabled(REACH_EVENT_CATEGORY, true);
}
@ -1999,6 +2001,35 @@ class _ASRouter {
lazy.RemoteImages.prefetchImagesFor(messages);
}
}
async forcePBWindow(browser, msg) {
const privateBrowserOpener = await new Promise((
resolveOnContentBrowserCreated // wrap this in a promise to give back the right browser
) =>
browser.ownerGlobal.openTrustedLinkIn(
"about:privatebrowsing?debug",
"window",
{
private: true,
triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(
{}
),
csp: null,
resolveOnContentBrowserCreated,
opener: "devtools",
}
)
);
lazy.setTimeout(() => {
// setTimeout is necessary to make sure the private browsing window has a chance to open before the message is sent
privateBrowserOpener.browsingContext.currentWindowGlobal
.getActor("AboutPrivateBrowsing")
.sendAsyncMessage("ShowDevToolsMessage", msg);
}, 100);
return privateBrowserOpener;
}
}
/**

Просмотреть файл

@ -147,6 +147,9 @@ class ASRouterParentProcessMessageHandler {
case msg.FORCE_ATTRIBUTION: {
return this._router.forceAttribution(data);
}
case msg.FORCE_PRIVATE_BROWSING_WINDOW: {
return this._router.forcePBWindow(browser, data.message);
}
case msg.FORCE_WHATSNEW_PANEL: {
return this._router.forceWNPanel(browser);
}

Просмотреть файл

@ -18,6 +18,7 @@ describe("ASRouterParentProcessMessageHandler", () => {
"forceAttribution",
"forceWNPanel",
"closeWNPanel",
"forcePBWindow",
"resetGroupsState",
].forEach(method => sandbox.stub(router, `${method}`).resolves());
[
@ -356,6 +357,17 @@ describe("ASRouterParentProcessMessageHandler", () => {
assert.calledWith(config.router.closeWNPanel, { ownerGlobal: {} });
});
});
describe("FORCE_PRIVATE_BROWSING_WINDOW action", () => {
it("default calls forcePBWindow", () => {
handler.handleMessage(
msg.FORCE_PRIVATE_BROWSING_WINDOW,
{},
{ browser: { ownerGlobal: {} } }
);
assert.calledOnce(config.router.forcePBWindow);
assert.calledWith(config.router.forcePBWindow, { ownerGlobal: {} });
});
});
describe("MODIFY_MESSAGE_JSON action", () => {
it("default calls routeCFRMessage", async () => {
const result = await handler.handleMessage(

Просмотреть файл

@ -240,10 +240,10 @@ async function handlePromoOnPreload(message) {
}
}
async function setupMessageConfig() {
let config = null;
async function setupMessageConfig(config = null) {
let message = null;
if (!config) {
let hideDefault = window.PrivateBrowsingShouldHideDefault();
try {
let response = await window.ASRouterMessage({
@ -254,6 +254,7 @@ async function setupMessageConfig() {
config = message?.content;
config.messageId = message?.id;
} catch (e) {}
}
await renderInfo(config);
let hasRendered = await renderPromo(config);
@ -265,7 +266,20 @@ async function setupMessageConfig() {
document.documentElement.setAttribute("PrivateBrowsingRenderComplete", true);
}
let SHOW_DEVTOOLS_MESSAGE = "ShowDevToolsMessage";
function showDevToolsMessage(msg) {
msg.data.content.messageId = "DEVTOOLS_MESSAGE";
setupMessageConfig(msg?.data?.content);
RPMRemoveMessageListener(SHOW_DEVTOOLS_MESSAGE, showDevToolsMessage);
}
document.addEventListener("DOMContentLoaded", function() {
// check the url to see if we're rendering a devtools message
if (document.location.toString().includes("debug")) {
RPMAddMessageListener(SHOW_DEVTOOLS_MESSAGE, showDevToolsMessage);
return;
}
if (!RPMIsWindowPrivate()) {
document.documentElement.classList.remove("private");
document.documentElement.classList.add("normal");