diff options
Diffstat (limited to 'browser/components/messagepreview')
8 files changed, 282 insertions, 0 deletions
diff --git a/browser/components/messagepreview/actors/AboutMessagePreviewChild.sys.mjs b/browser/components/messagepreview/actors/AboutMessagePreviewChild.sys.mjs new file mode 100644 index 0000000000..15c100328b --- /dev/null +++ b/browser/components/messagepreview/actors/AboutMessagePreviewChild.sys.mjs @@ -0,0 +1,58 @@ +/* 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/. */ + +import { AppConstants } from "resource://gre/modules/AppConstants.sys.mjs"; + +export class AboutMessagePreviewChild extends JSWindowActorChild { + handleEvent(event) { + console.log(`Received page event ${event.type}`); + } + + actorCreated() { + this.exportFunctions(); + } + + exportFunctions() { + if (this.contentWindow) { + for (const name of ["MPShowMessage", "MPIsEnabled", "MPShouldShowHint"]) { + Cu.exportFunction(this[name].bind(this), this.contentWindow, { + defineAs: name, + }); + } + } + } + + /** + * Check if the Message Preview feature is enabled. This reflects the value of + * the pref `browser.newtabpage.activity-stream.asrouter.devtoolsEnabled`. + * + * @returns {boolean} + */ + MPIsEnabled() { + return Services.prefs.getBoolPref( + "browser.newtabpage.activity-stream.asrouter.devtoolsEnabled", + false + ); + } + + /** + * Route a message to the parent process to be displayed with the relevant + * messaging surface. + * + * @param {object} message + */ + MPShowMessage(message) { + this.sendAsyncMessage(`MessagePreview:SHOW_MESSAGE`, message); + } + + /** + * Check if a hint should be shown about how to enable Message Preview. The + * hint is only displayed in local/unofficial builds. + * + * @returns {boolean} + */ + MPShouldShowHint() { + return !this.MPIsEnabled() && !AppConstants.MOZILLA_OFFICIAL; + } +} diff --git a/browser/components/messagepreview/actors/AboutMessagePreviewParent.sys.mjs b/browser/components/messagepreview/actors/AboutMessagePreviewParent.sys.mjs new file mode 100644 index 0000000000..7651170fef --- /dev/null +++ b/browser/components/messagepreview/actors/AboutMessagePreviewParent.sys.mjs @@ -0,0 +1,93 @@ +/* vim: set ts=2 sw=2 sts=2 et tw=80: */ +/* 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/. */ + +import { XPCOMUtils } from "resource://gre/modules/XPCOMUtils.sys.mjs"; +import { JsonSchema } from "resource://gre/modules/JsonSchema.sys.mjs"; + +const lazy = {}; + +ChromeUtils.defineESModuleGetters(lazy, { + SpecialMessageActions: + "resource://messaging-system/lib/SpecialMessageActions.sys.mjs", +}); +XPCOMUtils.defineLazyModuleGetters(lazy, { + InfoBar: "resource://activity-stream/lib/InfoBar.jsm", + Spotlight: "resource://activity-stream/lib/Spotlight.jsm", + CFRPageActions: "resource://activity-stream/lib/CFRPageActions.jsm", +}); + +function dispatchCFRAction({ type, data }, browser) { + if (type === "USER_ACTION") { + lazy.SpecialMessageActions.handleAction(data, browser); + } +} + +export class AboutMessagePreviewParent extends JSWindowActorParent { + showInfoBar(message, browser) { + lazy.InfoBar.showInfoBarMessage(browser, message, dispatchCFRAction); + } + + showSpotlight(message, browser) { + lazy.Spotlight.showSpotlightDialog(browser, message, () => {}); + } + + showCFR(message, browser) { + lazy.CFRPageActions.forceRecommendation( + browser, + message, + dispatchCFRAction + ); + } + + async showMessage(data) { + let message; + try { + message = JSON.parse(data); + } catch (e) { + console.error("Could not parse message", e); + return; + } + + const schema = await fetch( + "resource://activity-stream/schemas/MessagingExperiment.schema.json", + { credentials: "omit" } + ).then(rsp => rsp.json()); + + const result = JsonSchema.validate(message, schema); + if (!result.valid) { + console.error( + `Invalid message: ${JSON.stringify(result.errors, undefined, 2)}` + ); + } + + const browser = + this.browsingContext.topChromeWindow.gBrowser.selectedBrowser; + switch (message.template) { + case "infobar": + this.showInfoBar(message, browser); + return; + case "spotlight": + this.showSpotlight(message, browser); + return; + case "cfr_doorhanger": + this.showCFR(message, browser); + return; + default: + console.error(`Unsupported message template ${message.template}`); + } + } + + receiveMessage(message) { + const { name, data } = message; + + switch (name) { + case "MessagePreview:SHOW_MESSAGE": + this.showMessage(data); + break; + default: + console.log(`Unexpected event ${name} was not handled.`); + } + } +} diff --git a/browser/components/messagepreview/jar.mn b/browser/components/messagepreview/jar.mn new file mode 100644 index 0000000000..110476d794 --- /dev/null +++ b/browser/components/messagepreview/jar.mn @@ -0,0 +1,9 @@ +# 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/. + +browser.jar: + content/browser/messagepreview/messagepreview.html + content/browser/messagepreview/messagepreview.js + content/browser/messagepreview/limelight.svg + content/browser/messagepreview/messagepreview.css diff --git a/browser/components/messagepreview/limelight.svg b/browser/components/messagepreview/limelight.svg new file mode 100644 index 0000000000..938a17b3b2 --- /dev/null +++ b/browser/components/messagepreview/limelight.svg @@ -0,0 +1,4 @@ +<!-- 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/. --> +<svg version="1.0" xmlns="http://www.w3.org/2000/svg" width="200pt" height="200pt" viewBox="0 0 200 200" fill="context-fill" fill-opacity="context-fill-opacity"><path d="M118.083 16.167c-7.533 1.183-15.1 6.366-18.816 12.883l-.717 1.267-.283-.617c-1-2.117-4.55-6.317-5.85-6.933-1.517-.734-3.25.316-3.25 1.95 0 .9.183 1.183 1.75 2.7 2.966 2.883 4.883 7 5.666 12.166.134.917.25 2.184.25 2.834l-.016 1.166-1.117.5c-1.367.617-2.767 1.95-3.45 3.3-.367.7-.617.984-.917 1.05-.233.05-1.383.4-2.583.767-2.85.867-5.967 2.383-8.75 4.25-1.233.817-3.033 1.933-4 2.467-3.883 2.166-6.833 4.4-10.1 7.666C58.317 71.117 53.717 80.55 52.317 91.5c-.284 2.133-.267 7.7.016 10.25.634 5.733 2.234 11.133 4.817 16.2 1.85 3.65 3.467 6.05 6.533 9.733 5.784 6.934 10.917 15.7 13.267 22.634l.633 1.85 21.3-.034 21.3-.05.467-1.416c2.233-6.6 7.25-15.417 12.333-21.634.7-.85 1.884-2.316 2.65-3.25 5.45-6.683 8.834-15.033 9.817-24.083.333-3.217.217-8.5-.283-11.733-2.184-14.483-10.734-26.767-23.717-34.117-1-.55-2.233-1.35-2.75-1.733-1.4-1.083-4.233-2.75-6.033-3.567-1.467-.65-4.284-1.633-5.967-2.05-.617-.15-.75-.283-1.133-1.033-.6-1.183-2.05-2.65-3.234-3.283l-1-.534v-1.533a23.86 23.86 0 0 0-.433-4.333l-.1-.45h1.317c2.767 0 6.783-1.034 9.733-2.5 5.3-2.634 10.25-7.55 12.25-12.15.75-1.734 1.233-3.65 1.233-4.867v-.967l-1.116-.35c-1.3-.416-4.5-.583-6.134-.333zM83.533 68.35c.217.083.584.433.8.767.384.55.417.766.4 2.366 0 1.567-.066 1.934-.516 3.15-.867 2.25-2.034 4.017-4.45 6.684-3.384 3.716-4.967 7.4-4.967 11.516.017 1.35.1 2.284.333 3.184.5 1.95.1 3.316-1.367 4.6-2.1 1.85-4.15 1.15-5.616-1.867-1.134-2.333-1.384-3.583-1.384-6.833-.016-2.534.034-3.017.434-4.617 1.016-4 3.416-8.817 6.283-12.55 1.15-1.5 3.633-4.033 4.783-4.85 2.117-1.517 4.084-2.1 5.267-1.55zm44.317 39.267c1.183.616 1.85 1.55 1.95 2.783.1 1.15-.183 1.967-.95 2.817-.75.833-1.417 1.116-2.55 1.116-2.233-.016-3.817-1.783-3.6-4.033.167-1.733 1.783-3.1 3.65-3.133.333 0 .983.2 1.5.45zm4.117 8.916c2.116 1.084 2.483 4.084.683 5.717-.867.783-1.35.967-2.55.933-1.233-.016-2.183-.533-2.867-1.55-.416-.633-.483-.866-.483-1.983 0-1.1.067-1.35.45-1.95 1.083-1.617 2.983-2.083 4.767-1.167zm-9.834 3.5c1.417.667 2.2 2.4 1.8 3.95-.4 1.534-1.3 2.4-2.783 2.717-1.3.25-2.183-.033-3.167-1.017-1.416-1.4-1.533-3.366-.283-4.783 1.183-1.333 2.75-1.65 4.433-.867zm31.684-87.183c-.467.5-1.567 1.717-2.45 2.717s-2.484 2.766-3.55 3.933c-2.434 2.683-2.6 3.133-1.984 5.15.5 1.633.834 1.717 2.467.567 1.45-1.034 3.883-3.467 5.067-5.05 2.25-3.05 2.966-4.584 2.966-6.334 0-1.05-.333-1.533-1.216-1.766-.417-.1-.567 0-1.3.783zM40.25 33.95c-.05.133-.083.6-.083 1.033s-.05.85-.117.9c-.2.217-.55-.266-.667-.916-.116-.75-.483-1-.816-.55-.35.483-.3 2.683.1 3.95.416 1.383 1.216 2.583 3.333 5.05 4.317 5.016 10.717 11.833 11.35 12.1.65.25 1.2.016 2.617-1.167.833-.683 1.033-.967 1.033-1.333 0-.717-2.55-4.25-7.417-10.284-2.733-3.4-4.2-5.366-5.316-7.183-.95-1.533-1.134-1.667-2.634-1.75-1.016-.067-1.3-.033-1.383.15zm133.5 24.733c-.267.084-3.533.684-7.25 1.334-8.15 1.416-8.833 1.55-9.667 1.983-.7.367-1.05.767-1.35 1.633-.233.683-.066 1.9.334 2.383l.3.367 1.816-.283c1-.15 3.584-.417 5.734-.6 4.7-.4 6.15-.583 7.95-1 2.5-.583 3.6-1.35 4.383-3.05.767-1.683.767-1.717.117-2.367-.617-.616-1.284-.733-2.367-.4zm-148.917.434c-.983.166-2.516.766-2.666 1.05-.25.466-.2 1.383.1 1.8.133.2.7.666 1.25 1.033.533.383 2.733 2.05 4.866 3.717 5.517 4.35 7.6 5.916 8.384 6.283 1.35.667 2.7.333 3.633-.883.75-.984.633-1.267-1.1-2.667-.85-.683-2.45-2.1-3.55-3.133-5.767-5.417-7.8-6.884-9.917-7.184a4.07 4.07 0 0 0-1-.016zM161.967 85.65c-3.467.117-3.534.15-3.8 1.767-.35 2.15-.184 2.866.75 3.133.9.267 6.366.817 10.366 1.033 5.467.317 7.534.5 9.934.917 1.033.183 2.05.333 2.25.333.25 0 .683-.3 1.2-.833.45-.467.883-.833.983-.833.333 0 .183-.3-.567-1.1-.416-.434-.75-.85-.75-.934 0-.233.567-.15 1.134.2.733.45 1.033.434 1.033-.066 0-.9-2.65-2.817-4.517-3.267-1.65-.4-10.716-.567-18.016-.35zM23.5 90.433c-4.483.584-5.367.884-6.817 2.234-.65.616-.716.75-.633 1.283.183 1.1-.15 1.05 6.933 1.05 7.734 0 7.5.05 8.917-2.083.483-.734.55-1.284.183-1.634-.55-.566-6.366-1.133-8.583-.85zm54.2 76.434c.05 5.666.083 6.3.383 7.133.4 1.15 5.617 9 6.6 9.95.984.933 2.5 1.817 3.8 2.217 1 .316 1.584.333 10.367.333h9.3l1.3-.417c1.317-.416 2.683-1.2 3.7-2.15.717-.666 5.417-7.683 6.05-9.016.85-1.85.967-2.8.967-8.8v-5.45H77.65l.05 6.2z"/></svg> diff --git a/browser/components/messagepreview/messagepreview.css b/browser/components/messagepreview/messagepreview.css new file mode 100644 index 0000000000..f81c2d2623 --- /dev/null +++ b/browser/components/messagepreview/messagepreview.css @@ -0,0 +1,33 @@ +/* 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/. */ + +html { + position: fixed; +} + +html, +body { + height: 100%; + width: 100%; +} + +body { + background: url(chrome://browser/content/messagepreview/limelight.svg) + center/contain no-repeat; + -moz-context-properties: fill, fill-opacity; + fill: var(--in-content-icon-color); + fill-opacity: 0.2; +} + +.hint-box { + display: flex; + align-items: center; + justify-content: center; +} + +.hint { + max-width: 40em; + font-size: 1.2em; + text-align: center; +} diff --git a/browser/components/messagepreview/messagepreview.html b/browser/components/messagepreview/messagepreview.html new file mode 100644 index 0000000000..57169d3403 --- /dev/null +++ b/browser/components/messagepreview/messagepreview.html @@ -0,0 +1,29 @@ +<!-- +# 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/. +--> +<!DOCTYPE html> + +<html> + <head> + <meta charset="utf-8" /> + <meta + http-equiv="Content-Security-Policy" + content="default-src resource: chrome:; object-src 'none'; img-src data: chrome:;" + /> + <title>about:messagepreview</title> + <link + rel="icon" + href="chrome://browser/content/messagepreview/limelight.svg" + /> + <link rel="stylesheet" href="chrome://global/skin/in-content/common.css" /> + <link + rel="stylesheet" + href="chrome://browser/content/messagepreview/messagepreview.css" + /> + <script src="chrome://browser/content/messagepreview/messagepreview.js"></script> + </head> + + <body></body> +</html> diff --git a/browser/components/messagepreview/messagepreview.js b/browser/components/messagepreview/messagepreview.js new file mode 100644 index 0000000000..48e5fb1ff5 --- /dev/null +++ b/browser/components/messagepreview/messagepreview.js @@ -0,0 +1,39 @@ +/* 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/. */ + +/* global MPShowMessage, MPIsEnabled, MPShouldShowHint */ + +"use strict"; + +function decodeMessageFromUrl() { + const url = new URL(document.location.href); + + if (url.searchParams.has("json")) { + const encodedMessage = url.searchParams.get("json"); + + return atob(encodedMessage); + } + return null; +} + +function showHint() { + document.body.classList.add("hint-box"); + document.body.innerHTML = `<div class="hint">Message preview is not enabled. Enable it in about:config by setting <code>browser.newtabpage.activity-stream.asrouter.devtoolsEnabled</code> to true.</div>`; +} + +const message = decodeMessageFromUrl(); + +if (message) { + // If message preview is enabled, show the message. + if (MPIsEnabled()) { + MPShowMessage(message); + } else if (MPShouldShowHint()) { + // If running in a local build, show a hint about how to enable preview. + if (document.body) { + showHint(); + } else { + document.addEventListener("DOMContentLoaded", showHint, { once: true }); + } + } +} diff --git a/browser/components/messagepreview/moz.build b/browser/components/messagepreview/moz.build new file mode 100644 index 0000000000..5b528d73f7 --- /dev/null +++ b/browser/components/messagepreview/moz.build @@ -0,0 +1,17 @@ +# -*- 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"] + +FINAL_LIBRARY = "browsercomps" + +with Files("**"): + BUG_COMPONENT = ("Firefox", "Messaging System") + +FINAL_TARGET_FILES.actors += [ + "actors/AboutMessagePreviewChild.sys.mjs", + "actors/AboutMessagePreviewParent.sys.mjs", +] |