Bug 1357005 - Create onboarding icon which toggles a first-time use dialog on net newtab. draft
authorRex Lee <rexboy@mozilla.com>
Mon, 22 May 2017 17:00:16 +0800
changeset 586978 e85f15908741997bc09286b987078eec191c5dcb
parent 586775 9a5c710587f9e64bf044602d5e988b152ef4f40c
child 631162 c8eadcc542f51474e4e08e337d69d3a63cd3257c
push id61590
push userbmo:rexboy@mozilla.com
push dateWed, 31 May 2017 10:59:31 +0000
bugs1357005
milestone55.0a1
Bug 1357005 - Create onboarding icon which toggles a first-time use dialog on net newtab. MozReview-Commit-ID: J4IAHyVKXAW
browser/app/permissions
browser/app/profile/firefox.js
browser/extensions/moz.build
browser/extensions/onboarding/bootstrap.js
browser/extensions/onboarding/content/img/overlay-icon.svg
browser/extensions/onboarding/content/onboarding.css
browser/extensions/onboarding/content/onboarding.js
browser/extensions/onboarding/install.rdf.in
browser/extensions/onboarding/jar.mn
browser/extensions/onboarding/moz.build
--- a/browser/app/permissions
+++ b/browser/app/permissions
@@ -7,16 +7,17 @@
 # See nsPermissionManager.cpp for more...
 
 # UITour
 origin	uitour	1	https://www.mozilla.org
 origin	uitour	1	https://support.mozilla.org
 origin	uitour	1	https://addons.mozilla.org
 origin	uitour	1	https://discovery.addons.mozilla.org
 origin	uitour	1	about:home
+origin	uitour	1	about:newtab
 
 # XPInstall
 origin	install	1	https://addons.mozilla.org
 origin	install	1	https://testpilot.firefox.com
 
 # Remote troubleshooting
 origin	remote-troubleshooting	1	https://input.mozilla.org
 origin	remote-troubleshooting	1	https://support.mozilla.org
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -1658,8 +1658,11 @@ pref("browser.sessionstore.restore_tabs_
 
 // Enable safebrowsing v4 tables (suffixed by "-proto") update.
 #ifdef NIGHTLY_BUILD
 pref("urlclassifier.malwareTable", "goog-malware-shavar,goog-unwanted-shavar,goog-malware-proto,goog-unwanted-proto,test-malware-simple,test-unwanted-simple");
 pref("urlclassifier.phishTable", "goog-phish-shavar,goog-phish-proto,test-phish-simple");
 #endif
 
 pref("browser.suppress_first_window_animation", true);
+
+// Preferences for Photon onboarding system extension
+pref("browser.onboarding.disabled", false);
--- a/browser/extensions/moz.build
+++ b/browser/extensions/moz.build
@@ -28,9 +28,10 @@ if CONFIG['MOZ_MORTAR']:
     DIRS += [
         'mortar',
     ]
 
 # Nightly-only system add-ons
 if CONFIG['NIGHTLY_BUILD']:
     DIRS += [
         'activity-stream',
+        'onboarding',
     ]
new file mode 100644
--- /dev/null
+++ b/browser/extensions/onboarding/bootstrap.js
@@ -0,0 +1,18 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* 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";
+
+const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
+Cu.import("resource://gre/modules/Services.jsm");
+
+function install(aData, aReason) {}
+
+function uninstall(aData, aReason) {}
+
+function startup(aData, reason) {
+  Services.mm.loadFrameScript("resource://onboarding/onboarding.js", true);
+}
+
+function shutdown(aData, reason) {}
new file mode 100644
--- /dev/null
+++ b/browser/extensions/onboarding/content/img/overlay-icon.svg
@@ -0,0 +1,2 @@
+
+<svg width="36" height="29" viewBox="0 0 36 29" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><title>overlayfox</title><defs><path id="a" d="M.002.058h35.953V27.94H.002z"/><path id="c" d="M0 17.39V.42h35.957v16.97H0z"/></defs><g fill="none" fill-rule="evenodd"><g transform="translate(0 .55)"><mask id="b" fill="#fff"><use xlink:href="#a"/></mask><path d="M35.953 16.593c.006-.19-.036-.386-.133-.562-1.02-1.884-2.052-3.65-3.17-5.243.773-.62 1.448-1.394 1.975-2.312 1.497-2.61 1.413-5.72.042-8.175-.063-.114-.176-.2-.294-.242.002.01-.006.016-.006.024-.008-.012-.018-.024-.03-.024-2.825-.03-5.558 1.46-7.112 4.09-.16.27-.3.572-.418.896-2.394-1.464-5.24-2.31-8.822-2.31-3.57 0-6.416.832-8.806 2.283v.007l-.02.014c-.12-.322-.257-.623-.416-.89C7.19 1.52 4.457.03 1.632.06c-.014 0-.028.014-.035.028 0-.007.007-.007.007-.014-.14.036-.267.12-.337.256-1.37 2.455-1.462 5.557.042 8.175.526.926 1.208 1.7 1.988 2.327-1.118 1.586-2.15 3.344-3.163 5.23-.092.166-.13.352-.13.533H.002c0 .007.002.013 0 .02v.016h.002c-.006.17.032.344.117.504 3.685 6.71 7.6 9.377 15 9.88.807.58 1.79.928 2.857.928 1.065 0 2.05-.347 2.857-.93 7.4-.5 11.323-3.168 15-9.878.09-.162.13-.35.12-.534v-.003-.004" fill="#F70" mask="url(#b)"/></g><g transform="translate(0 10.268)"><mask id="d" fill="#fff"><use xlink:href="#c"/></mask><path d="M17.978 17.39c9.31 0 13.732-2.447 17.857-9.975.09-.163.133-.356.12-.54h-4.238V5.23h-.014c.007-.113.014-.234.014-.348 0-2.462-1.975-4.46-4.407-4.46-2.43 0-4.406 1.998-4.406 4.46 0 .12.008.235.014.35h-9.88c.007-.1.014-.208.014-.314 0-2.462-1.974-4.462-4.406-4.462-2.43 0-4.406 2-4.406 4.462 0 .106.007.206.014.313h-.007v1.644H.002c-.013.185.03.37.12.54 4.132 7.53 8.545 9.976 17.856 9.976" fill="#FFC899" mask="url(#d)"/></g><path d="M35.954 17.15c.007-.192-.035-.39-.134-.57-1.018-1.885-2.05-3.65-3.17-5.243.774-.62 1.45-1.395 1.976-2.312 1.497-2.61 1.413-5.72.042-8.175-.063-.114-.175-.2-.295-.242.007.02.007.043-.014.057-.746.37-3.943 2.15-5.756 6.19-2.74-2.242-6.1-3.572-10.62-3.572-3.568 0-6.414.832-8.804 2.284v.007c-.632.384-1.23.81-1.8 1.28-1.474-3.28-3.85-5.065-5.1-5.82-.008 0-.008-.006-.015-.006C2.175.97 2.09.92 2.013.878c-.008 0-.015-.007-.015-.007C1.963.85 1.935.836 1.9.82c-.007 0-.007-.006-.014-.006-.035-.02-.064-.035-.098-.05-.008 0-.008-.006-.015-.006-.02-.015-.05-.03-.07-.036-.007 0-.014-.008-.02-.008C1.66.7 1.632.694 1.612.68 1.604.68 1.604.67 1.597.67L1.59.665V.65c0-.007 0-.007.008-.014 0-.007.007-.007.007-.014-.14.036-.267.12-.338.256-1.37 2.455-1.46 5.557.042 8.175.527.925 1.208 1.7 1.988 2.327-1.117 1.587-2.15 3.344-3.162 5.23-.098.177-.14.377-.133.57H4.24v-1.645h.007c-.007-.1-.014-.207-.014-.313 0-2.462 1.975-4.46 4.406-4.46 2.43 0 4.405 1.998 4.405 4.46 0 .106-.007.206-.014.313h.015v7.96c0 2.755 2.207 4.996 4.933 4.996 2.72 0 4.933-2.233 4.933-4.994v-7.99h.01c0-.042-.01-.085-.01-.128v-.47c.128-2.347 2.047-4.21 4.4-4.21 2.432 0 4.407 1.998 4.407 4.46 0 .12-.007.235-.015.348h.015v1.644h4.237z" fill="#F70"/><path d="M16.453 19.832s.05 0 .134.008c.084.006.204.014.345.014.14.007.31.007.49.014.177 0 .374.007.563.007.19 0 .38 0 .563-.007.175 0 .344-.007.492-.014.14-.008.26-.014.344-.014.084-.008.133-.008.133-.008.598-.057 1.132.39 1.18.996.03.3-.07.584-.245.804l-.942 1.146-.035.035c-.02.022-.056.058-.098.093-.043.036-.092.078-.148.114-.057.043-.127.078-.197.12-.07.036-.148.072-.233.107-.084.03-.168.057-.26.08-.175.042-.372.056-.56.048-.1-.006-.19-.014-.29-.028-.05-.007-.09-.014-.14-.02-.05-.008-.092-.023-.134-.03-.042-.007-.09-.028-.133-.035-.042-.015-.084-.03-.127-.043-.042-.015-.084-.03-.12-.05-.034-.015-.077-.036-.112-.05-.035-.022-.07-.036-.105-.057-.036-.022-.064-.036-.092-.058-.057-.035-.106-.07-.148-.106-.042-.03-.077-.065-.098-.08l-.036-.035-.906-.946c-.45-.47-.436-1.21.02-1.666.254-.25.577-.356.893-.342" fill="#994C00"/><path d="M8.407 19.398c-.618 0-1.243-.135-1.82-.412-.28-.136-.4-.477-.267-.762.134-.284.47-.405.752-.27.87.42 1.884.406 2.77-.043.28-.14.617-.027.75.258.14.284.03.625-.252.76-.612.314-1.272.47-1.933.47M26.938 19.398c-.618 0-1.244-.135-1.82-.412-.28-.136-.4-.477-.267-.762.135-.284.472-.405.753-.27.87.42 1.883.406 2.77-.043.28-.14.617-.027.75.258.134.284.03.625-.252.76-.61.314-1.27.47-1.932.47" fill="#F70"/><path d="M10.91 15.926c-.008-.064-.03-.12-.057-.178-.45-1.024-1.363-1.657-2.39-1.657-1.025 0-1.94.634-2.39 1.658-.027.057-.04.12-.055.178-.14.3-.077.67.183.904.31.277.788.25 1.07-.064.3-.342.736-.54 1.194-.54.456 0 .9.198 1.194.54.148.17.358.256.57.256.175 0 .358-.064.498-.192.26-.235.323-.605.183-.904M29.44 15.926c-.007-.064-.028-.12-.057-.178-.45-1.024-1.363-1.657-2.39-1.657-1.024 0-1.938.634-2.388 1.658-.028.057-.042.12-.056.178-.142.3-.078.67.182.904.14.128.323.192.5.192.21 0 .413-.086.568-.256.302-.342.737-.54 1.194-.54.457 0 .9.198 1.195.54.273.313.75.348 1.067.064.26-.235.323-.605.183-.904" fill="#363959"/><path d="M17.978 27.438c-1.405 0-2.122-.718-2.473-1.323-.373-.648-.415-1.288-.415-1.31-.007-.092.042-.184.12-.234.077-.05.175-.056.26-.014.007.008.934.456 2.48.456 1.553 0 2.53-.456 2.544-.456.085-.042.183-.028.26.022.078.05.12.142.112.235 0 .028-.042.67-.414 1.31-.352.597-1.068 1.315-2.474 1.315" fill="#994C00"/><path d="M28.597 6.855c1.468-3.28 3.843-5.066 5.094-5.82.008 0 .008-.007.016-.007.09-.057.175-.107.252-.15.007 0 .015-.007.015-.007.034-.02.063-.034.098-.05.008 0 .008-.006.015-.006.035-.02.063-.035.098-.05.007 0 .007-.007.015-.007.02-.014.05-.028.07-.035.006 0 .014-.008.02-.008.022-.014.05-.02.07-.035.008 0 .008-.008.015-.008l.007-.008V.65c0-.007 0-.007-.007-.013-.007-.015-.02-.03-.035-.03C31.513.58 28.78 2.068 27.226 4.7c-.16.27-.302.575-.42.902.617.356 1.215.783 1.79 1.253M7.374 6.855C5.906 3.575 3.53 1.79 2.28 1.035c-.008 0-.008-.007-.015-.007C2.175.97 2.09.92 2.013.878c-.008 0-.015-.007-.015-.007C1.963.85 1.935.837 1.9.82c-.007 0-.007-.006-.014-.006-.035-.02-.064-.035-.098-.05-.008 0-.008-.007-.015-.007-.02-.014-.05-.028-.07-.035-.007 0-.014-.008-.02-.008C1.66.7 1.632.694 1.612.68 1.604.68 1.604.67 1.597.67L1.59.664V.65c0-.007 0-.007.008-.013.007-.015.02-.03.035-.03C4.458.58 7.19 2.068 8.745 4.7c.16.27.302.575.42.902-.624.356-1.22.783-1.79 1.253" fill="#FF9F4D"/></g></svg>
new file mode 100644
--- /dev/null
+++ b/browser/extensions/onboarding/content/onboarding.css
@@ -0,0 +1,88 @@
+/* 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/. */
+#onboarding-overlay * {
+  box-sizing: border-box;
+}
+
+#onboarding-overlay {
+  position: fixed;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  /* Ensuring we can put the overlay over elements using
+     z-index on original page */
+  z-index: 999;
+  color: #4d4d4d;
+  background: rgb(54, 57, 89, 0.8); /* #363959, 0.8 opacity */
+  display: none;
+}
+
+#onboarding-overlay.opened {
+  display: block;
+}
+
+#onboarding-overlay-icon {
+  width: 52px;
+  height: 40px;
+  position: absolute;
+  cursor: pointer;
+  top: 30px;
+  offset-inline-start: 30px;
+  background: url("img/overlay-icon.svg") no-repeat;
+}
+
+#onboarding-overlay-dialog {
+  display: none;
+}
+
+#onboarding-tour-close-btn {
+  position: absolute;
+  top: 15px;
+  offset-inline-end: 15px;
+}
+
+#onboarding-overlay.opened > #onboarding-overlay-dialog {
+  width: 1200px;
+  height: 550px;
+  background: #f5f5f7;
+  border: 1px solid rgba(9, 6, 13, 0.1); /* #09060D, 0.1 opacity */
+  position: relative;
+  margin: 0 calc(50% - 600px);
+  top: calc(50% - 275px);
+  display: grid;
+  grid-template-rows: [dialog-start] 76px [page-start] 1fr [footer-start] 40px [dialog-end];
+  grid-template-columns: [dialog-start] 240px [page-start] 1fr [dialog-end];
+}
+
+@media (max-height: 550px) {
+  #onboarding-overlay.opened > #onboarding-overlay-dialog {
+    top: 0;
+  }
+}
+
+#onboarding-overlay-dialog > header {
+  grid-row: dialog-start / page-start;
+  grid-column: dialog-start / tour-end;
+  margin-top: 36px;
+  margin-bottom: 0;
+  margin-inline-end: 0;
+  margin-inline-start: 36px;
+  font-size: 22px;
+}
+
+#onboarding-overlay-dialog > nav {
+  grid-row: dialog-start / footer-start;
+  grid-column-start: dialog-start;
+  margin-top: 40px;
+  margin-bottom: 0;
+  margin-inline-end: 0;
+  margin-inline-start: 0;
+  padding: 0;
+}
+
+#onboarding-overlay-dialog > footer {
+  grid-row: footer-start;
+  grid-column: dialog-start / tour-end;
+}
new file mode 100644
--- /dev/null
+++ b/browser/extensions/onboarding/content/onboarding.js
@@ -0,0 +1,113 @@
+/* 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 content */
+
+"use strict";
+
+const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
+Cu.import("resource://gre/modules/Services.jsm");
+
+const ONBOARDING_CSS_URL = "resource://onboarding/onboarding.css";
+const ABOUT_NEWTAB_URL = "about:newtab";
+
+/**
+ * The script won't be initialized if we turned off onboarding by
+ * setting "browser.onboarding.disabled" to true.
+ */
+class Onboarding {
+  constructor(contentWindow) {
+    this.init(contentWindow);
+  }
+
+  async init(contentWindow) {
+    this._window = contentWindow;
+    // We want to create and append elements after CSS is loaded so
+    // no flash of style changes and no additional reflow.
+    await this._loadCSS();
+    this._overlayIcon = this._renderOverlayIcon();
+    this._overlay = this._renderOverlay();
+    this._window.document.body.appendChild(this._overlayIcon);
+    this._window.document.body.appendChild(this._overlay);
+
+    this._overlayIcon.addEventListener("click", this);
+    this._overlay.addEventListener("click", this);
+    // Destroy on unload. This is to ensure we remove all the stuff we left.
+    // No any leak out there.
+    this._window.addEventListener("unload", () => this.destroy());
+  }
+
+  handleEvent(evt) {
+    switch (evt.target.id) {
+      case "onboarding-overlay-icon":
+      case "onboarding-tour-close-btn":
+      // If the clicking target is directly on the outer-most overlay,
+      // that means clicking outside the tour content area.
+      // Let's toggle the overlay.
+      case "onboarding-overlay":
+        this.toggleOverlay();
+      break;
+    }
+  }
+
+  destroy() {
+    this._overlayIcon.remove();
+    this._overlay.remove();
+  }
+
+  toggleOverlay() {
+    this._overlay.classList.toggle("opened");
+  }
+
+  _renderOverlay() {
+    let div = this._window.document.createElement("div");
+    div.id = "onboarding-overlay";
+    // Here we use `innerHTML` is for more friendly reading.
+    // The security should be fine because this is not from an external input.
+    // We're not shipping yet so l10n strings is going to be closed for now.
+    div.innerHTML = `
+      <div id="onboarding-overlay-dialog">
+        <button id="onboarding-tour-close-btn">X</button>
+        <header>Getting started?</header>
+        <nav>
+          <ul></ul>
+        </nav>
+        <footer>
+        </footer>
+      </div>
+    `;
+    return div;
+  }
+
+  _renderOverlayIcon() {
+    let img = this._window.document.createElement("div");
+    img.id = "onboarding-overlay-icon";
+    return img;
+  }
+
+  _loadCSS() {
+    // Returning a Promise so we can inform caller of loading complete
+    // by resolving it.
+    return new Promise(resolve => {
+      let doc = this._window.document;
+      let link = doc.createElement("link");
+      link.rel = "stylesheet";
+      link.type = "text/css";
+      link.href = ONBOARDING_CSS_URL;
+      link.addEventListener("load", resolve);
+      doc.head.appendChild(link);
+    });
+  }
+}
+
+addEventListener("load", function(evt) {
+  // Load onboarding module only when we enable it.
+  if (content.location.href == ABOUT_NEWTAB_URL &&
+      !Services.prefs.getBoolPref("browser.onboarding.disabled")) {
+
+    content.requestIdleCallback(() => {
+      new Onboarding(content);
+    });
+  }
+}, true);
new file mode 100644
--- /dev/null
+++ b/browser/extensions/onboarding/install.rdf.in
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--  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/. -->
+
+#filter substitution
+
+<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+     xmlns:em="http://www.mozilla.org/2004/em-rdf#">
+  <Description about="urn:mozilla:install-manifest">
+    <em:id>onboarding@mozilla.org</em:id>
+    <em:name>Photon onboarding</em:name>
+    <em:description>Photon onboarding</em:description>
+    <em:version>0.1</em:version>
+    <em:bootstrap>true</em:bootstrap>
+    <em:type>2</em:type>
+    <em:multiprocessCompatible>true</em:multiprocessCompatible>
+
+    <em:targetApplication>
+      <Description>
+        <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id> <!--Firefox-->
+        <em:minVersion>@MOZ_APP_VERSION@</em:minVersion>
+        <em:maxVersion>@MOZ_APP_MAXVERSION@</em:maxVersion>
+      </Description>
+    </em:targetApplication>
+    <em:strictCompatibility>false</em:strictCompatibility>
+  </Description>
+</RDF>
new file mode 100644
--- /dev/null
+++ b/browser/extensions/onboarding/jar.mn
@@ -0,0 +1,7 @@
+# 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/onboarding@mozilla.org] chrome.jar:
+% resource onboarding %content/
+  content/ (content/*)
new file mode 100644
--- /dev/null
+++ b/browser/extensions/onboarding/moz.build
@@ -0,0 +1,18 @@
+# -*- 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']
+
+FINAL_TARGET_PP_FILES.features['onboarding@mozilla.org'] += [
+  'install.rdf.in'
+]
+
+FINAL_TARGET_FILES.features['onboarding@mozilla.org'] += [
+  'bootstrap.js',
+]
+
+JAR_MANIFESTS += ['jar.mn']