Bug 1408334 - add form to subscribe to mozilla developer newsletter in about:devtools
MozReview-Commit-ID: JuJqNS3r6NH
--- a/devtools/shim/aboutdevtools/aboutdevtools.css
+++ b/devtools/shim/aboutdevtools/aboutdevtools.css
@@ -1,55 +1,63 @@
-:root {
+/* 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/. */
+
+ :root {
/* Photon color variables used on the aboutdevtools page */
--blue-60: #0060df;
--blue-70: #003eaa;
--blue-80: #002275;
--grey-30: #d7d7db;
+ --grey-90-alpha-30: rgba(12, 12, 13, .3);
+ --grey-90-alpha-40: rgba(12, 12, 13, .4);
+ --grey-90-alpha-50: rgba(12, 12, 13, .5);
+ --red-50: #ff0039;
+ --teal-60: #00c8d7;
--white: #ffffff;
+
+ /* Shared variables */
+ --line-height: 1.5em;
}
html, body {
min-width: 600px;
height: 100%;
}
p {
- line-height: 1.5em;
+ line-height: var(--line-height);
}
.box {
width: 100%;
max-width: 850px;
display: flex;
- align-items: center;
- height: 400px;
flex-shrink: 0;
+ padding: 34px 0 50px 0;
}
.wrapper {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
}
.left-pane {
- width: 360px;
- height: 100%;
+ width: 300px;
+ height: 300px;
background-image: url(images/otter.svg);
- background-size: 80%;
+ background-size: 100%;
background-position: 50%;
background-repeat: no-repeat;
flex-shrink: 0;
-}
-
-.right-pane {
- height: 250px;
+ margin-right: 20px;
}
.features {
max-width: 980px;
border-top: 1px solid var(--grey-30);
}
.features-list {
@@ -75,17 +83,20 @@ p {
font-weight: 300;
margin: 10px 0;
}
.feature-desc {
margin: 1em 20px;
}
-.installpage-link {
+.external,
+.external:hover,
+.external:visited,
+.external:hover:active {
color: var(--blue-60);
-moz-context-properties: fill;
fill: var(--blue-60);
}
.external::after {
content: "";
@@ -103,47 +114,47 @@ p {
.title {
font-weight: 300;
font-size: 32px;
margin-top: 16px;
line-height: 44px;
}
-.installpage-button {
+.main-button {
display: block;
- margin: 2em 0 0 0;
+ margin: 20px 0 0 0;
padding: 10px 20px;
border: none;
border-radius: 2px;
font-size: 15px;
font-weight: 400;
line-height: 21px;
background-color: var(--blue-60);
color: var(--white);
box-shadow: 0 1px 0 rgba(0,0,0,0.23);
cursor: pointer;
}
-.installpage-button:enabled:hover {
+.main-button:enabled:hover {
background-color: var(--blue-70)
}
-.installpage-button:active,
-.installpage-button:hover:active,
-.installpage-button:enabled:hover:active {
+.main-button:active,
+.main-button:hover:active,
+.main-button:enabled:hover:active {
background-color: var(--blue-80);
}
/* Remove light gray outline when clicking on the button */
-.installpage-button::-moz-focus-inner {
+.main-button::-moz-focus-inner {
border: 0;
}
[hidden="true"] {
display: none;
}
footer {
--- a/devtools/shim/aboutdevtools/aboutdevtools.xhtml
+++ b/devtools/shim/aboutdevtools/aboutdevtools.xhtml
@@ -9,17 +9,19 @@
]>
<html xmlns="http://www.w3.org/1999/xhtml" dir="&locale.dir;">
<head>
<title>&aboutDevtools.headTitle;</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>a
<link rel="stylesheet" href="chrome://global/skin/in-content/common.css" type="text/css"/>
<link rel="stylesheet" href="chrome://devtools-shim/content/aboutdevtools/aboutdevtools.css" type="text/css"/>
+ <link rel="stylesheet" href="chrome://devtools-shim/content/aboutdevtools/subscribe.css" type="text/css"/>
<script type="application/javascript" src="chrome://devtools-shim/content/aboutdevtools/aboutdevtools.js"></script>
+ <script type="application/javascript" src="chrome://devtools-shim/content/aboutdevtools/subscribe.js"></script>
</head>
<body>
<div id="install-page" class="wrapper" hidden="true">
<div class="box">
<div class="left-pane" />
<div class="right-pane">
<h1 class="title" id="common-title" hidden="true">&aboutDevtools.enable.title;</h1>
<h1 class="title" id="inspect-title" hidden="true">&aboutDevtools.enable.inspectElementTitle;</h1>
@@ -28,28 +30,57 @@
as we can't lazily load localized strings from dtd -->
<p id="about-debugging-message" hidden="true">&aboutDevtools.enable.aboutDebuggingMessage;</p>
<p id="menu-message" hidden="true">&aboutDevtools.enable.menuMessage;</p>
<p id="key-shortcut-message" hidden="true">&aboutDevtools.enable.keyShortcutMessage;</p>
<p id="inspect-element-message" hidden="true">&aboutDevtools.enable.inspectElementMessage;</p>
<p>&aboutDevtools.enable.commonMessage;</p>
<a class="external installpage-link" href="https://developer.mozilla.org/docs/Tools" target="_blank">&aboutDevtools.enable.learnMoreLink;</a>
- <button class="installpage-button" id="install">&aboutDevtools.enable.installButton;</button>
+ <button class="main-button" id="install">&aboutDevtools.enable.installButton;</button>
</div>
</div>
</div>
<!-- This page, hidden by default is displayed once the add-on is installed -->
<div id="welcome-page" class="wrapper" hidden="true">
<div class="box">
<div class="left-pane" />
<div class="right-pane">
<h1 class="title" >&aboutDevtools.welcome.title;</h1>
<p id="welcome-message">&aboutDevtools.welcome.message;</p>
+
+ <!-- Form dedicated to the newsletter subscription -->
+ <div class="newsletter">
+ <h2 class="newsletter-title">Mozilla Developer Newsletter</h2>
+ <p>Get developer news, tricks and resources sent straight to your inbox.</p>
+
+ <form id="newsletter-form" name="newsletter-form" action="https://www.mozilla.org/en-US/newsletter/" method="post">
+ <input type="hidden" id="fmt" name="fmt" value="H" />
+ <input type="hidden" id="newsletters" name="newsletters" value="app-dev" />
+ <div id="newsletter_errors"></div>
+ <div id="newsletter_email" class="newsletter-form-section">
+ <input type="email" id="email" name="email" class="form_input" required="true" placeholder="Email" />
+ </div>
+
+ <div id="newsletter-privacy" class="newsletter-form-section">
+ <input type="checkbox" id="privacy" name="privacy" required="true" />
+ <label for="privacy">
+ I'm okay with Mozilla handling my info as explained in this <a class="external" href="https://www.mozilla.org/privacy/">Privacy Policy</a>.
+ </label>
+ </div>
+ <div>
+ <button type="submit" class="main-button">Subscribe</button>
+ </div>
+ </form>
+ <div id="newsletter-thanks">
+ <h2>Thanks!</h2>
+ <p>If you haven’t previously confirmed a subscription to a Mozilla-related newsletter you may have to do so. Please check your inbox or your spam filter for an email from us.</p>
+ </div>
+ </div>
</div>
</div>
<div class="features">
<ul class="features-list">
<li class="feature">
<img class="feature-icon" src="chrome://devtools-shim/content/aboutdevtools/images/feature-inspector.svg" alt=""/>
<h3 class="feature-name">Inspector</h3>
new file mode 100644
--- /dev/null
+++ b/devtools/shim/aboutdevtools/subscribe.css
@@ -0,0 +1,93 @@
+/* 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/. */
+
+#newsletter_errors {
+ display: none; /* hide by default */
+ margin-bottom: 20px;
+ border-radius: 2px;
+ padding: 10px;
+ background-color: var(--red-50);
+ color: var(--white);
+}
+
+#newsletter_errors .error:last-child {
+ margin: 0 0 10px 0;
+}
+
+#newsletter_errors .error:last-child {
+ margin-bottom: 0;
+}
+
+#newsletter-thanks {
+ display: none;
+}
+
+.newsletter-form-section {
+ display: block;
+ margin-bottom: 20px;
+ width: 320px;
+}
+
+#newsletter-privacy {
+ display: flex;
+
+ /* The privacy section is hidden by default and only displayed on focus */
+ transition: all 0.5s;
+ height: 0;
+ margin-bottom: -20px;
+ overflow: hidden;
+}
+
+#newsletter-privacy.show {
+ height: 65px;
+}
+
+#newsletter-privacy label {
+ line-height: var(--line-height);
+}
+
+#privacy {
+ width: 20px;
+ height: 20px;
+ margin: 2px;
+ margin-inline-end: 10px;
+ flex-shrink: 0;
+ border-color: var(--grey-90-alpha-30);
+}
+
+#email {
+ width: 100%;
+ box-sizing: border-box;
+ padding: 12px 15px;
+ border-color: var(--grey-90-alpha-30);
+}
+
+#email:hover,
+#privacy:hover{
+ border-color: var(--grey-90-alpha-50);
+}
+
+#email:focus,
+#privacy:focus {
+ border-color: var(--teal-60);
+ box-shadow: 0 0 2px 0 var(--teal-60);
+}
+
+#newsletter-form button {
+ cursor: pointer;
+}
+
+#newsletter-form button::-moz-focus-inner,
+#newsletter-form input[type="button"]::-moz-focus-inner,
+#newsletter-form input[type="submit"]::-moz-focus-inner,
+#newsletter-form input[type="reset"]::-moz-focus-inner {
+ padding: 0 !important;
+ border: 0 none !important;
+ cursor: pointer;
+}
+
+#newsletter-form ::placeholder {
+ color: var(--grey-90-alpha-40);
+}
+
new file mode 100644
--- /dev/null
+++ b/devtools/shim/aboutdevtools/subscribe.js
@@ -0,0 +1,115 @@
+/* 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";
+
+window.addEventListener("load", function () {
+ let newsletterForm = document.getElementById("newsletter-form");
+ let emailInput = document.getElementById("email");
+
+ // Show the additional form fields on focus of the email input.
+ emailInput.addEventListener("focus", () => {
+ document.getElementById("newsletter_privacy").classList.add("show");
+ });
+
+ // Handle errors.
+ let errorArray = [];
+ let newsletterErrors = document.getElementById("newsletter_errors");
+ function newsletterError(e) {
+ if (errorArray.length) {
+ for (let i = 0; i < errorArray.length; i++) {
+ let item = document.createElement("p");
+ item.classList.add("error");
+ item.appendChild(document.createTextNode(errorArray[i]));
+ newsletterErrors.appendChild(item);
+ }
+ } else {
+ // No error messages, forward to server for better troubleshooting.
+ newsletterForm.setAttribute("data-skip-xhr", true);
+ newsletterForm.submit();
+ }
+
+ newsletterErrors.style.display = "block";
+ }
+
+ // Show sucess message.
+ function newsletterThanks() {
+ let thanks = document.getElementById("newsletter-thanks");
+ thanks.style.display = "block";
+ }
+
+ // XHR subscribe; handle errors; display thanks message on success.
+ function newsletterSubscribe(evt) {
+ let skipXHR = newsletterForm.getAttribute("data-skip-xhr");
+ if (skipXHR) {
+ return true;
+ }
+ evt.preventDefault();
+ evt.stopPropagation();
+
+ // New submission, clear old errors
+ errorArray = [];
+ newsletterErrors.style.display = "none";
+ while (newsletterErrors.firstChild) {
+ newsletterErrors.firstChild.remove();
+ }
+
+ let fmt = document.getElementById("fmt").value;
+ let email = document.getElementById("email").value;
+ let newsletter = document.getElementById("newsletters").value;
+
+ let isPrivacyChecked = document.querySelector('input[name="privacy"]:checked');
+ let privacy = isPrivacyChecked ? "&privacy=true" : "";
+ let params = "email=" + encodeURIComponent(email) +
+ "&newsletters=" + newsletter +
+ privacy +
+ "&fmt=" + fmt;
+
+ let xhr = new XMLHttpRequest();
+
+ xhr.onload = function (r) {
+ if (r.target.status >= 200 && r.target.status < 300) {
+ let response = r.target.response;
+
+ // response is null if handled by service worker
+ if (response === null) {
+ newsletterError(new Error());
+ return;
+ }
+
+ if (response.success === true) {
+ newsletterForm.style.display = "none";
+ newsletterThanks();
+ } else {
+ if (response.errors) {
+ for (let i = 0; i < response.errors.length; i++) {
+ errorArray.push(response.errors[i]);
+ }
+ }
+ newsletterError(new Error());
+ }
+ } else {
+ newsletterError(new Error());
+ }
+ };
+
+ xhr.onerror = function (e) {
+ newsletterError(e);
+ };
+
+ let url = newsletterForm.getAttribute("action");
+
+ xhr.open("POST", url, true);
+ xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
+ xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
+ xhr.timeout = 5000;
+ xhr.ontimeout = newsletterError;
+ xhr.responseType = "json";
+ xhr.send(params);
+
+ return false;
+ }
+
+ newsletterForm.addEventListener("submit", newsletterSubscribe);
+}, { once: true });
--- a/devtools/shim/jar.mn
+++ b/devtools/shim/jar.mn
@@ -2,16 +2,18 @@
# 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/.
devtools-shim.jar:
% content devtools-shim %content/
content/aboutdevtools/aboutdevtools.xhtml (aboutdevtools/aboutdevtools.xhtml)
content/aboutdevtools/aboutdevtools.css (aboutdevtools/aboutdevtools.css)
content/aboutdevtools/aboutdevtools.js (aboutdevtools/aboutdevtools.js)
+ content/aboutdevtools/subscribe.css (aboutdevtools/subscribe.css)
+ content/aboutdevtools/subscribe.js (aboutdevtools/subscribe.js)
content/aboutdevtools/images/otter.svg (aboutdevtools/images/otter.svg)
# Temporary localisation file, move back to devtools/shim/locales/en-US when ready for localization
# See https://bugzilla.mozilla.org/show_bug.cgi?id=1408369
content/aboutdevtools/tmp-locale/aboutdevtools.dtd (aboutdevtools/tmp-locale/aboutdevtools.dtd)
content/aboutdevtools/images/dev-edition-logo.svg (aboutdevtools/images/dev-edition-logo.svg)