Bug 618913 - Implement in product notifications to set up Sync.

Further modified by Stephen Horlander <shorlander@mozilla.com>.
r=dolske ui-r=shorlander
This commit is contained in:
Marco Bonardo 2011-05-20 09:53:51 -07:00
parent 707aefca28
commit bf10f29624
14 changed files with 221 additions and 9 deletions

View File

@ -3,6 +3,8 @@
%brandDTD;
<!ENTITY % browserDTD SYSTEM "chrome://browser/locale/browser.dtd" >
%browserDTD;
<!ENTITY % syncBrandDTD SYSTEM "chrome://browser/locale/syncBrand.dtd">
%syncBrandDTD;
<!ENTITY % baseMenuDTD SYSTEM "chrome://browser/locale/baseMenuOverlay.dtd" >
%baseMenuDTD;
<!ENTITY % charsetDTD SYSTEM "chrome://global/locale/charsetOverlay.dtd" >

View File

@ -8671,3 +8671,54 @@ XPCOMUtils.defineLazyGetter(window, "gShowPageResizers", function () {
#endif
});
let gSyncPromoNotification = {
// This preference counts down the number of times the promotion notification
// must be shown yet.
VIEWS_LEFT_PREF: "browser.syncPromoViewsLeft",
onPopupShowing: function SPN_onPopupShowing(event)
{
if (event.target != event.currentTarget)
return;
this._panel = event.target;
let viewsLeft = 5;
try {
viewsLeft = Services.prefs.getIntPref(this.VIEWS_LEFT_PREF);
} catch(ex) {}
if (viewsLeft) {
if (Services.prefs.prefHasUserValue("services.sync.username")) {
// If the user has already setup Sync, don't show the notification.
Services.prefs.setIntPref(this.VIEWS_LEFT_PREF, 0);
// Be sure to hide the panel, in case it was visible and the user
// decided to setup Sync after noticing it.
viewsLeft = 0;
}
else {
Services.prefs.setIntPref(this.VIEWS_LEFT_PREF, viewsLeft - 1);
}
}
// This has to be done regardless, since the panel could have been made
// visible by a previous call.
this._panel.querySelector(".sync-promo-notification").hidden = !viewsLeft;
if (viewsLeft) {
// HACK: The description element doesn't wrap correctly in panels, thus
// set a width on it, based on the available space.
let descElt = this._panel.querySelector(".sync-promo-description");
let textContent = descElt.firstChild.textContent;
descElt.firstChild.textContent = "";
this._panel.addEventListener("popupshown", function () {
event.target.removeEventListener("popupshown", arguments.callee, true);
descElt.width = descElt.getBoundingClientRect().width;
descElt.firstChild.textContent = textContent;
}, true);
}
},
onCloseButtonCommand: function SPN_onCloseButtonCommand() {
Services.prefs.setIntPref(this.VIEWS_LEFT_PREF, 0);
this._panel.querySelector(".sync-promo-notification").hidden = true;
}
}

View File

@ -180,6 +180,7 @@
orient="vertical"
ignorekeys="true"
hidden="true"
onpopupshowing="gSyncPromoNotification.onPopupShowing(event);"
onpopupshown="StarUI.panelShown(event);"
aria-labelledby="editBookmarkPanelTitle">
<row id="editBookmarkPanelHeader" align="center" hidden="true">
@ -221,6 +222,17 @@
oncommand="StarUI.panel.hidePopup();"/>
#endif
</hbox>
<hbox class="sync-promo-notification" hidden="true" align="start">
<hbox align="center" flex="1">
<image class="sync-promo-icon"/>
<description flex="1" class="sync-promo-description">
&syncPromoNotification.bookmarks.label; <description class="text-link" href="https://services.mozilla.com/">&syncPromoNotification.learnMoreLinkText;</description>
</description>
</hbox>
<toolbarbutton class="sync-promo-closebutton"
tooltiptext="&syncPromoNotification.closeButtonTooltip;"
oncommand="gSyncPromoNotification.onCloseButtonCommand();"/>
</hbox>
</panel>
<panel id="highlighter-panel"
@ -338,7 +350,21 @@
<menupopup id="placesContext"/>
<panel id="notification-popup" type="arrow" position="after_start"
hidden="true" orient="vertical"/>
hidden="true" orient="vertical"
onpopupshowing="if (/^password-/.test(event.target.firstChild.firstChild.getAttribute('id'))) gSyncPromoNotification.onPopupShowing(event);">
<hbox class="notification-popup-children"/>
<hbox class="sync-promo-notification" hidden="true" align="start">
<hbox align="center" flex="1">
<image class="sync-promo-icon"/>
<description flex="1" class="sync-promo-description">
&syncPromoNotification.passwords.label; <description class="text-link inline-link" href="https://services.mozilla.com/">&syncPromoNotification.learnMoreLinkText;</description>
</description>
</hbox>
<toolbarbutton class="sync-promo-closebutton"
tooltiptext="&syncPromoNotification.closeButtonTooltip;"
oncommand="gSyncPromoNotification.onCloseButtonCommand();"/>
</hbox>
</panel>
<!-- Popup for site identity information -->
<panel id="identity-popup"

View File

@ -559,13 +559,18 @@ just addresses the organization to follow, e.g. "This site is run by " -->
<!-- LOCALIZATION NOTE (syncTabsMenu.label): This appears in the history menu -->
<!ENTITY syncTabsMenu.label "Tabs From Other Computers">
<!ENTITY syncBrand.shortName.label "Sync">
<!ENTITY syncSetup.label "Set Up &syncBrand.shortName.label;…">
<!ENTITY syncSetup.accesskey "Y">
<!ENTITY syncSyncNowItem.label "Sync Now">
<!ENTITY syncSyncNowItem.accesskey "S">
<!ENTITY syncToolbarButton.label "Sync">
<!-- LOCALIZATION NOTE (syncPromoNotification.bookmarks.label): This appears in the new bookmark panel -->
<!ENTITY syncPromoNotification.bookmarks.label "You can access your bookmarks on all your devices with &syncBrand.fullName.label;.">
<!-- LOCALIZATION NOTE (syncPromoNotification.passwords.label): This appears in the remember password panel -->
<!ENTITY syncPromoNotification.passwords.label "You can access your passwords on all your devices with &syncBrand.fullName.label;.">
<!ENTITY syncPromoNotification.learnMoreLinkText "Learn More">
<!ENTITY syncPromoNotification.closeButtonTooltip "Close this message">
<!ENTITY addonBarCloseButton.tooltip "Close Add-on Bar">
<!ENTITY toggleAddonBarCmd.key "/">

View File

@ -1404,6 +1404,36 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
min-width: 27em;
}
.sync-promo-notification {
margin: 8px -10px -10px -10px;
padding: 8px 16px;
border-top: 1px solid ThreeDShadow;
background-image: -moz-linear-gradient(hsla(0,0%,0%,.15), hsla(0,0%,0%,.08) 6px);
}
.sync-promo-icon {
list-style-image: url("chrome://browser/skin/sync-24.png");
-moz-margin-end: 10px;
vertical-align: middle;
}
.sync-promo-description > .text-link {
margin: 0;
padding: 0;
}
.sync-promo-closebutton {
list-style-image: url("moz-icon://stock/gtk-close?size=menu");
margin-top: 0;
margin-bottom: 0;
-moz-margin-end: -6px;
}
.sync-promo-closebutton > .toolbarbutton-text {
padding: 0;
margin: 0;
}
/* Content area */
#sidebar {
background-color: Window;

View File

@ -86,6 +86,7 @@ browser.jar:
#ifdef MOZ_SERVICES_SYNC
skin/classic/browser/sync-16-throbber.png
skin/classic/browser/sync-16.png
skin/classic/browser/sync-24.png
skin/classic/browser/sync-24-throbber.png
skin/classic/browser/sync-32.png
skin/classic/browser/sync-bg.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -1394,6 +1394,49 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
text-align: end;
}
.sync-promo-notification {
margin: 8px -16px -16px -16px;
padding: 8px 16px;
background-color: hsla(0,0%,7%,.3);
border-top: 1px solid hsla(0,0%,100%,.1);
border-bottom-left-radius: 6px;
border-bottom-right-radius: 6px;
box-shadow: 0 1px 1px hsla(0,0%,0%,.25) inset;
}
.sync-promo-icon {
list-style-image: url("chrome://browser/skin/sync-24.png");
-moz-margin-end: 10px;
vertical-align: middle;
}
.sync-promo-description > .text-link {
margin: 0;
padding: 0;
color: hsl(210,100%,75%);
}
.sync-promo-closebutton {
list-style-image: url("chrome://global/skin/notification/close.png");
-moz-image-region: rect(0, 16px, 16px, 0);
border: none;
-moz-margin-end: -14px;
margin-top: -8px;
}
.sync-promo-closebutton:hover {
-moz-image-region: rect(0, 32px, 16px, 16px);
}
.sync-promo-closebutton:hover:active {
-moz-image-region: rect(0, 48px, 16px, 32px);
}
.sync-promo-closebutton > .toolbarbutton-text {
padding: 0;
margin: 0;
}
/* ----- SIDEBAR ELEMENTS ----- */
#sidebar,

View File

@ -125,6 +125,7 @@ browser.jar:
#ifdef MOZ_SERVICES_SYNC
skin/classic/browser/sync-throbber.png
skin/classic/browser/sync-16.png
skin/classic/browser/sync-24.png
skin/classic/browser/sync-32.png
skin/classic/browser/sync-bg.png
skin/classic/browser/sync-desktopIcon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -1515,6 +1515,50 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
min-width: 27em;
}
.sync-promo-notification {
margin: 8px -16px -16px -16px;
padding: 8px 16px;
background-color: #f1f5fb;
%ifndef WINSTRIPE_AERO
border-bottom-left-radius: 6px;
border-bottom-right-radius: 6px;
%endif
box-shadow: 0px 1px 2px rgb(204,214,234) inset;
}
.sync-promo-icon {
list-style-image: url("chrome://browser/skin/sync-24.png");
-moz-margin-end: 10px;
vertical-align: middle;
}
.sync-promo-description > .text-link {
margin: 0;
padding: 0;
}
.sync-promo-closebutton {
-moz-appearance: none;
list-style-image: url("chrome://global/skin/icons/close.png");
-moz-image-region: rect(0, 16px, 16px, 0);
border: none;
-moz-margin-end: -12px;
margin-top: -8px;
}
.sync-promo-closebutton:hover {
-moz-image-region: rect(0, 32px, 16px, 16px);
}
.sync-promo-closebutton:hover:active {
-moz-image-region: rect(0, 48px, 16px, 32px);
}
.sync-promo-closebutton > .toolbarbutton-text {
padding: 0;
margin: 0;
}
/* ::::: content area ::::: */
#sidebar {

View File

@ -103,6 +103,7 @@ browser.jar:
#ifdef MOZ_SERVICES_SYNC
skin/classic/browser/sync-throbber.png
skin/classic/browser/sync-16.png
skin/classic/browser/sync-24.png
skin/classic/browser/sync-32.png
skin/classic/browser/sync-bg.png
skin/classic/browser/sync-desktopIcon.png
@ -216,6 +217,7 @@ browser.jar:
#ifdef MOZ_SERVICES_SYNC
skin/classic/aero/browser/sync-throbber.png
skin/classic/aero/browser/sync-16.png
skin/classic/aero/browser/sync-24.png
skin/classic/aero/browser/sync-32.png
skin/classic/aero/browser/sync-bg.png
skin/classic/aero/browser/sync-desktopIcon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -376,12 +376,19 @@ PopupNotifications.prototype = {
this._ignoreDismissal = false;
},
get panelChildrenElement() {
delete this.panelChildrenElement;
return this.panelChildrenElement =
this.panel.querySelector(".notification-popup-children") || this.panel;
},
/**
*
*/
_refreshPanel: function PopupNotifications_refreshPanel(notificationsToShow) {
while (this.panel.lastChild)
this.panel.removeChild(this.panel.lastChild);
while (this.panelChildrenElement.lastChild) {
this.panelChildrenElement.removeChild(this.panelChildrenElement.lastChild);
}
const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
@ -420,7 +427,7 @@ PopupNotifications.prototype = {
}
}
this.panel.appendChild(popupnotification);
this.panelChildrenElement.appendChild(popupnotification);
}, this);
},
@ -544,14 +551,14 @@ PopupNotifications.prototype = {
if (event.target != this.panel || this._ignoreDismissal)
return;
let browser = this.panel.firstChild &&
this.panel.firstChild.notification.browser;
let browser = this.panelChildrenElement.firstChild &&
this.panelChildrenElement.firstChild.notification.browser;
if (!browser)
return;
let notifications = this._getNotificationsForBrowser(browser);
// Mark notifications as dismissed and call dismissal callbacks
Array.forEach(this.panel.childNodes, function (nEl) {
Array.forEach(this.panelChildrenElement.childNodes, function (nEl) {
let notificationObj = nEl.notification;
// Never call a dismissal handler on a notification that's been removed.
if (notifications.indexOf(notificationObj) == -1)