Bug 1040369 - Replace sponsored icon with identifying text [r=adw]

Add sponsored text next to title that triggers explanation text. Remove unused sponsored icon and related files.
This commit is contained in:
Ed Lee 2014-08-21 19:21:38 -07:00
parent 3f9402bca3
commit 36f8360fb3
16 changed files with 163 additions and 133 deletions

View File

@ -168,8 +168,7 @@ let gGrid = {
' class="newtab-control newtab-control-pin"/>' +
'<input type="button" title="' + newTabString("block") + '"' +
' class="newtab-control newtab-control-block"/>' +
'<input type="button" title="' + newTabString("sponsored") + '"' +
' class="newtab-control newtab-control-sponsored"/>';
'<span class="newtab-sponsored">' + newTabString("sponsored.button") + '</span>';
this._siteFragment = document.createDocumentFragment();
this._siteFragment.appendChild(site);

View File

@ -149,19 +149,77 @@ input[type=button] {
}
/* TITLES */
.newtab-sponsored,
.newtab-title {
bottom: -26px;
font-size: 13px;
left: 0;
overflow: hidden;
padding-top: 14px;
position: absolute;
right: 0;
text-align: center;
text-overflow: ellipsis;
white-space: nowrap;
}
.newtab-title {
font-size: 13px;
left: 0;
padding-top: 14px;
text-overflow: ellipsis;
}
.newtab-sponsored {
background-color: #f9f9f9;
border: 1px solid #dcdcdc;
border-radius: 2px;
color: #9b9b9b;
cursor: pointer;
display: none;
font-family: Arial;
font-size: 10px;
height: 17px;
line-height: 17px;
margin-bottom: -1px;
padding: 0 4px;
}
.newtab-sponsored:-moz-any(:hover, [active]) {
background-color: #dcdcdc;
color: #666666;
}
.newtab-sponsored:-moz-locale-dir(rtl) {
left: 0;
right: auto;
}
.newtab-site:-moz-any([type=enhanced], [type=sponsored]) .newtab-sponsored {
display: block;
}
.sponsored-explain,
.sponsored-explain a {
color: white;
}
.sponsored-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;
}
.sponsored-explain input {
background-size: 20px;
height: 20px;
opacity: 1;
pointer-events: none;
position: static;
width: 20px;
}
/* CONTROLS */
.newtab-control {
position: absolute;
@ -185,31 +243,16 @@ input[type=button] {
}
}
.newtab-control-sponsored:-moz-locale-dir(rtl),
.newtab-control-pin:-moz-locale-dir(ltr),
.newtab-control-block:-moz-locale-dir(rtl) {
left: 4px;
}
.newtab-control-sponsored:-moz-locale-dir(ltr),
.newtab-control-block:-moz-locale-dir(ltr),
.newtab-control-pin:-moz-locale-dir(rtl) {
right: 4px;
}
.newtab-control.newtab-control-sponsored {
bottom: -20px;
height: 14px;
-moz-margin-end: -5px;
opacity: 1;
top: auto;
width: 14px;
}
.newtab-site:not([type=sponsored]) .newtab-control-sponsored {
display: none;
}
/* DRAG & DROP */
/*
@ -224,19 +267,6 @@ input[type=button] {
opacity: 0.01;
}
/* SPONSORED PANEL */
#sponsored-panel {
width: 330px;
}
#sponsored-panel description {
margin: 0;
}
#sponsored-panel .text-link {
margin: 12px 0 0;
}
/* SEARCH */
#newtab-search-container {
display: -moz-box;

View File

@ -35,7 +35,13 @@ XPCOMUtils.defineLazyGetter(this, "gStringBundle", function() {
createBundle("chrome://browser/locale/newTab.properties");
});
function newTabString(name) gStringBundle.GetStringFromName('newtab.' + name);
function newTabString(name, args) {
let stringName = "newtab." + name;
if (!args) {
return gStringBundle.GetStringFromName(stringName);
}
return gStringBundle.formatStringFromName(stringName, args, args.length);
}
function inPrivateBrowsingMode() {
return PrivateBrowsingUtils.isWindowPrivate(window);
@ -44,6 +50,8 @@ function inPrivateBrowsingMode() {
const HTML_NAMESPACE = "http://www.w3.org/1999/xhtml";
const XUL_NAMESPACE = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
const TILES_EXPLAIN_LINK = "https://support.mozilla.org/kb/how-do-sponsored-tiles-work";
#include transformations.js
#include page.js
#include grid.js

View File

@ -20,14 +20,6 @@
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
title="&newtab.pageTitle;">
<xul:panel id="sponsored-panel" orient="vertical" type="arrow">
<xul:description id="sponsored-panel-release-descr">&newtab.sponsored.release.message;</xul:description>
<xul:description id="sponsored-panel-trial-descr">&newtab.sponsored.trial.message2;</xul:description>
<xul:label class="text-link"
href="https://support.mozilla.org/kb/how-do-sponsored-tiles-work"
value="&newtab.panel.link.text;" />
</xul:panel>
<xul:panel id="newtab-search-panel" orient="vertical" type="arrow"
noautohide="true">
<xul:hbox id="newtab-search-manage" class="newtab-search-panel-engine">

View File

@ -24,17 +24,6 @@ let gPage = {
// listen from the xul window and filter then delegate
addEventListener("click", this, false);
// Initialize sponsored panel
this._sponsoredPanel = document.getElementById("sponsored-panel");
let link = this._sponsoredPanel.querySelector(".text-link");
link.addEventListener("click", () => this._sponsoredPanel.hidePopup());
if (UpdateChannel.get().startsWith("release")) {
document.getElementById("sponsored-panel-trial-descr").style.display = "none";
}
else {
document.getElementById("sponsored-panel-release-descr").style.display = "none";
}
// Check if the new tab feature is enabled.
let enabled = gAllPages.enabled;
if (enabled)
@ -89,21 +78,6 @@ let gPage = {
}
},
/**
* Shows sponsored panel
*/
showSponsoredPanel: function Page_showSponsoredPanel(aTarget) {
if (this._sponsoredPanel.state == "closed") {
let self = this;
this._sponsoredPanel.addEventListener("popuphidden", function onPopupHidden(aEvent) {
self._sponsoredPanel.removeEventListener("popuphidden", onPopupHidden, false);
aTarget.removeAttribute("panelShown");
});
}
aTarget.setAttribute("panelShown", "true");
this._sponsoredPanel.openPopup(aTarget);
},
/**
* Internally initializes the page. This runs only when/if the feature
* is/gets enabled.

View File

@ -120,8 +120,9 @@ Site.prototype = {
* Renders the site's data (fills the HTML fragment).
*/
_render: function Site_render() {
let enhanced = gAllPages.enhanced && DirectoryLinksProvider.getEnhancedLink(this.link);
let url = this.url;
let title = this.title || url;
let title = enhanced && enhanced.title || this.title || url;
let tooltip = (title == url ? title : title + "\n" + url);
let link = this._querySelector(".newtab-link");
@ -185,7 +186,7 @@ Site.prototype = {
this._node.addEventListener("mouseover", this, false);
// Specially treat the sponsored icon to prevent regular hover effects
let sponsored = this._querySelector(".newtab-control-sponsored");
let sponsored = this._querySelector(".newtab-sponsored");
sponsored.addEventListener("mouseover", () => {
this.cell.node.setAttribute("ignorehover", "true");
});
@ -218,6 +219,30 @@ Site.prototype = {
.add(aIndex);
},
_toggleSponsored: function() {
let button = this._querySelector(".newtab-sponsored");
if (button.hasAttribute("active")) {
let explain = this._querySelector(".sponsored-explain");
explain.parentNode.removeChild(explain);
button.removeAttribute("active");
}
else {
let explain = document.createElementNS(HTML_NAMESPACE, "div");
explain.className = "sponsored-explain";
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") + '"/>';
explain.innerHTML = newTabString(type + ".explain", [icon, link]);
button.setAttribute("active", "true");
}
},
/**
* Handles site click events.
*/
@ -226,6 +251,8 @@ Site.prototype = {
let pinned = this.isPinned();
let tileIndex = this.cell.index;
let {button, target} = aEvent;
// Handle tile/thumbnail link click
if (target.classList.contains("newtab-link") ||
target.parentElement.classList.contains("newtab-link")) {
// Record for primary and middle clicks
@ -234,6 +261,10 @@ Site.prototype = {
action = "click";
}
}
// Handle sponsored explanation link click
else if (target.parentElement.classList.contains("sponsored-explain")) {
action = "sponsored_link";
}
// Only handle primary clicks for the remaining targets
else if (button == 0) {
aEvent.preventDefault();
@ -241,8 +272,9 @@ Site.prototype = {
this.block();
action = "block";
}
else if (target.classList.contains("newtab-control-sponsored")) {
gPage.showSponsoredPanel(target);
else if (target.classList.contains("sponsored-explain") ||
target.classList.contains("newtab-sponsored")) {
this._toggleSponsored();
action = "sponsored";
}
else if (pinned) {

View File

@ -7,6 +7,7 @@ gDirectorySource = "data:application/json," + JSON.stringify({
"en-US": [{
url: "http://example.com/",
enhancedImageURI: "data:image/png;base64,helloWORLD",
title: "title",
type: "organic"
}]
});
@ -28,6 +29,7 @@ function runTests() {
return {
type: siteNode.getAttribute("type"),
enhanced: siteNode.querySelector(".enhanced-content").style.backgroundImage,
title: siteNode.querySelector(".newtab-title").textContent,
};
}
@ -37,27 +39,40 @@ function runTests() {
// Test with enhanced = false
NewTabUtils.allPages.enhanced = false;
yield addNewTabPageTab();
let {type, enhanced} = getData(0);
let {type, enhanced, title} = getData(0);
is(type, "organic", "directory link is organic");
isnot(enhanced, "", "directory link has enhanced image");
is(title, "title");
is(getData(1), null, "history link pushed out by directory link");
// Test with enhanced = true
NewTabUtils.allPages.enhanced = true;
yield addNewTabPageTab();
let {type, enhanced} = getData(0);
let {type, enhanced, title} = getData(0);
is(type, "organic", "directory link is still organic");
isnot(enhanced, "", "directory link still has enhanced image");
is(title, "title");
is(getData(1), null, "history link still pushed out by directory link");
// Test with a pinned link
setPinnedLinks("-1");
yield addNewTabPageTab();
let {type, enhanced} = getData(0);
let {type, enhanced, title} = getData(0);
is(type, "enhanced", "pinned history link is enhanced");
isnot(enhanced, "", "pinned history link has enhanced image");
is(title, "title");
is(getData(1), null, "directory link pushed out by pinned history link");
// Test pinned link with enhanced = false
NewTabUtils.allPages.enhanced = false;
yield addNewTabPageTab();
let {type, enhanced, title} = getData(0);
isnot(type, "enhanced", "history link is not enhanced");
is(enhanced, "", "history link has no enhanced image");
is(title, "site#-1");
is(getData(1), null, "directory link still pushed out by pinned history link");
}

View File

@ -8,26 +8,29 @@ function runTests() {
let site = getCell(0).node.querySelector(".newtab-site");
site.setAttribute("type", "sponsored");
let sponsoredPanel = getContentDocument().getElementById("sponsored-panel");
is(sponsoredPanel.state, "closed", "Sponsored panel must be closed");
// test explain text appearing upon a click
let sponsoredButton = site.querySelector(".newtab-sponsored");
EventUtils.synthesizeMouseAtCenter(sponsoredButton, {}, getContentWindow());
let explain = site.querySelector(".sponsored-explain");
isnot(explain, null, "Sponsored explanation shown");
ok(explain.querySelector("input").classList.contains("newtab-control-block"), "sponsored tiles show blocked image");
ok(sponsoredButton.hasAttribute("active"), "Sponsored button has active attribute");
function continueOnceOn(event) {
sponsoredPanel.addEventListener(event, function listener() {
sponsoredPanel.removeEventListener(event, listener);
executeSoon(TestRunner.next);
});
}
// test dismissing sponsored explain
EventUtils.synthesizeMouseAtCenter(sponsoredButton, {}, getContentWindow());
is(site.querySelector(".sponsored-explain"), null, "Sponsored explanation no longer shown");
ok(!sponsoredButton.hasAttribute("active"), "Sponsored button does not have active attribute");
// test sponsoredPanel appearing upon a click
continueOnceOn("popupshown");
let sponsoredButton = site.querySelector(".newtab-control-sponsored");
yield EventUtils.synthesizeMouseAtCenter(sponsoredButton, {}, getContentWindow());
is(sponsoredPanel.state, "open", "Sponsored panel opens on click");
ok(sponsoredButton.hasAttribute("panelShown"), "Sponsored button has panelShown attribute");
// test with enhanced tile
site.setAttribute("type", "enhanced");
EventUtils.synthesizeMouseAtCenter(sponsoredButton, {}, getContentWindow());
explain = site.querySelector(".sponsored-explain");
isnot(explain, null, "Sponsored explanation shown");
ok(explain.querySelector("input").classList.contains("newtab-customize"), "enhanced tiles show customize image");
ok(sponsoredButton.hasAttribute("active"), "Sponsored button has active attribute");
// test sponsoredPanel hiding
continueOnceOn("popuphidden");
yield sponsoredPanel.hidePopup();
is(sponsoredPanel.state, "closed", "Sponsored panel correctly closed/hidden");
ok(!sponsoredButton.hasAttribute("panelShown"), "Sponsored button does not have panelShown attribute");
// test dismissing enhanced explain
EventUtils.synthesizeMouseAtCenter(sponsoredButton, {}, getContentWindow());
is(site.querySelector(".sponsored-explain"), null, "Sponsored explanation no longer shown");
ok(!sponsoredButton.hasAttribute("active"), "Sponsored button does not have active attribute");
}

View File

@ -12,6 +12,3 @@
<!ENTITY newtab.undo.undoButton "Undo.">
<!ENTITY newtab.undo.restoreButton "Restore All.">
<!ENTITY newtab.undo.closeTooltip "Hide">
<!ENTITY newtab.sponsored.release.message "This Sponsor site was suggested because we hoped youd find it interesting and because it supports Mozillas mission.">
<!ENTITY newtab.sponsored.trial.message2 "This site was suggested because we hoped youd find it interesting and because it supports Mozillas mission.">
<!ENTITY newtab.panel.link.text "Learn more…">

View File

@ -5,4 +5,16 @@
newtab.pin=Pin this site at its current position
newtab.unpin=Unpin this site
newtab.block=Remove this site
newtab.sponsored=Show information on sponsored tiles
# LOCALIZATION NOTE(newtab.sponsored.button): This text appears for sponsored
# and enhanced tiles on the same line as the tile's title, so prefer short
# strings to avoid overlap. This string should be uppercase.
newtab.sponsored.button=SPONSORED
# 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.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
newtab.learn.link=Learn more…

View File

@ -118,8 +118,6 @@ browser.jar:
skin/classic/browser/feeds/subscribe.css (feeds/subscribe.css)
skin/classic/browser/feeds/subscribe-ui.css (feeds/subscribe-ui.css)
* skin/classic/browser/newtab/newTab.css (newtab/newTab.css)
skin/classic/browser/newtab/controls.png (../shared/newtab/controls.png)
skin/classic/browser/newtab/controls@2x.png (../shared/newtab/controls@2x.png)
skin/classic/browser/newtab/controls.svg (../shared/newtab/controls.svg)
skin/classic/browser/places/bookmarksMenu.png (places/bookmarksMenu.png)
skin/classic/browser/places/bookmarksToolbar.png (places/bookmarksToolbar.png)

View File

@ -192,8 +192,6 @@ browser.jar:
skin/classic/browser/feeds/audioFeedIcon.png (feeds/feedIcon.png)
skin/classic/browser/feeds/audioFeedIcon16.png (feeds/feedIcon16.png)
* skin/classic/browser/newtab/newTab.css (newtab/newTab.css)
skin/classic/browser/newtab/controls.png (../shared/newtab/controls.png)
skin/classic/browser/newtab/controls@2x.png (../shared/newtab/controls@2x.png)
skin/classic/browser/newtab/controls.svg (../shared/newtab/controls.svg)
skin/classic/browser/setDesktopBackground.css
skin/classic/browser/monitor.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

View File

@ -62,7 +62,8 @@
}
/* CUSTOMIZE */
#newtab-customize-button {
#newtab-customize-button,
.newtab-customize {
background-color: transparent;
background-image: -moz-image-rect(url(chrome://browser/skin/newtab/controls.svg), 0, 32, 32, 0);
background-size: 28px;
@ -160,10 +161,6 @@
font-weight: bold;
}
.newtab-site[type=sponsored] .newtab-title {
-moz-padding-end: 24px;
}
/* CONTROLS */
.newtab-control {
background-color: transparent;
@ -199,24 +196,3 @@
.newtab-control-block:hover:active {
background-image: -moz-image-rect(url(chrome://browser/skin/newtab/controls.svg), 0, 256, 32, 224);
}
.newtab-control-sponsored {
background-image: url(chrome://browser/skin/newtab/controls.png);
background-position: -249px -1px;
background-size: auto;
}
@media (min-resolution: 2dppx) {
.newtab-control-sponsored {
background-image: url(chrome://browser/skin/newtab/controls@2x.png);
background-size: 296px;
}
}
.newtab-control-sponsored:hover {
background-position: -265px -1px;
}
.newtab-control-sponsored[panelShown] {
background-position: -281px -1px;
}

View File

@ -141,8 +141,6 @@ browser.jar:
skin/classic/browser/feeds/subscribe.css (feeds/subscribe.css)
skin/classic/browser/feeds/subscribe-ui.css (feeds/subscribe-ui.css)
* skin/classic/browser/newtab/newTab.css (newtab/newTab.css)
skin/classic/browser/newtab/controls.png (../shared/newtab/controls.png)
skin/classic/browser/newtab/controls@2x.png (../shared/newtab/controls@2x.png)
skin/classic/browser/newtab/controls.svg (../shared/newtab/controls.svg)
skin/classic/browser/places/places.css (places/places.css)
* skin/classic/browser/places/organizer.css (places/organizer.css)
@ -556,8 +554,6 @@ browser.jar:
skin/classic/aero/browser/feeds/subscribe.css (feeds/subscribe.css)
skin/classic/aero/browser/feeds/subscribe-ui.css (feeds/subscribe-ui.css)
* skin/classic/aero/browser/newtab/newTab.css (newtab/newTab.css)
skin/classic/aero/browser/newtab/controls.png (../shared/newtab/controls.png)
skin/classic/aero/browser/newtab/controls@2x.png (../shared/newtab/controls@2x.png)
skin/classic/aero/browser/newtab/controls.svg (../shared/newtab/controls.svg)
* skin/classic/aero/browser/places/places.css (places/places-aero.css)
* skin/classic/aero/browser/places/organizer.css (places/organizer-aero.css)