[Centaury] Port PM Sync Client

This commit is contained in:
Fedor 2019-05-20 09:02:13 +03:00
parent b9a6c8d251
commit 0437f42ca6
56 changed files with 4506 additions and 920 deletions

View File

@ -283,9 +283,11 @@ body[narrow] #restorePreviousSession {
content: url("chrome://browser/content/abouthome/addons.png");
}
%ifdef MOZ_SERVICES_SYNC
#sync::before {
content: url("chrome://browser/content/abouthome/sync.png");
}
%endif
#settings::before {
content: url("chrome://browser/content/abouthome/settings.png");
@ -369,9 +371,11 @@ body[narrow] #restorePreviousSession::before {
content: url("chrome://browser/content/abouthome/addons@2x.png");
}
%ifdef MOZ_SERVICES_SYNC
#sync::before {
content: url("chrome://browser/content/abouthome/sync@2x.png");
}
%endif
#settings::before {
content: url("chrome://browser/content/abouthome/settings@2x.png");

View File

@ -54,7 +54,9 @@
<button class="launchButton" id="bookmarks">&abouthome.bookmarksButton.label;</button>
<button class="launchButton" id="history">&abouthome.historyButton.label;</button>
<button class="launchButton" id="addons">&abouthome.addonsButton.label;</button>
#ifdef MOZ_SERVICES_SYNC
<button class="launchButton" id="sync">&abouthome.syncButton.label;</button>
#endif
#ifdef XP_WIN
<button class="launchButton" id="settings">&abouthome.preferencesButtonWin.label;</button>
#else

View File

@ -249,13 +249,6 @@
accesskey="&savePageCmd.accesskey2;"
oncommand="gContextMenu.savePageAs();"/>
<menuseparator id="context-sep-sendpagetodevice" hidden="true"/>
<menu id="context-sendpagetodevice"
label="&sendPageToDevice.label;"
accesskey="&sendPageToDevice.accesskey;"
hidden="true">
<menupopup id="context-sendpagetodevice-popup"
onpopupshowing="(() => { let browser = gBrowser || getPanelBrowser(); gFxAccounts.populateSendTabToDevicesMenu(event.target, browser.currentURI.spec, browser.contentTitle); })()"/>
</menu>
<menuseparator id="context-sep-viewbgimage"/>
<menuitem id="context-viewbgimage"
label="&viewBGImageCmd.label;"
@ -296,13 +289,6 @@
<menuitem id="context-searchselect"
oncommand="BrowserSearch.loadSearchFromContext(this.searchTerms);"/>
<menuseparator id="context-sep-sendlinktodevice" hidden="true"/>
<menu id="context-sendlinktodevice"
label="&sendLinkToDevice.label;"
accesskey="&sendLinkToDevice.accesskey;"
hidden="true">
<menupopup id="context-sendlinktodevice-popup"
onpopupshowing="gFxAccounts.populateSendTabToDevicesMenu(event.target, gContextMenu.linkURL, gContextMenu.linkTextStr);"/>
</menu>
<menuseparator id="frame-sep"/>
<menu id="frame" label="&thisFrameMenu.label;" accesskey="&thisFrameMenu.accesskey;">
<menupopup>

View File

@ -19,7 +19,9 @@
#endif
<!ENTITY % aboutHomeDTD SYSTEM "chrome://browser/locale/aboutHome.dtd">
%aboutHomeDTD;
#ifdef MOZ_SERVICES_SYNC
<!ENTITY % syncBrandDTD SYSTEM "chrome://browser/locale/syncBrand.dtd">
%syncBrandDTD;
#endif
]>

View File

@ -314,11 +314,13 @@
key="key_sanitize"
command="Tools:Sanitize"/>
<menuseparator id="sanitizeSeparator"/>
#ifdef MOZ_SERVICES_SYNC
<menuitem id="sync-tabs-menuitem"
class="syncTabsMenuItem"
label="&syncTabsMenu3.label;"
label="&syncTabsMenu2.label;"
oncommand="BrowserOpenSyncTabs();"
hidden="true"/>
disabled="true"/>
#endif
<menuitem id="historyRestoreLastSession"
label="&historyRestoreLastSession.label;"
command="Browser:RestoreLastSession"/>
@ -436,7 +438,11 @@
label="&toolsMenu.label;"
accesskey="&toolsMenu.accesskey;"
onpopupshowing="mirrorShow(this)">
<menupopup id="menu_ToolsPopup">
<menupopup id="menu_ToolsPopup"
#ifdef MOZ_SERVICES_SYNC
onpopupshowing="gSyncUI.updateUI();"
#endif
>
<menuitem id="menu_openDownloads"
label="&downloads.label;"
accesskey="&downloads.accesskey;"
@ -447,6 +453,19 @@
accesskey="&addons.accesskey;"
key="key_openAddons"
command="Tools:Addons"/>
#ifdef MOZ_SERVICES_SYNC
<!-- only one of sync-setup or sync-menu will be showing at once -->
<menuitem id="sync-setup"
label="&syncSetup.label;"
accesskey="&syncSetup.accesskey;"
observes="sync-setup-state"
oncommand="gSyncUI.openSetup()"/>
<menuitem id="sync-syncnowitem"
label="&syncSyncNowItem.label;"
accesskey="&syncSyncNowItem.accesskey;"
observes="sync-syncnow-state"
oncommand="gSyncUI.doSync(event);"/>
#endif
<menuseparator id="devToolsSeparator"/>
<menu id="webDeveloperMenu"
label="&webDeveloperMenu.label;"

View File

@ -804,18 +804,29 @@ HistoryMenu.prototype = {
},
toggleTabsFromOtherComputers: function PHM_toggleTabsFromOtherComputers() {
// This is a no-op if MOZ_SERVICES_SYNC isn't defined
#ifdef MOZ_SERVICES_SYNC
// Enable/disable the Tabs From Other Computers menu. Some of the menus handled
// by HistoryMenu do not have this menuitem.
let menuitem = this._rootElt.getElementsByClassName("syncTabsMenuItem")[0];
if (!menuitem)
return;
if (!PlacesUIUtils.shouldShowTabsFromOtherComputersMenuitem()) {
// If Sync isn't configured yet, then don't show the menuitem.
if (Weave.Status.checkSetup() == Weave.CLIENT_NOT_CONFIGURED ||
Weave.Svc.Prefs.get("firstSync", "") == "notReady") {
menuitem.setAttribute("hidden", true);
return;
}
// The tabs engine might never be inited (if services.sync.registerEngines
// is modified), so make sure we avoid undefined errors.
let enabled = Weave.Service.isLoggedIn &&
Weave.Service.engineManager.get("tabs") &&
Weave.Service.engineManager.get("tabs").enabled;
menuitem.setAttribute("disabled", !enabled);
menuitem.setAttribute("hidden", false);
#endif
},
_onPopupShowing: function HM__onPopupShowing(aEvent) {

View File

@ -163,12 +163,13 @@
<!-- A broadcaster of a number of attributes suitable for "sync now" UI -
A 'syncstatus' attribute is set while actively syncing, and the label
attribute which changes from "sync now" to "syncing" etc. -->
#ifdef MOZ_SERVICES_SYNC
<broadcaster id="sync-status"/>
<!-- broadcasters of the "hidden" attribute to reflect setup state for
menus -->
<broadcaster id="sync-setup-state"/>
<broadcaster id="sync-syncnow-state" hidden="true"/>
<broadcaster id="sync-reauth-state" hidden="true"/>
#endif
<broadcaster id="workOfflineMenuitemState"/>
<broadcaster id="devtoolsMenuBroadcaster_ErrorConsole"

View File

@ -0,0 +1,470 @@
# 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/.
// gSyncUI handles updating the tools menu
var gSyncUI = {
_obs: ["weave:service:sync:start",
"weave:service:sync:delayed",
"weave:service:quota:remaining",
"weave:service:setup-complete",
"weave:service:login:start",
"weave:service:login:finish",
"weave:service:logout:finish",
"weave:service:start-over",
"weave:ui:login:error",
"weave:ui:sync:error",
"weave:ui:sync:finish",
"weave:ui:clear-error",
],
_unloaded: false,
init: function SUI_init() {
// Proceed to set up the UI if Sync has already started up.
// Otherwise we'll do it when Sync is firing up.
let xps = Components.classes["@mozilla.org/weave/service;1"]
.getService(Components.interfaces.nsISupports)
.wrappedJSObject;
if (xps.ready) {
this.initUI();
return;
}
Services.obs.addObserver(this, "weave:service:ready", true);
// Remove the observer if the window is closed before the observer
// was triggered.
window.addEventListener("unload", function onUnload() {
gSyncUI._unloaded = true;
window.removeEventListener("unload", onUnload, false);
Services.obs.removeObserver(gSyncUI, "weave:service:ready");
if (Weave.Status.ready) {
gSyncUI._obs.forEach(function(topic) {
Services.obs.removeObserver(gSyncUI, topic);
});
}
}, false);
},
initUI: function SUI_initUI() {
// If this is a browser window?
if (gBrowser) {
this._obs.push("weave:notification:added");
}
this._obs.forEach(function(topic) {
Services.obs.addObserver(this, topic, true);
}, this);
if (gBrowser && Weave.Notifications.notifications.length) {
this.initNotifications();
}
this.updateUI();
},
initNotifications: function SUI_initNotifications() {
const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
let notificationbox = document.createElementNS(XULNS, "notificationbox");
notificationbox.id = "sync-notifications";
notificationbox.setAttribute("flex", "1");
let bottombox = document.getElementById("browser-bottombox");
bottombox.insertBefore(notificationbox, bottombox.firstChild);
// Force a style flush to ensure that our binding is attached.
notificationbox.clientTop;
// notificationbox will listen to observers from now on.
Services.obs.removeObserver(this, "weave:notification:added");
},
_wasDelayed: false,
_needsSetup: function SUI__needsSetup() {
let firstSync = "";
try {
firstSync = Services.prefs.getCharPref("services.sync.firstSync");
} catch (e) { }
return Weave.Status.checkSetup() == Weave.CLIENT_NOT_CONFIGURED ||
firstSync == "notReady";
},
updateUI: function SUI_updateUI() {
let needsSetup = this._needsSetup();
document.getElementById("sync-setup-state").hidden = !needsSetup;
document.getElementById("sync-syncnow-state").hidden = needsSetup;
if (!gBrowser)
return;
let button = document.getElementById("sync-button");
if (!button)
return;
button.removeAttribute("status");
this._updateLastSyncTime();
if (needsSetup)
button.removeAttribute("tooltiptext");
},
// Functions called by observers
onActivityStart: function SUI_onActivityStart() {
if (!gBrowser)
return;
let button = document.getElementById("sync-button");
if (!button)
return;
button.setAttribute("status", "active");
},
onSyncDelay: function SUI_onSyncDelay() {
// basically, we want to just inform users that stuff is going to take a while
let title = this._stringBundle.GetStringFromName("error.sync.no_node_found.title");
let description = this._stringBundle.GetStringFromName("error.sync.no_node_found");
let buttons = [new Weave.NotificationButton(
this._stringBundle.GetStringFromName("error.sync.serverStatusButton.label"),
this._stringBundle.GetStringFromName("error.sync.serverStatusButton.accesskey"),
function() { gSyncUI.openServerStatus(); return true; }
)];
let notification = new Weave.Notification(
title, description, null, Weave.Notifications.PRIORITY_INFO, buttons);
Weave.Notifications.replaceTitle(notification);
this._wasDelayed = true;
},
onLoginFinish: function SUI_onLoginFinish() {
// Clear out any login failure notifications
let title = this._stringBundle.GetStringFromName("error.login.title");
this.clearError(title);
},
onSetupComplete: function SUI_onSetupComplete() {
this.onLoginFinish();
},
onLoginError: function SUI_onLoginError() {
// if login fails, any other notifications are essentially moot
Weave.Notifications.removeAll();
// if we haven't set up the client, don't show errors
if (this._needsSetup()) {
this.updateUI();
return;
}
let title = this._stringBundle.GetStringFromName("error.login.title");
let description;
if (Weave.Status.sync == Weave.PROLONGED_SYNC_FAILURE) {
// Convert to days
let lastSync =
Services.prefs.getIntPref("services.sync.errorhandler.networkFailureReportTimeout") / 86400;
description =
this._stringBundle.formatStringFromName("error.sync.prolonged_failure", [lastSync], 1);
} else {
let reason = Weave.Utils.getErrorString(Weave.Status.login);
description =
this._stringBundle.formatStringFromName("error.sync.description", [reason], 1);
}
let buttons = [];
buttons.push(new Weave.NotificationButton(
this._stringBundle.GetStringFromName("error.login.prefs.label"),
this._stringBundle.GetStringFromName("error.login.prefs.accesskey"),
function() { gSyncUI.openPrefs(); return true; }
));
let notification = new Weave.Notification(title, description, null,
Weave.Notifications.PRIORITY_WARNING, buttons);
Weave.Notifications.replaceTitle(notification);
this.updateUI();
},
onLogout: function SUI_onLogout() {
this.updateUI();
},
onStartOver: function SUI_onStartOver() {
this.clearError();
},
onQuotaNotice: function onQuotaNotice(subject, data) {
let title = this._stringBundle.GetStringFromName("warning.sync.quota.label");
let description = this._stringBundle.GetStringFromName("warning.sync.quota.description");
let buttons = [];
buttons.push(new Weave.NotificationButton(
this._stringBundle.GetStringFromName("error.sync.viewQuotaButton.label"),
this._stringBundle.GetStringFromName("error.sync.viewQuotaButton.accesskey"),
function() { gSyncUI.openQuotaDialog(); return true; }
));
let notification = new Weave.Notification(
title, description, null, Weave.Notifications.PRIORITY_WARNING, buttons);
Weave.Notifications.replaceTitle(notification);
},
openServerStatus: function () {
let statusURL = Services.prefs.getCharPref("services.sync.statusURL");
window.openUILinkIn(statusURL, "tab");
},
// Commands
doSync: function SUI_doSync() {
setTimeout(function() Weave.Service.errorHandler.syncAndReportErrors(), 0);
},
handleToolbarButton: function SUI_handleStatusbarButton() {
if (this._needsSetup())
this.openSetup();
else
this.doSync();
},
//XXXzpao should be part of syncCommon.js - which we might want to make a module...
// To be fixed in a followup (bug 583366)
/**
* Invoke the Sync setup wizard.
*
* @param wizardType
* Indicates type of wizard to launch:
* null -- regular set up wizard
* "pair" -- pair a device first
* "reset" -- reset sync
*/
openSetup: function SUI_openSetup(wizardType) {
let win = Services.wm.getMostRecentWindow("Weave:AccountSetup");
if (win)
win.focus();
else {
window.openDialog("chrome://browser/content/sync/setup.xul",
"weaveSetup", "centerscreen,chrome,resizable=no",
wizardType);
}
},
openAddDevice: function () {
if (!Weave.Utils.ensureMPUnlocked())
return;
let win = Services.wm.getMostRecentWindow("Sync:AddDevice");
if (win)
win.focus();
else
window.openDialog("chrome://browser/content/sync/addDevice.xul",
"syncAddDevice", "centerscreen,chrome,resizable=no");
},
openQuotaDialog: function SUI_openQuotaDialog() {
let win = Services.wm.getMostRecentWindow("Sync:ViewQuota");
if (win)
win.focus();
else
Services.ww.activeWindow.openDialog(
"chrome://browser/content/sync/quota.xul", "",
"centerscreen,chrome,dialog,modal");
},
openPrefs: function SUI_openPrefs() {
openPreferences("paneSync");
},
// Helpers
_updateLastSyncTime: function SUI__updateLastSyncTime() {
if (!gBrowser)
return;
let syncButton = document.getElementById("sync-button");
if (!syncButton)
return;
let lastSync;
try {
lastSync = Services.prefs.getCharPref("services.sync.lastSync");
}
catch (e) { };
if (!lastSync || this._needsSetup()) {
syncButton.removeAttribute("tooltiptext");
return;
}
// Show the day-of-week and time (HH:MM) of last sync
let lastSyncDate = new Date(lastSync).toLocaleFormat("%a %H:%M");
let lastSyncLabel =
this._stringBundle.formatStringFromName("lastSync2.label", [lastSyncDate], 1);
syncButton.setAttribute("tooltiptext", lastSyncLabel);
},
clearError: function SUI_clearError(errorString) {
Weave.Notifications.removeAll(errorString);
this.updateUI();
},
onSyncFinish: function SUI_onSyncFinish() {
let title = this._stringBundle.GetStringFromName("error.sync.title");
// Clear out sync failures on a successful sync
this.clearError(title);
if (this._wasDelayed && Weave.Status.sync != Weave.NO_SYNC_NODE_FOUND) {
title = this._stringBundle.GetStringFromName("error.sync.no_node_found.title");
this.clearError(title);
this._wasDelayed = false;
}
},
onSyncError: function SUI_onSyncError() {
let title = this._stringBundle.GetStringFromName("error.sync.title");
if (Weave.Status.login != Weave.LOGIN_SUCCEEDED) {
this.onLoginError();
return;
}
let description;
if (Weave.Status.sync == Weave.PROLONGED_SYNC_FAILURE) {
// Convert to days
let lastSync =
Services.prefs.getIntPref("services.sync.errorhandler.networkFailureReportTimeout") / 86400;
description =
this._stringBundle.formatStringFromName("error.sync.prolonged_failure", [lastSync], 1);
} else {
let error = Weave.Utils.getErrorString(Weave.Status.sync);
description =
this._stringBundle.formatStringFromName("error.sync.description", [error], 1);
}
let priority = Weave.Notifications.PRIORITY_WARNING;
let buttons = [];
// Check if the client is outdated in some way
let outdated = Weave.Status.sync == Weave.VERSION_OUT_OF_DATE;
for (let [engine, reason] in Iterator(Weave.Status.engines))
outdated = outdated || reason == Weave.VERSION_OUT_OF_DATE;
if (outdated) {
description = this._stringBundle.GetStringFromName(
"error.sync.needUpdate.description");
buttons.push(new Weave.NotificationButton(
this._stringBundle.GetStringFromName("error.sync.needUpdate.label"),
this._stringBundle.GetStringFromName("error.sync.needUpdate.accesskey"),
function() {
window.openUILinkIn(Services.prefs.getCharPref("services.sync.outdated.url"), "tab");
return true;
}
));
}
else if (Weave.Status.sync == Weave.OVER_QUOTA) {
description = this._stringBundle.GetStringFromName(
"error.sync.quota.description");
buttons.push(new Weave.NotificationButton(
this._stringBundle.GetStringFromName(
"error.sync.viewQuotaButton.label"),
this._stringBundle.GetStringFromName(
"error.sync.viewQuotaButton.accesskey"),
function() { gSyncUI.openQuotaDialog(); return true; } )
);
}
else if (Weave.Status.enforceBackoff) {
priority = Weave.Notifications.PRIORITY_INFO;
buttons.push(new Weave.NotificationButton(
this._stringBundle.GetStringFromName("error.sync.serverStatusButton.label"),
this._stringBundle.GetStringFromName("error.sync.serverStatusButton.accesskey"),
function() { gSyncUI.openServerStatus(); return true; }
));
}
else {
priority = Weave.Notifications.PRIORITY_INFO;
buttons.push(new Weave.NotificationButton(
this._stringBundle.GetStringFromName("error.sync.tryAgainButton.label"),
this._stringBundle.GetStringFromName("error.sync.tryAgainButton.accesskey"),
function() { gSyncUI.doSync(); return true; }
));
}
let notification =
new Weave.Notification(title, description, null, priority, buttons);
Weave.Notifications.replaceTitle(notification);
if (this._wasDelayed && Weave.Status.sync != Weave.NO_SYNC_NODE_FOUND) {
title = this._stringBundle.GetStringFromName("error.sync.no_node_found.title");
Weave.Notifications.removeAll(title);
this._wasDelayed = false;
}
this.updateUI();
},
observe: function SUI_observe(subject, topic, data) {
if (this._unloaded) {
Cu.reportError("SyncUI observer called after unload: " + topic);
return;
}
switch (topic) {
case "weave:service:sync:start":
this.onActivityStart();
break;
case "weave:ui:sync:finish":
this.onSyncFinish();
break;
case "weave:ui:sync:error":
this.onSyncError();
break;
case "weave:service:sync:delayed":
this.onSyncDelay();
break;
case "weave:service:quota:remaining":
this.onQuotaNotice();
break;
case "weave:service:setup-complete":
this.onSetupComplete();
break;
case "weave:service:login:start":
this.onActivityStart();
break;
case "weave:service:login:finish":
this.onLoginFinish();
break;
case "weave:ui:login:error":
this.onLoginError();
break;
case "weave:service:logout:finish":
this.onLogout();
break;
case "weave:service:start-over":
this.onStartOver();
break;
case "weave:service:ready":
this.initUI();
break;
case "weave:notification:added":
this.initNotifications();
break;
case "weave:ui:clear-error":
this.clearError();
break;
}
},
QueryInterface: XPCOMUtils.generateQI([
Ci.nsIObserver,
Ci.nsISupportsWeakReference
])
};
XPCOMUtils.defineLazyGetter(gSyncUI, "_stringBundle", function() {
//XXXzpao these strings should probably be moved from /services to /browser... (bug 583381)
// but for now just make it work
return Cc["@mozilla.org/intl/stringbundle;1"].
getService(Ci.nsIStringBundleService).
createBundle("chrome://weave/locale/services/sync.properties");
});

View File

@ -687,6 +687,18 @@ window[chromehidden~="toolbar"] toolbar:not(#nav-bar):not(#TabsToolbar):not(#pri
min-width: 1px;
}
%ifdef MOZ_SERVICES_SYNC
/* Sync notification UI */
#sync-notifications {
-moz-binding: url("chrome://browser/content/sync/notification.xml#notificationbox");
overflow-y: visible !important;
}
#sync-notifications notification {
-moz-binding: url("chrome://browser/content/sync/notification.xml#notification");
}
%endif
/* History Swipe Animation */
#historySwipeAnimationContainer {

View File

@ -102,6 +102,12 @@ XPCOMUtils.defineLazyGetter(this, "PageMenuParent", function() {
return new tmp.PageMenuParent();
});
#ifdef MOZ_SERVICES_SYNC
XPCOMUtils.defineLazyModuleGetter(this, "Weave",
"resource://services-sync/main.js");
#endif
XPCOMUtils.defineLazyGetter(this, "PopupNotifications", function () {
let tmp = {};
Cu.import("resource://gre/modules/PopupNotifications.jsm", tmp);
@ -207,6 +213,10 @@ var gInitialPages = [
"about:logopage"
];
#ifdef MOZ_SERVICES_SYNC
#include browser-syncui.js
#endif
function* browserWindows() {
let windows = Services.wm.getEnumerator("navigator:browser");
while (windows.hasMoreElements())
@ -1306,6 +1316,11 @@ var gBrowserInit = {
if (AppConstants.MOZ_DATA_REPORTING)
gDataNotificationInfoBar.init();
#ifdef MOZ_SERVICES_SYNC
// initialize the sync UI
gSyncUI.init();
#endif
gBrowserThumbnails.init();
gMenuButtonBadgeManager.init();
@ -1596,6 +1611,11 @@ if (AppConstants.platform == "macosx") {
// initialize the private browsing UI
gPrivateBrowsingUI.init();
#ifdef MOZ_SERVICES_SYNC
// initialize the sync UI
gSyncUI.init();
#endif
};
gBrowserInit.nonBrowserWindowShutdown = function() {
@ -3147,12 +3167,14 @@ var PrintPreviewListener = {
this._chromeState.globalNotificationsOpen = !globalNotificationBox.notificationsHidden;
globalNotificationBox.notificationsHidden = true;
#ifdef MOZ_SERVICES_SYNC
this._chromeState.syncNotificationsOpen = false;
var syncNotifications = document.getElementById("sync-notifications");
if (syncNotifications) {
this._chromeState.syncNotificationsOpen = !syncNotifications.notificationsHidden;
syncNotifications.notificationsHidden = true;
}
#endif
},
_showChrome: function () {
if (this._chromeState.notificationsOpen)
@ -3164,8 +3186,10 @@ var PrintPreviewListener = {
if (this._chromeState.globalNotificationsOpen)
document.getElementById("global-notificationbox").notificationsHidden = false;
#ifdef MOZ_SERVICES_SYNC
if (this._chromeState.syncNotificationsOpen)
document.getElementById("sync-notifications").notificationsHidden = false;
#endif
if (this._chromeState.sidebarOpen)
SidebarUI.show(this._sidebarCommand);
@ -6204,9 +6228,14 @@ function checkEmptyPageOrigin(browser = gBrowser.selectedBrowser,
return ssm.isSystemPrincipal(contentPrincipal);
}
#ifdef MOZ_SERVICES_SYNC
function BrowserOpenSyncTabs() {
switchToTabHavingURI("about:sync-tabs", true);
if (gSyncUI._needsSetup())
gSyncUI.openSetup();
else
switchToTabHavingURI("about:sync-tabs", true);
}
#endif
/**
* Format a URL

View File

@ -100,11 +100,6 @@
tbattr="tabbrowser-multiple"
oncommand="gBrowser.replaceTabWithWindow(TabContextMenu.contextTab);"/>
<menuseparator id="context_sendTabToDevice_separator" hidden="true"/>
<menu id="context_sendTabToDevice" label="&sendTabToDevice.label;"
accesskey="&sendTabToDevice.accesskey;" hidden="true">
<menupopup id="context_sendTabToDevicePopupMenu"
onpopupshowing="gFxAccounts.populateSendTabToDevicesMenu(event.target, TabContextMenu.contextTab.linkedBrowser.currentURI.spec, TabContextMenu.contextTab.linkedBrowser.contentTitle);"/>
</menu>
<menuseparator/>
<menuitem id="context_reloadAllTabs" label="&reloadAllTabs.label;" accesskey="&reloadAllTabs.accesskey;"
tbattr="tabbrowser-multiple-visible"
@ -911,6 +906,18 @@
type="checkbox"
label="&fullScreenCmd.label;"
tooltip="dynamic-shortcut-tooltip"/>
#ifdef MOZ_SERVICES_SYNC
<toolbarbutton id="sync-button"
class="toolbarbutton-1 chromeclass-toolbar-additional"
label="&syncToolbarButton.label;"
oncommand="gSyncUI.handleToolbarButton();"/>>
<toolbarbutton id="sync-tabs-button"
class="toolbarbutton-1 chromeclass-toolbar-additional"
label="&syncTabsToolbarButton.label;"
oncommand="BrowserOpenSyncTabs();"/>
#endif
</toolbarpalette>
</toolbox>

View File

@ -24,7 +24,9 @@ browser.jar:
content/browser/abouthome/bookmarks.png (content/abouthome/bookmarks.png)
content/browser/abouthome/history.png (content/abouthome/history.png)
content/browser/abouthome/addons.png (content/abouthome/addons.png)
#ifdef MOZ_SERVICES_SYNC
content/browser/abouthome/sync.png (content/abouthome/sync.png)
#endif
content/browser/abouthome/settings.png (content/abouthome/settings.png)
content/browser/abouthome/restore.png (content/abouthome/restore.png)
content/browser/abouthome/restore-large.png (content/abouthome/restore-large.png)
@ -35,7 +37,9 @@ browser.jar:
content/browser/abouthome/bookmarks@2x.png (content/abouthome/bookmarks@2x.png)
content/browser/abouthome/history@2x.png (content/abouthome/history@2x.png)
content/browser/abouthome/addons@2x.png (content/abouthome/addons@2x.png)
#ifdef MOZ_SERVICES_SYNC
content/browser/abouthome/sync@2x.png (content/abouthome/sync@2x.png)
#endif
content/browser/abouthome/settings@2x.png (content/abouthome/settings@2x.png)
content/browser/abouthome/restore@2x.png (content/abouthome/restore@2x.png)
content/browser/abouthome/restore-large@2x.png (content/abouthome/restore-large@2x.png)
@ -64,7 +68,7 @@ browser.jar:
content/browser/browser-fullZoom.js (content/browser-fullZoom.js)
content/browser/browser-gestureSupport.js (content/browser-gestureSupport.js)
* content/browser/browser-media.js (content/browser-media.js)
content/browser/browser-places.js (content/browser-places.js)
* content/browser/browser-places.js (content/browser-places.js)
content/browser/browser-plugins.js (content/browser-plugins.js)
content/browser/browser-refreshblocker.js (content/browser-refreshblocker.js)
#ifdef MOZ_SAFE_BROWSING

View File

@ -92,10 +92,16 @@ static RedirEntry kRedirMap[] = {
"welcomeback", "chrome://browser/content/aboutWelcomeBack.xhtml",
nsIAboutModule::ALLOW_SCRIPT
},
#ifdef MOZ_SERVICES_SYNC
{
"sync-progress", "chrome://browser/content/sync/progress.xhtml",
nsIAboutModule::ALLOW_SCRIPT
},
{
"sync-tabs", "chrome://browser/content/sync/aboutSyncTabs.xul",
nsIAboutModule::ALLOW_SCRIPT
},
#endif
{ "home", "chrome://browser/content/abouthome/aboutHome.xhtml",
nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT |
nsIAboutModule::URI_MUST_LOAD_IN_CHILD |

View File

@ -97,7 +97,10 @@ static const mozilla::Module::ContractIDEntry kBrowserContracts[] = {
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "searchreset", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "sessionrestore", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "welcomeback", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
#ifdef MOZ_SERVICES_SYNC
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "sync-tabs", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "sync-progress", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
#endif
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "home", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "newtab", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "preferences", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },

View File

@ -22,6 +22,9 @@ DIRS += [
'translation',
]
if CONFIG['MOZ_SERVICES_SYNC']:
DIRS += ['sync']
if CONFIG['MOZ_WEBEXTENSIONS']:
DIRS += ['webextensions']
@ -37,6 +40,9 @@ XPIDL_MODULE = 'browsercompsbase'
EXTRA_COMPONENTS += [
'BrowserComponents.manifest',
'nsBrowserContentHandler.js',
]
EXTRA_PP_COMPONENTS += [
'nsBrowserGlue.js',
]

View File

@ -143,6 +143,7 @@ BrowserGlue.prototype = {
Services.prefs.savePrefFile(null);
},
#ifdef MOZ_SERVICES_SYNC
_setSyncAutoconnectDelay: function BG__setSyncAutoconnectDelay() {
// Assume that a non-zero value for services.sync.autoconnectDelay should override
if (Services.prefs.prefHasUserValue("services.sync.autoconnectDelay")) {
@ -164,6 +165,7 @@ BrowserGlue.prototype = {
Cu.import("resource://services-sync/main.js");
Weave.Service.scheduler.delayedAutoConnect(delay);
},
#endif
// nsIObserver implementation
observe: function BG_observe(subject, topic, data) {
@ -210,18 +212,14 @@ BrowserGlue.prototype = {
this._setPrefToSaveSession();
}
break;
#ifdef MOZ_SERVICES_SYNC
case "weave:service:ready":
this._setSyncAutoconnectDelay();
break;
case "fxaccounts:onverified":
this._showSyncStartedDoorhanger();
break;
case "fxaccounts:device_disconnected":
this._onDeviceDisconnected();
break;
case "weave:engine:clients:display-uris":
this._onDisplaySyncURIs(subject);
break;
case "weave:engine:clients:display-uri":
this._onDisplaySyncURI(subject);
break;
#endif
case "session-save":
this._setPrefToSaveSession(true);
subject.QueryInterface(Ci.nsISupportsPRBool);
@ -428,10 +426,10 @@ BrowserGlue.prototype = {
os.addObserver(this, "browser-lastwindow-close-requested", false);
os.addObserver(this, "browser-lastwindow-close-granted", false);
}
#ifdef MOZ_SERVICES_SYNC
os.addObserver(this, "weave:service:ready", false);
os.addObserver(this, "fxaccounts:onverified", false);
os.addObserver(this, "fxaccounts:device_disconnected", false);
os.addObserver(this, "weave:engine:clients:display-uris", false);
os.addObserver(this, "weave:engine:clients:display-uri", false);
#endif
os.addObserver(this, "session-save", false);
os.addObserver(this, "places-init-complete", false);
this._isPlacesInitObserver = true;
@ -479,10 +477,10 @@ BrowserGlue.prototype = {
os.removeObserver(this, "browser-lastwindow-close-requested");
os.removeObserver(this, "browser-lastwindow-close-granted");
}
#ifdef MOZ_SERVICES_SYNC
os.removeObserver(this, "weave:service:ready");
os.removeObserver(this, "fxaccounts:onverified");
os.removeObserver(this, "fxaccounts:device_disconnected");
os.removeObserver(this, "weave:engine:clients:display-uris");
os.removeObserver(this, "weave:engine:clients:display-uri");
#endif
os.removeObserver(this, "session-save");
if (this._bookmarksBackupIdleTime) {
this._idleService.removeIdleObserver(this, this._bookmarksBackupIdleTime);
@ -2273,90 +2271,29 @@ BrowserGlue.prototype = {
chromeWindow.openPreferences(...args);
},
#ifdef MOZ_SERVICES_SYNC
/**
* Called as an observer when Sync's "display URIs" notification is fired.
* Called as an observer when Sync's "display URI" notification is fired.
*
* We open the received URIs in background tabs.
* We open the received URI in a background tab.
*
* Eventually, this will likely be replaced by a more robust tab syncing
* feature. This functionality is considered somewhat evil by UX because it
* opens a new tab automatically without any prompting. However, it is a
* lesser evil than sending a tab to a specific device (from e.g. Fennec)
* and having nothing happen on the receiving end.
*/
_onDisplaySyncURIs: function _onDisplaySyncURIs(data) {
_onDisplaySyncURI: function _onDisplaySyncURI(data) {
try {
let tabbrowser = RecentWindow.getMostRecentBrowserWindow({private: false}).gBrowser;
// The payload is wrapped weirdly because of how Sync does notifications.
const URIs = data.wrappedJSObject.object;
const findWindow = () => RecentWindow.getMostRecentBrowserWindow({private: false});
// win can be null, but it's ok, we'll assign it later in openTab()
let win = findWindow();
const openTab = URI => {
let tab;
if (!win) {
Services.appShell.hiddenDOMWindow.open(URI.uri);
win = findWindow();
tab = win.gBrowser.tabs[0];
} else {
tab = win.gBrowser.addTab(URI.uri);
}
tab.setAttribute("attention", true);
return tab;
};
const firstTab = openTab(URIs[0]);
URIs.slice(1).forEach(URI => openTab(URI));
let title, body;
const deviceName = Weave.Service.clientsEngine.getClientName(URIs[0].clientId);
const bundle = Services.strings.createBundle("chrome://browser/locale/accounts.properties");
if (URIs.length == 1) {
// Due to bug 1305895, tabs from iOS may not have device information, so
// we have separate strings to handle those cases. (See Also
// unnamedTabsArrivingNotificationNoDevice.body below)
if (deviceName) {
title = bundle.formatStringFromName("tabArrivingNotificationWithDevice.title", [deviceName], 1);
} else {
title = bundle.GetStringFromName("tabArrivingNotification.title");
}
// Use the page URL as the body. We strip the fragment and query to
// reduce size, and also format it the same way that the url bar would.
body = URIs[0].uri.replace(/[?#].*$/, "");
if (win.gURLBar) {
body = win.gURLBar.trimValue(body);
}
} else {
title = bundle.GetStringFromName("tabsArrivingNotification.title");
const allSameDevice = URIs.every(URI => URI.clientId == URIs[0].clientId);
const unknownDevice = allSameDevice && !deviceName;
let tabArrivingBody;
if (unknownDevice) {
tabArrivingBody = "unnamedTabsArrivingNotificationNoDevice.body";
} else if (allSameDevice) {
tabArrivingBody = "unnamedTabsArrivingNotification2.body";
} else {
tabArrivingBody = "unnamedTabsArrivingNotificationMultiple2.body"
}
body = bundle.GetStringFromName(tabArrivingBody);
body = PluralForm.get(URIs.length, body);
body = body.replace("#1", URIs.length);
body = body.replace("#2", deviceName);
}
const clickCallback = (subject, topic, data) => {
if (topic == "alertclickcallback") {
win.gBrowser.selectedTab = firstTab;
}
}
// Specify an icon because on Windows no icon is shown at the moment
let imageURL;
if (AppConstants.platform == "win") {
imageURL = "chrome://branding/content/icon64.png";
}
AlertsService.showAlertNotification(imageURL, title, body, true, null, clickCallback);
tabbrowser.addTab(data.wrappedJSObject.object.uri);
} catch (ex) {
Cu.reportError("Error displaying tab(s) received by Sync: " + ex);
Cu.reportError("Error displaying tab received by Sync: " + ex);
}
},
#endif
_onDeviceDisconnected() {
let bundle = Services.strings.createBundle("chrome://browser/locale/accounts.properties");

View File

@ -1,32 +1,16 @@
/* 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/. */
* 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/. */
Components.utils.import("resource://services-sync/main.js");
Components.utils.import("resource://gre/modules/Services.jsm");
XPCOMUtils.defineLazyGetter(this, "FxAccountsCommon", function () {
return Components.utils.import("resource://gre/modules/FxAccountsCommon.js", {});
});
XPCOMUtils.defineLazyModuleGetter(this, "fxAccounts",
"resource://gre/modules/FxAccounts.jsm");
const PAGE_NO_ACCOUNT = 0;
const PAGE_HAS_ACCOUNT = 1;
const PAGE_NEEDS_UPDATE = 2;
const FXA_PAGE_LOGGED_OUT = 3;
const FXA_PAGE_LOGGED_IN = 4;
// Indexes into the "login status" deck.
// We are in a successful verified state - everything should work!
const FXA_LOGIN_VERIFIED = 0;
// We have logged in to an unverified account.
const FXA_LOGIN_UNVERIFIED = 1;
// We are logged in locally, but the server rejected our credentials.
const FXA_LOGIN_FAILED = 2;
var gSyncPane = {
_stringBundle: null,
prefArray: ["engine.bookmarks", "engine.passwords", "engine.prefs",
"engine.tabs", "engine.history"],
@ -45,13 +29,11 @@ var gSyncPane = {
needsUpdate: function () {
this.page = PAGE_NEEDS_UPDATE;
let label = document.getElementById("loginError");
label.textContent = Weave.Utils.getErrorString(Weave.Status.login);
label.value = Weave.Utils.getErrorString(Weave.Status.login);
label.className = "error";
},
init: function () {
this._setupEventListeners();
// If the Service hasn't finished initializing, wait for it.
let xps = Components.classes["@mozilla.org/weave/service;1"]
.getService(Components.interfaces.nsISupports)
@ -62,10 +44,6 @@ var gSyncPane = {
return;
}
// it may take some time before we can determine what provider to use
// and the state of that provider, so show the "please wait" page.
this._showLoadPage(xps);
let onUnload = function () {
window.removeEventListener("unload", onUnload, false);
try {
@ -85,235 +63,50 @@ var gSyncPane = {
xps.ensureLoaded();
},
_showLoadPage: function (xps) {
let username;
try {
username = Services.prefs.getCharPref("services.sync.username");
} catch (e) {}
if (!username) {
this.page = FXA_PAGE_LOGGED_OUT;
} else {
this.page = PAGE_HAS_ACCOUNT;
}
},
_init: function () {
let topics = ["weave:service:login:error",
"weave:service:login:finish",
"weave:service:start-over:finish",
"weave:service:start-over",
"weave:service:setup-complete",
"weave:service:logout:finish",
FxAccountsCommon.ONVERIFIED_NOTIFICATION,
FxAccountsCommon.ONLOGIN_NOTIFICATION,
FxAccountsCommon.ON_PROFILE_CHANGE_NOTIFICATION,
];
"weave:service:logout:finish"];
// Add the observers now and remove them on unload
// XXXzpao This should use Services.obs.* but Weave's Obs does nice handling
//XXXzpao This should use Services.obs.* but Weave's Obs does nice handling
// of `this`. Fix in a followup. (bug 583347)
topics.forEach(function (topic) {
Weave.Svc.Obs.add(topic, this.updateWeavePrefs, this);
}, this);
window.addEventListener("unload", function() {
topics.forEach(function (topic) {
Weave.Svc.Obs.remove(topic, this.updateWeavePrefs, this);
}, gSyncPane);
}, false);
XPCOMUtils.defineLazyGetter(this, '_stringBundle', () => {
return Services.strings.createBundle("chrome://browser/locale/preferences/preferences.properties");
});
XPCOMUtils.defineLazyGetter(this, '_accountsStringBundle', () => {
return Services.strings.createBundle("chrome://browser/locale/accounts.properties");
});
let url = Services.prefs.getCharPref("identity.mobilepromo.android") + "sync-preferences";
document.getElementById("fxaMobilePromo-android").setAttribute("href", url);
document.getElementById("fxaMobilePromo-android-hasFxaAccount").setAttribute("href", url);
url = Services.prefs.getCharPref("identity.mobilepromo.ios") + "sync-preferences";
document.getElementById("fxaMobilePromo-ios").setAttribute("href", url);
document.getElementById("fxaMobilePromo-ios-hasFxaAccount").setAttribute("href", url);
document.getElementById("tosPP-small-ToS").setAttribute("href", gSyncUtils.tosURL);
document.getElementById("tosPP-normal-ToS").setAttribute("href", gSyncUtils.tosURL);
document.getElementById("tosPP-small-PP").setAttribute("href", gSyncUtils.privacyPolicyURL);
document.getElementById("tosPP-normal-PP").setAttribute("href", gSyncUtils.privacyPolicyURL);
fxAccounts.promiseAccountsManageURI(this._getEntryPoint()).then(url => {
document.getElementById("verifiedManage").setAttribute("href", url);
});
this._stringBundle =
Services.strings.createBundle("chrome://browser/locale/preferences/preferences.properties");
this.updateWeavePrefs();
this._initProfileImageUI();
},
_toggleComputerNameControls: function(editMode) {
let textbox = document.getElementById("fxaSyncComputerName");
textbox.disabled = !editMode;
document.getElementById("fxaChangeDeviceName").hidden = editMode;
document.getElementById("fxaCancelChangeDeviceName").hidden = !editMode;
document.getElementById("fxaSaveChangeDeviceName").hidden = !editMode;
},
_focusComputerNameTextbox: function() {
let textbox = document.getElementById("fxaSyncComputerName");
let valLength = textbox.value.length;
textbox.focus();
textbox.setSelectionRange(valLength, valLength);
},
_blurComputerNameTextbox: function() {
document.getElementById("fxaSyncComputerName").blur();
},
_focusAfterComputerNameTextbox: function() {
// Focus the most appropriate element that's *not* the "computer name" box.
Services.focus.moveFocus(window,
document.getElementById("fxaSyncComputerName"),
Services.focus.MOVEFOCUS_FORWARD, 0);
},
_updateComputerNameValue: function(save) {
if (save) {
let textbox = document.getElementById("fxaSyncComputerName");
Weave.Service.clientsEngine.localName = textbox.value;
}
this._populateComputerName(Weave.Service.clientsEngine.localName);
},
_setupEventListeners: function() {
function setEventListener(aId, aEventType, aCallback)
{
document.getElementById(aId)
.addEventListener(aEventType, aCallback.bind(gSyncPane));
}
setEventListener("noAccountSetup", "click", function (aEvent) {
aEvent.stopPropagation();
gSyncPane.openSetup(null);
});
setEventListener("noAccountPair", "click", function (aEvent) {
aEvent.stopPropagation();
gSyncPane.openSetup('pair');
});
setEventListener("syncChangePassword", "command",
() => gSyncUtils.changePassword());
setEventListener("syncResetPassphrase", "command",
() => gSyncUtils.resetPassphrase());
setEventListener("syncReset", "command", gSyncPane.resetSync);
setEventListener("syncAddDeviceLabel", "click", function () {
gSyncPane.openAddDevice();
return false;
});
setEventListener("syncEnginesList", "select", function () {
if (this.selectedCount)
this.clearSelection();
});
setEventListener("syncComputerName", "change", function (e) {
gSyncUtils.changeName(e.target);
});
setEventListener("fxaChangeDeviceName", "command", function () {
this._toggleComputerNameControls(true);
this._focusComputerNameTextbox();
});
setEventListener("fxaCancelChangeDeviceName", "command", function () {
// We explicitly blur the textbox because of bug 75324, then after
// changing the state of the buttons, force focus to whatever the focus
// manager thinks should be next (which on the mac, depends on an OSX
// keyboard access preference)
this._blurComputerNameTextbox();
this._toggleComputerNameControls(false);
this._updateComputerNameValue(false);
this._focusAfterComputerNameTextbox();
});
setEventListener("fxaSaveChangeDeviceName", "command", function () {
// Work around bug 75324 - see above.
this._blurComputerNameTextbox();
this._toggleComputerNameControls(false);
this._updateComputerNameValue(true);
this._focusAfterComputerNameTextbox();
});
setEventListener("unlinkDevice", "click", function () {
gSyncPane.startOver(true);
return false;
});
setEventListener("loginErrorUpdatePass", "click", function () {
gSyncPane.updatePass();
return false;
});
setEventListener("loginErrorResetPass", "click", function () {
gSyncPane.resetPass();
return false;
});
setEventListener("loginErrorStartOver", "click", function () {
gSyncPane.startOver(true);
return false;
});
setEventListener("noFxaSignUp", "command", function () {
gSyncPane.signUp();
return false;
});
setEventListener("noFxaSignIn", "command", function () {
gSyncPane.signIn();
return false;
});
setEventListener("fxaUnlinkButton", "command", function () {
gSyncPane.unlinkFirefoxAccount(true);
});
setEventListener("verifyFxaAccount", "command",
gSyncPane.verifyFirefoxAccount);
setEventListener("unverifiedUnlinkFxaAccount", "command", function () {
/* no warning as account can't have previously synced */
gSyncPane.unlinkFirefoxAccount(false);
});
setEventListener("rejectReSignIn", "command",
gSyncPane.reSignIn);
setEventListener("rejectUnlinkFxaAccount", "command", function () {
gSyncPane.unlinkFirefoxAccount(true);
});
setEventListener("fxaSyncComputerName", "keypress", function (e) {
if (e.keyCode == KeyEvent.DOM_VK_RETURN) {
document.getElementById("fxaSaveChangeDeviceName").click();
} else if (e.keyCode == KeyEvent.DOM_VK_ESCAPE) {
document.getElementById("fxaCancelChangeDeviceName").click();
}
});
},
_initProfileImageUI: function () {
try {
if (Services.prefs.getBoolPref("identity.fxaccounts.profile_image.enabled")) {
document.getElementById("fxaProfileImage").hidden = false;
}
} catch (e) { }
document.getElementById("weavePrefsDeck").setAttribute("hidden", "");
},
updateWeavePrefs: function () {
let service = Components.classes["@mozilla.org/weave/service;1"]
.getService(Components.interfaces.nsISupports)
.wrappedJSObject;
if (Weave.Status.service == Weave.CLIENT_NOT_CONFIGURED ||
Weave.Svc.Prefs.get("firstSync", "") == "notReady") {
this.page = PAGE_NO_ACCOUNT;
// else: sync was previously configured for the legacy provider, so we
// make the "old" panels available.
} else if (Weave.Status.login == Weave.LOGIN_FAILED_INVALID_PASSPHRASE ||
Weave.Status.login == Weave.LOGIN_FAILED_LOGIN_REJECTED) {
this.needsUpdate();
} else {
this.page = PAGE_HAS_ACCOUNT;
document.getElementById("accountName").textContent = Weave.Service.identity.account;
document.getElementById("accountName").value = Weave.Service.identity.account;
document.getElementById("syncComputerName").value = Weave.Service.clientsEngine.localName;
document.getElementById("tosPP-normal").hidden = this._usingCustomServer;
document.getElementById("tosPP").hidden = this._usingCustomServer;
}
},
startOver: function (showDialog) {
if (showDialog) {
let flags = Services.prompt.BUTTON_POS_0 * Services.prompt.BUTTON_TITLE_IS_STRING +
Services.prompt.BUTTON_POS_1 * Services.prompt.BUTTON_TITLE_CANCEL +
Services.prompt.BUTTON_POS_1 * Services.prompt.BUTTON_TITLE_CANCEL +
Services.prompt.BUTTON_POS_1_DEFAULT;
let buttonChoice =
Services.prompt.confirmEx(window,
@ -324,8 +117,9 @@ var gSyncPane = {
null, null, null, {});
// If the user selects cancel, just bail
if (buttonChoice == 1)
if (buttonChoice == 1) {
return;
}
}
Weave.Service.startOver();
@ -333,33 +127,19 @@ var gSyncPane = {
},
updatePass: function () {
if (Weave.Status.login == Weave.LOGIN_FAILED_LOGIN_REJECTED)
if (Weave.Status.login == Weave.LOGIN_FAILED_LOGIN_REJECTED) {
gSyncUtils.changePassword();
else
} else {
gSyncUtils.updatePassphrase();
}
},
resetPass: function () {
if (Weave.Status.login == Weave.LOGIN_FAILED_LOGIN_REJECTED)
if (Weave.Status.login == Weave.LOGIN_FAILED_LOGIN_REJECTED) {
gSyncUtils.resetPassword();
else
} else {
gSyncUtils.resetPassphrase();
},
_getEntryPoint: function () {
let params = new URLSearchParams(document.URL.split("#")[0].split("?")[1] || "");
return params.get("entrypoint") || "preferences";
},
_openAboutAccounts: function(action) {
let entryPoint = this._getEntryPoint();
let params = new URLSearchParams();
if (action) {
params.set("action", action);
}
params.set("entrypoint", entryPoint);
this.replaceTabWithUrl("about:accounts?" + params);
},
/**
@ -372,159 +152,16 @@ var gSyncPane = {
* "reset" -- reset sync
*/
openSetup: function (wizardType) {
let service = Components.classes["@mozilla.org/weave/service;1"]
.getService(Components.interfaces.nsISupports)
.wrappedJSObject;
let win = Services.wm.getMostRecentWindow("Weave:AccountSetup");
if (win)
if (win) {
win.focus();
else {
} else {
window.openDialog("chrome://browser/content/sync/setup.xul",
"weaveSetup", "centerscreen,chrome,resizable=no",
wizardType);
}
},
openContentInBrowser: function(url, options) {
let win = Services.wm.getMostRecentWindow("navigator:browser");
if (!win) {
// no window to use, so use _openLink to create a new one. We don't
// always use that as it prefers to open a new window rather than use
// an existing one.
gSyncUtils._openLink(url);
return;
}
win.switchToTabHavingURI(url, true, options);
},
// Replace the current tab with the specified URL.
replaceTabWithUrl(url) {
// Get the <browser> element hosting us.
let browser = window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShell)
.chromeEventHandler;
// And tell it to load our URL.
browser.loadURI(url);
},
signUp: function() {
this._openAboutAccounts("signup");
},
signIn: function() {
this._openAboutAccounts("signin");
},
reSignIn: function() {
this._openAboutAccounts("reauth");
},
clickOrSpaceOrEnterPressed: function(event) {
// Note: charCode is deprecated, but 'char' not yet implemented.
// Replace charCode with char when implemented, see Bug 680830
return ((event.type == "click" && event.button == 0) ||
(event.type == "keypress" &&
(event.charCode == KeyEvent.DOM_VK_SPACE || event.keyCode == KeyEvent.DOM_VK_RETURN)));
},
openChangeProfileImage: function(event) {
if (this.clickOrSpaceOrEnterPressed(event)) {
fxAccounts.promiseAccountsChangeProfileURI(this._getEntryPoint(), "avatar")
.then(url => {
this.openContentInBrowser(url, {
replaceQueryString: true
});
});
// Prevent page from scrolling on the space key.
event.preventDefault();
}
},
openManageFirefoxAccount: function(event) {
if (this.clickOrSpaceOrEnterPressed(event)) {
this.manageFirefoxAccount();
// Prevent page from scrolling on the space key.
event.preventDefault();
}
},
manageFirefoxAccount: function() {
fxAccounts.promiseAccountsManageURI(this._getEntryPoint())
.then(url => {
this.openContentInBrowser(url, {
replaceQueryString: true
});
});
},
verifyFirefoxAccount: function() {
let showVerifyNotification = (data) => {
let isError = !data;
let maybeNot = isError ? "Not" : "";
let sb = this._accountsStringBundle;
let title = sb.GetStringFromName("verification" + maybeNot + "SentTitle");
let email = !isError && data ? data.email : "";
let body = sb.formatStringFromName("verification" + maybeNot + "SentBody", [email], 1);
new Notification(title, { body })
}
let onError = () => {
showVerifyNotification();
};
let onSuccess = data => {
if (data) {
showVerifyNotification(data);
} else {
onError();
}
};
fxAccounts.resendVerificationEmail()
.then(fxAccounts.getSignedInUser, onError)
.then(onSuccess, onError);
},
openOldSyncSupportPage: function() {
let url = Services.urlFormatter.formatURLPref("app.support.baseURL") + "old-sync";
this.openContentInBrowser(url);
},
unlinkFirefoxAccount: function(confirm) {
if (confirm) {
// We use a string bundle shared with aboutAccounts.
let sb = Services.strings.createBundle("chrome://browser/locale/syncSetup.properties");
let disconnectLabel = sb.GetStringFromName("disconnect.label");
let title = sb.GetStringFromName("disconnect.verify.title");
let body = sb.GetStringFromName("disconnect.verify.bodyHeading") +
"\n\n" +
sb.GetStringFromName("disconnect.verify.bodyText");
let ps = Services.prompt;
let buttonFlags = (ps.BUTTON_POS_0 * ps.BUTTON_TITLE_IS_STRING) +
(ps.BUTTON_POS_1 * ps.BUTTON_TITLE_CANCEL) +
ps.BUTTON_POS_1_DEFAULT;
let factory = Cc["@mozilla.org/prompter;1"]
.getService(Ci.nsIPromptFactory);
let prompt = factory.getPrompt(window, Ci.nsIPrompt);
let bag = prompt.QueryInterface(Ci.nsIWritablePropertyBag2);
bag.setPropertyAsBool("allowTabModal", true);
let pressed = prompt.confirmEx(title, body, buttonFlags,
disconnectLabel, null, null, null, {});
if (pressed != 0) { // 0 is the "continue" button
return;
}
}
fxAccounts.signOut().then(() => {
this.updateWeavePrefs();
});
},
openQuotaDialog: function () {
let win = Services.wm.getMostRecentWindow("Sync:ViewQuota");
if (win) {
@ -536,27 +173,21 @@ var gSyncPane = {
},
openAddDevice: function () {
if (!Weave.Utils.ensureMPUnlocked())
if (!Weave.Utils.ensureMPUnlocked()) {
return;
}
let win = Services.wm.getMostRecentWindow("Sync:AddDevice");
if (win)
if (win) {
win.focus();
else
} else {
window.openDialog("chrome://browser/content/sync/addDevice.xul",
"syncAddDevice", "centerscreen,chrome,resizable=no");
}
},
resetSync: function () {
this.openSetup("reset");
},
_populateComputerName(value) {
let textbox = document.getElementById("fxaSyncComputerName");
if (!textbox.hasAttribute("placeholder")) {
textbox.setAttribute("placeholder",
Weave.Utils.getDefaultDeviceName());
}
textbox.value = value;
},
};

View File

@ -1,35 +1,22 @@
# 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/.
<!-- Sync panel -->
<preferences id="syncEnginePrefs" hidden="true" data-category="paneSync">
<preference id="engine.addons"
name="services.sync.engine.addons"
type="bool"/>
<preference id="engine.bookmarks"
name="services.sync.engine.bookmarks"
type="bool"/>
<preference id="engine.history"
name="services.sync.engine.history"
type="bool"/>
<preference id="engine.tabs"
name="services.sync.engine.tabs"
type="bool"/>
<preference id="engine.prefs"
name="services.sync.engine.prefs"
type="bool"/>
<preference id="engine.passwords"
name="services.sync.engine.passwords"
type="bool"/>
</preferences>
<!-- 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/. -->
<script type="application/javascript"
src="chrome://browser/content/preferences/in-content/sync.js"/>
<script type="application/javascript"
src="chrome://browser/content/sync/utils.js"/>
<preferences>
<!-- <preference id="engine.addons" name="services.sync.engine.addons" type="bool"/> -->
<preference id="engine.bookmarks" name="services.sync.engine.bookmarks" type="bool"/>
<preference id="engine.history" name="services.sync.engine.history" type="bool"/>
<preference id="engine.tabs" name="services.sync.engine.tabs" type="bool"/>
<preference id="engine.prefs" name="services.sync.engine.prefs" type="bool"/>
<preference id="engine.passwords" name="services.sync.engine.passwords" type="bool"/>
</preferences>
<hbox id="header-sync"
class="header"
hidden="true"
@ -39,22 +26,19 @@
</hbox>
<deck id="weavePrefsDeck" data-category="paneSync" hidden="true">
<!-- These panels are for the "legacy" sync provider -->
<vbox id="noAccount" align="center">
<spacer flex="1"/>
<description id="syncDesc">
&weaveDesc.label;
</description>
<separator/>
<label id="noAccountSetup" class="text-link">
&setupButton.label;
</label>
<vbox id="pairDevice">
<separator/>
<label id="noAccountPair" class="text-link">
&pairDevice.label;
</label>
</vbox>
<label class="text-link"
onclick="event.stopPropagation(); gSyncPane.openSetup(null);"
value="&setupButton.label;"/>
<separator/>
<label class="text-link"
onclick="event.stopPropagation(); gSyncPane.openSetup('pair');"
value="&pairDevice.label;"/>
<spacer flex="3"/>
</vbox>
@ -63,7 +47,7 @@
<!-- label is set to account name -->
<caption id="accountCaption" align="center">
<image id="accountCaptionImage"/>
<label id="accountName"/>
<label id="accountName" value=""/>
</caption>
<hbox>
@ -71,28 +55,39 @@
label="&manageAccount.label;"
accesskey="&manageAccount.accesskey;">
<menupopup>
<menuitem id="syncViewQuota" label="&viewQuota.label;"
<menuitem label="&viewQuota.label;"
oncommand="gSyncPane.openQuotaDialog();"/>
<menuseparator/>
<menuitem id="syncChangePassword" label="&changePassword2.label;"/>
<menuitem id="syncResetPassphrase" label="&myRecoveryKey.label;"/>
<menuseparator/>
<menuitem id="syncReset" label="&resetSync2.label;"/>
<menuitem label="&changePassword2.label;"
oncommand="gSyncUtils.changePassword();"/>
<menuitem label="&myRecoveryKey.label;"
oncommand="gSyncUtils.resetPassphrase();"/>
<menuseparator/>
<menuitem label="&resetSync2.label;"
oncommand="gSyncPane.resetSync();"/>
</menupopup>
</button>
</hbox>
<hbox>
<label id="syncAddDeviceLabel"
class="text-link">
&pairDevice.label;
</label>
class="text-link"
onclick="gSyncPane.openAddDevice(); return false;"
value="&pairDevice.label;"/>
</hbox>
<vbox>
<label>&syncMy.label;</label>
<label value="&syncMy.label;" />
<richlistbox id="syncEnginesList"
orient="vertical">
orient="vertical"
onselect="if (this.selectedCount) this.clearSelection();">
<!--
<richlistitem>
<checkbox label="&engine.addons.label;"
accesskey="&engine.addons.accesskey;"
preference="engine.addons"/>
</richlistitem>
-->
<richlistitem>
<checkbox label="&engine.bookmarks.label;"
accesskey="&engine.bookmarks.accesskey;"
@ -130,228 +125,42 @@
</columns>
<rows>
<row align="center">
<label control="syncComputerName">
&syncDeviceName.label;
</label>
<textbox id="syncComputerName"/>
<label value="&syncDeviceName.label;"
accesskey="&syncDeviceName.accesskey;"
control="syncComputerName"/>
<textbox id="syncComputerName"
onchange="gSyncUtils.changeName(this)"/>
</row>
</rows>
</grid>
<hbox>
<label id="unlinkDevice" class="text-link">
&unlinkDevice.label;
</label>
<label class="text-link"
onclick="gSyncPane.startOver(true); return false;"
value="&unlinkDevice.label;"/>
</hbox>
</groupbox>
<vbox id="tosPP-normal">
<label id="tosPP-normal-ToS" class="text-link">
&prefs.tosLink.label;
</label>
<label id="tosPP-normal-PP" class="text-link">
&prefs.ppLink.label;
</label>
</vbox>
<hbox id="tosPP" pack="center">
<label class="text-link"
onclick="event.stopPropagation();gSyncUtils.openToS();"
value="&prefs.tosLink.label;"/>
<label class="text-link"
onclick="event.stopPropagation();gSyncUtils.openPrivacyPolicy();"
value="&prefs.ppLink.label;"/>
</hbox>
</vbox>
<vbox id="needsUpdate" align="center" pack="center">
<hbox>
<label id="loginError"/>
<label id="loginErrorUpdatePass" class="text-link">
&updatePass.label;
</label>
<label id="loginErrorResetPass" class="text-link">
&resetPass.label;
</label>
<label id="loginError" value=""/>
<label class="text-link"
onclick="gSyncPane.updatePass(); return false;"
value="&updatePass.label;"/>
<label class="text-link"
onclick="gSyncPane.resetPass(); return false;"
value="&resetPass.label;"/>
</hbox>
<label id="loginErrorStartOver" class="text-link">
&unlinkDevice.label;
</label>
</vbox>
<!-- These panels are for the Firefox Accounts identity provider -->
<vbox id="noFxaAccount">
<hbox>
<vbox id="fxaContentWrapper">
<groupbox id="noFxaGroup">
<vbox>
<label id="noFxaCaption">&signedOut.caption;</label>
<description id="noFxaDescription" flex="1">&signedOut.description;</description>
<hbox class="fxaAccountBox">
<vbox>
<image class="fxaFirefoxLogo"/>
</vbox>
<vbox flex="1">
<label id="signedOutAccountBoxTitle">&signedOut.accountBox.title;</label>
<hbox class="fxaAccountBoxButtons">
<button id="noFxaSignUp" label="&signedOut.accountBox.create;" accesskey="&signedOut.accountBox.create.accesskey;"></button>
<button id="noFxaSignIn" label="&signedOut.accountBox.signin;" accesskey="&signedOut.accountBox.signin.accesskey;"></button>
</hbox>
</vbox>
</hbox>
</vbox>
</groupbox>
</vbox>
<vbox>
<image class="fxaSyncIllustration"/>
</vbox>
</hbox>
<label class="fxaMobilePromo">
&mobilePromo3.start;<!-- We put these comments to avoid inserting white spaces
--><label id="fxaMobilePromo-android"
class="androidLink text-link"><!--
-->&mobilePromo3.androidLink;</label><!--
-->&mobilePromo3.iOSBefore;<!--
--><label id="fxaMobilePromo-ios"
class="iOSLink text-link"><!--
-->&mobilePromo3.iOSLink;</label><!--
-->&mobilePromo3.end;
</label>
</vbox>
<vbox id="hasFxaAccount">
<hbox>
<vbox id="fxaContentWrapper">
<groupbox id="fxaGroup">
<caption><label>&syncBrand.fxAccount.label;</label></caption>
<deck id="fxaLoginStatus">
<!-- logged in and verified and all is good -->
<hbox id="fxaLoginVerified" class="fxaAccountBox">
<vbox align="center" pack="center">
<image id="fxaProfileImage" class="actionable"
role="button"
onclick="gSyncPane.openChangeProfileImage(event);" hidden="true"
onkeypress="gSyncPane.openChangeProfileImage(event);"
tooltiptext="&profilePicture.tooltip;"/>
</vbox>
<vbox flex="1" pack="center">
<label id="fxaDisplayName" hidden="true"/>
<label id="fxaEmailAddress1"/>
<hbox class="fxaAccountBoxButtons">
<button id="fxaUnlinkButton" label="&disconnect.label;" accesskey="&disconnect.accesskey;"/>
<html:a id="verifiedManage" target="_blank"
accesskey="&verifiedManage.accesskey;"
onkeypress="gSyncPane.openManageFirefoxAccount(event);"><!--
-->&verifiedManage.label;</html:a>
</hbox>
</vbox>
</hbox>
<!-- logged in to an unverified account -->
<hbox id="fxaLoginUnverified" class="fxaAccountBox">
<vbox>
<image id="fxaProfileImage"/>
</vbox>
<vbox flex="1">
<hbox>
<vbox><image id="fxaLoginRejectedWarning"/></vbox>
<description flex="1">
&signedInUnverified.beforename.label;
<label id="fxaEmailAddress2"/>
&signedInUnverified.aftername.label;
</description>
</hbox>
<hbox class="fxaAccountBoxButtons">
<button id="verifyFxaAccount" accesskey="&verify.accesskey;">&verify.label;</button>
<button id="unverifiedUnlinkFxaAccount" accesskey="&forget.accesskey;">&forget.label;</button>
</hbox>
</vbox>
</hbox>
<!-- logged in locally but server rejected credentials -->
<hbox id="fxaLoginRejected" class="fxaAccountBox">
<vbox>
<image id="fxaProfileImage"/>
</vbox>
<vbox flex="1">
<hbox>
<vbox><image id="fxaLoginRejectedWarning"/></vbox>
<description flex="1">
&signedInLoginFailure.beforename.label;
<label id="fxaEmailAddress3"/>
&signedInLoginFailure.aftername.label;
</description>
</hbox>
<hbox class="fxaAccountBoxButtons">
<button id="rejectReSignIn" accessky="&signIn.accesskey;">&signIn.label;</button>
<button id="rejectUnlinkFxaAccount" accesskey="&forget.accesskey;">&forget.label;</button>
</hbox>
</vbox>
</hbox>
</deck>
</groupbox>
<groupbox id="syncOptions">
<caption><label>&signedIn.engines.label;</label></caption>
<hbox id="fxaSyncEngines">
<vbox align="start" flex="1">
<checkbox label="&engine.tabs.label;"
accesskey="&engine.tabs.accesskey;"
preference="engine.tabs"/>
<checkbox label="&engine.bookmarks.label;"
accesskey="&engine.bookmarks.accesskey;"
preference="engine.bookmarks"/>
<checkbox label="&engine.passwords.label;"
accesskey="&engine.passwords.accesskey;"
preference="engine.passwords"/>
</vbox>
<vbox align="start" flex="1">
<checkbox label="&engine.history.label;"
accesskey="&engine.history.accesskey;"
preference="engine.history"/>
<checkbox label="&engine.addons.label;"
accesskey="&engine.addons.accesskey;"
preference="engine.addons"/>
<checkbox label="&engine.prefs.label;"
accesskey="&engine.prefs.accesskey;"
preference="engine.prefs"/>
</vbox>
<spacer/>
</hbox>
</groupbox>
</vbox>
<vbox>
<image class="fxaSyncIllustration"/>
</vbox>
</hbox>
<groupbox>
<caption>
<label control="fxaSyncComputerName">
&fxaSyncDeviceName.label;
</label>
</caption>
<hbox id="fxaDeviceName">
<textbox id="fxaSyncComputerName" disabled="true"/>
<hbox>
<button id="fxaChangeDeviceName"
label="&changeSyncDeviceName.label;"
accesskey="&changeSyncDeviceName.accesskey;"/>
<button id="fxaCancelChangeDeviceName"
label="&cancelChangeSyncDeviceName.label;"
accesskey="&cancelChangeSyncDeviceName.accesskey;"
hidden="true"/>
<button id="fxaSaveChangeDeviceName"
label="&saveChangeSyncDeviceName.label;"
accesskey="&saveChangeSyncDeviceName.accesskey;"
hidden="true"/>
</hbox>
</hbox>
</groupbox>
<label class="fxaMobilePromo">
&mobilePromo3.start;<!-- We put these comments to avoid inserting white spaces
--><label class="androidLink text-link" id="fxaMobilePromo-android-hasFxaAccount"><!--
-->&mobilePromo3.androidLink;</label><!--
-->&mobilePromo3.iOSBefore;<!--
--><label class="iOSLink text-link" id="fxaMobilePromo-ios-hasFxaAccount"><!--
-->&mobilePromo3.iOSLink;</label><!--
-->&mobilePromo3.end;
</label>
<vbox id="tosPP-small" align="start">
<label id="tosPP-small-ToS" class="text-link">
&prefs.tosLink.label;
</label>
<label id="tosPP-small-PP" class="text-link">
&fxaPrivacyNotice.link.label;
</label>
</vbox>
<label class="text-link"
onclick="gSyncPane.startOver(true); return false;"
value="&unlinkDevice.label;"/>
</vbox>
</deck>

View File

@ -0,0 +1,46 @@
<?xml version="1.0"?>
<!-- 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/. -->
<bindings id="tabBindings"
xmlns="http://www.mozilla.org/xbl"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:xbl="http://www.mozilla.org/xbl">
<binding id="tab-listing" extends="chrome://global/content/bindings/richlistbox.xml#richlistitem">
<content>
<xul:hbox flex="1">
<xul:vbox pack="start">
<xul:image class="tabIcon"
xbl:inherits="src=icon"/>
</xul:vbox>
<xul:vbox pack="start" flex="1">
<xul:label xbl:inherits="value=title,selected"
crop="end" flex="1" class="title"/>
<xul:label xbl:inherits="value=url,selected"
crop="end" flex="1" class="url"/>
</xul:vbox>
</xul:hbox>
</content>
<handlers>
<handler event="dblclick" button="0">
<![CDATA[
RemoteTabViewer.openSelected();
]]>
</handler>
</handlers>
</binding>
<binding id="client-listing" extends="chrome://global/content/bindings/richlistbox.xml#richlistitem">
<content>
<xul:hbox pack="start" align="center" onfocus="event.target.blur()" onselect="return false;">
<xul:image/>
<xul:label xbl:inherits="value=clientName"
class="clientName"
crop="center" flex="1"/>
</xul:hbox>
</content>
</binding>
</bindings>

View File

@ -0,0 +1,11 @@
/* 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/. */
richlistitem[type="tab"] {
-moz-binding: url(chrome://browser/content/sync/aboutSyncTabs-bindings.xml#tab-listing);
}
richlistitem[type="client"] {
-moz-binding: url(chrome://browser/content/sync/aboutSyncTabs-bindings.xml#client-listing);
}

View File

@ -0,0 +1,313 @@
/* 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/. */
var Cu = Components.utils;
Cu.import("resource://services-common/utils.js");
Cu.import("resource://services-sync/main.js");
Cu.import("resource:///modules/PlacesUIUtils.jsm");
Cu.import("resource://gre/modules/PlacesUtils.jsm", this);
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
var RemoteTabViewer = {
_tabsList: null,
init: function () {
Services.obs.addObserver(this, "weave:service:login:finish", false);
Services.obs.addObserver(this, "weave:engine:sync:finish", false);
this._tabsList = document.getElementById("tabsList");
this.buildList(true);
},
uninit: function () {
Services.obs.removeObserver(this, "weave:service:login:finish");
Services.obs.removeObserver(this, "weave:engine:sync:finish");
},
createItem: function(attrs) {
let item = document.createElement("richlistitem");
// Copy the attributes from the argument into the item
for (let attr in attrs) {
item.setAttribute(attr, attrs[attr]);
}
if (attrs["type"] == "tab") {
item.label = attrs.title != "" ? attrs.title : attrs.url;
}
return item;
},
filterTabs: function(event) {
let val = event.target.value.toLowerCase();
let numTabs = this._tabsList.getRowCount();
let clientTabs = 0;
let currentClient = null;
for (let i = 0; i < numTabs; i++) {
let item = this._tabsList.getItemAtIndex(i);
let hide = false;
if (item.getAttribute("type") == "tab") {
if (!item.getAttribute("url").toLowerCase().includes(val) &&
!item.getAttribute("title").toLowerCase().includes(val)) {
hide = true;
} else {
clientTabs++;
}
}
else if (item.getAttribute("type") == "client") {
if (currentClient) {
if (clientTabs == 0) {
currentClient.hidden = true;
}
}
currentClient = item;
clientTabs = 0;
}
item.hidden = hide;
}
if (clientTabs == 0) {
currentClient.hidden = true;
}
},
openSelected: function() {
let items = this._tabsList.selectedItems;
let urls = [];
for (let i = 0;i < items.length;i++) {
if (items[i].getAttribute("type") == "tab") {
urls.push(items[i].getAttribute("url"));
let index = this._tabsList.getIndexOfItem(items[i]);
this._tabsList.removeItemAt(index);
}
}
if (urls.length) {
getTopWin().gBrowser.loadTabs(urls);
this._tabsList.clearSelection();
}
},
bookmarkSingleTab: function() {
let item = this._tabsList.selectedItems[0];
let uri = Weave.Utils.makeURI(item.getAttribute("url"));
let title = item.getAttribute("title");
PlacesUIUtils.showBookmarkDialog({ action: "add"
, type: "bookmark"
, uri: uri
, title: title
, hiddenRows: [ "description"
, "location"
, "loadInSidebar"
, "keyword" ]
}, window.top);
},
bookmarkSelectedTabs: function() {
let items = this._tabsList.selectedItems;
let URIs = [];
for (let i = 0;i < items.length;i++) {
if (items[i].getAttribute("type") == "tab") {
let uri = Weave.Utils.makeURI(items[i].getAttribute("url"));
if (!uri) {
continue;
}
URIs.push(uri);
}
}
if (URIs.length) {
PlacesUIUtils.showBookmarkDialog({ action: "add"
, type: "folder"
, URIList: URIs
, hiddenRows: [ "description" ]
}, window.top);
}
},
getIcon: function (iconUri, defaultIcon) {
try {
let iconURI = Weave.Utils.makeURI(iconUri);
return PlacesUtils.favicons.getFaviconLinkForIcon(iconURI).spec;
} catch (ex) {
// Do nothing.
}
// Just give the provided default icon or the system's default.
return defaultIcon || PlacesUtils.favicons.defaultFavicon.spec;
},
_waitingForBuildList: false,
_buildListRequested: false,
buildList: function (force) {
if (this._waitingForBuildList) {
this._buildListRequested = true;
return;
}
this._waitingForBuildList = true;
this._buildListRequested = false;
this._clearTabList();
if (Weave.Service.isLoggedIn && this._refetchTabs(force)) {
this._generateWeaveTabList();
} else {
//XXXzpao We should say something about not being logged in & not having data
// or tell the appropriate condition. (bug 583344)
}
function complete() {
this._waitingForBuildList = false;
if (this._buildListRequested) {
CommonUtils.nextTick(this.buildList, this);
}
}
complete();
},
_clearTabList: function () {
let list = this._tabsList;
// Clear out existing richlistitems
let count = list.getRowCount();
if (count > 0) {
for (let i = count - 1; i >= 0; i--) {
list.removeItemAt(i);
}
}
},
_generateWeaveTabList: function () {
let engine = Weave.Service.engineManager.get("tabs");
let list = this._tabsList;
let seenURLs = new Set();
let localURLs = engine.getOpenURLs();
for (let [guid, client] in Iterator(engine.getAllClients())) {
// Create the client node, but don't add it in-case we don't show any tabs
let appendClient = true;
client.tabs.forEach(function({title, urlHistory, icon}) {
let url = urlHistory[0];
if (!url || localURLs.has(url) || seenURLs.has(url)) {
return;
}
seenURLs.add(url);
if (appendClient) {
let attrs = {
type: "client",
clientName: client.clientName,
class: Weave.Service.clientsEngine.isMobile(client.id) ? "mobile" : "desktop"
};
let clientEnt = this.createItem(attrs);
list.appendChild(clientEnt);
appendClient = false;
clientEnt.disabled = true;
}
let attrs = {
type: "tab",
title: title || url,
url: url,
icon: this.getIcon(icon),
}
let tab = this.createItem(attrs);
list.appendChild(tab);
}, this);
}
},
adjustContextMenu: function(event) {
let mode = "all";
switch (this._tabsList.selectedItems.length) {
case 0:
break;
case 1:
mode = "single"
break;
default:
mode = "multiple";
break;
}
let menu = document.getElementById("tabListContext");
let el = menu.firstChild;
while (el) {
let showFor = el.getAttribute("showFor");
if (showFor) {
el.hidden = showFor != mode && showFor != "all";
}
el = el.nextSibling;
}
},
_refetchTabs: function(force) {
if (!force) {
// Don't bother refetching tabs if we already did so recently
let lastFetch = 0;
try {
lastFetch = Services.prefs.getIntPref("services.sync.lastTabFetch");
}
catch (e) {
/* Just use the default value of 0 */
}
let now = Math.floor(Date.now() / 1000);
if (now - lastFetch < 30) {
return false;
}
}
// if Clients hasn't synced yet this session, we need to sync it as well.
if (Weave.Service.clientsEngine.lastSync == 0) {
Weave.Service.clientsEngine.sync();
}
// Force a sync only for the tabs engine
let engine = Weave.Service.engineManager.get("tabs");
engine.lastModified = null;
engine.sync();
Services.prefs.setIntPref("services.sync.lastTabFetch",
Math.floor(Date.now() / 1000));
return true;
},
observe: function(subject, topic, data) {
switch (topic) {
case "weave:service:login:finish":
this.buildList(true);
break;
case "weave:engine:sync:finish":
if (subject == "tabs") {
this.buildList(false);
}
break;
}
},
handleClick: function(event) {
if (event.target.getAttribute("type") != "tab") {
return;
}
if (event.button == 1) {
let url = event.target.getAttribute("url");
openUILink(url, event);
let index = this._tabsList.getIndexOfItem(event.target);
this._tabsList.removeItemAt(index);
}
}
}

View File

@ -0,0 +1,68 @@
<?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/. -->
<?xml-stylesheet href="chrome://browser/skin/" type="text/css"?>
<?xml-stylesheet href="chrome://browser/skin/aboutSyncTabs.css" type="text/css"?>
<?xml-stylesheet href="chrome://browser/content/sync/aboutSyncTabs.css" type="text/css"?>
<!DOCTYPE window [
<!ENTITY % aboutSyncTabsDTD SYSTEM "chrome://browser/locale/aboutSyncTabs.dtd">
%aboutSyncTabsDTD;
]>
<window id="tabs-display"
onload="RemoteTabViewer.init()"
onunload="RemoteTabViewer.uninit()"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:html="http://www.w3.org/1999/xhtml"
title="&tabs.otherDevices.label;">
<script type="application/javascript;version=1.8" src="chrome://browser/content/sync/aboutSyncTabs.js"/>
<script type="application/javascript" src="chrome://browser/content/utilityOverlay.js"/>
<html:head>
<html:link rel="icon" href="chrome://browser/skin/sync-16.png"/>
</html:head>
<popupset id="contextmenus">
<menupopup id="tabListContext">
<menuitem label="&tabs.context.openTab.label;"
accesskey="&tabs.context.openTab.accesskey;"
oncommand="RemoteTabViewer.openSelected()"
showFor="single"/>
<menuitem label="&tabs.context.bookmarkSingleTab.label;"
accesskey="&tabs.context.bookmarkSingleTab.accesskey;"
oncommand="RemoteTabViewer.bookmarkSingleTab(event)"
showFor="single"/>
<menuitem label="&tabs.context.openMultipleTabs.label;"
accesskey="&tabs.context.openMultipleTabs.accesskey;"
oncommand="RemoteTabViewer.openSelected()"
showFor="multiple"/>
<menuitem label="&tabs.context.bookmarkMultipleTabs.label;"
accesskey="&tabs.context.bookmarkMultipleTabs.accesskey;"
oncommand="RemoteTabViewer.bookmarkSelectedTabs()"
showFor="multiple"/>
<menuseparator/>
<menuitem label="&tabs.context.refreshList.label;"
accesskey="&tabs.context.refreshList.accesskey;"
oncommand="RemoteTabViewer.buildList()"
showFor="all"/>
</menupopup>
</popupset>
<richlistbox context="tabListContext" id="tabsList" seltype="multiple"
align="center" flex="1"
onclick="RemoteTabViewer.handleClick(event)"
oncontextmenu="RemoteTabViewer.adjustContextMenu(event)">
<hbox id="headers" align="center">
<label id="tabsListHeading"
value="&tabs.otherDevices.label;"/>
<spacer flex="1"/>
<textbox type="search"
emptytext="&tabs.searchText.label;"
oncommand="RemoteTabViewer.filterTabs(event)"/>
</hbox>
</richlistbox>
</window>

View File

@ -0,0 +1,157 @@
/* 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/. */
var Ci = Components.interfaces;
var Cc = Components.classes;
var Cu = Components.utils;
Cu.import("resource://services-sync/main.js");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
const PIN_PART_LENGTH = 4;
const ADD_DEVICE_PAGE = 0;
const SYNC_KEY_PAGE = 1;
const DEVICE_CONNECTED_PAGE = 2;
var gSyncAddDevice = {
init: function init() {
this.pin1.setAttribute("maxlength", PIN_PART_LENGTH);
this.pin2.setAttribute("maxlength", PIN_PART_LENGTH);
this.pin3.setAttribute("maxlength", PIN_PART_LENGTH);
this.nextFocusEl = {pin1: this.pin2,
pin2: this.pin3,
pin3: this.wizard.getButton("next")};
this.throbber = document.getElementById("pairDeviceThrobber");
this.errorRow = document.getElementById("errorRow");
// Kick off a sync. That way the server will have the most recent data from
// this computer and it will show up immediately on the new device.
Weave.Service.scheduler.scheduleNextSync(0);
},
onPageShow: function onPageShow() {
this.wizard.getButton("back").hidden = true;
switch (this.wizard.pageIndex) {
case ADD_DEVICE_PAGE:
this.onTextBoxInput();
this.wizard.canRewind = false;
this.wizard.getButton("next").hidden = false;
this.pin1.focus();
break;
case SYNC_KEY_PAGE:
this.wizard.canAdvance = false;
this.wizard.canRewind = true;
this.wizard.getButton("back").hidden = false;
this.wizard.getButton("next").hidden = true;
document.getElementById("weavePassphrase").value =
Weave.Utils.hyphenatePassphrase(Weave.Service.identity.syncKey);
break;
case DEVICE_CONNECTED_PAGE:
this.wizard.canAdvance = true;
this.wizard.canRewind = false;
this.wizard.getButton("cancel").hidden = true;
break;
}
},
onWizardAdvance: function onWizardAdvance() {
switch (this.wizard.pageIndex) {
case ADD_DEVICE_PAGE:
this.startTransfer();
return false;
case DEVICE_CONNECTED_PAGE:
window.close();
return false;
}
return true;
},
startTransfer: function startTransfer() {
this.errorRow.hidden = true;
// When onAbort is called, Weave may already be gone.
const JPAKE_ERROR_USERABORT = Weave.JPAKE_ERROR_USERABORT;
let self = this;
let jpakeclient = this._jpakeclient = new Weave.JPAKEClient({
onPaired: function onPaired() {
let credentials = {account: Weave.Service.identity.account,
password: Weave.Service.identity.basicPassword,
synckey: Weave.Service.identity.syncKey,
serverURL: Weave.Service.serverURL};
jpakeclient.sendAndComplete(credentials);
},
onComplete: function onComplete() {
delete self._jpakeclient;
self.wizard.pageIndex = DEVICE_CONNECTED_PAGE;
// Schedule a Sync for soonish to fetch the data uploaded by the
// device with which we just paired.
Weave.Service.scheduler.scheduleNextSync(Weave.Service.scheduler.activeInterval);
},
onAbort: function onAbort(error) {
delete self._jpakeclient;
// Aborted by user, ignore.
if (error == JPAKE_ERROR_USERABORT) {
return;
}
self.errorRow.hidden = false;
self.throbber.hidden = true;
self.pin1.value = self.pin2.value = self.pin3.value = "";
self.pin1.disabled = self.pin2.disabled = self.pin3.disabled = false;
self.pin1.focus();
}
});
this.throbber.hidden = false;
this.pin1.disabled = this.pin2.disabled = this.pin3.disabled = true;
this.wizard.canAdvance = false;
let pin = this.pin1.value + this.pin2.value + this.pin3.value;
let expectDelay = false;
jpakeclient.pairWithPIN(pin, expectDelay);
},
onWizardBack: function onWizardBack() {
if (this.wizard.pageIndex != SYNC_KEY_PAGE)
return true;
this.wizard.pageIndex = ADD_DEVICE_PAGE;
return false;
},
onWizardCancel: function onWizardCancel() {
if (this._jpakeclient) {
this._jpakeclient.abort();
delete this._jpakeclient;
}
return true;
},
onTextBoxInput: function onTextBoxInput(textbox) {
if (textbox && textbox.value.length == PIN_PART_LENGTH)
this.nextFocusEl[textbox.id].focus();
this.wizard.canAdvance = (this.pin1.value.length == PIN_PART_LENGTH
&& this.pin2.value.length == PIN_PART_LENGTH
&& this.pin3.value.length == PIN_PART_LENGTH);
},
goToSyncKeyPage: function goToSyncKeyPage() {
this.wizard.pageIndex = SYNC_KEY_PAGE;
}
};
// onWizardAdvance() and onPageShow() are run before init() so we'll set
// these up as lazy getters.
["wizard", "pin1", "pin2", "pin3"].forEach(function (id) {
XPCOMUtils.defineLazyGetter(gSyncAddDevice, id, function() {
return document.getElementById(id);
});
});

View File

@ -0,0 +1,129 @@
<?xml version="1.0"?>
<!-- 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/. -->
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<?xml-stylesheet href="chrome://browser/skin/syncSetup.css" type="text/css"?>
<?xml-stylesheet href="chrome://browser/skin/syncCommon.css" type="text/css"?>
<!DOCTYPE window [
<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">
<!ENTITY % syncBrandDTD SYSTEM "chrome://browser/locale/syncBrand.dtd">
<!ENTITY % syncSetupDTD SYSTEM "chrome://browser/locale/syncSetup.dtd">
%brandDTD;
%syncBrandDTD;
%syncSetupDTD;
]>
<wizard xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:html="http://www.w3.org/1999/xhtml"
id="wizard"
title="&pairDevice.title.label;"
windowtype="Sync:AddDevice"
persist="screenX screenY"
onwizardnext="return gSyncAddDevice.onWizardAdvance();"
onwizardback="return gSyncAddDevice.onWizardBack();"
onwizardcancel="gSyncAddDevice.onWizardCancel();"
onload="gSyncAddDevice.init();">
<script type="application/javascript"
src="chrome://browser/content/sync/addDevice.js"/>
<script type="application/javascript"
src="chrome://browser/content/sync/utils.js"/>
<script type="application/javascript"
src="chrome://browser/content/utilityOverlay.js"/>
<script type="application/javascript"
src="chrome://global/content/printUtils.js"/>
<wizardpage id="addDevicePage"
label="&pairDevice.title.label;"
onpageshow="gSyncAddDevice.onPageShow();">
<description>
&pairDevice.dialog.description.label;
<label class="text-link"
value="&addDevice.showMeHow.label;"
href="http://www.palemoon.org/sync/help/easy-setup.shtml"/>
</description>
<separator class="groove-thin"/>
<description>
&addDevice.dialog.enterCode.label;
</description>
<separator class="groove-thin"/>
<vbox align="center">
<textbox id="pin1"
class="pin"
oninput="gSyncAddDevice.onTextBoxInput(this);"
onfocus="this.select();"
/>
<textbox id="pin2"
class="pin"
oninput="gSyncAddDevice.onTextBoxInput(this);"
onfocus="this.select();"
/>
<textbox id="pin3"
class="pin"
oninput="gSyncAddDevice.onTextBoxInput(this);"
onfocus="this.select();"
/>
</vbox>
<separator class="groove-thin"/>
<vbox id="pairDeviceThrobber" align="center" hidden="true">
<image/>
</vbox>
<hbox id="errorRow" pack="center" hidden="true">
<image class="statusIcon" status="error"/>
<label class="status"
value="&addDevice.dialog.tryAgain.label;"/>
</hbox>
<spacer flex="3"/>
<label class="text-link"
value="&addDevice.dontHaveDevice.label;"
onclick="gSyncAddDevice.goToSyncKeyPage();"/>
</wizardpage>
<!-- Need a non-empty label here, otherwise we get a default label on Mac -->
<wizardpage id="syncKeyPage"
label=" "
onpageshow="gSyncAddDevice.onPageShow();">
<description>
&addDevice.dialog.recoveryKey.label;
</description>
<spacer/>
<groupbox>
<label value="&recoveryKeyEntry.label;"
accesskey="&recoveryKeyEntry.accesskey;"
control="weavePassphrase"/>
<textbox id="weavePassphrase"
readonly="true"/>
</groupbox>
<groupbox align="center">
<description>&recoveryKeyBackup.description;</description>
<hbox>
<button id="printSyncKeyButton"
label="&button.syncKeyBackup.print.label;"
accesskey="&button.syncKeyBackup.print.accesskey;"
oncommand="gSyncUtils.passphrasePrint('weavePassphrase');"/>
<button id="saveSyncKeyButton"
label="&button.syncKeyBackup.save.label;"
accesskey="&button.syncKeyBackup.save.accesskey;"
oncommand="gSyncUtils.passphraseSave('weavePassphrase');"/>
</hbox>
</groupbox>
</wizardpage>
<wizardpage id="deviceConnectedPage"
label="&addDevice.dialog.connected.label;"
onpageshow="gSyncAddDevice.onPageShow();">
<vbox align="center">
<image id="successPageIcon"/>
</vbox>
<separator/>
<description class="normal">
&addDevice.dialog.successful.label;
</description>
</wizardpage>
</wizard>

View File

@ -0,0 +1,234 @@
/* 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/. */
var Ci = Components.interfaces;
var Cc = Components.classes;
Components.utils.import("resource://services-sync/main.js");
Components.utils.import("resource://gre/modules/Services.jsm");
var Change = {
_dialog: null,
_dialogType: null,
_status: null,
_statusIcon: null,
_firstBox: null,
_secondBox: null,
get _passphraseBox() {
delete this._passphraseBox;
return this._passphraseBox = document.getElementById("passphraseBox");
},
get _currentPasswordInvalid() {
return Weave.Status.login == Weave.LOGIN_FAILED_LOGIN_REJECTED;
},
get _updatingPassphrase() {
return this._dialogType == "UpdatePassphrase";
},
onLoad: function Change_onLoad() {
/* Load labels */
let introText = document.getElementById("introText");
let introText2 = document.getElementById("introText2");
let warningText = document.getElementById("warningText");
// load some other elements & info from the window
this._dialog = document.getElementById("change-dialog");
this._dialogType = window.arguments[0];
this._duringSetup = window.arguments[1];
this._status = document.getElementById("status");
this._statusIcon = document.getElementById("statusIcon");
this._statusRow = document.getElementById("statusRow");
this._firstBox = document.getElementById("textBox1");
this._secondBox = document.getElementById("textBox2");
this._dialog.getButton("finish").disabled = true;
this._dialog.getButton("back").hidden = true;
this._stringBundle =
Services.strings.createBundle("chrome://browser/locale/syncGenericChange.properties");
switch (this._dialogType) {
case "UpdatePassphrase":
case "ResetPassphrase":
document.getElementById("textBox1Row").hidden = true;
document.getElementById("textBox2Row").hidden = true;
document.getElementById("passphraseLabel").value
= this._str("new.recoverykey.label");
document.getElementById("passphraseSpacer").hidden = false;
if (this._updatingPassphrase) {
document.getElementById("passphraseHelpBox").hidden = false;
document.title = this._str("new.recoverykey.title");
introText.textContent = this._str("new.recoverykey.introText");
this._dialog.getButton("finish").label
= this._str("new.recoverykey.acceptButton");
}
else {
document.getElementById("generatePassphraseButton").hidden = false;
document.getElementById("passphraseBackupButtons").hidden = false;
let pp = Weave.Service.identity.syncKey;
if (Weave.Utils.isPassphrase(pp))
pp = Weave.Utils.hyphenatePassphrase(pp);
this._passphraseBox.value = pp;
this._passphraseBox.focus();
document.title = this._str("change.recoverykey.title");
introText.textContent = this._str("change.synckey.introText2");
warningText.textContent = this._str("change.recoverykey.warningText");
this._dialog.getButton("finish").label
= this._str("change.recoverykey.acceptButton");
if (this._duringSetup) {
this._dialog.getButton("finish").disabled = false;
}
}
break;
case "ChangePassword":
document.getElementById("passphraseRow").hidden = true;
let box1label = document.getElementById("textBox1Label");
let box2label = document.getElementById("textBox2Label");
box1label.value = this._str("new.password.label");
if (this._currentPasswordInvalid) {
document.title = this._str("new.password.title");
introText.textContent = this._str("new.password.introText");
this._dialog.getButton("finish").label
= this._str("new.password.acceptButton");
document.getElementById("textBox2Row").hidden = true;
}
else {
document.title = this._str("change.password.title");
box2label.value = this._str("new.password.confirm");
introText.textContent = this._str("change.password3.introText");
warningText.textContent = this._str("change.password.warningText");
this._dialog.getButton("finish").label
= this._str("change.password.acceptButton");
}
break;
}
document.getElementById("change-page")
.setAttribute("label", document.title);
},
_clearStatus: function _clearStatus() {
this._status.value = "";
this._statusIcon.removeAttribute("status");
},
_updateStatus: function Change__updateStatus(str, state) {
this._updateStatusWithString(this._str(str), state);
},
_updateStatusWithString: function Change__updateStatusWithString(string, state) {
this._statusRow.hidden = false;
this._status.value = string;
this._statusIcon.setAttribute("status", state);
let error = state == "error";
this._dialog.getButton("cancel").disabled = !error;
this._dialog.getButton("finish").disabled = !error;
document.getElementById("printSyncKeyButton").disabled = !error;
document.getElementById("saveSyncKeyButton").disabled = !error;
if (state == "success")
window.setTimeout(window.close, 1500);
},
onDialogAccept: function() {
switch (this._dialogType) {
case "UpdatePassphrase":
case "ResetPassphrase":
return this.doChangePassphrase();
break;
case "ChangePassword":
return this.doChangePassword();
break;
}
},
doGeneratePassphrase: function () {
let passphrase = Weave.Utils.generatePassphrase();
this._passphraseBox.value = Weave.Utils.hyphenatePassphrase(passphrase);
this._dialog.getButton("finish").disabled = false;
},
doChangePassphrase: function Change_doChangePassphrase() {
let pp = Weave.Utils.normalizePassphrase(this._passphraseBox.value);
if (this._updatingPassphrase) {
Weave.Service.identity.syncKey = pp;
if (Weave.Service.login()) {
this._updateStatus("change.recoverykey.success", "success");
Weave.Service.persistLogin();
Weave.Service.scheduler.delayedAutoConnect(0);
}
else {
this._updateStatus("new.passphrase.status.incorrect", "error");
}
}
else {
this._updateStatus("change.recoverykey.label", "active");
if (Weave.Service.changePassphrase(pp))
this._updateStatus("change.recoverykey.success", "success");
else
this._updateStatus("change.recoverykey.error", "error");
}
return false;
},
doChangePassword: function Change_doChangePassword() {
if (this._currentPasswordInvalid) {
Weave.Service.identity.basicPassword = this._firstBox.value;
if (Weave.Service.login()) {
this._updateStatus("change.password.status.success", "success");
Weave.Service.persistLogin();
}
else {
this._updateStatus("new.password.status.incorrect", "error");
}
}
else {
this._updateStatus("change.password.status.active", "active");
if (Weave.Service.changePassword(this._firstBox.value))
this._updateStatus("change.password.status.success", "success");
else
this._updateStatus("change.password.status.error", "error");
}
return false;
},
validate: function (event) {
let valid = false;
let errorString = "";
if (this._dialogType == "ChangePassword") {
if (this._currentPasswordInvalid)
[valid, errorString] = gSyncUtils.validatePassword(this._firstBox);
else
[valid, errorString] = gSyncUtils.validatePassword(this._firstBox, this._secondBox);
}
else {
//Pale Moon: Enforce minimum length of 8 for allowed custom passphrase
//and don't restrict it to "out of sync" situations only. People who
//go to this page generally know what they are doing ;)
valid = this._passphraseBox.value.length >= 8;
}
if (errorString == "")
this._clearStatus();
else
this._updateStatusWithString(errorString, "error");
this._statusRow.hidden = valid;
this._dialog.getButton("finish").disabled = !valid;
},
_str: function Change__string(str) {
return this._stringBundle.GetStringFromName(str);
}
};

View File

@ -0,0 +1,123 @@
<?xml version="1.0"?>
<!-- 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/. -->
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<?xml-stylesheet href="chrome://browser/skin/syncSetup.css" type="text/css"?>
<?xml-stylesheet href="chrome://browser/skin/syncCommon.css" type="text/css"?>
<!DOCTYPE window [
<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">
<!ENTITY % syncBrandDTD SYSTEM "chrome://browser/locale/syncBrand.dtd">
<!ENTITY % syncSetupDTD SYSTEM "chrome://browser/locale/syncSetup.dtd">
%brandDTD;
%syncBrandDTD;
%syncSetupDTD;
]>
<wizard xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:html="http://www.w3.org/1999/xhtml"
id="change-dialog"
windowtype="Weave:ChangeSomething"
persist="screenX screenY"
onwizardnext="Change.onLoad()"
onwizardfinish="return Change.onDialogAccept();">
<script type="application/javascript"
src="chrome://browser/content/sync/genericChange.js"/>
<script type="application/javascript"
src="chrome://browser/content/sync/utils.js"/>
<script type="application/javascript"
src="chrome://global/content/printUtils.js"/>
<wizardpage id="change-page"
label="">
<description id="introText">
</description>
<separator class="thin"/>
<groupbox>
<grid>
<columns>
<column align="right"/>
<column flex="3"/>
<column flex="1"/>
</columns>
<rows>
<row id="textBox1Row" align="center">
<label id="textBox1Label" control="textBox1"/>
<textbox id="textBox1" type="password" oninput="Change.validate()"/>
<spacer/>
</row>
<row id="textBox2Row" align="center">
<label id="textBox2Label" control="textBox2"/>
<textbox id="textBox2" type="password" oninput="Change.validate()"/>
<spacer/>
</row>
</rows>
</grid>
<vbox id="passphraseRow">
<hbox flex="1">
<label id="passphraseLabel" control="passphraseBox"/>
<spacer flex="1"/>
<label id="generatePassphraseButton"
hidden="true"
value="&syncGenerateNewKey.label;"
class="text-link inline-link"
onclick="event.stopPropagation();
Change.doGeneratePassphrase();"/>
</hbox>
<textbox id="passphraseBox"
flex="1"
onfocus="this.select()"
oninput="Change.validate()"/>
</vbox>
<vbox id="feedback" pack="center">
<hbox id="statusRow" align="center">
<image id="statusIcon" class="statusIcon"/>
<label id="status" class="status" value=" "/>
</hbox>
</vbox>
</groupbox>
<separator class="thin"/>
<hbox id="passphraseBackupButtons"
hidden="true"
pack="center">
<button id="printSyncKeyButton"
label="&button.syncKeyBackup.print.label;"
accesskey="&button.syncKeyBackup.print.accesskey;"
oncommand="gSyncUtils.passphrasePrint('passphraseBox');"/>
<button id="saveSyncKeyButton"
label="&button.syncKeyBackup.save.label;"
accesskey="&button.syncKeyBackup.save.accesskey;"
oncommand="gSyncUtils.passphraseSave('passphraseBox');"/>
</hbox>
<vbox id="passphraseHelpBox"
hidden="true">
<description>
&existingRecoveryKey.description;
<label class="text-link"
href="http://www.palemoon.org/sync/help/recoverykey.shtml">
&addDevice.showMeHow.label;
</label>
</description>
</vbox>
<spacer id="passphraseSpacer"
flex="1"
hidden="true"/>
<description id="warningText" class="data">
</description>
<spacer flex="1"/>
</wizardpage>
</wizard>

View File

@ -0,0 +1,22 @@
# 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/.
browser.jar:
content/browser/sync/aboutSyncTabs.xul
content/browser/sync/aboutSyncTabs.js
content/browser/sync/aboutSyncTabs.css
content/browser/sync/aboutSyncTabs-bindings.xml
content/browser/sync/setup.xul
content/browser/sync/addDevice.js
content/browser/sync/addDevice.xul
content/browser/sync/setup.js
content/browser/sync/genericChange.xul
content/browser/sync/genericChange.js
content/browser/sync/key.xhtml
content/browser/sync/notification.xml
content/browser/sync/quota.xul
content/browser/sync/quota.js
content/browser/sync/utils.js
content/browser/sync/progress.js
content/browser/sync/progress.xhtml

View File

@ -0,0 +1,54 @@
<?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/. -->
<!DOCTYPE html [
<!ENTITY % htmlDTD PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd">
%htmlDTD;
<!ENTITY % syncBrandDTD SYSTEM "chrome://browser/locale/syncBrand.dtd">
%syncBrandDTD;
<!ENTITY % syncKeyDTD SYSTEM "chrome://browser/locale/syncKey.dtd">
%syncKeyDTD;
<!ENTITY % globalDTD SYSTEM "chrome://global/locale/global.dtd" >
%globalDTD;
]>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>&syncKey.page.title;</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<meta name="robots" content="noindex"/>
<style type="text/css">
#synckey { font-size: 150% }
footer { font-size: 70% }
/* Bug 575675: Need to have an a:visited rule in a chrome document. */
a:visited { color: purple; }
</style>
</head>
<body dir="&locale.dir;">
<h1>&syncKey.page.title;</h1>
<p id="synckey" dir="ltr">SYNCKEY</p>
<p>&syncKey.page.description2;</p>
<div id="column1">
<h2>&syncKey.keepItSecret.heading;</h2>
<p>&syncKey.keepItSecret.description;</p>
</div>
<div id="column2">
<h2>&syncKey.keepItSafe.heading;</h2>
<p><em>&syncKey.keepItSafe1.description;</em>&syncKey.keepItSafe2.description;<em>&syncKey.keepItSafe3.description;</em>&syncKey.keepItSafe4a.description;</p>
</div>
<p>&syncKey.findOutMore1.label;<a href="http://www.palemoon.org/sync/">http://www.palemoon.org/sync/</a>&syncKey.findOutMore2.label;</p>
<footer>
&syncKey.footer1.label;<a id="tosLink" href="termsURL">termsURL</a>&syncKey.footer2.label;<a id="ppLink" href="privacyURL">privacyURL</a>&syncKey.footer3.label;
</footer>
</body>
</html>

View File

@ -0,0 +1,8 @@
# -*- Mode: python; c-basic-offset: 4; 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/.
JAR_MANIFESTS += ['jar.mn']

View File

@ -0,0 +1,129 @@
<?xml version="1.0"?>
<!-- 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/. -->
<!DOCTYPE bindings [
<!ENTITY % notificationDTD SYSTEM "chrome://global/locale/notification.dtd">
%notificationDTD;
]>
<bindings id="notificationBindings"
xmlns="http://www.mozilla.org/xbl"
xmlns:xbl="http://www.mozilla.org/xbl"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<binding id="notificationbox" extends="chrome://global/content/bindings/notification.xml#notificationbox">
<content>
<xul:vbox xbl:inherits="hidden=notificationshidden">
<xul:spacer/>
<children includes="notification"/>
</xul:vbox>
<children/>
</content>
<implementation>
<constructor><![CDATA[
let temp = {};
Cu.import("resource://services-common/observers.js", temp);
temp.Observers.add("weave:notification:added", this.onNotificationAdded, this);
temp.Observers.add("weave:notification:removed", this.onNotificationRemoved, this);
for each (var notification in Weave.Notifications.notifications)
this._appendNotification(notification);
]]></constructor>
<destructor><![CDATA[
let temp = {};
Cu.import("resource://services-common/observers.js", temp);
temp.Observers.remove("weave:notification:added", this.onNotificationAdded, this);
temp.Observers.remove("weave:notification:removed", this.onNotificationRemoved, this);
]]></destructor>
<method name="onNotificationAdded">
<parameter name="subject"/>
<parameter name="data"/>
<body><![CDATA[
this._appendNotification(subject);
]]></body>
</method>
<method name="onNotificationRemoved">
<parameter name="subject"/>
<parameter name="data"/>
<body><![CDATA[
// If the view of the notification hasn't been removed yet, remove it.
var notifications = this.allNotifications;
for each (var notification in notifications) {
if (notification.notification == subject) {
notification.close();
break;
}
}
]]></body>
</method>
<method name="_appendNotification">
<parameter name="notification"/>
<body><![CDATA[
var node = this.appendNotification(notification.description,
notification.title,
notification.iconURL,
notification.priority,
notification.buttons);
node.notification = notification;
]]></body>
</method>
</implementation>
</binding>
<binding id="notification" extends="chrome://global/content/bindings/notification.xml#notification">
<content>
<xul:hbox class="notification-inner outset" flex="1" xbl:inherits="type">
<xul:toolbarbutton ondblclick="event.stopPropagation();"
class="messageCloseButton close-icon tabbable"
xbl:inherits="hidden=hideclose"
tooltiptext="&closeNotification.tooltip;"
oncommand="document.getBindingParent(this).close()"/>
<xul:hbox anonid="details" align="center" flex="1">
<xul:image anonid="messageImage" class="messageImage" xbl:inherits="src=image,type"/>
<xul:description anonid="messageText" class="messageText" xbl:inherits="xbl:text=label"/>
<!-- The children are the buttons defined by the notification. -->
<xul:hbox oncommand="document.getBindingParent(this)._doButtonCommand(event);">
<children/>
</xul:hbox>
</xul:hbox>
</xul:hbox>
</content>
<implementation>
<!-- Note: this used to be a field, but for some reason it kept getting
- reset to its default value for TabNotification elements.
- As a property, that doesn't happen, even though the property stores
- its value in a JS property |_notification| that is not defined
- in XBL as a field or property. Maybe this is wrong, but it works.
-->
<property name="notification"
onget="return this._notification"
onset="this._notification = val; return val;"/>
<method name="close">
<body><![CDATA[
Weave.Notifications.remove(this.notification);
// We should be able to call the base class's close method here
// to remove the notification element from the notification box,
// but we can't because of bug 373652, so instead we copied its code
// and execute it below.
var control = this.control;
if (control)
control.removeNotification(this);
else
this.hidden = true;
]]></body>
</method>
</implementation>
</binding>
</bindings>

View File

@ -0,0 +1,71 @@
/* 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/. */
const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://services-sync/main.js");
var gProgressBar;
var gCounter = 0;
function onLoad(event) {
Services.obs.addObserver(onEngineSync, "weave:engine:sync:finish", false);
Services.obs.addObserver(onEngineSync, "weave:engine:sync:error", false);
Services.obs.addObserver(onServiceSync, "weave:service:sync:finish", false);
Services.obs.addObserver(onServiceSync, "weave:service:sync:error", false);
gProgressBar = document.getElementById('uploadProgressBar');
if (Services.prefs.getPrefType("services.sync.firstSync") != Ci.nsIPrefBranch.PREF_INVALID) {
gProgressBar.hidden = false;
}
else {
gProgressBar.hidden = true;
}
}
function onUnload(event) {
cleanUpObservers();
}
function cleanUpObservers() {
try {
Services.obs.removeObserver(onEngineSync, "weave:engine:sync:finish");
Services.obs.removeObserver(onEngineSync, "weave:engine:sync:error");
Services.obs.removeObserver(onServiceSync, "weave:service:sync:finish");
Services.obs.removeObserver(onServiceSync, "weave:service:sync:error");
}
catch (e) {
// may be double called by unload & exit. Ignore.
}
}
function onEngineSync(subject, topic, data) {
// The Clients engine syncs first. At this point we don't necessarily know
// yet how many engines will be enabled, so we'll ignore the Clients engine
// and evaluate how many engines are enabled when the first "real" engine
// syncs.
if (data == "clients") {
return;
}
if (!gCounter &&
Services.prefs.getPrefType("services.sync.firstSync") != Ci.nsIPrefBranch.PREF_INVALID) {
gProgressBar.max = Weave.Service.engineManager.getEnabled().length;
}
gCounter += 1;
gProgressBar.setAttribute("value", gCounter);
}
function onServiceSync(subject, topic, data) {
// To address the case where 0 engines are synced, we will fill the
// progress bar so the user knows that the sync has finished.
gProgressBar.setAttribute("value", gProgressBar.max);
cleanUpObservers();
}
function closeTab() {
window.close();
}

View File

@ -0,0 +1,55 @@
<?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/. -->
<!DOCTYPE html [
<!ENTITY % htmlDTD
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"DTD/xhtml1-strict.dtd">
%htmlDTD;
<!ENTITY % syncProgressDTD
SYSTEM "chrome://browser/locale/syncProgress.dtd">
%syncProgressDTD;
<!ENTITY % syncSetupDTD
SYSTEM "chrome://browser/locale/syncSetup.dtd">
%syncSetupDTD;
<!ENTITY % globalDTD
SYSTEM "chrome://global/locale/global.dtd">
%globalDTD;
]>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>&syncProgress.pageTitle;</title>
<link rel="stylesheet" type="text/css" media="all"
href="chrome://browser/skin/syncProgress.css"/>
<link rel="icon" type="image/png" id="favicon"
href="chrome://browser/skin/sync-16.png"/>
<script type="text/javascript;version=1.8"
src="chrome://browser/content/sync/progress.js"/>
</head>
<body onload="onLoad(event)" onunload="onUnload(event)" dir="&locale.dir;">
<title>&setup.successPage.title;</title>
<div id="floatingBox" class="main-content">
<div id="title">
<h1>&setup.successPage.title;</h1>
</div>
<div id="successLogo">
<img id="brandSyncLogo" src="chrome://browser/skin/sync-128.png" alt="&syncProgress.logoAltText;" />
</div>
<div id="loadingText">
<p id="blurb">&syncProgress.textBlurb; </p>
</div>
<div id="progressBar">
<progress id="uploadProgressBar" value="0"/>
</div>
<div id="bottomRow">
<button id="closeButton" onclick="closeTab()">&syncProgress.closeButton; </button>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,247 @@
/* 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/. */
const Ci = Components.interfaces;
const Cc = Components.classes;
const Cr = Components.results;
const Cu = Components.utils;
Cu.import("resource://services-sync/main.js");
Cu.import("resource://gre/modules/DownloadUtils.jsm");
var gSyncQuota = {
init: function init() {
this.bundle = document.getElementById("quotaStrings");
let caption = document.getElementById("treeCaption");
caption.firstChild.nodeValue = this.bundle.getString("quota.treeCaption.label");
gUsageTreeView.init();
this.tree = document.getElementById("usageTree");
this.tree.view = gUsageTreeView;
this.loadData();
},
loadData: function loadData() {
this._usage_req = Weave.Service.getStorageInfo(Weave.INFO_COLLECTION_USAGE,
function (error, usage) {
delete gSyncQuota._usage_req;
// displayUsageData handles null values, so no need to check 'error'.
gUsageTreeView.displayUsageData(usage);
});
let usageLabel = document.getElementById("usageLabel");
let bundle = this.bundle;
this._quota_req = Weave.Service.getStorageInfo(Weave.INFO_QUOTA,
function (error, quota) {
delete gSyncQuota._quota_req;
if (error) {
usageLabel.value = bundle.getString("quota.usageError.label");
return;
}
let used = gSyncQuota.convertKB(quota[0]);
if (!quota[1]) {
// No quota on the server.
usageLabel.value = bundle.getFormattedString(
"quota.usageNoQuota.label", used);
return;
}
let percent = Math.round(100 * quota[0] / quota[1]);
let total = gSyncQuota.convertKB(quota[1]);
usageLabel.value = bundle.getFormattedString(
"quota.usagePercentage.label", [percent].concat(used).concat(total));
});
},
onCancel: function onCancel() {
if (this._usage_req) {
this._usage_req.abort();
}
if (this._quota_req) {
this._quota_req.abort();
}
return true;
},
onAccept: function onAccept() {
let engines = gUsageTreeView.getEnginesToDisable();
for each (let engine in engines) {
Weave.Service.engineManager.get(engine).enabled = false;
}
if (engines.length) {
// The 'Weave' object will disappear once the window closes.
let Service = Weave.Service;
Weave.Utils.nextTick(function() { Service.sync(); });
}
return this.onCancel();
},
convertKB: function convertKB(value) {
return DownloadUtils.convertByteUnits(value * 1024);
}
};
var gUsageTreeView = {
_ignored: {keys: true,
meta: true,
clients: true},
/*
* Internal data structures underlaying the tree.
*/
_collections: [],
_byname: {},
init: function init() {
let retrievingLabel = gSyncQuota.bundle.getString("quota.retrieving.label");
for each (let engine in Weave.Service.engineManager.getEnabled()) {
if (this._ignored[engine.name])
continue;
// Some engines use the same pref, which means they can only be turned on
// and off together. We need to combine them here as well.
let existing = this._byname[engine.prefName];
if (existing) {
existing.engines.push(engine.name);
continue;
}
let obj = {name: engine.prefName,
title: this._collectionTitle(engine),
engines: [engine.name],
enabled: true,
sizeLabel: retrievingLabel};
this._collections.push(obj);
this._byname[engine.prefName] = obj;
}
},
_collectionTitle: function _collectionTitle(engine) {
try {
return gSyncQuota.bundle.getString(
"collection." + engine.prefName + ".label");
} catch (ex) {
return engine.Name;
}
},
/*
* Process the quota information as returned by info/collection_usage.
*/
displayUsageData: function displayUsageData(data) {
for each (let coll in this._collections) {
coll.size = 0;
// If we couldn't retrieve any data, just blank out the label.
if (!data) {
coll.sizeLabel = "";
continue;
}
for each (let engineName in coll.engines)
coll.size += data[engineName] || 0;
let sizeLabel = "";
sizeLabel = gSyncQuota.bundle.getFormattedString(
"quota.sizeValueUnit.label", gSyncQuota.convertKB(coll.size));
coll.sizeLabel = sizeLabel;
}
let sizeColumn = this.treeBox.columns.getNamedColumn("size");
this.treeBox.invalidateColumn(sizeColumn);
},
/*
* Handle click events on the tree.
*/
onTreeClick: function onTreeClick(event) {
if (event.button == 2)
return;
let cell = this.treeBox.getCellAt(event.clientX, event.clientY);
if (cell.col && cell.col.id == "enabled")
this.toggle(cell.row);
},
/*
* Toggle enabled state of an engine.
*/
toggle: function toggle(row) {
// Update the tree
let collection = this._collections[row];
collection.enabled = !collection.enabled;
this.treeBox.invalidateRow(row);
},
/*
* Return a list of engines (or rather their pref names) that should be
* disabled.
*/
getEnginesToDisable: function getEnginesToDisable() {
// Tycho: return [coll.name for each (coll in this._collections) if (!coll.enabled)];
let engines = [];
for each (let coll in this._collections) {
if (!coll.enabled) {
engines.push(coll.name);
}
}
return engines;
},
// nsITreeView
get rowCount() {
return this._collections.length;
},
getRowProperties: function(index) { return ""; },
getCellProperties: function(row, col) { return ""; },
getColumnProperties: function(col) { return ""; },
isContainer: function(index) { return false; },
isContainerOpen: function(index) { return false; },
isContainerEmpty: function(index) { return false; },
isSeparator: function(index) { return false; },
isSorted: function() { return false; },
canDrop: function(index, orientation, dataTransfer) { return false; },
drop: function(row, orientation, dataTransfer) {},
getParentIndex: function(rowIndex) {},
hasNextSibling: function(rowIndex, afterIndex) { return false; },
getLevel: function(index) { return 0; },
getImageSrc: function(row, col) {},
getCellValue: function(row, col) {
return this._collections[row].enabled;
},
getCellText: function getCellText(row, col) {
let collection = this._collections[row];
switch (col.id) {
case "collection":
return collection.title;
case "size":
return collection.sizeLabel;
default:
return "";
}
},
setTree: function setTree(tree) {
this.treeBox = tree;
},
toggleOpenState: function(index) {},
cycleHeader: function(col) {},
selectionChanged: function() {},
cycleCell: function(row, col) {},
isEditable: function(row, col) { return false; },
isSelectable: function (row, col) { return false; },
setCellValue: function(row, col, value) {},
setCellText: function(row, col, value) {},
performAction: function(action) {},
performActionOnRow: function(action, row) {},
performActionOnCell: function(action, row, col) {}
};

View File

@ -0,0 +1,65 @@
<?xml version="1.0"?>
<!-- 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/. -->
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<?xml-stylesheet href="chrome://browser/skin/syncQuota.css"?>
<!DOCTYPE dialog [
<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">
<!ENTITY % syncBrandDTD SYSTEM "chrome://browser/locale/syncBrand.dtd">
<!ENTITY % syncQuotaDTD SYSTEM "chrome://browser/locale/syncQuota.dtd">
%brandDTD;
%syncBrandDTD;
%syncQuotaDTD;
]>
<dialog id="quotaDialog"
windowtype="Sync:ViewQuota"
persist="screenX screenY width height"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:html="http://www.w3.org/1999/xhtml"
onload="gSyncQuota.init()"
buttons="accept,cancel"
title="&quota.dialogTitle.label;"
ondialogcancel="return gSyncQuota.onCancel();"
ondialogaccept="return gSyncQuota.onAccept();">
<script type="application/javascript"
src="chrome://browser/content/sync/quota.js"/>
<stringbundleset id="stringbundleset">
<stringbundle id="quotaStrings"
src="chrome://browser/locale/syncQuota.properties"/>
</stringbundleset>
<vbox flex="1">
<label id="usageLabel"
value="&quota.retrievingInfo.label;"/>
<separator/>
<tree id="usageTree"
seltype="single"
hidecolumnpicker="true"
onclick="gUsageTreeView.onTreeClick(event);"
flex="1">
<treecols>
<treecol id="enabled"
type="checkbox"
fixed="true"/>
<splitter class="tree-splitter"/>
<treecol id="collection"
label="&quota.typeColumn.label;"
flex="1"/>
<splitter class="tree-splitter"/>
<treecol id="size"
label="&quota.sizeColumn.label;"
flex="1"/>
</treecols>
<treechildren flex="1"/>
</tree>
<separator/>
<description id="treeCaption"> </description>
</vbox>
</dialog>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,491 @@
<?xml version="1.0"?>
<!-- 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/. -->
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<?xml-stylesheet href="chrome://browser/skin/syncSetup.css" type="text/css"?>
<?xml-stylesheet href="chrome://browser/skin/syncCommon.css" type="text/css"?>
<!DOCTYPE window [
<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">
<!ENTITY % syncBrandDTD SYSTEM "chrome://browser/locale/syncBrand.dtd">
<!ENTITY % syncSetupDTD SYSTEM "chrome://browser/locale/syncSetup.dtd">
%brandDTD;
%syncBrandDTD;
%syncSetupDTD;
]>
<wizard id="wizard"
title="&accountSetupTitle.label;"
windowtype="Weave:AccountSetup"
persist="screenX screenY"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:html="http://www.w3.org/1999/xhtml"
onwizardnext="return gSyncSetup.onWizardAdvance()"
onwizardback="return gSyncSetup.onWizardBack()"
onwizardcancel="gSyncSetup.onWizardCancel()"
onload="gSyncSetup.init()">
<script type="application/javascript"
src="chrome://browser/content/sync/setup.js"/>
<script type="application/javascript"
src="chrome://browser/content/sync/utils.js"/>
<script type="application/javascript"
src="chrome://browser/content/utilityOverlay.js"/>
<script type="application/javascript"
src="chrome://global/content/printUtils.js"/>
<wizardpage id="addDevicePage"
label="&pairDevice.title.label;"
onpageshow="gSyncSetup.onPageShow()">
<description>
&pairDevice.dialog.description.label;
<label class="text-link"
value="&addDevice.showMeHow.label;"
href="http://www.palemoon.org/sync/help/easy-setup.shtml"/>
</description>
<separator class="groove-thin"/>
<description>
&addDevice.dialog.enterCode.label;
</description>
<separator class="groove-thin"/>
<vbox align="center">
<textbox id="pin1"
class="pin"
oninput="gSyncSetup.onPINInput(this);"
onfocus="this.select();"
/>
<textbox id="pin2"
class="pin"
oninput="gSyncSetup.onPINInput(this);"
onfocus="this.select();"
/>
<textbox id="pin3"
class="pin"
oninput="gSyncSetup.onPINInput(this);"
onfocus="this.select();"
/>
</vbox>
<separator class="groove-thin"/>
<vbox id="pairDeviceThrobber" align="center" hidden="true">
<image/>
</vbox>
<hbox id="pairDeviceErrorRow" pack="center" hidden="true">
<image class="statusIcon" status="error"/>
<label class="status"
value="&addDevice.dialog.tryAgain.label;"/>
</hbox>
</wizardpage>
<wizardpage id="pickSetupType"
label="&syncBrand.fullName.label;"
onpageshow="gSyncSetup.onPageShow()">
<vbox align="center" flex="1">
<description style="padding: 0 7em;">
&setup.pickSetupType.description2;
</description>
<spacer flex="3"/>
<button id="newAccount"
class="accountChoiceButton"
label="&button.createNewAccount.label;"
oncommand="gSyncSetup.startNewAccountSetup()"
align="center"/>
<spacer flex="1"/>
</vbox>
<separator class="groove"/>
<vbox align="center" flex="1">
<spacer flex="1"/>
<button id="existingAccount"
class="accountChoiceButton"
label="&button.haveAccount.label;"
oncommand="gSyncSetup.useExistingAccount()"/>
<spacer flex="3"/>
</vbox>
</wizardpage>
<wizardpage label="&setup.newAccountDetailsPage.title.label;"
id="newAccountStart"
onextra1="gSyncSetup.onSyncOptions()"
onpageshow="gSyncSetup.onPageShow();">
<grid>
<columns>
<column/>
<column class="inputColumn" flex="1"/>
</columns>
<rows>
<row id="emailRow" align="center">
<label value="&setup.emailAddress.label;"
accesskey="&setup.emailAddress.accesskey;"
control="weaveEmail"/>
<textbox id="weaveEmail"
oninput="gSyncSetup.onEmailInput()"/>
</row>
<row id="emailFeedbackRow" align="center" hidden="true">
<spacer/>
<hbox>
<image class="statusIcon"/>
<label class="status" value=" "/>
</hbox>
</row>
<row id="passwordRow" align="center">
<label value="&setup.choosePassword.label;"
accesskey="&setup.choosePassword.accesskey;"
control="weavePassword"/>
<textbox id="weavePassword"
type="password"
onchange="gSyncSetup.onPasswordChange()"/>
</row>
<row id="confirmRow" align="center">
<label value="&setup.confirmPassword.label;"
accesskey="&setup.confirmPassword.accesskey;"
control="weavePasswordConfirm"/>
<textbox id="weavePasswordConfirm"
type="password"
onchange="gSyncSetup.onPasswordChange()"/>
</row>
<row id="passwordFeedbackRow" align="center" hidden="true">
<spacer/>
<hbox>
<image class="statusIcon"/>
<label class="status" value=" "/>
</hbox>
</row>
<row align="center">
<label control="server"
value="&server.label;"/>
<menulist id="server"
oncommand="gSyncSetup.onServerCommand()"
oninput="gSyncSetup.onServerInput()">
<menupopup>
<menuitem label="&serverType.default.label;"
value="main"/>
<menuitem label="&serverType.custom2.label;"
value="custom"/>
</menupopup>
</menulist>
</row>
<row id="serverFeedbackRow" align="center" hidden="true">
<spacer/>
<hbox>
<image class="statusIcon"/>
<label class="status" value=" "/>
</hbox>
</row>
<row id="TOSRow" align="center">
<spacer/>
<hbox align="center">
<checkbox id="tos"
accesskey="&setup.tosAgree1.accesskey;"
oncommand="this.focus(); gSyncSetup.checkFields();"/>
<description id="tosDesc"
flex="1"
onclick="document.getElementById('tos').focus();
document.getElementById('tos').click()">
&setup.tosAgree1.label;
<label class="text-link inline-link"
onclick="event.stopPropagation();gSyncUtils.openToS();">
&setup.tosLink.label;
</label>
&setup.tosAgree2.label;
<label class="text-link inline-link"
onclick="event.stopPropagation();gSyncUtils.openPrivacyPolicy();">
&setup.ppLink.label;
</label>
&setup.tosAgree3.label;
</description>
</hbox>
</row>
</rows>
</grid>
<spacer flex="1"/>
<vbox flex="1" align="center">
<browser height="150"
width="500"
id="captcha"
type="content"
disablehistory="true"/>
<spacer flex="1"/>
<hbox id="captchaFeedback">
<image class="statusIcon"/>
<label class="status" value=" "/>
</hbox>
</vbox>
</wizardpage>
<wizardpage id="addDevice"
label="&pairDevice.title.label;"
onextra1="gSyncSetup.onSyncOptions()"
onpageshow="gSyncSetup.onPageShow()">
<description>
&pairDevice.setup.description.label;
<label class="text-link"
value="&addDevice.showMeHow.label;"
href="http://www.palemoon.org/sync/help/easy-setup.shtml"/>
</description>
<label value="&addDevice.setup.enterCode.label;"
control="easySetupPIN1"/>
<spacer flex="1"/>
<vbox align="center" flex="1">
<textbox id="easySetupPIN1"
class="pin"
value=""
readonly="true"
/>
<textbox id="easySetupPIN2"
class="pin"
value=""
readonly="true"
/>
<textbox id="easySetupPIN3"
class="pin"
value=""
readonly="true"
/>
</vbox>
<spacer flex="3"/>
<label class="text-link"
value="&addDevice.dontHaveDevice.label;"
onclick="gSyncSetup.manualSetup();"/>
</wizardpage>
<wizardpage id="existingAccount"
label="&setup.signInPage.title.label;"
onextra1="gSyncSetup.onSyncOptions()"
onpageshow="gSyncSetup.onPageShow()">
<grid>
<columns>
<column/>
<column class="inputColumn" flex="1"/>
</columns>
<rows>
<row id="existingAccountRow" align="center">
<label id="existingAccountLabel"
value="&signIn.account2.label;"
accesskey="&signIn.account2.accesskey;"
control="existingAccount"/>
<textbox id="existingAccountName"
oninput="gSyncSetup.checkFields(event)"
onchange="gSyncSetup.checkFields(event)"/>
</row>
<row id="existingPasswordRow" align="center">
<label id="existingPasswordLabel"
value="&signIn.password.label;"
accesskey="&signIn.password.accesskey;"
control="existingPassword"/>
<textbox id="existingPassword"
type="password"
onkeyup="gSyncSetup.checkFields(event)"
onchange="gSyncSetup.checkFields(event)"/>
</row>
<row id="existingPasswordFeedbackRow" align="center" hidden="true">
<spacer/>
<hbox>
<image class="statusIcon"/>
<label class="status" value=" "/>
</hbox>
</row>
<row align="center">
<spacer/>
<label class="text-link"
value="&resetPassword.label;"
onclick="gSyncUtils.resetPassword(); return false;"/>
</row>
<row align="center">
<label control="existingServer"
value="&server.label;"/>
<menulist id="existingServer"
oncommand="gSyncSetup.onExistingServerCommand()"
oninput="gSyncSetup.onExistingServerInput()">
<menupopup>
<menuitem label="&serverType.default.label;"
value="main"/>
<menuitem label="&serverType.custom2.label;"
value="custom"/>
</menupopup>
</menulist>
</row>
<row id="existingServerFeedbackRow" align="center" hidden="true">
<spacer/>
<hbox>
<image class="statusIcon"/>
<vbox>
<label class="status" value=" "/>
</vbox>
</hbox>
</row>
</rows>
</grid>
<groupbox>
<label id="existingPassphraseLabel"
value="&signIn.recoveryKey.label;"
accesskey="&signIn.recoveryKey.accesskey;"
control="existingPassphrase"/>
<textbox id="existingPassphrase"
oninput="gSyncSetup.checkFields()"/>
<hbox id="login-throbber" hidden="true">
<image/>
<label value="&verifying.label;"/>
</hbox>
<vbox align="left" id="existingPassphraseFeedbackRow" hidden="true">
<hbox>
<image class="statusIcon"/>
<label class="status" value=" "/>
</hbox>
</vbox>
</groupbox>
<vbox id="passphraseHelpBox">
<description>
&existingRecoveryKey.description;
<label class="text-link"
href="http://www.palemoon.org/sync/help/recoverykey.shtml">
&addDevice.showMeHow.label;
</label>
<spacer id="passphraseHelpSpacer"/>
<label class="text-link"
onclick="gSyncSetup.resetPassphrase(); return false;">
&resetSyncKey.label;
</label>
</description>
</vbox>
</wizardpage>
<wizardpage id="syncOptionsPage"
label="&setup.optionsPage.title;"
onpageshow="gSyncSetup.onPageShow()">
<groupbox id="syncOptions">
<grid>
<columns>
<column/>
<column flex="1" style="-moz-margin-end: 2px"/>
</columns>
<rows>
<row align="center">
<label value="&syncDeviceName.label;"
accesskey="&syncDeviceName.accesskey;"
control="syncComputerName"/>
<textbox id="syncComputerName" flex="1"
onchange="gSyncUtils.changeName(this)"/>
</row>
<row>
<label value="&syncMy.label;" />
<vbox>
<checkbox label="&engine.addons.label;"
accesskey="&engine.addons.accesskey;"
id="engine.addons"
checked="false"
hidden="true"/>
<checkbox label="&engine.bookmarks.label;"
accesskey="&engine.bookmarks.accesskey;"
id="engine.bookmarks"
checked="true"/>
<checkbox label="&engine.passwords.label;"
accesskey="&engine.passwords.accesskey;"
id="engine.passwords"
checked="true"/>
<checkbox label="&engine.prefs.label;"
accesskey="&engine.prefs.accesskey;"
id="engine.prefs"
checked="true"/>
<checkbox label="&engine.history.label;"
accesskey="&engine.history.accesskey;"
id="engine.history"
checked="true"/>
<checkbox label="&engine.tabs.label;"
accesskey="&engine.tabs.accesskey;"
id="engine.tabs"
checked="true"/>
</vbox>
</row>
</rows>
</grid>
</groupbox>
<groupbox id="mergeOptions">
<radiogroup id="mergeChoiceRadio" pack="start">
<grid>
<columns>
<column/>
<column flex="1"/>
</columns>
<rows flex="1">
<row align="center">
<radio id="resetClient"
class="mergeChoiceButton"
aria-labelledby="resetClientLabel"/>
<label id="resetClientLabel" control="resetClient">
<html:strong>&choice2.merge.recommended.label;</html:strong>
&choice2a.merge.main.label;
</label>
</row>
<row align="center">
<radio id="wipeClient"
class="mergeChoiceButton"
aria-labelledby="wipeClientLabel"/>
<label id="wipeClientLabel"
control="wipeClient">
&choice2a.client.main.label;
</label>
</row>
<row align="center">
<radio id="wipeRemote"
class="mergeChoiceButton"
aria-labelledby="wipeRemoteLabel"/>
<label id="wipeRemoteLabel"
control="wipeRemote">
&choice2a.server.main.label;
</label>
</row>
</rows>
</grid>
</radiogroup>
</groupbox>
</wizardpage>
<wizardpage id="syncOptionsConfirm"
label="&setup.optionsConfirmPage.title;"
onpageshow="gSyncSetup.onPageShow()">
<deck id="chosenActionDeck">
<vbox id="chosenActionMerge" class="confirm">
<description class="normal">
&confirm.merge2.label;
</description>
</vbox>
<vbox id="chosenActionWipeClient" class="confirm">
<description class="normal">
&confirm.client3.label;
</description>
<separator class="thin"/>
<vbox id="dataList">
<label class="data indent" id="bookmarkCount"/>
<label class="data indent" id="historyCount"/>
<label class="data indent" id="passwordCount"/>
<label class="data indent" id="addonCount"/>
<label class="data indent" id="prefsWipe"
value="&engine.prefs.label;"/>
</vbox>
<separator class="thin"/>
<description class="normal">
&confirm.client2.moreinfo.label;
</description>
</vbox>
<vbox id="chosenActionWipeServer" class="confirm">
<description class="normal">
&confirm.server2.label;
</description>
<separator class="thin"/>
<vbox id="clientList">
</vbox>
</vbox>
</deck>
</wizardpage>
<!-- In terms of the wizard flow shown to the user, the 'syncOptionsConfirm'
page above is not the last wizard page. To prevent the wizard binding from
assuming that it is, we're inserting this dummy page here. This also means
that the wizard needs to always be closed manually via wizardFinish(). -->
<wizardpage>
</wizardpage>
</wizard>

View File

@ -0,0 +1,218 @@
/* 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/. */
// Equivalent to 0o600 permissions; used for saved Sync Recovery Key.
// This constant can be replaced when the equivalent values are available to
// chrome JS; see Bug 433295 and Bug 757351.
const PERMISSIONS_RWUSR = 0x180;
// Weave should always exist before before this file gets included.
var gSyncUtils = {
get bundle() {
delete this.bundle;
return this.bundle = Services.strings.createBundle("chrome://browser/locale/syncSetup.properties");
},
// opens in a new window if we're in a modal prefwindow world, in a new tab otherwise
_openLink: function (url) {
let thisDocEl = document.documentElement,
openerDocEl = window.opener && window.opener.document.documentElement;
if (thisDocEl.id == "accountSetup" && window.opener &&
openerDocEl.id == "BrowserPreferences" && !openerDocEl.instantApply)
openUILinkIn(url, "window");
else if (thisDocEl.id == "BrowserPreferences" && !thisDocEl.instantApply)
openUILinkIn(url, "window");
else if (document.documentElement.id == "change-dialog")
Services.wm.getMostRecentWindow("navigator:browser")
.openUILinkIn(url, "tab");
else
openUILinkIn(url, "tab");
},
changeName: function changeName(input) {
// Make sure to update to a modified name, e.g., empty-string -> default
Weave.Service.clientsEngine.localName = input.value;
input.value = Weave.Service.clientsEngine.localName;
},
openChange: function openChange(type, duringSetup) {
// Just re-show the dialog if it's already open
let openedDialog = Services.wm.getMostRecentWindow("Sync:" + type);
if (openedDialog != null) {
openedDialog.focus();
return;
}
// Open up the change dialog
let changeXUL = "chrome://browser/content/sync/genericChange.xul";
let changeOpt = "centerscreen,chrome,resizable=no";
Services.ww.activeWindow.openDialog(changeXUL, "", changeOpt,
type, duringSetup);
},
changePassword: function () {
if (Weave.Utils.ensureMPUnlocked())
this.openChange("ChangePassword");
},
resetPassphrase: function (duringSetup) {
if (Weave.Utils.ensureMPUnlocked())
this.openChange("ResetPassphrase", duringSetup);
},
updatePassphrase: function () {
if (Weave.Utils.ensureMPUnlocked())
this.openChange("UpdatePassphrase");
},
resetPassword: function () {
this._openLink(Weave.Service.pwResetURL);
},
openToS: function () {
this._openLink(Weave.Svc.Prefs.get("termsURL"));
},
openPrivacyPolicy: function () {
this._openLink(Weave.Svc.Prefs.get("privacyURL"));
},
openFirstSyncProgressPage: function () {
this._openLink("about:sync-progress");
},
/**
* Prepare an invisible iframe with the passphrase backup document.
* Used by both the print and saving methods.
*
* @param elid : ID of the form element containing the passphrase.
* @param callback : Function called once the iframe has loaded.
*/
_preparePPiframe: function(elid, callback) {
let pp = document.getElementById(elid).value;
// Create an invisible iframe whose contents we can print.
let iframe = document.createElement("iframe");
iframe.setAttribute("src", "chrome://browser/content/sync/key.xhtml");
iframe.collapsed = true;
document.documentElement.appendChild(iframe);
iframe.contentWindow.addEventListener("load", function() {
iframe.contentWindow.removeEventListener("load", arguments.callee, false);
// Insert the Sync Key into the page.
let el = iframe.contentDocument.getElementById("synckey");
el.firstChild.nodeValue = pp;
// Insert the TOS and Privacy Policy URLs into the page.
let termsURL = Weave.Svc.Prefs.get("termsURL");
el = iframe.contentDocument.getElementById("tosLink");
el.setAttribute("href", termsURL);
el.firstChild.nodeValue = termsURL;
let privacyURL = Weave.Svc.Prefs.get("privacyURL");
el = iframe.contentDocument.getElementById("ppLink");
el.setAttribute("href", privacyURL);
el.firstChild.nodeValue = privacyURL;
callback(iframe);
}, false);
},
/**
* Print passphrase backup document.
*
* @param elid : ID of the form element containing the passphrase.
*/
passphrasePrint: function(elid) {
this._preparePPiframe(elid, function(iframe) {
let webBrowserPrint = iframe.contentWindow
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebBrowserPrint);
let printSettings = PrintUtils.getPrintSettings();
// Display no header/footer decoration except for the date.
printSettings.headerStrLeft
= printSettings.headerStrCenter
= printSettings.headerStrRight
= printSettings.footerStrLeft
= printSettings.footerStrCenter = "";
printSettings.footerStrRight = "&D";
try {
webBrowserPrint.print(printSettings, null);
} catch (ex) {
// print()'s return codes are expressed as exceptions. Ignore.
}
});
},
/**
* Save passphrase backup document to disk as HTML file.
*
* @param elid : ID of the form element containing the passphrase.
*/
passphraseSave: function(elid) {
let dialogTitle = this.bundle.GetStringFromName("save.recoverykey.title");
let defaultSaveName = this.bundle.GetStringFromName("save.recoverykey.defaultfilename");
this._preparePPiframe(elid, function(iframe) {
let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
let fpCallback = function fpCallback_done(aResult) {
if (aResult == Ci.nsIFilePicker.returnOK ||
aResult == Ci.nsIFilePicker.returnReplace) {
let stream = Cc["@mozilla.org/network/file-output-stream;1"].
createInstance(Ci.nsIFileOutputStream);
stream.init(fp.file, -1, PERMISSIONS_RWUSR, 0);
let serializer = new XMLSerializer();
let output = serializer.serializeToString(iframe.contentDocument);
output = output.replace(/<!DOCTYPE (.|\n)*?]>/,
'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" ' +
'"DTD/xhtml1-strict.dtd">');
output = Weave.Utils.encodeUTF8(output);
stream.write(output, output.length);
}
};
fp.init(window, dialogTitle, Ci.nsIFilePicker.modeSave);
fp.appendFilters(Ci.nsIFilePicker.filterHTML);
fp.defaultString = defaultSaveName;
fp.open(fpCallback);
return false;
});
},
/**
* validatePassword
*
* @param el1 : the first textbox element in the form
* @param el2 : the second textbox element, if omitted it's an update form
*
* returns [valid, errorString]
*/
validatePassword: function (el1, el2) {
let valid = false;
let val1 = el1.value;
let val2 = el2 ? el2.value : "";
let error = "";
if (!el2)
valid = val1.length >= Weave.MIN_PASS_LENGTH;
else if (val1 && val1 == Weave.Service.identity.username)
error = "change.password.pwSameAsUsername";
else if (val1 && val1 == Weave.Service.identity.account)
error = "change.password.pwSameAsEmail";
else if (val1 && val1 == Weave.Service.identity.basicPassword)
error = "change.password.pwSameAsPassword";
else if (val1 && val2) {
if (val1 == val2 && val1.length >= Weave.MIN_PASS_LENGTH)
valid = true;
else if (val1.length < Weave.MIN_PASS_LENGTH)
error = "change.password.tooShort";
else if (val1 != val2)
error = "change.password.mismatch";
}
let errorString = error ? Weave.Utils.getErrorString(error) : "";
return [valid, errorString];
}
};

View File

@ -4,8 +4,10 @@
<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">
%brandDTD;
#ifdef MOZ_SERVICES_SYNC
<!ENTITY % syncBrandDTD SYSTEM "chrome://browser/locale/syncBrand.dtd">
%syncBrandDTD;
#endif
<!-- These strings are used in the about:home page -->
@ -32,7 +34,9 @@
<!ENTITY abouthome.preferencesButtonUnix.label "Preferences">
<!ENTITY abouthome.addonsButton.label "Add-ons">
<!ENTITY abouthome.downloadsButton.label "Downloads">
#ifdef MOZ_SERVICES_SYNC
<!ENTITY abouthome.syncButton.label "&syncBrand.shortName.label;">
#endif
<!-- LOCALIZATION NOTE (abouthome.aboutMozilla.label): The (invisible) label for
the mozilla wordmark in the top-right corner that links to Mozilla's main

View File

@ -40,12 +40,6 @@ can reach it easily. -->
<!ENTITY pinTab.accesskey "P">
<!ENTITY unpinTab.label "Unpin Tab">
<!ENTITY unpinTab.accesskey "b">
<!ENTITY sendTabToDevice.label "Send Tab to Device">
<!ENTITY sendTabToDevice.accesskey "D">
<!ENTITY sendPageToDevice.label "Send Page to Device">
<!ENTITY sendPageToDevice.accesskey "D">
<!ENTITY sendLinkToDevice.label "Send Link to Device">
<!ENTITY sendLinkToDevice.accesskey "D">
<!ENTITY moveToNewWindow.label "Move to New Window">
<!ENTITY moveToNewWindow.accesskey "W">
<!ENTITY bookmarkAllTabs.label "Bookmark All Tabs…">
@ -115,11 +109,6 @@ These should match what Safari and other Apple applications use on OS X Lion. --
<!ENTITY showAllTabsCmd.accesskey "A">
<!ENTITY toggleReaderMode.key "R">
<!ENTITY fxaSignIn.label "Sign in to &syncBrand.shortName.label;">
<!ENTITY fxaSignInError.label "Reconnect to &syncBrand.shortName.label;">
<!ENTITY fxaUnverified.label "Verify Your Account">
<!ENTITY syncSettings.label "Open &syncBrand.shortName.label; settings">
<!ENTITY fullScreenMinimize.tooltip "Minimize">
<!ENTITY fullScreenRestore.tooltip "Restore">
<!ENTITY fullScreenClose.tooltip "Close">
@ -333,23 +322,6 @@ These should match what Safari and other Apple applications use on OS X Lion. --
<!ENTITY appMenuHistory.viewSidebar.label "View History Sidebar">
<!ENTITY appMenuHelp.tooltip "Open Help Menu">
<!ENTITY appMenuRemoteTabs.label "Synced Tabs">
<!-- LOCALIZATION NOTE (appMenuRemoteTabs.notabs.label): This is shown beneath
the name of a device when that device has no open tabs -->
<!ENTITY appMenuRemoteTabs.notabs.label "No open tabs">
<!-- LOCALIZATION NOTE (appMenuRemoteTabs.tabsnotsyncing.label): This is shown
when Sync is configured but syncing tabs is disabled. -->
<!ENTITY appMenuRemoteTabs.tabsnotsyncing.label "Turn on tab syncing to view a list of tabs from your other devices.">
<!-- LOCALIZATION NOTE (appMenuRemoteTabs.noclients.label): This is shown
when Sync is configured but this appears to be the only device attached to
the account. We also show links to download Firefox for android/ios. -->
<!ENTITY appMenuRemoteTabs.noclients.title "No synced tabs… yet!">
<!ENTITY appMenuRemoteTabs.noclients.subtitle "Want to see your tabs from other devices here?">
<!ENTITY appMenuRemoteTabs.openprefs.label "Sync Preferences">
<!ENTITY appMenuRemoteTabs.notsignedin.label "Sign in to view a list of tabs from your other devices.">
<!ENTITY appMenuRemoteTabs.signin.label "Sign in to Sync">
<!ENTITY appMenuRemoteTabs.sidebar.label "View Synced Tabs">
<!ENTITY customizeMenu.addToToolbar.label "Add to Toolbar">
<!ENTITY customizeMenu.addToToolbar.accesskey "A">
<!ENTITY customizeMenu.addToPanel.label "Add to Menu">
@ -723,18 +695,19 @@ you can use these alternative items. Otherwise, their values should be empty. -
The word "toolbar" is appended automatically and should not be contained below! -->
<!ENTITY tabsToolbar.label "Browser tabs">
<!-- LOCALIZATION NOTE (syncTabsMenu3.label): This appears in the history menu -->
<!ENTITY syncTabsMenu3.label "Synced Tabs">
#ifdef MOZ_SERVICES_SYNC
<!-- LOCALIZATION NOTE (syncTabsMenu2.label): This appears in the history menu -->
<!ENTITY syncTabsMenu2.label "Tabs From Other Devices">
<!ENTITY syncBrand.shortName.label "Sync">
<!ENTITY syncSignIn.label "Sign In To &syncBrand.shortName.label;…">
<!ENTITY syncSignIn.accesskey "Y">
<!ENTITY syncSetup.label "Set Up &syncBrand.shortName.label;…">
<!ENTITY syncSetup.accesskey "Y">
<!ENTITY syncSyncNowItem.label "Sync Now">
<!ENTITY syncSyncNowItem.accesskey "S">
<!ENTITY syncReAuthItem.label "Reconnect to &syncBrand.shortName.label;…">
<!ENTITY syncReAuthItem.accesskey "R">
<!ENTITY syncToolbarButton.label "Sync">
<!ENTITY syncTabsToolbarButton.label "Synced Tabs">
#endif
<!ENTITY customizeMode.menuAndToolbars.header2 "Additional Tools and Features">
<!ENTITY customizeMode.menuAndToolbars.empty "Want more tools?">

View File

@ -39,80 +39,9 @@
<!-- Device Settings -->
<!ENTITY syncDeviceName.label "Device Name:">
<!ENTITY fxaSyncDeviceName.label "Device Name">
<!ENTITY changeSyncDeviceName.label "Change Device Name…">
<!ENTITY changeSyncDeviceName.accesskey "h">
<!ENTITY cancelChangeSyncDeviceName.label "Cancel">
<!ENTITY cancelChangeSyncDeviceName.accesskey "n">
<!ENTITY saveChangeSyncDeviceName.label "Save">
<!ENTITY saveChangeSyncDeviceName.accesskey "v">
<!ENTITY syncDeviceName.accesskey "c">
<!ENTITY unlinkDevice.label "Unlink This Device">
<!-- Footer stuff -->
<!ENTITY prefs.tosLink.label "Terms of Service">
<!ENTITY prefs.ppLink.label "Privacy Policy">
<!-- Firefox Accounts stuff -->
<!ENTITY fxaPrivacyNotice.link.label "Privacy Notice">
<!ENTITY determiningAcctStatus.label "Determining your account status…">
<!-- LOCALIZATION NOTE (signedInUnverified.beforename.label,
signedInUnverified.aftername.label): these two string are used respectively
before and after the account email address. Localizers can use one of them, or
both, to better adapt this sentence to their language.
-->
<!ENTITY signedInUnverified.beforename.label "">
<!ENTITY signedInUnverified.aftername.label "is not verified.">
<!-- LOCALIZATION NOTE (signedInLoginFailure.beforename.label,
signedInLoginFailure.aftername.label): these two string are used respectively
before and after the account email address. Localizers can use one of them, or
both, to better adapt this sentence to their language.
-->
<!ENTITY signedInLoginFailure.beforename.label "Please sign in to reconnect">
<!ENTITY signedInLoginFailure.aftername.label "">
<!ENTITY notSignedIn.label "You are not signed in.">
<!ENTITY signIn.label "Sign in">
<!ENTITY signIn.accesskey "g">
<!ENTITY profilePicture.tooltip "Change profile picture">
<!ENTITY verifiedManage.label "Manage Account">
<!ENTITY verifiedManage.accesskey "o">
<!ENTITY disconnect.label "Disconnect…">
<!ENTITY disconnect.accesskey "D">
<!ENTITY verify.label "Verify Email">
<!ENTITY verify.accesskey "V">
<!ENTITY forget.label "Forget this Email">
<!ENTITY forget.accesskey "F">
<!ENTITY welcome.description "Access your tabs, bookmarks, passwords and more wherever you use &brandShortName;.">
<!ENTITY welcome.signIn.label "Sign In">
<!ENTITY welcome.createAccount.label "Create Account">
<!ENTITY welcome.useOldSync.label "Using an older version of Sync?">
<!ENTITY signedOut.caption "Take your Web with you">
<!ENTITY signedOut.description "Synchronize your bookmarks, history, tabs, passwords, add-ons, and preferences across all your devices.">
<!ENTITY signedOut.accountBox.title "Connect with a &syncBrand.fxAccount.label;">
<!ENTITY signedOut.accountBox.create "Create Account">
<!ENTITY signedOut.accountBox.create.accesskey "C">
<!ENTITY signedOut.accountBox.signin "Sign In">
<!ENTITY signedOut.accountBox.signin.accesskey "I">
<!ENTITY signedIn.engines.label "Sync across all devices">
<!-- LOCALIZATION NOTE (mobilePromo3.*): the following strings will be used to
create a single sentence with active links.
The resulting sentence in English is: "Download Firefox for
Android or iOS to sync with your mobile device." -->
<!ENTITY mobilePromo3.start "Download Firefox for ">
<!-- LOCALIZATION NOTE (mobilePromo3.androidLink): This is a link title that links to https://www.mozilla.org/firefox/android/ -->
<!ENTITY mobilePromo3.androidLink "Android">
<!-- LOCALIZATION NOTE (mobilePromo3.iOSBefore): This is text displayed between mobilePromo3.androidLink and mobilePromo3.iosLink -->
<!ENTITY mobilePromo3.iOSBefore " or ">
<!-- LOCALIZATION NOTE (mobilePromo3.iOSLink): This is a link title that links to https://www.mozilla.org/firefox/ios/ -->
<!ENTITY mobilePromo3.iOSLink "iOS">
<!ENTITY mobilePromo3.end " to sync with your mobile device.">

View File

@ -4,4 +4,3 @@
<!ENTITY syncBrand.shortName.label "Sync">
<!ENTITY syncBrand.fullName.label "Pale Moon Sync">
<!ENTITY syncBrand.fxAccount.label "Firefox Account">

View File

@ -5,12 +5,12 @@
<!ENTITY syncKey.page.title "Your &syncBrand.fullName.label; Key">
<!ENTITY syncKey.page.description2 "This key is used to decode the data in your &syncBrand.fullName.label; account. You will need to enter the key each time you configure &syncBrand.fullName.label; on a new device.">
<!ENTITY syncKey.keepItSecret.heading "Keep it secret">
<!ENTITY syncKey.keepItSecret.description "Your &syncBrand.fullName.label; account is encrypted to protect your privacy. Without this key, it would take years for anyone to decode your personal information. You are the only person who holds this key. This means youre the only one who can access your &syncBrand.fullName.label; data.">
<!ENTITY syncKey.keepItSecret.description "Your &syncBrand.fullName.label; account is encrypted to protect your privacy. Without this key, it would take years for anyone to decode your personal information. You are the only person who holds this key. This means you're the only one who can access your &syncBrand.fullName.label; data.">
<!ENTITY syncKey.keepItSafe.heading "Keep it safe">
<!ENTITY syncKey.keepItSafe1.description "Do not lose this key.">
<!ENTITY syncKey.keepItSafe2.description " We dont keep a copy of your key (that wouldnt be keeping it secret!) so ">
<!ENTITY syncKey.keepItSafe3.description "we cant help you recover it">
<!ENTITY syncKey.keepItSafe4a.description " if its lost. Youll need to use this key any time you connect a new device to &syncBrand.fullName.label;.">
<!ENTITY syncKey.keepItSafe2.description " We don't keep a copy of your key (that wouldn't be keeping it secret!) so ">
<!ENTITY syncKey.keepItSafe3.description "we can't help you recover it">
<!ENTITY syncKey.keepItSafe4a.description " if it's lost. You'll need to use this key any time you connect a new device to &syncBrand.fullName.label;.">
<!ENTITY syncKey.findOutMore1.label "Find out more about &syncBrand.fullName.label; and your privacy at ">
<!ENTITY syncKey.findOutMore2.label ".">
<!ENTITY syncKey.footer1.label "&syncBrand.fullName.label; Terms of Service are available at ">

View File

@ -0,0 +1,15 @@
<!-- 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/. -->
<!ENTITY % brandDTD
SYSTEM "chrome://branding/locale/brand.dtd">
%brandDTD;
<!-- These strings are used in the sync progress upload page -->
<!ENTITY syncProgress.pageTitle "Your First Sync">
<!ENTITY syncProgress.textBlurb "Your data is now being encrypted and uploaded in the background. You can close this tab and continue using &brandShortName;.">
<!ENTITY syncProgress.closeButton "Close">
<!ENTITY syncProgress.logoAltText "&brandShortName; logo">
<!ENTITY syncProgress.diffText "&brandShortName; will now automatically sync in the background. You can close this tab and continue using &brandShortName;.">

View File

@ -30,7 +30,7 @@ quota.remove.label = Remove
quota.treeCaption.label = Uncheck items to stop syncing them and free up space on the server.
# LOCALIZATION NOTE (quota.removal.label): %S is a list of engines that will be
# disabled and whose data will be removed once the user confirms.
quota.removal.label = Firefox Sync will remove the following data: %S.
quota.removal.label = Sync will remove the following data: %S.
# LOCALIZATION NOTE (quota.list.separator): This is the separator string used
# for the list of engines (incl. spaces where appropriate)
quota.list.separator = ,\u0020

View File

@ -6,13 +6,13 @@
<!-- First page of the wizard -->
<!ENTITY setup.pickSetupType.description2 "Welcome! If youve never used &syncBrand.fullName.label; before, you will need to create a new account.">
<!ENTITY setup.pickSetupType.description2 "Welcome! If you've never used &syncBrand.fullName.label; before, you will need to create a new account.">
<!ENTITY button.createNewAccount.label "Create a New Account">
<!ENTITY button.haveAccount.label "I Have an Account">
<!ENTITY setup.choicePage.title.label "Have you used &syncBrand.fullName.label; before?">
<!ENTITY setup.choicePage.new.label "Ive never used &syncBrand.shortName.label; before">
<!ENTITY setup.choicePage.existing2.label "Im already using &syncBrand.shortName.label; on another device">
<!ENTITY setup.choicePage.new.label "I've never used &syncBrand.shortName.label; before">
<!ENTITY setup.choicePage.existing2.label "I'm already using &syncBrand.shortName.label; on another device">
<!-- New Account AND Existing Account -->
<!ENTITY server.label "Server">
@ -33,6 +33,8 @@
<!ENTITY setup.choosePassword.accesskey "P">
<!ENTITY setup.confirmPassword.label "Confirm Password">
<!ENTITY setup.confirmPassword.accesskey "m">
<!ENTITY setup.setupMetro.label "Sync with Windows 8 style &brandShortName;">
<!ENTITY setup.setupMetro.accesskey "S">
<!-- LOCALIZATION NOTE: tosAgree1, tosLink, tosAgree2, ppLink, tosAgree3 are
joined with implicit white space, so spaces in the strings aren't necessary -->
@ -60,7 +62,7 @@
<!-- Existing Account Page 1: Pair a Device (incl. Pair a Device dialog strings) -->
<!ENTITY pairDevice.title.label "Pair a Device">
<!ENTITY addDevice.showMeHow.label "Show me how.">
<!ENTITY addDevice.dontHaveDevice.label "I dont have the device with me">
<!ENTITY addDevice.dontHaveDevice.label "I don't have the device with me">
<!ENTITY pairDevice.setup.description.label "To activate, select &#x0022;Pair a Device&#x0022; on your other device.">
<!ENTITY addDevice.setup.enterCode.label "Then, enter this code:">
<!ENTITY pairDevice.dialog.description.label "To activate your new device, select &#x0022;Set Up Sync&#x0022; on the device.">
@ -72,7 +74,7 @@
<!-- Existing Account Page 2: Manual Login -->
<!ENTITY setup.signInPage.title.label "Sign In">
<!ENTITY existingRecoveryKey.description "You can get a copy of your Recovery Key by going to &syncBrand.shortName.label; Preferences on your other device, and selecting &#x0022;My Recovery Key&#x0022; under &#x0022;Manage Account&#x0022;.">
<!ENTITY existingRecoveryKey.description "You can get a copy of your Recovery Key by going to &syncBrand.shortName.label; Options on your other device, and selecting &#x0022;My Recovery Key&#x0022; under &#x0022;Manage Account&#x0022;.">
<!ENTITY verifying.label "Verifying…">
<!ENTITY resetPassword.label "Reset Password">
<!ENTITY resetSyncKey.label "I have lost my other device.">
@ -96,14 +98,14 @@
<!ENTITY engine.addons.label "Add-ons">
<!ENTITY engine.addons.accesskey "A">
<!ENTITY choice2a.merge.main.label "Merge this devices data with my &syncBrand.shortName.label; data">
<!ENTITY choice2a.merge.main.label "Merge this device's data with my &syncBrand.shortName.label; data">
<!ENTITY choice2.merge.recommended.label "Recommended:">
<!ENTITY choice2a.client.main.label "Replace all data on this device with my &syncBrand.shortName.label; data">
<!ENTITY choice2a.server.main.label "Replace all other devices with this devices data">
<!ENTITY choice2a.server.main.label "Replace all other devices with this device's data">
<!-- Confirm Merge Options -->
<!ENTITY setup.optionsConfirmPage.title "Confirm">
<!ENTITY confirm.merge2.label "&syncBrand.fullName.label; will now merge all this devices browser data into your Sync account.">
<!ENTITY confirm.merge2.label "&syncBrand.fullName.label; will now merge all this device's browser data into your Sync account.">
<!ENTITY confirm.client3.label "Warning: The following &brandShortName; data on this device will be deleted:">
<!ENTITY confirm.client2.moreinfo.label "&brandShortName; will then copy your &syncBrand.fullName.label; data to this device.">
<!ENTITY confirm.server2.label "Warning: The following devices will be overwritten with your local data:">

View File

@ -35,33 +35,17 @@ passwordsCount.label = #1 password;#1 passwords
# LOCALIZATION NOTE (addonsCount.label): Semicolon-separated list of plural forms.
# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
# #1 is the number of add-ons, see the link above for forms
addonsCount.label = #1 add-on;#1 add-ons
addonsCount.label = #1 addon;#1 addons
save.recoverykey.title = Save Recovery Key
save.recoverykey.defaultfilename = Firefox Recovery Key.html
save.recoverykey.defaultfilename = Pale Moon Recovery Key.html
newAccount.action.label = Firefox Sync is now set up to automatically sync all of your browser data.
newAccount.action.label = Sync is now set up to automatically sync all of your browser data.
newAccount.change.label = You can choose exactly what to sync by selecting Sync Options below.
resetClient.change2.label = Firefox Sync will now merge all this devices browser data into your Sync account.
wipeClient.change2.label = Firefox Sync will now replace all of the browser data on this device with the data in your Sync account.
wipeRemote.change2.label = Firefox Sync will now replace all of the browser data in your Sync account with the data on this device.
resetClient.change2.label = Sync will now merge all this device's browser data into your Sync account.
wipeClient.change2.label = Sync will now replace all of the browser data on this device with the data in your Sync account.
wipeRemote.change2.label = Sync will now replace all of the browser data in your Sync account with the data on this device.
existingAccount.change.label = You can change this preference by selecting Sync Options below.
# Several other strings are used (via Weave.Status.login), but they come from
# /services/sync
# Firefox Accounts based setup.
continue.label = Continue
# LOCALIZATION NOTE (disconnect.label, disconnect.verify.title, disconnect.verify.bodyHeading, disconnect.verify.bodyText):
# These strings are used in the confirmation dialog shown when the user hits the disconnect button
# LOCALIZATION NOTE (disconnect.label): This is the label for the disconnect button
disconnect.label = Disconnect
disconnect.verify.title = Disconnect
disconnect.verify.bodyHeading = Disconnect from Sync?
disconnect.verify.bodyText = Your browsing data will remain on this computer, but it will no longer sync with your account.
relinkVerify.title = Merge Warning
relinkVerify.heading = Are you sure you want to sign in to Sync?
# LOCALIZATION NOTE (relinkVerify.description): Email address of a user previously signed into sync.
relinkVerify.description = A different user was previously signed in to Sync on this computer. Signing in will merge this browsers bookmarks, passwords and other settings with %S

View File

@ -10,7 +10,7 @@
locale/browser/aboutDialog.dtd (%chrome/browser/aboutDialog.dtd)
locale/browser/aboutPrivateBrowsing.dtd (%chrome/browser/aboutPrivateBrowsing.dtd)
locale/browser/aboutPrivateBrowsing.properties (%chrome/browser/aboutPrivateBrowsing.properties)
locale/browser/aboutHome.dtd (%chrome/browser/aboutHome.dtd)
* locale/browser/aboutHome.dtd (%chrome/browser/aboutHome.dtd)
locale/browser/accounts.properties (%chrome/browser/accounts.properties)
#ifdef MOZ_SERVICES_HEALTHREPORT
locale/browser/aboutHealthReport.dtd (%chrome/browser/aboutHealthReport.dtd)
@ -19,8 +19,7 @@
locale/browser/aboutSessionRestore.dtd (%chrome/browser/aboutSessionRestore.dtd)
locale/browser/aboutTabCrashed.dtd (%chrome/browser/aboutTabCrashed.dtd)
locale/browser/syncCustomize.dtd (%chrome/browser/syncCustomize.dtd)
locale/browser/aboutSyncTabs.dtd (%chrome/browser/aboutSyncTabs.dtd)
locale/browser/browser.dtd (%chrome/browser/browser.dtd)
* locale/browser/browser.dtd (%chrome/browser/browser.dtd)
locale/browser/baseMenuOverlay.dtd (%chrome/browser/baseMenuOverlay.dtd)
locale/browser/browser.properties (%chrome/browser/browser.properties)
locale/browser/customizableui/customizableWidgets.properties (%chrome/browser/customizableui/customizableWidgets.properties)
@ -79,9 +78,12 @@
locale/browser/preferences/preferences.properties (%chrome/browser/preferences/preferences.properties)
* locale/browser/preferences/privacy.dtd (%chrome/browser/preferences/privacy.dtd)
locale/browser/preferences/security.dtd (%chrome/browser/preferences/security.dtd)
#ifdef MOZ_SERVICES_SYNC
locale/browser/preferences/sync.dtd (%chrome/browser/preferences/sync.dtd)
#endif
locale/browser/preferences/tabs.dtd (%chrome/browser/preferences/tabs.dtd)
locale/browser/preferences/search.dtd (%chrome/browser/preferences/search.dtd)
#ifdef MOZ_SERVICES_SYNC
locale/browser/syncBrand.dtd (%chrome/browser/syncBrand.dtd)
locale/browser/syncSetup.dtd (%chrome/browser/syncSetup.dtd)
locale/browser/syncSetup.properties (%chrome/browser/syncSetup.properties)
@ -89,6 +91,9 @@
locale/browser/syncKey.dtd (%chrome/browser/syncKey.dtd)
locale/browser/syncQuota.dtd (%chrome/browser/syncQuota.dtd)
locale/browser/syncQuota.properties (%chrome/browser/syncQuota.properties)
locale/browser/syncProgress.dtd (%chrome/browser/syncProgress.dtd)
locale/browser/aboutSyncTabs.dtd (%chrome/browser/aboutSyncTabs.dtd)
#endif
% resource search-plugins chrome://browser/locale/searchplugins/
#if BUILD_FASTER
locale/browser/searchplugins/ (searchplugins/*.xml)

View File

@ -8,7 +8,9 @@ browser.jar:
#include ../shared/jar.inc.mn
skin/classic/browser/sanitizeDialog.css
skin/classic/browser/aboutSessionRestore-window-icon.png
#ifdef MOZ_SERVICES_SYNC
skin/classic/browser/aboutSyncTabs.css
#endif
skin/classic/browser/actionicon-tab.png
* skin/classic/browser/browser.css
* skin/classic/browser/devedition.css
@ -106,6 +108,7 @@ browser.jar:
skin/classic/browser/tabbrowser/tab-stroke-start@2x.png (tabbrowser/tab-stroke-start@2x.png)
skin/classic/browser/tabbrowser/tabDragIndicator.png (tabbrowser/tabDragIndicator.png)
#ifdef MOZ_SERVICES_SYNC
skin/classic/browser/sync-16.png
skin/classic/browser/sync-32.png
skin/classic/browser/sync-bg.png
@ -124,6 +127,8 @@ browser.jar:
skin/classic/browser/syncQuota.css
skin/classic/browser/syncProgress-horizontalbar.png
skin/classic/browser/syncProgress-horizontalbar@2x.png
skin/classic/browser/syncProgress.css
#endif
[extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}] chrome.jar:
% override chrome://browser/skin/feeds/audioFeedIcon.png chrome://browser/skin/feeds/feedIcon.png

View File

@ -0,0 +1,46 @@
/* 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/. */
@import url(chrome://global/skin/inContentUI.css);
:root {
height: 100%;
width: 100%;
padding: 0;
}
body {
margin: 0;
padding: 0 2em;
}
#floatingBox {
margin: 4em auto;
max-width: 40em;
min-width: 23em;
padding: 1em 1.5em;
position: relative;
text-align: center;
}
#successLogo {
margin: 1em 2em;
}
#loadingText {
margin: 2em 6em;
}
#progressBar {
margin: 2em 10em;
}
#uploadProgressBar{
width: 100%;
}
#bottomRow {
margin-top: 2em;
padding: 0;
text-align: end;
}

View File

@ -7,7 +7,9 @@ browser.jar:
#include ../shared/jar.inc.mn
skin/classic/browser/sanitizeDialog.css
skin/classic/browser/aboutSessionRestore-window-icon.png
#ifdef MOZ_SERVICES_SYNC
skin/classic/browser/aboutSyncTabs.css
#endif
skin/classic/browser/actionicon-tab.png
skin/classic/browser/actionicon-tab@2x.png
* skin/classic/browser/browser.css
@ -158,6 +160,7 @@ browser.jar:
skin/classic/browser/tabbrowser/tab-stroke-start@2x.png (tabbrowser/tab-stroke-start@2x.png)
skin/classic/browser/tabbrowser/tabDragIndicator.png (tabbrowser/tabDragIndicator.png)
skin/classic/browser/tabbrowser/tabDragIndicator@2x.png (tabbrowser/tabDragIndicator@2x.png)
#ifdef MOZ_SERVICES_SYNC
skin/classic/browser/sync-16.png
skin/classic/browser/sync-32.png
skin/classic/browser/sync-bg.png
@ -178,6 +181,8 @@ browser.jar:
skin/classic/browser/syncProgress-toolbar@2x.png
skin/classic/browser/syncProgress-toolbar-inverted.png
skin/classic/browser/syncProgress-toolbar-inverted@2x.png
skin/classic/browser/syncProgress.css
#endif
skin/classic/browser/Toolbar-background-noise.png (Toolbar-background-noise.png)
skin/classic/browser/lion/toolbarbutton-dropmarker.png (toolbarbutton-dropmarker-lion.png)
skin/classic/browser/toolbarbutton-dropmarker@2x.png (toolbarbutton-dropmarker-lion@2x.png)
@ -194,8 +199,10 @@ browser.jar:
skin/classic/browser/yosemite/menuPanel-help@2x.png (menuPanel-help-yosemite@2x.png)
skin/classic/browser/yosemite/reload-stop-go.png (reload-stop-go-yosemite.png)
skin/classic/browser/yosemite/reload-stop-go@2x.png (reload-stop-go-yosemite@2x.png)
#ifdef MOZ_SERVICES_SYNC
skin/classic/browser/yosemite/sync-horizontalbar.png (sync-horizontalbar-yosemite.png)
skin/classic/browser/yosemite/sync-horizontalbar@2x.png (sync-horizontalbar-yosemite@2x.png)
#endif
skin/classic/browser/yosemite/tab-selected-end-inactive.svg (tabbrowser/tab-selected-end-yosemite-inactive.svg)
skin/classic/browser/yosemite/tab-selected-start-inactive.svg (tabbrowser/tab-selected-start-yosemite-inactive.svg)
skin/classic/browser/yosemite/tab-active-middle-inactive.png (tabbrowser/tab-active-middle-yosemite-inactive.png)
@ -223,5 +230,7 @@ browser.jar:
% override chrome://browser/skin/menuPanel-help@2x.png chrome://browser/skin/yosemite/menuPanel-help@2x.png os=Darwin osversion>=10.10
% override chrome://browser/skin/reload-stop-go.png chrome://browser/skin/yosemite/reload-stop-go.png os=Darwin osversion>=10.10
% override chrome://browser/skin/reload-stop-go@2x.png chrome://browser/skin/yosemite/reload-stop-go@2x.png os=Darwin osversion>=10.10
#ifdef MOZ_SERVICES_SYNC
% override chrome://browser/skin/sync-horizontalbar.png chrome://browser/skin/yosemite/sync-horizontalbar.png os=Darwin osversion>=10.10
% override chrome://browser/skin/sync-horizontalbar@2x.png chrome://browser/skin/yosemite/sync-horizontalbar@2x.png os=Darwin osversion>=10.10
#endif

View File

@ -0,0 +1,46 @@
/* 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/. */
@import url(chrome://global/skin/inContentUI.css);
:root {
height: 100%;
width: 100%;
padding: 0;
}
body {
margin: 0;
padding: 0 2em;
}
#floatingBox {
margin: 4em auto;
max-width: 40em;
min-width: 23em;
padding: 1em 1.5em;
position: relative;
text-align: center;
}
#successLogo {
margin: 1em 2em;
}
#loadingText {
margin: 2em 6em;
}
#progressBar {
margin: 2em 10em;
}
#uploadProgressBar{
width: 100%;
}
#bottomRow {
margin-top: 2em;
padding: 0;
text-align: end;
}

View File

@ -2,7 +2,7 @@
% Note that zoom-reset-button is a bit different since it doesn't use an image and thus has the image with display: none.
%define nestedButtons #zoom-out-button, #zoom-reset-button, #zoom-in-button, #cut-button, #copy-button, #paste-button
%define primaryToolbarButtons #back-button, #forward-button, #home-button, #print-button, #downloads-button, #bookmarks-menu-button, #new-tab-button, #new-window-button, #fullscreen-button, #sync-button, #feed-button, #open-file-button, #find-button, #developer-button, #preferences-button, #privatebrowsing-button, #save-page-button, #add-ons-button, #history-panelmenu, #nav-bar-overflow-button, #PanelUI-menu-button, #characterencoding-button, #email-link-button, #sidebar-button, @nestedButtons@, #e10s-button, #panic-button, #webide-button, #containers-panelmenu
%define primaryToolbarButtons #back-button, #forward-button, #home-button, #print-button, #downloads-button, #bookmarks-menu-button, #new-tab-button, #new-window-button, #fullscreen-button, #sync-button, #sync-tabs-button, #feed-button, #open-file-button, #find-button, #developer-button, #preferences-button, #privatebrowsing-button, #save-page-button, #add-ons-button, #history-panelmenu, #nav-bar-overflow-button, #PanelUI-menu-button, #characterencoding-button, #email-link-button, #sidebar-button, @nestedButtons@, #e10s-button, #panic-button, #webide-button, #containers-panelmenu
%ifdef XP_MACOSX
% Prior to 10.7 there wasn't a native fullscreen button so we use #restore-button to exit fullscreen

View File

@ -48,10 +48,29 @@ toolbarpaletteitem[place="palette"] > #save-page-button {
-moz-image-region: rect(0px, 352px, 32px, 320px);
}
%ifdef MOZ_SERVICES_SYNC
#sync-button[cui-areatype="menu-panel"],
toolbarpaletteitem[place="palette"] > #sync-button {
-moz-image-region: rect(0px, 384px, 32px, 352px)
}
#sync-button[cui-areatype="menu-panel"][status="active"] {
list-style-image: url("chrome://browser/skin/syncProgress-menuPanel.png");
-moz-image-region: rect(0, 32px, 32px, 0);
}
@media (min-resolution: 1.1dppx) {
#sync-button[cui-areatype="menu-panel"][status="active"] {
list-style-image: url("chrome://browser/skin/syncProgress-menuPanel@2x.png");
-moz-image-region: rect(0, 64px, 64px, 0);
}
}
#sync-tabs-button[cui-areatype="menu-panel"],
toolbarpaletteitem[place="palette"] > #sync-tabs-button {
-moz-image-region: rect(0px, 1024px, 32px, 992px);
}
%endif
#containers-panelmenu[cui-areatype="menu-panel"],
toolbarpaletteitem[place="palette"] > #containers-panelmenu {

View File

@ -52,9 +52,32 @@ toolbar[brighttext] #bookmarks-menu-button > .toolbarbutton-menubutton-dropmarke
-moz-image-region: rect(0, 252px, 18px, 234px);
}
%ifdef MOZ_SERVICES_SYNC
#sync-button[cui-areatype="toolbar"] {
-moz-image-region: rect(0, 270px, 18px, 252px);
}
#sync-button[cui-areatype="toolbar"][status="active"] {
list-style-image: url("chrome://browser/skin/syncProgress-toolbar.png");
-moz-image-region: rect(0, 18px, 18px, 0);
}
@media (-moz-os-version: windows-win7) {
#sync-button[cui-areatype="toolbar"][status="active"] {
list-style-image: url("chrome://browser/skin/syncProgress-toolbar-win7.png");
-moz-image-region: rect(0, 18px, 18px, 0);
}
}
toolbar[brighttext] #sync-button[cui-areatype="toolbar"][status="active"] {
list-style-image: url("chrome://browser/skin/syncProgress-toolbar-inverted.png");
-moz-image-region: rect(0, 18px, 18px, 0);
}
#sync-tabs-button[cui-areatype="toolbar"] {
-moz-image-region: rect(0, 792px, 18px, 774px);
}
%endif
#containers-panelmenu[cui-areatype="toolbar"] {
-moz-image-region: rect(0, 810px, 18px, 792px);
@ -226,9 +249,32 @@ toolbar[brighttext] #bookmarks-menu-button > .toolbarbutton-menubutton-dropmarke
-moz-image-region: rect(0, 504px, 36px, 468px);
}
%ifdef MOZ_SERVICES_SYNC
#sync-button[cui-areatype="toolbar"] {
-moz-image-region: rect(0, 540px, 36px, 504px);
}
#sync-button[cui-areatype="toolbar"][status="active"] {
list-style-image: url("chrome://browser/skin/syncProgress-toolbar@2x.png");
-moz-image-region: rect(0, 36px, 36px, 0);
}
@media (-moz-os-version: windows-win7) {
#sync-button[cui-areatype="toolbar"][status="active"] {
list-style-image: url("chrome://browser/skin/syncProgress-toolbar-win7@2x.png");
-moz-image-region: rect(0, 36px, 36px, 0);
}
}
toolbar[brighttext] #sync-button[cui-areatype="toolbar"][status="active"] {
list-style-image: url("chrome://browser/skin/syncProgress-toolbar-inverted@2x.png");
-moz-image-region: rect(0, 36px, 36px, 0);
}
#sync-tabs-button[cui-areatype="toolbar"] {
-moz-image-region: rect(0, 1584px, 36px, 1548px);
}
%endif
#containers-panelmenu[cui-areatype="toolbar"] {
-moz-image-region: rect(0, 1620px, 36px, 1584px);

View File

@ -7,7 +7,9 @@ browser.jar:
#include ../shared/jar.inc.mn
skin/classic/browser/sanitizeDialog.css
skin/classic/browser/aboutSessionRestore-window-icon.png
#ifdef MOZ_SERVICES_SYNC
skin/classic/browser/aboutSyncTabs.css
#endif
skin/classic/browser/actionicon-tab.png
skin/classic/browser/actionicon-tab@2x.png
skin/classic/browser/actionicon-tab-win7.png
@ -140,6 +142,7 @@ browser.jar:
skin/classic/browser/tabbrowser/tab-stroke-start.png (tabbrowser/tab-stroke-start.png)
skin/classic/browser/tabbrowser/tab-stroke-start@2x.png (tabbrowser/tab-stroke-start@2x.png)
skin/classic/browser/tabbrowser/tabDragIndicator.png (tabbrowser/tabDragIndicator.png)
#ifdef MOZ_SERVICES_SYNC
skin/classic/browser/sync-16.png
skin/classic/browser/sync-32.png
skin/classic/browser/sync-128.png
@ -166,6 +169,8 @@ browser.jar:
skin/classic/browser/syncProgress-toolbar-inverted@2x.png
skin/classic/browser/syncProgress-toolbar-win7.png
skin/classic/browser/syncProgress-toolbar-win7@2x.png
skin/classic/browser/syncProgress.css
#endif
[extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}] chrome.jar:
% override chrome://browser/skin/page-livemarks.png chrome://browser/skin/feeds/feedIcon16.png
@ -181,12 +186,14 @@ browser.jar:
% override chrome://browser/skin/privatebrowsing-mask-titlebar.png chrome://browser/skin/privatebrowsing-mask-titlebar-win7.png os=WINNT osversion<=6.1
% override chrome://browser/skin/reload-stop-go.png chrome://browser/skin/reload-stop-go-win7.png os=WINNT osversion<=6.1
% override chrome://browser/skin/reload-stop-go@2x.png chrome://browser/skin/reload-stop-go-win7@2x.png os=WINNT osversion<=6.1
#ifdef MOZ_SERVICES_SYNC
% override chrome://browser/skin/sync-horizontalbar.png chrome://browser/skin/sync-horizontalbar-win7.png os=WINNT osversion<=6.1
% override chrome://browser/skin/sync-horizontalbar@2x.png chrome://browser/skin/sync-horizontalbar-win7@2x.png os=WINNT osversion<=6.1
% override chrome://browser/skin/syncProgress-horizontalbar.png chrome://browser/skin/syncProgress-horizontalbar-win7.png os=WINNT osversion<=6.1
% override chrome://browser/skin/syncProgress-horizontalbar@2x.png chrome://browser/skin/syncProgress-horizontalbar-win7@2x.png os=WINNT osversion<=6.1
% override chrome://browser/skin/syncProgress-toolbar.png chrome://browser/skin/syncProgress-toolbar-win7.png os=WINNT osversion<=6.1
% override chrome://browser/skin/syncProgress-toolbar@2x.png chrome://browser/skin/syncProgress-toolbar-win7@2x.png os=WINNT osversion<=6.1
#endif
% override chrome://browser/skin/toolbarbutton-dropdown-arrow.png chrome://browser/skin/toolbarbutton-dropdown-arrow-win7.png os=WINNT osversion<=6.1
% override chrome://browser/skin/urlbar-history-dropmarker.png chrome://browser/skin/urlbar-history-dropmarker-win7.png os=WINNT osversion<=6.1
% override chrome://browser/skin/urlbar-history-dropmarker@2x.png chrome://browser/skin/urlbar-history-dropmarker-win7@2x.png os=WINNT osversion<=6.1

View File

@ -0,0 +1,46 @@
/* 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/. */
@import url(chrome://global/skin/inContentUI.css);
:root {
height: 100%;
width: 100%;
padding: 0;
}
body {
margin: 0;
padding: 0 2em;
}
#floatingBox {
margin: 4em auto;
max-width: 40em;
min-width: 23em;
padding: 1em 1.5em;
position: relative;
text-align: center;
}
#successLogo {
margin: 1em 2em;
}
#loadingText {
margin: 2em 6em;
}
#progressBar {
margin: 2em 10em;
}
#uploadProgressBar{
width: 100%;
}
#bottomRow {
margin-top: 2em;
padding: 0;
text-align: end;
}