Bug 1143797 - Allow clicking on suggested explanation text to see overlay explaining the suggested tile. r=adw
authorMarina Samuel <msamuel@mozilla.com>
Thu, 26 Mar 2015 17:05:44 -0400
changeset 264741 e70798a79585fdda38f48d22b991e888bcdda4b2
parent 264740 0f100d006b7c11a663f99563cde290915b6a162b
child 264742 ca81732ae41950fc50f448d50d7ac9bffb47cf0d
push id4718
push userraliiev@mozilla.com
push dateMon, 11 May 2015 18:39:53 +0000
treeherdermozilla-beta@c20c4ef55f08 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersadw
bugs1143797
milestone39.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1143797 - Allow clicking on suggested explanation text to see overlay explaining the suggested tile. r=adw
browser/base/content/newtab/newTab.css
browser/base/content/newtab/sites.js
browser/locales/en-US/chrome/browser/newTab.properties
browser/modules/DirectoryLinksProvider.jsm
browser/modules/test/xpcshell/test_DirectoryLinksProvider.js
browser/themes/shared/newtab/newTab.inc.css
--- a/browser/base/content/newtab/newTab.css
+++ b/browser/base/content/newtab/newTab.css
@@ -257,38 +257,42 @@ input[type=button] {
   left: 0;
   right: auto;
 }
 
 .newtab-site:-moz-any([type=enhanced], [type=sponsored]) .newtab-sponsored {
   display: block;
 }
 
-.newtab-site[type=related] .newtab-suggested {
+.newtab-site[type=suggested] .newtab-suggested {
   display: table;
 }
 
 .sponsored-explain,
-.sponsored-explain a {
+.sponsored-explain a,
+.suggested-explain,
+.suggested-explain a {
   color: white;
 }
 
-.sponsored-explain {
+.sponsored-explain,
+.suggested-explain {
   background-color: rgba(51, 51, 51, 0.95);
   border-bottom-left-radius: 6px;
   border-bottom-right-radius: 6px;
   bottom: 0px;
   line-height: 20px;
   padding: 15px 10px;
   position: absolute;
   text-align: start;
 }
 
 #newtab-intro-panel input,
-.sponsored-explain input {
+.sponsored-explain input,
+.suggested-explain input {
   background-size: 18px;
   height: 18px;
   opacity: 1;
   pointer-events: none;
   position: static;
   width: 18px;
 }
 
--- a/browser/base/content/newtab/sites.js
+++ b/browser/base/content/newtab/sites.js
@@ -228,34 +228,34 @@ Site.prototype = {
       // We only want to get indices for the default configuration, everything
       // else goes in the same bucket.
       aIndex = 9;
     }
     Services.telemetry.getHistogramById("NEWTAB_PAGE_SITE_CLICKED")
                       .add(aIndex);
   },
 
-  _toggleSponsored: function() {
-    let button = this._querySelector(".newtab-sponsored");
+  _toggleLegalText: function(buttonClass, explanationTextClass) {
+    let button = this._querySelector(buttonClass);
     if (button.hasAttribute("active")) {
-      let explain = this._querySelector(".sponsored-explain");
+      let explain = this._querySelector(explanationTextClass);
       explain.parentNode.removeChild(explain);
 
       button.removeAttribute("active");
     }
     else {
       let explain = document.createElementNS(HTML_NAMESPACE, "div");
-      explain.className = "sponsored-explain";
+      explain.className = explanationTextClass.slice(1); // Slice off the first character, '.'
       this.node.appendChild(explain);
 
       let link = '<a href="' + TILES_EXPLAIN_LINK + '">' +
                  newTabString("learn.link") + "</a>";
       let type = this.node.getAttribute("type");
       let icon = '<input type="button" class="newtab-control newtab-' +
-                 (type == "sponsored" ? "control-block" : "customize") + '"/>';
+                 (type == "enhanced" ? "customize" : "control-block") + '"/>';
       explain.innerHTML = newTabString(type + ".explain", [icon, link]);
 
       button.setAttribute("active", "true");
     }
   },
 
   /**
    * Handles site click events.
@@ -274,34 +274,38 @@ Site.prototype = {
         this._recordSiteClicked(tileIndex);
         action = "click";
       }
     }
     // Handle sponsored explanation link click
     else if (target.parentElement.classList.contains("sponsored-explain")) {
       action = "sponsored_link";
     }
+    else if (target.parentElement.classList.contains("suggested-explain")) {
+      action = "suggested_link";
+    }
     // Only handle primary clicks for the remaining targets
     else if (button == 0) {
-      if (target.parentElement.classList.contains("newtab-suggested") ||
-          target.classList.contains("newtab-suggested")) {
-        // Suggested explanation text should do nothing when clicked and
-        // the link in the suggested explanation should act as default.
-        return;
-      }
       aEvent.preventDefault();
       if (target.classList.contains("newtab-control-block")) {
         this.block();
         action = "block";
       }
       else if (target.classList.contains("sponsored-explain") ||
                target.classList.contains("newtab-sponsored")) {
-        this._toggleSponsored();
+        this._toggleLegalText(".newtab-sponsored", ".sponsored-explain");
         action = "sponsored";
       }
+      else if (target.classList.contains("suggested-explain") ||
+               target.classList.contains("newtab-suggested-bounds") ||
+               target.parentElement.classList.contains("newtab-suggested-bounds") ||
+               target.classList.contains("newtab-suggested")) {
+        this._toggleLegalText(".newtab-suggested", ".suggested-explain");
+        action = "suggested";
+      }
       else if (pinned) {
         this.unpin();
         action = "unpin";
       }
       else {
         this.pin();
         action = "pin";
       }
--- a/browser/locales/en-US/chrome/browser/newTab.properties
+++ b/browser/locales/en-US/chrome/browser/newTab.properties
@@ -13,16 +13,20 @@ newtab.sponsored.button=SPONSORED
 # one of the user's top 100 sites that triggered this suggested tile.
 # This text appears for suggested tiles under the tile's title, so prefer short
 # strings to avoid truncating important text.
 newtab.suggested.button=Suggested for %1$S visitors
 # LOCALIZATION NOTE(newtab.sponsored.explain): %1$S will be replaced inline by
 # the (X) block icon. %2$S will be replaced by an active link using string
 # newtab.learn.link as text.
 newtab.sponsored.explain=This tile is being shown to you on behalf of a Mozilla partner. You can remove it at any time by clicking the %1$S button. %2$S
+# LOCALIZATION NOTE(newtab.suggested.explain): %1$S will be replaced inline by
+# the (X) block icon. %2$S will be replaced by an active link using string
+# newtab.learn.link as text.
+newtab.suggested.explain=This site is suggested to you by Mozilla. You can remove it at any time by clicking the %1$S button. %2$S
 # LOCALIZATION NOTE(newtab.enhanced.explain): %1$S will be replaced inline by
 # the gear icon used to customize the new tab window. %2$S will be replaced by
 # an active link using string newtab.learn.link as text.
 newtab.enhanced.explain=A Mozilla partner has visually enhanced this tile, replacing the screenshot. You can turn off enhanced tiles by clicking the %1$S button for your preferences. %2$S
 # LOCALIZATION NOTE(newtab.intro.paragraph1): %1$S will be replaced inline by
 # active link using string newtab.learn.link as text.
 newtab.intro.paragraph1=When you open a new tab, you’ll see tiles from the sites you frequently visit, along with tiles that we think might be of interest to you. Some of these tiles may be sponsored by Mozilla partners. We’ll always indicate to you which tiles are sponsored. %1$S
 # LOCALIZATION NOTE(newtab.intro.paragraph2): %1$S will be replaced inline by
--- a/browser/modules/DirectoryLinksProvider.jsm
+++ b/browser/modules/DirectoryLinksProvider.jsm
@@ -197,17 +197,17 @@ let DirectoryLinksProvider = {
   _removePrefsObserver: function DirectoryLinksProvider_removeObserver() {
     for (let pref in this._observedPrefs) {
       let prefName = this._observedPrefs[pref];
       Services.prefs.removeObserver(prefName, this);
     }
   },
 
   _cacheRelatedLinks: function(link) {
-    for (let relatedSite of link.related) {
+    for (let relatedSite of link.suggested) {
       let relatedMap = this._relatedLinks.get(relatedSite) || new Map();
       relatedMap.set(link.url, link);
       this._relatedLinks.set(relatedSite, relatedMap);
     }
   },
 
   _fetchAndCacheLinks: function DirectoryLinksProvider_fetchAndCacheLinks(uri) {
     // Replace with the same display locale used for selecting links data
@@ -425,17 +425,17 @@ let DirectoryLinksProvider = {
         // Stash the enhanced image for the site
         if (link.enhancedImageURI) {
           this._enhancedLinks.set(NewTabUtils.extractSite(link.url), link);
         }
         link.lastVisitDate = rawLinks.length - position;
 
         // We cache related tiles here but do not push any of them in the links list yet.
         // The decision for which related tile to include will be made separately.
-        if ("related" == link.type) {
+        if ("suggested" == link.type) {
           this._cacheRelatedLinks(link);
           return;
         }
         link.frecency = DIRECTORY_FRECENCY;
         links.push(link);
       });
       return links;
     }).catch(ex => {
@@ -537,22 +537,22 @@ let DirectoryLinksProvider = {
       return;
     }
 
     // Delete the current related tile, if one exists.
     let initialLength = sortedLinks.length;
     this.maxNumLinks = initialLength;
     if (initialLength) {
       let mostFrecentLink = sortedLinks[0];
-      if ("related" == mostFrecentLink.type) {
+      if ("suggested" == mostFrecentLink.type) {
         this._callObservers("onLinkChanged", {
           url: mostFrecentLink.url,
           frecency: 0,
           lastVisitDate: mostFrecentLink.lastVisitDate,
-          type: "related",
+          type: "suggested",
         }, 0, true);
       }
     }
 
     if (this._topSitesWithRelatedLinks.size == 0) {
       // There are no potential related links we can show.
       return;
     }
@@ -584,17 +584,17 @@ let DirectoryLinksProvider = {
     let chosenRelatedLink = flattenedLinks[relatedIndex];
 
     // Show the new directory tile.
     this._callObservers("onLinkChanged", {
       url: chosenRelatedLink.url,
       title: chosenRelatedLink.title,
       frecency: RELATED_FRECENCY,
       lastVisitDate: chosenRelatedLink.lastVisitDate,
-      type: "related",
+      type: "suggested",
 
       // Choose the first site a user has visited as the target. In the future,
       // this should be the site with the highest frecency. However, we currently
       // store frecency by URL not by site.
       targetedSite: targetedSites.get(chosenRelatedLink.url).length ?
         targetedSites.get(chosenRelatedLink.url)[0] : null
     });
     return chosenRelatedLink;
--- a/browser/modules/test/xpcshell/test_DirectoryLinksProvider.js
+++ b/browser/modules/test/xpcshell/test_DirectoryLinksProvider.js
@@ -58,41 +58,41 @@ kHttpHandlerData[kExamplePath] = {"en-US
 const BinaryInputStream = CC("@mozilla.org/binaryinputstream;1",
                               "nsIBinaryInputStream",
                               "setInputStream");
 
 let gLastRequestPath;
 
 let relatedTile1 = {
   url: "http://turbotax.com",
-  type: "related",
+  type: "suggested",
   lastVisitDate: 4,
-  related: [
+  suggested: [
     "taxact.com",
     "hrblock.com",
     "1040.com",
     "taxslayer.com"
   ]
 };
 let relatedTile2 = {
   url: "http://irs.gov",
-  type: "related",
+  type: "suggested",
   lastVisitDate: 3,
-  related: [
+  suggested: [
     "taxact.com",
     "hrblock.com",
     "freetaxusa.com",
     "taxslayer.com"
   ]
 };
 let relatedTile3 = {
   url: "http://hrblock.com",
-  type: "related",
+  type: "suggested",
   lastVisitDate: 2,
-  related: [
+  suggested: [
     "taxact.com",
     "freetaxusa.com",
     "1040.com",
     "taxslayer.com"
   ]
 };
 let someOtherSite = {url: "http://someothersite.com", title: "Not_A_Related_Site"};
 
@@ -243,31 +243,31 @@ add_task(function test_updateRelatedTile
     this.promise = new Promise(resolve => {
       this.onLinkChanged = (directoryLinksProvider, link) => {
         links.unshift(link);
         let possibleLinks = [relatedTile1.url, relatedTile2.url, relatedTile3.url];
 
         isIdentical([...DirectoryLinksProvider._topSitesWithRelatedLinks], ["hrblock.com", "1040.com", "freetaxusa.com"]);
         do_check_true(possibleLinks.indexOf(link.url) > -1);
         do_check_eq(link.frecency, Infinity);
-        do_check_eq(link.type, "related");
+        do_check_eq(link.type, "suggested");
         resolve();
       };
     });
   }
 
   function TestChangingRelatedTile() {
     this.count = 0;
     this.promise = new Promise(resolve => {
       this.onLinkChanged = (directoryLinksProvider, link) => {
         this.count++;
         let possibleLinks = [relatedTile1.url, relatedTile2.url, relatedTile3.url];
 
         do_check_true(possibleLinks.indexOf(link.url) > -1);
-        do_check_eq(link.type, "related");
+        do_check_eq(link.type, "suggested");
         do_check_true(this.count <= 2);
 
         if (this.count == 1) {
           // The removed related link is the one we added initially.
           do_check_eq(link.url, links.shift().url);
           do_check_eq(link.frecency, 0);
         } else {
           links.unshift(link);
@@ -280,17 +280,17 @@ add_task(function test_updateRelatedTile
   }
 
   function TestRemovingRelatedTile() {
     this.count = 0;
     this.promise = new Promise(resolve => {
       this.onLinkChanged = (directoryLinksProvider, link) => {
         this.count++;
 
-        do_check_eq(link.type, "related");
+        do_check_eq(link.type, "suggested");
         do_check_eq(this.count, 1);
         do_check_eq(link.frecency, 0);
         do_check_eq(link.url, links.shift().url);
         isIdentical([...DirectoryLinksProvider._topSitesWithRelatedLinks], []);
         resolve();
       }
     });
   }
--- a/browser/themes/shared/newtab/newTab.inc.css
+++ b/browser/themes/shared/newtab/newTab.inc.css
@@ -137,16 +137,27 @@
 /* TITLES */
 #newtab-intro-what,
 .newtab-sponsored,
 .newtab-title,
 .newtab-suggested  {
   color: #5c5c5c;
 }
 
+.newtab-suggested:hover {
+  color: #588FE4;
+  border: 1px solid #588FE4;
+}
+
+.newtab-suggested[active] {
+  background-color: rgba(51, 51, 51, 0.95);
+  border: 0;
+  color: white;
+}
+
 .newtab-suggested {
   background-color: white;
 }
 
 .newtab-site:hover .newtab-title {
   color: #222;
 }