mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-05 23:38:38 +09:00
[BASILISK] Remove FxA infected Sync - Part 1: Remove or condition CUI and Integration Points
This commit is contained in:
parent
98ec471861
commit
b07b0d18b5
17 changed files with 30 additions and 1425 deletions
|
|
@ -1,314 +0,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/. */
|
||||
|
||||
var gFxAccounts = {
|
||||
|
||||
_initialized: false,
|
||||
_inCustomizationMode: false,
|
||||
_cachedProfile: null,
|
||||
|
||||
get weave() {
|
||||
delete this.weave;
|
||||
return this.weave = Cc["@mozilla.org/weave/service;1"]
|
||||
.getService(Ci.nsISupports)
|
||||
.wrappedJSObject;
|
||||
},
|
||||
|
||||
get topics() {
|
||||
// Do all this dance to lazy-load FxAccountsCommon.
|
||||
delete this.topics;
|
||||
return this.topics = [
|
||||
"weave:service:ready",
|
||||
"weave:service:login:change",
|
||||
"weave:service:setup-complete",
|
||||
"weave:service:sync:error",
|
||||
"weave:ui:login:error",
|
||||
this.FxAccountsCommon.ONLOGIN_NOTIFICATION,
|
||||
this.FxAccountsCommon.ONLOGOUT_NOTIFICATION,
|
||||
this.FxAccountsCommon.ON_PROFILE_CHANGE_NOTIFICATION,
|
||||
];
|
||||
},
|
||||
|
||||
get panelUIFooter() {
|
||||
delete this.panelUIFooter;
|
||||
return this.panelUIFooter = document.getElementById("PanelUI-footer-fxa");
|
||||
},
|
||||
|
||||
get panelUIStatus() {
|
||||
delete this.panelUIStatus;
|
||||
return this.panelUIStatus = document.getElementById("PanelUI-fxa-status");
|
||||
},
|
||||
|
||||
get panelUIAvatar() {
|
||||
delete this.panelUIAvatar;
|
||||
return this.panelUIAvatar = document.getElementById("PanelUI-fxa-avatar");
|
||||
},
|
||||
|
||||
get panelUILabel() {
|
||||
delete this.panelUILabel;
|
||||
return this.panelUILabel = document.getElementById("PanelUI-fxa-label");
|
||||
},
|
||||
|
||||
get panelUIIcon() {
|
||||
delete this.panelUIIcon;
|
||||
return this.panelUIIcon = document.getElementById("PanelUI-fxa-icon");
|
||||
},
|
||||
|
||||
get strings() {
|
||||
delete this.strings;
|
||||
return this.strings = Services.strings.createBundle(
|
||||
"chrome://browser/locale/accounts.properties"
|
||||
);
|
||||
},
|
||||
|
||||
get loginFailed() {
|
||||
// Referencing Weave.Service will implicitly initialize sync, and we don't
|
||||
// want to force that - so first check if it is ready.
|
||||
let service = Cc["@mozilla.org/weave/service;1"]
|
||||
.getService(Components.interfaces.nsISupports)
|
||||
.wrappedJSObject;
|
||||
if (!service.ready) {
|
||||
return false;
|
||||
}
|
||||
// LOGIN_FAILED_LOGIN_REJECTED explicitly means "you must log back in".
|
||||
// All other login failures are assumed to be transient and should go
|
||||
// away by themselves, so aren't reflected here.
|
||||
return Weave.Status.login == Weave.LOGIN_FAILED_LOGIN_REJECTED;
|
||||
},
|
||||
|
||||
init: function () {
|
||||
// Bail out if we're already initialized and for pop-up windows.
|
||||
if (this._initialized || !window.toolbar.visible) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (let topic of this.topics) {
|
||||
Services.obs.addObserver(this, topic, false);
|
||||
}
|
||||
|
||||
gNavToolbox.addEventListener("customizationstarting", this);
|
||||
gNavToolbox.addEventListener("customizationending", this);
|
||||
|
||||
EnsureFxAccountsWebChannel();
|
||||
this._initialized = true;
|
||||
|
||||
this.updateUI();
|
||||
},
|
||||
|
||||
uninit: function () {
|
||||
if (!this._initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (let topic of this.topics) {
|
||||
Services.obs.removeObserver(this, topic);
|
||||
}
|
||||
|
||||
this._initialized = false;
|
||||
},
|
||||
|
||||
observe: function (subject, topic, data) {
|
||||
switch (topic) {
|
||||
case this.FxAccountsCommon.ON_PROFILE_CHANGE_NOTIFICATION:
|
||||
this._cachedProfile = null;
|
||||
// Fallthrough intended
|
||||
default:
|
||||
this.updateUI();
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
handleEvent: function (event) {
|
||||
this._inCustomizationMode = event.type == "customizationstarting";
|
||||
this.updateAppMenuItem();
|
||||
},
|
||||
|
||||
updateUI: function () {
|
||||
// It's possible someone signed in to FxA after seeing our notification
|
||||
// about "Legacy Sync migration" (which now is actually "Legacy Sync
|
||||
// auto-disconnect") so kill that notification if it still exists.
|
||||
let nb = window.document.getElementById("global-notificationbox");
|
||||
let n = nb.getNotificationWithValue(this.SYNC_MIGRATION_NOTIFICATION_TITLE);
|
||||
if (n) {
|
||||
nb.removeNotification(n, true);
|
||||
}
|
||||
|
||||
this.updateAppMenuItem();
|
||||
},
|
||||
|
||||
// Note that updateAppMenuItem() returns a Promise that's only used by tests.
|
||||
updateAppMenuItem: function () {
|
||||
let profileInfoEnabled = false;
|
||||
try {
|
||||
profileInfoEnabled = Services.prefs.getBoolPref("identity.fxaccounts.profile_image.enabled");
|
||||
} catch (e) { }
|
||||
|
||||
this.panelUIFooter.hidden = false;
|
||||
|
||||
// Make sure the button is disabled in customization mode.
|
||||
if (this._inCustomizationMode) {
|
||||
this.panelUIStatus.setAttribute("disabled", "true");
|
||||
this.panelUILabel.setAttribute("disabled", "true");
|
||||
this.panelUIAvatar.setAttribute("disabled", "true");
|
||||
this.panelUIIcon.setAttribute("disabled", "true");
|
||||
} else {
|
||||
this.panelUIStatus.removeAttribute("disabled");
|
||||
this.panelUILabel.removeAttribute("disabled");
|
||||
this.panelUIAvatar.removeAttribute("disabled");
|
||||
this.panelUIIcon.removeAttribute("disabled");
|
||||
}
|
||||
|
||||
let defaultLabel = this.panelUIStatus.getAttribute("defaultlabel");
|
||||
let errorLabel = this.panelUIStatus.getAttribute("errorlabel");
|
||||
let unverifiedLabel = this.panelUIStatus.getAttribute("unverifiedlabel");
|
||||
let settingslabel = this.panelUIStatus.getAttribute("settingslabel");
|
||||
// The localization string is for the signed in text, but it's the default text as well
|
||||
let defaultTooltiptext = this.panelUIStatus.getAttribute("signedinTooltiptext");
|
||||
|
||||
let updateWithUserData = (userData) => {
|
||||
// Window might have been closed while fetching data.
|
||||
if (window.closed) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Reset the button to its original state.
|
||||
this.panelUILabel.setAttribute("label", defaultLabel);
|
||||
this.panelUIStatus.setAttribute("tooltiptext", defaultTooltiptext);
|
||||
this.panelUIFooter.removeAttribute("fxastatus");
|
||||
this.panelUIFooter.removeAttribute("fxaprofileimage");
|
||||
this.panelUIAvatar.style.removeProperty("list-style-image");
|
||||
|
||||
if (Weave.Status.service == Weave.CLIENT_NOT_CONFIGURED) {
|
||||
// Leave the default state
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.loginFailed) {
|
||||
this.panelUIFooter.setAttribute("fxastatus", "error");
|
||||
this.panelUILabel.setAttribute("label", errorLabel);
|
||||
} else {
|
||||
this.panelUIFooter.setAttribute("fxastatus", "signedin");
|
||||
this.panelUILabel.setAttribute("label", settingslabel);
|
||||
this.panelUIStatus.setAttribute("tooltiptext", "");
|
||||
}
|
||||
}
|
||||
|
||||
let updateWithProfile = (profile) => {
|
||||
if (profileInfoEnabled) {
|
||||
if (profile.displayName) {
|
||||
this.panelUILabel.setAttribute("label", profile.displayName);
|
||||
}
|
||||
if (profile.avatar) {
|
||||
this.panelUIFooter.setAttribute("fxaprofileimage", "set");
|
||||
let bgImage = "url(\"" + profile.avatar + "\")";
|
||||
this.panelUIAvatar.style.listStyleImage = bgImage;
|
||||
|
||||
let img = new Image();
|
||||
img.onerror = () => {
|
||||
// Clear the image if it has trouble loading. Since this callback is asynchronous
|
||||
// we check to make sure the image is still the same before we clear it.
|
||||
if (this.panelUIAvatar.style.listStyleImage === bgImage) {
|
||||
this.panelUIFooter.removeAttribute("fxaprofileimage");
|
||||
this.panelUIAvatar.style.removeProperty("list-style-image");
|
||||
}
|
||||
};
|
||||
img.src = profile.avatar;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return fxAccounts.getSignedInUser().then(userData => {
|
||||
// userData may be null here when the user is not signed-in, but that's expected
|
||||
updateWithUserData(userData);
|
||||
// unverified users cause us to spew log errors fetching an OAuth token
|
||||
// to fetch the profile, so don't even try in that case.
|
||||
if (!userData || !userData.verified || !profileInfoEnabled) {
|
||||
return null; // don't even try to grab the profile.
|
||||
}
|
||||
if (this._cachedProfile) {
|
||||
return this._cachedProfile;
|
||||
}
|
||||
return fxAccounts.getSignedInUserProfile().catch(err => {
|
||||
// Not fetching the profile is sad but the FxA logs will already have noise.
|
||||
return null;
|
||||
});
|
||||
}).then(profile => {
|
||||
if (!profile) {
|
||||
return;
|
||||
}
|
||||
updateWithProfile(profile);
|
||||
this._cachedProfile = profile; // Try to avoid fetching the profile on every UI update
|
||||
}).catch(error => {
|
||||
// This is most likely in tests, were we quickly log users in and out.
|
||||
// The most likely scenario is a user logged out, so reflect that.
|
||||
// Bug 995134 calls for better errors so we could retry if we were
|
||||
// sure this was the failure reason.
|
||||
this.FxAccountsCommon.log.error("Error updating FxA account info", error);
|
||||
updateWithUserData(null);
|
||||
});
|
||||
},
|
||||
|
||||
onMenuPanelCommand: function () {
|
||||
|
||||
switch (this.panelUIFooter.getAttribute("fxastatus")) {
|
||||
case "signedin":
|
||||
this.openPreferences();
|
||||
break;
|
||||
case "error":
|
||||
if (this.panelUIFooter.getAttribute("unverified")) {
|
||||
this.openPreferences();
|
||||
} else {
|
||||
this.openSignInAgainPage("menupanel");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
this.openPreferences();
|
||||
break;
|
||||
}
|
||||
|
||||
PanelUI.hide();
|
||||
},
|
||||
|
||||
openPreferences: function () {
|
||||
openPreferences("paneSync", { urlParams: { entrypoint: "menupanel" } });
|
||||
},
|
||||
|
||||
openAccountsPage: function (action, urlParams={}) {
|
||||
let params = new URLSearchParams();
|
||||
if (action) {
|
||||
params.set("action", action);
|
||||
}
|
||||
for (let name in urlParams) {
|
||||
if (urlParams[name] !== undefined) {
|
||||
params.set(name, urlParams[name]);
|
||||
}
|
||||
}
|
||||
let url = "about:accounts?" + params;
|
||||
switchToTabHavingURI(url, true, {
|
||||
replaceQueryString: true
|
||||
});
|
||||
},
|
||||
|
||||
openSignInAgainPage: function (entryPoint) {
|
||||
this.openAccountsPage("reauth", { entrypoint: entryPoint });
|
||||
},
|
||||
|
||||
updateTabContextMenu: function (aPopupMenu) {
|
||||
// STUB
|
||||
},
|
||||
|
||||
initPageContextMenu: function (contextMenu) {
|
||||
// STUB
|
||||
}
|
||||
};
|
||||
|
||||
XPCOMUtils.defineLazyGetter(gFxAccounts, "FxAccountsCommon", function () {
|
||||
return Cu.import("resource://gre/modules/FxAccountsCommon.js", {});
|
||||
});
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(gFxAccounts, "fxaMigrator",
|
||||
"resource://services-sync/FxaMigrator.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "EnsureFxAccountsWebChannel",
|
||||
"resource://gre/modules/FxAccountsWebChannel.jsm");
|
||||
|
|
@ -436,12 +436,7 @@
|
|||
label="&toolsMenu.label;"
|
||||
accesskey="&toolsMenu.accesskey;"
|
||||
onpopupshowing="mirrorShow(this)">
|
||||
<menupopup id="menu_ToolsPopup"
|
||||
# We have to use setTimeout() here to avoid a flickering menu bar when opening
|
||||
# the Tools menu, see bug 970769. This can be removed once we got rid of the
|
||||
# event loop spinning in Weave.Status._authManager.
|
||||
onpopupshowing="setTimeout(() => gSyncUI.updateUI());"
|
||||
>
|
||||
<menupopup id="menu_ToolsPopup">
|
||||
<menuitem id="menu_openDownloads"
|
||||
label="&downloads.label;"
|
||||
accesskey="&downloads.accesskey;"
|
||||
|
|
@ -452,23 +447,6 @@
|
|||
accesskey="&addons.accesskey;"
|
||||
key="key_openAddons"
|
||||
command="Tools:Addons"/>
|
||||
|
||||
<!-- only one of sync-setup, sync-syncnowitem or sync-reauthitem will be showing at once -->
|
||||
<menuitem id="sync-setup"
|
||||
label="&syncSignIn.label;"
|
||||
accesskey="&syncSignIn.accesskey;"
|
||||
observes="sync-setup-state"
|
||||
oncommand="gSyncUI.openSetup(null, 'menubar')"/>
|
||||
<menuitem id="sync-syncnowitem"
|
||||
label="&syncSyncNowItem.label;"
|
||||
accesskey="&syncSyncNowItem.accesskey;"
|
||||
observes="sync-syncnow-state"
|
||||
oncommand="gSyncUI.doSync(event);"/>
|
||||
<menuitem id="sync-reauthitem"
|
||||
label="&syncReAuthItem.label;"
|
||||
accesskey="&syncReAuthItem.accesskey;"
|
||||
observes="sync-reauth-state"
|
||||
oncommand="gSyncUI.openSignInAgainPage('menubar');"/>
|
||||
<menuseparator id="devToolsSeparator"/>
|
||||
<menu id="webDeveloperMenu"
|
||||
label="&webDeveloperMenu.label;"
|
||||
|
|
|
|||
|
|
@ -1,545 +0,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/. */
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "fxAccounts",
|
||||
"resource://gre/modules/FxAccounts.jsm");
|
||||
|
||||
const MIN_STATUS_ANIMATION_DURATION = 1600;
|
||||
|
||||
// gSyncUI handles updating the tools menu and displaying notifications.
|
||||
var gSyncUI = {
|
||||
_obs: ["weave:service:sync:start",
|
||||
"weave:service:sync:finish",
|
||||
"weave:service:sync:error",
|
||||
"weave:service:quota:remaining",
|
||||
"weave:service:setup-complete",
|
||||
"weave:service:login:start",
|
||||
"weave:service:login:finish",
|
||||
"weave:service:login:error",
|
||||
"weave:service:logout:finish",
|
||||
"weave:service:start-over",
|
||||
"weave:service:start-over:finish",
|
||||
"weave:ui:login:error",
|
||||
"weave:ui:sync:error",
|
||||
"weave:ui:sync:finish",
|
||||
"weave:ui:clear-error",
|
||||
"weave:engine:sync:finish"
|
||||
],
|
||||
|
||||
_unloaded: false,
|
||||
// The last sync start time. Used to calculate the leftover animation time
|
||||
// once syncing completes (bug 1239042).
|
||||
_syncStartTime: 0,
|
||||
_syncAnimationTimer: 0,
|
||||
|
||||
init: function () {
|
||||
Cu.import("resource://services-common/stringbundle.js");
|
||||
|
||||
// Proceed to set up the UI if Sync has already started up.
|
||||
// Otherwise we'll do it when Sync is firing up.
|
||||
if (this.weaveService.ready) {
|
||||
this.initUI();
|
||||
return;
|
||||
}
|
||||
|
||||
// Sync isn't ready yet, but we can still update the UI with an initial
|
||||
// state - we haven't called initUI() yet, but that's OK - that's more
|
||||
// about observers for state changes, and will be called once Sync is
|
||||
// ready to start sending notifications.
|
||||
this.updateUI();
|
||||
|
||||
Services.obs.addObserver(this, "weave:service:ready", true);
|
||||
Services.obs.addObserver(this, "quit-application", 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");
|
||||
Services.obs.removeObserver(gSyncUI, "quit-application");
|
||||
|
||||
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);
|
||||
|
||||
// initial label for the sync buttons.
|
||||
let broadcaster = document.getElementById("sync-status");
|
||||
broadcaster.setAttribute("label", this._stringBundle.GetStringFromName("syncnow.label"));
|
||||
|
||||
this.maybeMoveSyncedTabsButton();
|
||||
|
||||
this.updateUI();
|
||||
},
|
||||
|
||||
|
||||
// Returns a promise that resolves with true if Sync needs to be configured,
|
||||
// false otherwise.
|
||||
_needsSetup() {
|
||||
let firstSync = "";
|
||||
try {
|
||||
firstSync = Services.prefs.getCharPref("services.sync.firstSync");
|
||||
} catch (e) { }
|
||||
|
||||
return Promise.resolve(Weave.Status.checkSetup() == Weave.CLIENT_NOT_CONFIGURED ||
|
||||
firstSync == "notReady");
|
||||
},
|
||||
|
||||
// Returns a promise that resolves with true if the user currently signed in
|
||||
// to Sync needs to be verified, false otherwise.
|
||||
_needsVerification() {
|
||||
// For callers who care about the distinction between "needs setup" and
|
||||
// "needs verification". Only for fxAccounts. XXX: remove this check.
|
||||
// Since we are configured for legacy Sync only, which has no verification
|
||||
// concept, just return false.
|
||||
return Promise.resolve(false);
|
||||
},
|
||||
|
||||
// Note that we don't show login errors in a notification bar here, but do
|
||||
// still need to track a login-failed state so the "Tools" menu updates
|
||||
// with the correct state.
|
||||
_loginFailed: function () {
|
||||
// If Sync isn't already ready, we don't want to force it to initialize
|
||||
// by referencing Weave.Status - and it isn't going to be accurate before
|
||||
// Sync is ready anyway.
|
||||
if (!this.weaveService.ready) {
|
||||
this.log.debug("_loginFailed has sync not ready, so returning false");
|
||||
return false;
|
||||
}
|
||||
this.log.debug("_loginFailed has sync state=${sync}",
|
||||
{ sync: Weave.Status.login});
|
||||
return Weave.Status.login == Weave.LOGIN_FAILED_LOGIN_REJECTED;
|
||||
},
|
||||
|
||||
// Kick off an update of the UI - does *not* return a promise.
|
||||
updateUI() {
|
||||
this._promiseUpdateUI().catch(err => {
|
||||
this.log.error("updateUI failed", err);
|
||||
})
|
||||
},
|
||||
|
||||
// Updates the UI - returns a promise.
|
||||
_promiseUpdateUI() {
|
||||
return this._needsSetup().then(needsSetup => {
|
||||
if (!gBrowser)
|
||||
return Promise.resolve();
|
||||
|
||||
let loginFailed = this._loginFailed();
|
||||
|
||||
// Start off with a clean slate
|
||||
document.getElementById("sync-reauth-state").hidden = true;
|
||||
document.getElementById("sync-setup-state").hidden = true;
|
||||
document.getElementById("sync-syncnow-state").hidden = true;
|
||||
|
||||
if (loginFailed) {
|
||||
// unhiding this element makes the menubar show the login failure state.
|
||||
document.getElementById("sync-reauth-state").hidden = false;
|
||||
} else if (needsSetup) {
|
||||
document.getElementById("sync-setup-state").hidden = false;
|
||||
} else {
|
||||
document.getElementById("sync-syncnow-state").hidden = false;
|
||||
}
|
||||
|
||||
return this._updateSyncButtonsTooltip();
|
||||
});
|
||||
},
|
||||
|
||||
// Functions called by observers
|
||||
onActivityStart() {
|
||||
if (!gBrowser)
|
||||
return;
|
||||
|
||||
this.log.debug("onActivityStart");
|
||||
|
||||
clearTimeout(this._syncAnimationTimer);
|
||||
this._syncStartTime = Date.now();
|
||||
|
||||
let broadcaster = document.getElementById("sync-status");
|
||||
broadcaster.setAttribute("syncstatus", "active");
|
||||
broadcaster.setAttribute("label", this._stringBundle.GetStringFromName("syncing2.label"));
|
||||
broadcaster.setAttribute("disabled", "true");
|
||||
|
||||
this.updateUI();
|
||||
},
|
||||
|
||||
_updateSyncStatus() {
|
||||
if (!gBrowser)
|
||||
return;
|
||||
let broadcaster = document.getElementById("sync-status");
|
||||
broadcaster.removeAttribute("syncstatus");
|
||||
broadcaster.removeAttribute("disabled");
|
||||
broadcaster.setAttribute("label", this._stringBundle.GetStringFromName("syncnow.label"));
|
||||
this.updateUI();
|
||||
},
|
||||
|
||||
onActivityStop() {
|
||||
if (!gBrowser)
|
||||
return;
|
||||
this.log.debug("onActivityStop");
|
||||
|
||||
let now = Date.now();
|
||||
let syncDuration = now - this._syncStartTime;
|
||||
|
||||
if (syncDuration < MIN_STATUS_ANIMATION_DURATION) {
|
||||
let animationTime = MIN_STATUS_ANIMATION_DURATION - syncDuration;
|
||||
clearTimeout(this._syncAnimationTimer);
|
||||
this._syncAnimationTimer = setTimeout(() => this._updateSyncStatus(), animationTime);
|
||||
} else {
|
||||
this._updateSyncStatus();
|
||||
}
|
||||
},
|
||||
|
||||
onLoginError: function SUI_onLoginError() {
|
||||
this.log.debug("onLoginError: login=${login}, sync=${sync}", Weave.Status);
|
||||
|
||||
// We don't show any login errors here; browser-fxaccounts shows them in
|
||||
// the hamburger menu.
|
||||
this.updateUI();
|
||||
},
|
||||
|
||||
onLogout: function SUI_onLogout() {
|
||||
this.updateUI();
|
||||
},
|
||||
|
||||
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);
|
||||
},
|
||||
|
||||
_getAppName: function () {
|
||||
let brand = new StringBundle("chrome://branding/locale/brand.properties");
|
||||
return brand.get("brandShortName");
|
||||
},
|
||||
|
||||
// Commands
|
||||
// doSync forces a sync - it *does not* return a promise as it is called
|
||||
// via the various UI components.
|
||||
doSync() {
|
||||
this._needsSetup().then(needsSetup => {
|
||||
if (!needsSetup) {
|
||||
setTimeout(() => Weave.Service.errorHandler.syncAndReportErrors(), 0);
|
||||
}
|
||||
Services.obs.notifyObservers(null, "cloudsync:user-sync", null);
|
||||
}).catch(err => {
|
||||
this.log.error("Failed to force a sync", err);
|
||||
});
|
||||
},
|
||||
|
||||
// Handle clicking the toolbar button - which either opens the Sync setup
|
||||
// pages or forces a sync now. Does *not* return a promise as it is called
|
||||
// via the UI.
|
||||
handleToolbarButton() {
|
||||
this._needsSetup().then(needsSetup => {
|
||||
if (needsSetup || this._loginFailed()) {
|
||||
this.openSetup();
|
||||
} else {
|
||||
this.doSync();
|
||||
}
|
||||
}).catch(err => {
|
||||
this.log.error("Failed to handle toolbar button command", err);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @param entryPoint
|
||||
* Indicates the entrypoint from where this method was called.
|
||||
*/
|
||||
|
||||
openSetup: function SUI_openSetup(wizardType, entryPoint = "syncbutton") {
|
||||
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);
|
||||
}
|
||||
},
|
||||
|
||||
// Open the legacy-sync device pairing UI. Note used for FxA Sync.
|
||||
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");
|
||||
},
|
||||
|
||||
openPrefs: function (entryPoint) {
|
||||
openPreferences("paneSync", { urlParams: { entrypoint: entryPoint } });
|
||||
},
|
||||
|
||||
openSignInAgainPage: function (entryPoint = "syncbutton") {
|
||||
gFxAccounts.openSignInAgainPage(entryPoint);
|
||||
},
|
||||
|
||||
/* After Sync is initialized we perform a once-only check for the sync
|
||||
button being in "customize purgatory" and if so, move it to the panel.
|
||||
This is done primarily for profiles created before SyncedTabs landed,
|
||||
where the button defaulted to being in that purgatory.
|
||||
We use a preference to ensure we only do it once, so people can still
|
||||
customize it away and have it stick.
|
||||
*/
|
||||
maybeMoveSyncedTabsButton() {
|
||||
const prefName = "browser.migrated-sync-button";
|
||||
let migrated = false;
|
||||
try {
|
||||
migrated = Services.prefs.getBoolPref(prefName);
|
||||
} catch (_) {}
|
||||
if (migrated) {
|
||||
return;
|
||||
}
|
||||
if (!CustomizableUI.getPlacementOfWidget("sync-button")) {
|
||||
CustomizableUI.addWidgetToArea("sync-button", CustomizableUI.AREA_PANEL);
|
||||
}
|
||||
Services.prefs.setBoolPref(prefName, true);
|
||||
},
|
||||
|
||||
/* Update the tooltip for the sync-status broadcaster (which will update the
|
||||
Sync Toolbar button and the Sync spinner in the FxA hamburger area.)
|
||||
If Sync is configured, the tooltip is when the last sync occurred,
|
||||
otherwise the tooltip reflects the fact that Sync needs to be
|
||||
(re-)configured.
|
||||
*/
|
||||
_updateSyncButtonsTooltip: Task.async(function* () {
|
||||
if (!gBrowser)
|
||||
return;
|
||||
|
||||
let email;
|
||||
try {
|
||||
email = Services.prefs.getCharPref("services.sync.username");
|
||||
} catch (ex) {}
|
||||
|
||||
let needsSetup = yield this._needsSetup();
|
||||
let needsVerification = yield this._needsVerification();
|
||||
let loginFailed = this._loginFailed();
|
||||
// This is a little messy as the Sync buttons are 1/2 Sync related and
|
||||
// 1/2 FxA related - so for some strings we use Sync strings, but for
|
||||
// others we reach into gFxAccounts for strings.
|
||||
let tooltiptext;
|
||||
if (needsVerification) {
|
||||
// "needs verification"
|
||||
tooltiptext = gFxAccounts.strings.formatStringFromName("verifyDescription", [email], 1);
|
||||
} else if (needsSetup) {
|
||||
// "needs setup".
|
||||
tooltiptext = this._stringBundle.GetStringFromName("signInToSync.description");
|
||||
} else if (loginFailed) {
|
||||
// "need to reconnect/re-enter your password"
|
||||
tooltiptext = gFxAccounts.strings.formatStringFromName("reconnectDescription", [email], 1);
|
||||
} else {
|
||||
// Sync appears configured - format the "last synced at" time.
|
||||
try {
|
||||
let lastSync = new Date(Services.prefs.getCharPref("services.sync.lastSync"));
|
||||
tooltiptext = this.formatLastSyncDate(lastSync);
|
||||
}
|
||||
catch (e) {
|
||||
// pref doesn't exist (which will be the case until we've seen the
|
||||
// first successful sync) or is invalid (which should be impossible!)
|
||||
// Just leave tooltiptext as the empty string in these cases, which
|
||||
// will cause the tooltip to be removed below.
|
||||
}
|
||||
}
|
||||
|
||||
// We've done all our promise-y work and ready to update the UI - make
|
||||
// sure it hasn't been torn down since we started.
|
||||
if (!gBrowser)
|
||||
return;
|
||||
|
||||
let broadcaster = document.getElementById("sync-status");
|
||||
if (broadcaster) {
|
||||
if (tooltiptext) {
|
||||
broadcaster.setAttribute("tooltiptext", tooltiptext);
|
||||
} else {
|
||||
broadcaster.removeAttribute("tooltiptext");
|
||||
}
|
||||
}
|
||||
}),
|
||||
|
||||
formatLastSyncDate: function(date) {
|
||||
let dateFormat;
|
||||
let sixDaysAgo = (() => {
|
||||
let date = new Date();
|
||||
date.setDate(date.getDate() - 6);
|
||||
date.setHours(0, 0, 0, 0);
|
||||
return date;
|
||||
})();
|
||||
// It may be confusing for the user to see "Last Sync: Monday" when the last sync was a indeed a Monday but 3 weeks ago
|
||||
if (date < sixDaysAgo) {
|
||||
dateFormat = {month: 'long', day: 'numeric'};
|
||||
} else {
|
||||
dateFormat = {weekday: 'long', hour: 'numeric', minute: 'numeric'};
|
||||
}
|
||||
let lastSyncDateString = date.toLocaleDateString(undefined, dateFormat);
|
||||
return this._stringBundle.formatStringFromName("lastSync2.label", [lastSyncDateString], 1);
|
||||
},
|
||||
|
||||
onClientsSynced: function() {
|
||||
let broadcaster = document.getElementById("sync-syncnow-state");
|
||||
if (broadcaster) {
|
||||
if (Weave.Service.clientsEngine.stats.numClients > 1) {
|
||||
broadcaster.setAttribute("devices-status", "multi");
|
||||
} else {
|
||||
broadcaster.setAttribute("devices-status", "single");
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
onSyncError: function SUI_onSyncError() {
|
||||
this.log.debug("onSyncError: login=${login}, sync=${sync}", Weave.Status);
|
||||
let title = this._stringBundle.GetStringFromName("error.sync.title");
|
||||
let error = Weave.Utils.getErrorString(Weave.Status.sync);
|
||||
let description =
|
||||
this._stringBundle.formatStringFromName("error.sync.description", [error], 1);
|
||||
let priority = Weave.Notifications.PRIORITY_WARNING;
|
||||
let buttons = [];
|
||||
|
||||
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; } )
|
||||
);
|
||||
// Only show the notification bar on Quota error. the panel will show the rest.
|
||||
let notification =
|
||||
new Weave.Notification(title, description, null, priority, buttons);
|
||||
Weave.Notifications.replaceTitle(notification);
|
||||
}
|
||||
|
||||
this.updateUI();
|
||||
},
|
||||
|
||||
|
||||
observe: function SUI_observe(subject, topic, data) {
|
||||
this.log.debug("observed", topic);
|
||||
if (this._unloaded) {
|
||||
Cu.reportError("SyncUI observer called after unload: " + topic);
|
||||
return;
|
||||
}
|
||||
|
||||
// Unwrap, just like Svc.Obs, but without pulling in that dependency.
|
||||
if (subject && typeof subject == "object" &&
|
||||
("wrappedJSObject" in subject) &&
|
||||
("observersModuleSubjectWrapper" in subject.wrappedJSObject)) {
|
||||
subject = subject.wrappedJSObject.object;
|
||||
}
|
||||
|
||||
// First handle "activity" only.
|
||||
switch (topic) {
|
||||
case "weave:service:sync:start":
|
||||
this.onActivityStart();
|
||||
break;
|
||||
case "weave:service:sync:finish":
|
||||
case "weave:service:sync:error":
|
||||
this.onActivityStop();
|
||||
break;
|
||||
}
|
||||
// Now non-activity state (eg, enabled, errors, etc)
|
||||
// Note that sync uses the ":ui:" notifications for errors because sync.
|
||||
switch (topic) {
|
||||
case "weave:ui:sync:finish":
|
||||
// Do nothing.
|
||||
break;
|
||||
case "weave:ui:sync:error":
|
||||
this.onSyncError();
|
||||
break;
|
||||
case "weave:service:setup-complete":
|
||||
case "weave:service:login:finish":
|
||||
case "weave:service:login:start":
|
||||
case "weave:service:start-over":
|
||||
this.updateUI();
|
||||
break;
|
||||
case "weave:service:quota:remaining":
|
||||
this.onQuotaNotice();
|
||||
break;
|
||||
case "weave:ui:login:error":
|
||||
case "weave:service:login:error":
|
||||
this.onLoginError();
|
||||
break;
|
||||
case "weave:service:logout:finish":
|
||||
this.onLogout();
|
||||
break;
|
||||
case "weave:service:start-over:finish":
|
||||
this.updateUI();
|
||||
break;
|
||||
case "weave:service:ready":
|
||||
this.initUI();
|
||||
break;
|
||||
case "weave:notification:added":
|
||||
this.initNotifications();
|
||||
break;
|
||||
case "weave:engine:sync:finish":
|
||||
if (data != "clients") {
|
||||
return;
|
||||
}
|
||||
this.onClientsSynced();
|
||||
break;
|
||||
case "quit-application":
|
||||
// Stop the animation timer on shutdown, since we can't update the UI
|
||||
// after this.
|
||||
clearTimeout(this._syncAnimationTimer);
|
||||
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");
|
||||
});
|
||||
|
||||
XPCOMUtils.defineLazyGetter(gSyncUI, "log", function() {
|
||||
return Log.repository.getLogger("browserwindow.syncui");
|
||||
});
|
||||
|
||||
XPCOMUtils.defineLazyGetter(gSyncUI, "weaveService", function() {
|
||||
return Components.classes["@mozilla.org/weave/service;1"]
|
||||
.getService(Components.interfaces.nsISupports)
|
||||
.wrappedJSObject;
|
||||
});
|
||||
|
|
@ -46,7 +46,6 @@ Cu.import("resource://gre/modules/NotificationDB.jsm");
|
|||
["Task", "resource://gre/modules/Task.jsm"],
|
||||
["UpdateUtils", "resource://gre/modules/UpdateUtils.jsm"],
|
||||
["Weave", "resource://services-sync/main.js"],
|
||||
["fxAccounts", "resource://gre/modules/FxAccounts.jsm"],
|
||||
#ifdef MOZ_DEVTOOLS
|
||||
// Note: Do not delete! It is used for: base/content/nsContextMenu.js
|
||||
["gDevTools", "resource://devtools/client/framework/gDevTools.jsm"],
|
||||
|
|
@ -1310,10 +1309,6 @@ var gBrowserInit = {
|
|||
FullScreen.init();
|
||||
PointerLock.init();
|
||||
|
||||
// initialize the sync UI
|
||||
gSyncUI.init();
|
||||
gFxAccounts.init();
|
||||
|
||||
if (AppConstants.MOZ_DATA_REPORTING)
|
||||
gDataNotificationInfoBar.init();
|
||||
|
||||
|
|
@ -1450,8 +1445,6 @@ var gBrowserInit = {
|
|||
|
||||
FullScreen.uninit();
|
||||
|
||||
gFxAccounts.uninit();
|
||||
|
||||
Services.obs.removeObserver(gPluginHandler.NPAPIPluginCrashed, "plugin-crashed");
|
||||
|
||||
try {
|
||||
|
|
@ -1611,9 +1604,6 @@ if (AppConstants.platform == "macosx") {
|
|||
|
||||
// initialize the private browsing UI
|
||||
gPrivateBrowsingUI.init();
|
||||
|
||||
// initialize the sync UI
|
||||
gSyncUI.init();
|
||||
};
|
||||
|
||||
gBrowserInit.nonBrowserWindowShutdown = function() {
|
||||
|
|
@ -7548,8 +7538,6 @@ var TabContextMenu = {
|
|||
|
||||
this.contextTab.addEventListener("TabAttrModified", this, false);
|
||||
aPopupMenu.addEventListener("popuphiding", this, false);
|
||||
|
||||
gFxAccounts.updateTabContextMenu(aPopupMenu);
|
||||
},
|
||||
handleEvent(aEvent) {
|
||||
switch (aEvent.type) {
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@
|
|||
<script type="application/javascript" src="chrome://browser/content/browser-safebrowsing.js"/>
|
||||
#endif
|
||||
<script type="application/javascript" src="chrome://browser/content/browser-sidebar.js"/>
|
||||
<script type="application/javascript" src="chrome://browser/content/browser-syncui.js"/>
|
||||
<script type="application/javascript" src="chrome://browser/content/browser-tabsintitlebar.js"/>
|
||||
<script type="application/javascript" src="chrome://browser/content/browser-thumbnails.js"/>
|
||||
<script type="application/javascript" src="chrome://browser/content/browser-trackingprotection.js"/>
|
||||
|
|
|
|||
|
|
@ -112,7 +112,6 @@ nsContextMenu.prototype = {
|
|||
this.initLeaveDOMFullScreenItems();
|
||||
this.initClickToPlayItems();
|
||||
this.initPasswordManagerItems();
|
||||
this.initSyncItems();
|
||||
},
|
||||
|
||||
initPageMenuSeparator: function CM_initPageMenuSeparator() {
|
||||
|
|
@ -522,10 +521,6 @@ nsContextMenu.prototype = {
|
|||
popup.insertBefore(fragment, insertBeforeElement);
|
||||
},
|
||||
|
||||
initSyncItems: function() {
|
||||
gFxAccounts.initPageContextMenu(this);
|
||||
},
|
||||
|
||||
openPasswordManager: function() {
|
||||
LoginHelper.openPasswordManager(window, gContextMenuContentData.documentURIObject.host);
|
||||
},
|
||||
|
|
|
|||
|
|
@ -76,7 +76,6 @@ browser.jar:
|
|||
content/browser/browser-feeds.js (content/browser-feeds.js)
|
||||
content/browser/browser-fullScreenAndPointerLock.js (content/browser-fullScreenAndPointerLock.js)
|
||||
content/browser/browser-fullZoom.js (content/browser-fullZoom.js)
|
||||
content/browser/browser-fxaccounts.js (content/browser-fxaccounts.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)
|
||||
|
|
@ -86,7 +85,6 @@ browser.jar:
|
|||
content/browser/browser-safebrowsing.js (content/browser-safebrowsing.js)
|
||||
#endif
|
||||
content/browser/browser-sidebar.js (content/browser-sidebar.js)
|
||||
* content/browser/browser-syncui.js (content/browser-syncui.js)
|
||||
* content/browser/browser-tabPreviews.xml (content/browser-tabPreviews.xml)
|
||||
#ifdef CAN_DRAW_IN_TITLEBAR
|
||||
content/browser/browser-tabsintitlebar.js (content/browser-tabsintitlebar.js)
|
||||
|
|
|
|||
|
|
@ -200,7 +200,6 @@ var CustomizableUIInternal = {
|
|||
"find-button",
|
||||
"preferences-button",
|
||||
"add-ons-button",
|
||||
"sync-button",
|
||||
];
|
||||
|
||||
if (!AppConstants.MOZ_DEV_EDITION) {
|
||||
|
|
|
|||
|
|
@ -285,144 +285,6 @@ const CustomizableWidgets = [
|
|||
onViewHiding: function(aEvent) {
|
||||
log.debug("History view is being hidden!");
|
||||
}
|
||||
}, {
|
||||
id: "sync-button",
|
||||
label: "remotetabs-panelmenu.label",
|
||||
tooltiptext: "remotetabs-panelmenu.tooltiptext2",
|
||||
type: "view",
|
||||
viewId: "PanelUI-remotetabs",
|
||||
defaultArea: CustomizableUI.AREA_PANEL,
|
||||
deckIndices: {
|
||||
DECKINDEX_TABS: 0,
|
||||
DECKINDEX_TABSDISABLED: 1,
|
||||
DECKINDEX_FETCHING: 2,
|
||||
DECKINDEX_NOCLIENTS: 3,
|
||||
},
|
||||
onCreated(aNode) {
|
||||
// Add an observer to the button so we get the animation during sync.
|
||||
// (Note the observer sets many attributes, including label and
|
||||
// tooltiptext, but we only want the 'syncstatus' attribute for the
|
||||
// animation)
|
||||
let doc = aNode.ownerDocument;
|
||||
let obnode = doc.createElementNS(kNSXUL, "observes");
|
||||
obnode.setAttribute("element", "sync-status");
|
||||
obnode.setAttribute("attribute", "syncstatus");
|
||||
aNode.appendChild(obnode);
|
||||
},
|
||||
setDeckIndex(index) {
|
||||
let deck = this._tabsList.ownerDocument.getElementById("PanelUI-remotetabs-deck");
|
||||
// We call setAttribute instead of relying on the XBL property setter due
|
||||
// to things going wrong when we try and set the index before the XBL
|
||||
// binding has been created - see bug 1241851 for the gory details.
|
||||
deck.setAttribute("selectedIndex", index);
|
||||
},
|
||||
|
||||
_showTabsPromise: Promise.resolve(),
|
||||
// Update the tab list after any existing in-flight updates are complete.
|
||||
_showTabs() {
|
||||
this._showTabsPromise = this._showTabsPromise.then(() => {
|
||||
return this.__showTabs();
|
||||
});
|
||||
},
|
||||
// Return a new promise to update the tab list.
|
||||
__showTabs() {
|
||||
let doc = this._tabsList.ownerDocument;
|
||||
return SyncedTabs.getTabClients().then(clients => {
|
||||
// The view may have been hidden while the promise was resolving.
|
||||
if (!this._tabsList) {
|
||||
return;
|
||||
}
|
||||
if (clients.length === 0 && !SyncedTabs.hasSyncedThisSession) {
|
||||
// the "fetching tabs" deck is being shown - let's leave it there.
|
||||
// When that first sync completes we'll be notified and update.
|
||||
return;
|
||||
}
|
||||
|
||||
if (clients.length === 0) {
|
||||
this.setDeckIndex(this.deckIndices.DECKINDEX_NOCLIENTS);
|
||||
return;
|
||||
}
|
||||
|
||||
this.setDeckIndex(this.deckIndices.DECKINDEX_TABS);
|
||||
this._clearTabList();
|
||||
SyncedTabs.sortTabClientsByLastUsed(clients, 50 /* maxTabs */);
|
||||
let fragment = doc.createDocumentFragment();
|
||||
|
||||
for (let client of clients) {
|
||||
// add a menu separator for all clients other than the first.
|
||||
if (fragment.lastChild) {
|
||||
let separator = doc.createElementNS(kNSXUL, "menuseparator");
|
||||
fragment.appendChild(separator);
|
||||
}
|
||||
this._appendClient(client, fragment);
|
||||
}
|
||||
this._tabsList.appendChild(fragment);
|
||||
}).catch(err => {
|
||||
Cu.reportError(err);
|
||||
}).then(() => {
|
||||
// an observer for tests.
|
||||
Services.obs.notifyObservers(null, "synced-tabs-menu:test:tabs-updated", null);
|
||||
});
|
||||
},
|
||||
_clearTabList () {
|
||||
let list = this._tabsList;
|
||||
while (list.lastChild) {
|
||||
list.lastChild.remove();
|
||||
}
|
||||
},
|
||||
_showNoClientMessage() {
|
||||
this._appendMessageLabel("notabslabel");
|
||||
},
|
||||
_appendMessageLabel(messageAttr, appendTo = null) {
|
||||
if (!appendTo) {
|
||||
appendTo = this._tabsList;
|
||||
}
|
||||
let message = this._tabsList.getAttribute(messageAttr);
|
||||
let doc = this._tabsList.ownerDocument;
|
||||
let messageLabel = doc.createElementNS(kNSXUL, "label");
|
||||
messageLabel.textContent = message;
|
||||
appendTo.appendChild(messageLabel);
|
||||
return messageLabel;
|
||||
},
|
||||
_appendClient: function (client, attachFragment) {
|
||||
let doc = attachFragment.ownerDocument;
|
||||
// Create the element for the remote client.
|
||||
let clientItem = doc.createElementNS(kNSXUL, "label");
|
||||
clientItem.setAttribute("itemtype", "client");
|
||||
let window = doc.defaultView;
|
||||
clientItem.setAttribute("tooltiptext",
|
||||
window.gSyncUI.formatLastSyncDate(new Date(client.lastModified)));
|
||||
clientItem.textContent = client.name;
|
||||
|
||||
attachFragment.appendChild(clientItem);
|
||||
|
||||
if (client.tabs.length == 0) {
|
||||
let label = this._appendMessageLabel("notabsforclientlabel", attachFragment);
|
||||
label.setAttribute("class", "PanelUI-remotetabs-notabsforclient-label");
|
||||
} else {
|
||||
for (let tab of client.tabs) {
|
||||
let tabEnt = this._createTabElement(doc, tab);
|
||||
attachFragment.appendChild(tabEnt);
|
||||
}
|
||||
}
|
||||
},
|
||||
_createTabElement(doc, tabInfo) {
|
||||
let item = doc.createElementNS(kNSXUL, "toolbarbutton");
|
||||
let tooltipText = (tabInfo.title ? tabInfo.title + "\n" : "") + tabInfo.url;
|
||||
item.setAttribute("itemtype", "tab");
|
||||
item.setAttribute("class", "subviewbutton");
|
||||
item.setAttribute("targetURI", tabInfo.url);
|
||||
item.setAttribute("label", tabInfo.title != "" ? tabInfo.title : tabInfo.url);
|
||||
item.setAttribute("image", tabInfo.icon);
|
||||
item.setAttribute("tooltiptext", tooltipText);
|
||||
// We need to use "click" instead of "command" here so openUILink
|
||||
// respects different buttons (eg, to open in a new tab).
|
||||
item.addEventListener("click", e => {
|
||||
doc.defaultView.openUILink(tabInfo.url, e);
|
||||
CustomizableUI.hidePanelForNode(item);
|
||||
});
|
||||
return item;
|
||||
},
|
||||
}, {
|
||||
id: "privatebrowsing-button",
|
||||
shortcutId: "key_privatebrowsing",
|
||||
|
|
|
|||
|
|
@ -20,27 +20,6 @@
|
|||
oncommand="gMenuButtonUpdateBadge.onMenuPanelCommand(event);"
|
||||
wrap="true"
|
||||
hidden="true"/>
|
||||
<hbox id="PanelUI-footer-fxa">
|
||||
<hbox id="PanelUI-fxa-status"
|
||||
defaultlabel="&fxaSignIn.label;"
|
||||
signedinTooltiptext="&syncSettings.label;"
|
||||
tooltiptext="&syncSettings.label;"
|
||||
errorlabel="&fxaSignInError.label;"
|
||||
unverifiedlabel="&fxaUnverified.label;"
|
||||
settingslabel="&syncSettings.label;"
|
||||
onclick="if (event.which == 1) gFxAccounts.onMenuPanelCommand();">
|
||||
<image id="PanelUI-fxa-avatar"/>
|
||||
<toolbarbutton id="PanelUI-fxa-label"
|
||||
fxabrandname="&syncBrand.fxAccount.label;"/>
|
||||
</hbox>
|
||||
<toolbarseparator/>
|
||||
<toolbarbutton id="PanelUI-fxa-icon"
|
||||
oncommand="gSyncUI.doSync();"
|
||||
closemenu="none">
|
||||
<observes element="sync-status" attribute="syncstatus"/>
|
||||
<observes element="sync-status" attribute="tooltiptext"/>
|
||||
</toolbarbutton>
|
||||
</hbox>
|
||||
|
||||
<hbox id="PanelUI-footer-inner">
|
||||
<toolbarbutton id="PanelUI-customize" label="&appMenuCustomize.label;"
|
||||
|
|
@ -103,95 +82,6 @@
|
|||
oncommand="PlacesCommandHook.showPlacesOrganizer('History'); CustomizableUI.hidePanelForNode(this);"/>
|
||||
</panelview>
|
||||
|
||||
<panelview id="PanelUI-remotetabs" flex="1" class="PanelUI-subView">
|
||||
<label value="&appMenuRemoteTabs.label;" class="panel-subview-header"/>
|
||||
<vbox class="panel-subview-body">
|
||||
<!-- this widget has 3 boxes in the body, but only 1 is ever visible -->
|
||||
<!-- When Sync is ready to sync -->
|
||||
<vbox id="PanelUI-remotetabs-main" observes="sync-syncnow-state">
|
||||
<vbox id="PanelUI-remotetabs-buttons">
|
||||
<toolbarbutton id="PanelUI-remotetabs-view-sidebar"
|
||||
class="subviewbutton"
|
||||
oncommand="BrowserOpenSyncTabs();"
|
||||
label="&appMenuRemoteTabs.sidebar.label;"/>
|
||||
<toolbarbutton id="PanelUI-remotetabs-syncnow"
|
||||
observes="sync-status"
|
||||
class="subviewbutton"
|
||||
oncommand="gSyncUI.doSync();"
|
||||
closemenu="none"/>
|
||||
<menuseparator id="PanelUI-remotetabs-separator"/>
|
||||
</vbox>
|
||||
<deck id="PanelUI-remotetabs-deck">
|
||||
<!-- Sync is ready to Sync and the "tabs" engine is enabled -->
|
||||
<vbox id="PanelUI-remotetabs-tabspane">
|
||||
<vbox id="PanelUI-remotetabs-tabslist"
|
||||
notabsforclientlabel="&appMenuRemoteTabs.notabs.label;"
|
||||
/>
|
||||
</vbox>
|
||||
<!-- Sync is ready to Sync but the "tabs" engine isn't enabled-->
|
||||
<hbox id="PanelUI-remotetabs-tabsdisabledpane" pack="center" flex="1">
|
||||
<vbox class="PanelUI-remotetabs-instruction-box">
|
||||
<hbox pack="center">
|
||||
<image class="fxaSyncIllustration" alt=""/>
|
||||
</hbox>
|
||||
<label class="PanelUI-remotetabs-instruction-label">&appMenuRemoteTabs.tabsnotsyncing.label;</label>
|
||||
<hbox pack="center">
|
||||
<toolbarbutton class="PanelUI-remotetabs-prefs-button"
|
||||
label="&appMenuRemoteTabs.openprefs.label;"
|
||||
oncommand="gSyncUI.openSetup(null, 'synced-tabs');"/>
|
||||
</hbox>
|
||||
</vbox>
|
||||
</hbox>
|
||||
<!-- Sync is ready to Sync but we are still fetching the tabs to show -->
|
||||
<vbox id="PanelUI-remotetabs-fetching">
|
||||
<!-- Show intentionally blank panel, see bug 1239845 -->
|
||||
</vbox>
|
||||
<!-- Sync has only 1 (ie, this) device connected -->
|
||||
<hbox id="PanelUI-remotetabs-nodevicespane" pack="center" flex="1">
|
||||
<vbox class="PanelUI-remotetabs-instruction-box">
|
||||
<hbox pack="center">
|
||||
<image class="fxaSyncIllustration" alt=""/>
|
||||
</hbox>
|
||||
<label class="PanelUI-remotetabs-instruction-title">&appMenuRemoteTabs.noclients.title;</label>
|
||||
<label class="PanelUI-remotetabs-instruction-label">&appMenuRemoteTabs.noclients.subtitle;</label>
|
||||
<!-- The inner HTML for PanelUI-remotetabs-mobile-promo is built at runtime -->
|
||||
<label id="PanelUI-remotetabs-mobile-promo" fxAccountsBrand="&syncBrand.fxAccount.label;"/>
|
||||
</vbox>
|
||||
</hbox>
|
||||
</deck>
|
||||
</vbox>
|
||||
<!-- a box to ensure contained boxes are centered horizonally -->
|
||||
<hbox pack="center" flex="1">
|
||||
<!-- When Sync is not configured -->
|
||||
<vbox id="PanelUI-remotetabs-setupsync"
|
||||
flex="1"
|
||||
align="center"
|
||||
class="PanelUI-remotetabs-instruction-box"
|
||||
observes="sync-setup-state">
|
||||
<image class="fxaSyncIllustration" alt=""/>
|
||||
<label class="PanelUI-remotetabs-instruction-label">&appMenuRemoteTabs.notsignedin.label;</label>
|
||||
<toolbarbutton class="PanelUI-remotetabs-prefs-button"
|
||||
label="&appMenuRemoteTabs.signin.label;"
|
||||
oncommand="gSyncUI.openSetup(null, 'synced-tabs');"/>
|
||||
</vbox>
|
||||
<!-- When Sync needs re-authentication. This uses the exact same messaging
|
||||
as "Sync is not configured" but remains a separate box so we get
|
||||
the goodness of observing broadcasters to manage the hidden states -->
|
||||
<vbox id="PanelUI-remotetabs-reauthsync"
|
||||
flex="1"
|
||||
align="center"
|
||||
class="PanelUI-remotetabs-instruction-box"
|
||||
observes="sync-reauth-state">
|
||||
<image class="fxaSyncIllustration" alt=""/>
|
||||
<label class="PanelUI-remotetabs-instruction-label">&appMenuRemoteTabs.notsignedin.label;</label>
|
||||
<toolbarbutton class="PanelUI-remotetabs-prefs-button"
|
||||
label="&appMenuRemoteTabs.signin.label;"
|
||||
oncommand="gSyncUI.openSetup(null, 'synced-tabs');"/>
|
||||
</vbox>
|
||||
</hbox>
|
||||
</vbox>
|
||||
</panelview>
|
||||
|
||||
<panelview id="PanelUI-bookmarks" flex="1" class="PanelUI-subView">
|
||||
<label value="&bookmarksMenu.label;" class="panel-subview-header"/>
|
||||
<vbox class="panel-subview-body">
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ DIRS += [
|
|||
]
|
||||
|
||||
EXTRA_JS_MODULES += [
|
||||
'CustomizableUI.jsm',
|
||||
'CustomizableWidgets.jsm',
|
||||
'CustomizeMode.jsm',
|
||||
'DragPositionManager.jsm',
|
||||
|
|
@ -17,5 +16,9 @@ EXTRA_JS_MODULES += [
|
|||
'ScrollbarSampler.jsm',
|
||||
]
|
||||
|
||||
EXTRA_PP_JS_MODULES += [
|
||||
'CustomizableUI.jsm',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('windows', 'cocoa'):
|
||||
DEFINES['CAN_DRAW_IN_TITLEBAR'] = 1
|
||||
|
|
|
|||
|
|
@ -1418,9 +1418,9 @@ this.PlacesUIUtils = {
|
|||
},
|
||||
|
||||
shouldShowTabsFromOtherComputersMenuitem: function() {
|
||||
let weaveOK = Weave.Status.checkSetup() != Weave.CLIENT_NOT_CONFIGURED &&
|
||||
Weave.Svc.Prefs.get("firstSync", "") != "notReady";
|
||||
return weaveOK;
|
||||
#ifdef MOZ_SERVICES_SYNC
|
||||
// Weave code to enable menu item
|
||||
#endif
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -6,6 +6,6 @@
|
|||
|
||||
JAR_MANIFESTS += ['jar.mn']
|
||||
|
||||
EXTRA_JS_MODULES += [
|
||||
EXTRA_PP_JS_MODULES += [
|
||||
'PlacesUIUtils.jsm',
|
||||
]
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
browser.jar:
|
||||
content/browser/preferences/in-content/preferences.js
|
||||
* content/browser/preferences/in-content/preferences.js
|
||||
* content/browser/preferences/in-content/preferences.xul
|
||||
content/browser/preferences/in-content/subdialogs.js
|
||||
|
||||
|
|
@ -12,6 +12,8 @@ browser.jar:
|
|||
content/browser/preferences/in-content/advanced.js
|
||||
content/browser/preferences/in-content/applications.js
|
||||
* content/browser/preferences/in-content/content.js
|
||||
#ifdef MOZ_SERVICES_SYNC
|
||||
content/browser/preferences/in-content/sync.js
|
||||
#endif
|
||||
* content/browser/preferences/in-content/security.js
|
||||
content/browser/preferences/in-content/search.js
|
||||
|
|
|
|||
|
|
@ -64,7 +64,9 @@ function init_all() {
|
|||
register_module("paneAdvanced", gAdvancedPane);
|
||||
register_module("paneApplications", gApplicationsPane);
|
||||
register_module("paneContent", gContentPane);
|
||||
#ifdef MOZ_SERVICES_SYNC
|
||||
register_module("paneSync", gSyncPane);
|
||||
#endif
|
||||
register_module("paneSecurity", gSecurityPane);
|
||||
|
||||
let categories = document.getElementById("categories");
|
||||
|
|
|
|||
|
|
@ -22,8 +22,10 @@
|
|||
<!ENTITY % privacyDTD SYSTEM "chrome://browser/locale/preferences/privacy.dtd">
|
||||
<!ENTITY % tabsDTD SYSTEM "chrome://browser/locale/preferences/tabs.dtd">
|
||||
<!ENTITY % searchDTD SYSTEM "chrome://browser/locale/preferences/search.dtd">
|
||||
#ifdef MOZ_SERVICES_SYNC
|
||||
<!ENTITY % syncBrandDTD SYSTEM "chrome://browser/locale/syncBrand.dtd">
|
||||
<!ENTITY % syncDTD SYSTEM "chrome://browser/locale/preferences/sync.dtd">
|
||||
#endif
|
||||
<!ENTITY % securityDTD SYSTEM
|
||||
"chrome://browser/locale/preferences/security.dtd">
|
||||
<!ENTITY % sanitizeDTD SYSTEM "chrome://browser/locale/sanitize.dtd">
|
||||
|
|
@ -40,8 +42,10 @@
|
|||
%privacyDTD;
|
||||
%tabsDTD;
|
||||
%searchDTD;
|
||||
#ifdef MOZ_SERVICES_SYNC
|
||||
%syncBrandDTD;
|
||||
%syncDTD;
|
||||
#endif
|
||||
%securityDTD;
|
||||
%sanitizeDTD;
|
||||
%mainDTD;
|
||||
|
|
@ -140,6 +144,7 @@
|
|||
<label class="category-name" flex="1">&paneSecurity.title;</label>
|
||||
</richlistitem>
|
||||
|
||||
#ifdef MOZ_SERVICES_SYNC
|
||||
<richlistitem id="category-sync"
|
||||
class="category"
|
||||
value="paneSync"
|
||||
|
|
@ -149,6 +154,7 @@
|
|||
<image class="category-icon"/>
|
||||
<label class="category-name" flex="1">&paneSync.title;</label>
|
||||
</richlistitem>
|
||||
#endif
|
||||
|
||||
<richlistitem id="category-advanced"
|
||||
class="category"
|
||||
|
|
@ -177,7 +183,9 @@
|
|||
#include applications.xul
|
||||
#include content.xul
|
||||
#include security.xul
|
||||
#ifdef MOZ_SERVICES_SYNC
|
||||
#include sync.xul
|
||||
#endif
|
||||
</prefpane>
|
||||
</vbox>
|
||||
|
||||
|
|
|
|||
|
|
@ -61,8 +61,7 @@
|
|||
height: 13px;
|
||||
}
|
||||
|
||||
#PanelUI-menu-button[badge-status="download-warning"] > .toolbarbutton-badge-stack > .toolbarbutton-badge,
|
||||
#PanelUI-menu-button[badge-status="fxa-needs-authentication"] > .toolbarbutton-badge-stack > .toolbarbutton-badge {
|
||||
#PanelUI-menu-button[badge-status="download-warning"] > .toolbarbutton-badge-stack > .toolbarbutton-badge {
|
||||
box-shadow: none;
|
||||
filter: drop-shadow(0 1px 0 hsla(206, 50%, 10%, .15));
|
||||
}
|
||||
|
|
@ -86,13 +85,7 @@
|
|||
background: #D90000;
|
||||
}
|
||||
|
||||
#PanelUI-menu-button[badge-status="fxa-needs-authentication"] > .toolbarbutton-badge-stack > .toolbarbutton-badge {
|
||||
height: 13px;
|
||||
background: transparent url(chrome://browser/skin/warning.svg) no-repeat center;
|
||||
}
|
||||
|
||||
#PanelUI-menu-button[badge-status="download-warning"] > .toolbarbutton-badge-stack > .toolbarbutton-badge:-moz-window-inactive,
|
||||
#PanelUI-menu-button[badge-status="fxa-needs-authentication"] > .toolbarbutton-badge-stack > .toolbarbutton-badge:-moz-window-inactive {
|
||||
#PanelUI-menu-button[badge-status="download-warning"] > .toolbarbutton-badge-stack > .toolbarbutton-badge:-moz-window-inactive {
|
||||
filter: none;
|
||||
}
|
||||
|
||||
|
|
@ -381,9 +374,6 @@ toolbaritem[cui-areatype="menu-panel"][sdkstylewidget="true"] > iframe {
|
|||
#PanelUI-multiView[viewtype="subview"] #PanelUI-mainView > #PanelUI-contents-scroller > #PanelUI-contents > .panel-wide-item,
|
||||
#PanelUI-multiView[viewtype="subview"] #PanelUI-mainView > #PanelUI-contents-scroller > #PanelUI-contents > .toolbarbutton-1:not([panel-multiview-anchor="true"]),
|
||||
#PanelUI-multiView[viewtype="subview"] #PanelUI-mainView > #PanelUI-footer > #PanelUI-update-status,
|
||||
#PanelUI-multiView[viewtype="subview"] #PanelUI-mainView > #PanelUI-footer > #PanelUI-footer-fxa > #PanelUI-fxa-status > #PanelUI-fxa-avatar,
|
||||
#PanelUI-multiView[viewtype="subview"] #PanelUI-mainView > #PanelUI-footer > #PanelUI-footer-fxa > #PanelUI-fxa-status > #PanelUI-fxa-label,
|
||||
#PanelUI-multiView[viewtype="subview"] #PanelUI-mainView > #PanelUI-footer > #PanelUI-footer-fxa > #PanelUI-fxa-icon,
|
||||
#PanelUI-multiView[viewtype="subview"] #PanelUI-mainView > #PanelUI-footer > #PanelUI-footer-inner > toolbarseparator,
|
||||
#PanelUI-multiView[viewtype="subview"] #PanelUI-mainView > #PanelUI-footer > #PanelUI-footer-inner > #PanelUI-customize,
|
||||
#PanelUI-multiView[viewtype="subview"] #PanelUI-mainView > #PanelUI-footer > #PanelUI-footer-inner > #PanelUI-help:not([panel-multiview-anchor="true"]) {
|
||||
|
|
@ -481,26 +471,6 @@ toolbarpaletteitem[place="palette"] > toolbaritem > toolbarbutton {
|
|||
margin: 0;
|
||||
}
|
||||
|
||||
#main-window[customizing] #PanelUI-footer-fxa {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#PanelUI-footer-fxa:not([fxastatus="signedin"]) > toolbarseparator,
|
||||
#PanelUI-footer-fxa:not([fxastatus="signedin"]) > #PanelUI-fxa-icon,
|
||||
#PanelUI-footer-fxa:not([fxaprofileimage]) > #PanelUI-fxa-status > #PanelUI-fxa-avatar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#PanelUI-footer-fxa[fxastatus="error"] > #PanelUI-fxa-status::after {
|
||||
content: url(chrome://browser/skin/warning.svg);
|
||||
filter: drop-shadow(0 1px 0 hsla(206,50%,10%,.15));
|
||||
width: 47px;
|
||||
padding-top: 1px;
|
||||
display: block;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
top: 25%;
|
||||
}
|
||||
|
||||
#PanelUI-update-status[update-status]::after {
|
||||
content: "";
|
||||
|
|
@ -523,40 +493,28 @@ toolbarpaletteitem[place="palette"] > toolbaritem > toolbarbutton {
|
|||
background-color: #D90000;
|
||||
}
|
||||
|
||||
#PanelUI-fxa-status {
|
||||
display: flex;
|
||||
flex: 1 1 0%;
|
||||
width: 1px;
|
||||
}
|
||||
|
||||
#PanelUI-footer-inner,
|
||||
#PanelUI-footer-fxa:not([hidden]) {
|
||||
#PanelUI-footer-inner {
|
||||
display: flex;
|
||||
border-top: 1px solid var(--panel-separator-color);
|
||||
}
|
||||
|
||||
#PanelUI-multiView[viewtype="subview"] #PanelUI-footer-inner,
|
||||
#PanelUI-multiView[viewtype="subview"] #PanelUI-footer-fxa {
|
||||
#PanelUI-multiView[viewtype="subview"] #PanelUI-footer-inner {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#PanelUI-footer-inner > toolbarseparator,
|
||||
#PanelUI-footer-fxa > toolbarseparator {
|
||||
#PanelUI-footer-inner > toolbarseparator {
|
||||
border: 0;
|
||||
border-left: 1px solid var(--panel-separator-color);
|
||||
margin: 7px 0 7px;
|
||||
-moz-appearance: none;
|
||||
}
|
||||
|
||||
#PanelUI-footer-inner:hover > toolbarseparator,
|
||||
#PanelUI-footer-fxa:hover > toolbarseparator {
|
||||
#PanelUI-footer-inner:hover > toolbarseparator {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#PanelUI-update-status,
|
||||
#PanelUI-help,
|
||||
#PanelUI-fxa-label,
|
||||
#PanelUI-fxa-icon,
|
||||
#PanelUI-customize,
|
||||
#PanelUI-quit {
|
||||
margin: 0;
|
||||
|
|
@ -590,7 +548,6 @@ toolbarpaletteitem[place="palette"] > toolbaritem > toolbarbutton {
|
|||
}
|
||||
|
||||
#PanelUI-update-status > .toolbarbutton-text,
|
||||
#PanelUI-fxa-label > .toolbarbutton-text,
|
||||
#PanelUI-customize > .toolbarbutton-text {
|
||||
margin: 0;
|
||||
padding: 0 6px;
|
||||
|
|
@ -598,37 +555,23 @@ toolbarpaletteitem[place="palette"] > toolbaritem > toolbarbutton {
|
|||
}
|
||||
|
||||
#PanelUI-help > .toolbarbutton-text,
|
||||
#PanelUI-quit > .toolbarbutton-text,
|
||||
#PanelUI-fxa-avatar > .toolbarbutton-text {
|
||||
#PanelUI-quit > .toolbarbutton-text {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#PanelUI-update-status > .toolbarbutton-icon,
|
||||
#PanelUI-fxa-label > .toolbarbutton-icon,
|
||||
#PanelUI-fxa-icon > .toolbarbutton-icon,
|
||||
#PanelUI-customize > .toolbarbutton-icon,
|
||||
#PanelUI-help > .toolbarbutton-icon,
|
||||
#PanelUI-quit > .toolbarbutton-icon {
|
||||
margin-inline-end: 0;
|
||||
}
|
||||
|
||||
#PanelUI-fxa-icon {
|
||||
padding-inline-start: 15px;
|
||||
padding-inline-end: 15px;
|
||||
}
|
||||
|
||||
#PanelUI-fxa-label,
|
||||
#PanelUI-customize {
|
||||
flex: 1;
|
||||
padding-inline-start: 15px;
|
||||
border-inline-start-style: none;
|
||||
}
|
||||
|
||||
#PanelUI-footer-fxa[fxaprofileimage="set"] > #PanelUI-fxa-status > #PanelUI-fxa-label,
|
||||
#PanelUI-footer-fxa[fxaprofileimage="enabled"]:not([fxastatus="error"]) > #PanelUI-fxa-status > #PanelUI-fxa-label {
|
||||
padding-inline-start: 0px;
|
||||
}
|
||||
|
||||
#PanelUI-update-status {
|
||||
width: calc(@menuPanelWidth@ + 30px);
|
||||
padding-inline-start: 15px;
|
||||
|
|
@ -639,130 +582,6 @@ toolbarpaletteitem[place="palette"] > toolbaritem > toolbarbutton {
|
|||
list-style-image: url(chrome://branding/content/icon16.png);
|
||||
}
|
||||
|
||||
#PanelUI-fxa-label,
|
||||
#PanelUI-fxa-icon {
|
||||
list-style-image: url(chrome://browser/skin/sync-horizontalbar.png);
|
||||
}
|
||||
|
||||
#PanelUI-remotetabs {
|
||||
--panel-ui-sync-illustration-height: 157.5px;
|
||||
}
|
||||
|
||||
.PanelUI-remotetabs-instruction-title,
|
||||
.PanelUI-remotetabs-instruction-label,
|
||||
#PanelUI-remotetabs-mobile-promo {
|
||||
/* If you change the margin here, the min-height of the synced tabs panel
|
||||
(e.g. #PanelUI-remotetabs[mainview] #PanelUI-remotetabs-setupsync, etc) may
|
||||
need adjusting (see bug 1248506) */
|
||||
margin: 15px;
|
||||
text-align: center;
|
||||
text-shadow: none;
|
||||
max-width: 15em;
|
||||
color: GrayText;
|
||||
}
|
||||
|
||||
.PanelUI-remotetabs-instruction-title {
|
||||
font-size: 1.3em;
|
||||
}
|
||||
|
||||
/* The boxes with "instructions" get extra top and bottom padding for space
|
||||
around the illustration and buttons */
|
||||
.PanelUI-remotetabs-instruction-box {
|
||||
/* If you change the padding here, the min-height of the synced tabs panel
|
||||
(e.g. #PanelUI-remotetabs[mainview] #PanelUI-remotetabs-setupsync, etc) may
|
||||
need adjusting (see bug 1248506) */
|
||||
padding-bottom: 30px;
|
||||
padding-top: 15px;
|
||||
}
|
||||
|
||||
.PanelUI-remotetabs-prefs-button {
|
||||
-moz-appearance: none;
|
||||
background-color: #0096dd;
|
||||
/* !important for the color as an OSX specific rule when a lightweight theme
|
||||
is used for buttons in the toolbox overrides. See bug 1238531 for details */
|
||||
color: white !important;
|
||||
border-radius: 2px;
|
||||
/* If you change the margin or padding below, the min-height of the synced tabs
|
||||
panel (e.g. #PanelUI-remotetabs[mainview] #PanelUI-remotetabs-setupsync,
|
||||
etc) may need adjusting (see bug 1248506) */
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
padding: 8px;
|
||||
text-shadow: none;
|
||||
min-width: 200px;
|
||||
}
|
||||
|
||||
.PanelUI-remotetabs-prefs-button:hover,
|
||||
.PanelUI-remotetabs-prefs-button:hover:active {
|
||||
background-color: #018acb;
|
||||
}
|
||||
|
||||
.remotetabs-promo-link {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.PanelUI-remotetabs-notabsforclient-label {
|
||||
color: GrayText;
|
||||
/* This margin is to line this label up with the labels in toolbarbuttons. */
|
||||
margin-left: 28px;
|
||||
}
|
||||
|
||||
.fxaSyncIllustration {
|
||||
height: var(--panel-ui-sync-illustration-height);
|
||||
list-style-image: url(chrome://browser/skin/fxa/sync-illustration.svg);
|
||||
}
|
||||
|
||||
.PanelUI-remotetabs-prefs-button > .toolbarbutton-text {
|
||||
/* !important to override ".cui-widget-panel toolbarbutton > .toolbarbutton-text" above. */
|
||||
text-align: center !important;
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
#PanelUI-remotetabs[mainview] { /* panel anchored to toolbar button might be too skinny */
|
||||
min-width: 19em;
|
||||
}
|
||||
|
||||
/* Work around bug 1224412 - these boxes will cause scrollbars to appear when
|
||||
the panel is anchored to a toolbar button.
|
||||
*/
|
||||
#PanelUI-remotetabs[mainview] #PanelUI-remotetabs-setupsync,
|
||||
#PanelUI-remotetabs[mainview] #PanelUI-remotetabs-reauthsync,
|
||||
#PanelUI-remotetabs[mainview] #PanelUI-remotetabs-nodevicespane,
|
||||
#PanelUI-remotetabs[mainview] #PanelUI-remotetabs-tabsdisabledpane {
|
||||
min-height: calc(var(--panel-ui-sync-illustration-height) +
|
||||
20px + /* margin of .PanelUI-remotetabs-prefs-button */
|
||||
16px + /* padding of .PanelUI-remotetabs-prefs-button */
|
||||
30px + /* margin of .PanelUI-remotetabs-instruction-label */
|
||||
30px + 15px + /* padding of .PanelUI-remotetabs-instruction-box */
|
||||
11em);
|
||||
}
|
||||
|
||||
#PanelUI-remotetabs-tabslist > label[itemtype="client"] {
|
||||
color: GrayText;
|
||||
}
|
||||
|
||||
/* Collapse the non-active vboxes in the remotetabs deck to use only the
|
||||
height the active box needs */
|
||||
#PanelUI-remotetabs-deck:not([selectedIndex="1"]) > #PanelUI-remotetabs-tabsdisabledpane,
|
||||
#PanelUI-remotetabs-deck:not([selectedIndex="2"]) > #PanelUI-remotetabs-fetching,
|
||||
#PanelUI-remotetabs-deck:not([selectedIndex="3"]) > #PanelUI-remotetabs-nodevicespane {
|
||||
visibility: collapse;
|
||||
}
|
||||
|
||||
#PanelUI-remotetabs-main[devices-status="single"] > #PanelUI-remotetabs-buttons {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#PanelUI-fxa-icon[syncstatus="active"]:not([disabled]) {
|
||||
list-style-image: url(chrome://browser/skin/syncProgress-horizontalbar.png);
|
||||
}
|
||||
|
||||
#PanelUI-footer-fxa[fxastatus="migrate-signup"] > #PanelUI-fxa-status > #PanelUI-fxa-label,
|
||||
#PanelUI-footer-fxa[fxastatus="migrate-verify"] > #PanelUI-fxa-status > #PanelUI-fxa-label {
|
||||
list-style-image: url(chrome://browser/skin/warning.svg);
|
||||
-moz-image-region: auto;
|
||||
}
|
||||
|
||||
#PanelUI-customize {
|
||||
list-style-image: url(chrome://browser/skin/menuPanel-customize.png);
|
||||
}
|
||||
|
|
@ -780,46 +599,12 @@ toolbarpaletteitem[place="palette"] > toolbaritem > toolbarbutton {
|
|||
list-style-image: url(chrome://browser/skin/menuPanel-exit.png);
|
||||
}
|
||||
|
||||
#PanelUI-fxa-label,
|
||||
#PanelUI-fxa-icon,
|
||||
#PanelUI-customize,
|
||||
#PanelUI-help,
|
||||
#PanelUI-quit {
|
||||
-moz-image-region: rect(0, 16px, 16px, 0);
|
||||
}
|
||||
|
||||
#PanelUI-footer-fxa[fxastatus="signedin"] > #PanelUI-fxa-status > #PanelUI-fxa-label > .toolbarbutton-icon,
|
||||
#PanelUI-footer-fxa[fxastatus="error"][fxaprofileimage="set"] > #PanelUI-fxa-status > #PanelUI-fxa-label > .toolbarbutton-icon {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#PanelUI-footer-fxa[fxastatus="error"]:not([fxaprofileimage="set"]) > #PanelUI-fxa-status > #PanelUI-fxa-avatar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#PanelUI-fxa-status[disabled],
|
||||
#PanelUI-fxa-icon[disabled] {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
#PanelUI-fxa-avatar {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 50%;
|
||||
background-repeat: no-repeat;
|
||||
background-position: 0 0;
|
||||
background-size: contain;
|
||||
align-self: center;
|
||||
margin: 0px 7px;
|
||||
padding: 0px;
|
||||
border: 0px none;
|
||||
margin-inline-end: 0;
|
||||
}
|
||||
|
||||
#PanelUI-footer-fxa[fxaprofileimage="enabled"] > #PanelUI-fxa-status > #PanelUI-fxa-avatar {
|
||||
list-style-image: url(chrome://browser/skin/fxa/default-avatar.svg);
|
||||
}
|
||||
|
||||
#PanelUI-customize:hover,
|
||||
#PanelUI-help:not([disabled]):hover,
|
||||
#PanelUI-quit:not([disabled]):hover {
|
||||
|
|
@ -837,16 +622,10 @@ toolbarpaletteitem[place="palette"] > toolbaritem > toolbarbutton {
|
|||
}
|
||||
|
||||
#PanelUI-help[disabled],
|
||||
#PanelUI-quit[disabled],
|
||||
#PanelUI-fxa-icon[disabled],
|
||||
#PanelUI-fxa-avatar[disabled],
|
||||
#PanelUI-fxa-label[disabled] > .toolbarbutton-icon,
|
||||
#PanelUI-fxa-status::after {
|
||||
#PanelUI-quit[disabled] {
|
||||
opacity: 0.4;
|
||||
}
|
||||
|
||||
#PanelUI-fxa-status:not([disabled]):hover,
|
||||
#PanelUI-fxa-icon:not([disabled]):hover,
|
||||
#PanelUI-help:not([disabled]):hover,
|
||||
#PanelUI-customize:hover,
|
||||
#PanelUI-quit:not([disabled]):hover {
|
||||
|
|
@ -854,8 +633,6 @@ toolbarpaletteitem[place="palette"] > toolbaritem > toolbarbutton {
|
|||
background-color: var(--arrowpanel-dimmed);
|
||||
}
|
||||
|
||||
#PanelUI-fxa-status:not([disabled]):hover:active,
|
||||
#PanelUI-fxa-icon:not([disabled]):hover:active,
|
||||
#PanelUI-help:not([disabled]):hover:active,
|
||||
#PanelUI-customize:hover:active,
|
||||
#PanelUI-quit:not([disabled]):hover:active {
|
||||
|
|
@ -864,27 +641,6 @@ toolbarpaletteitem[place="palette"] > toolbaritem > toolbarbutton {
|
|||
box-shadow: 0 1px 0 hsla(210,4%,10%,.05) inset;
|
||||
}
|
||||
|
||||
#PanelUI-fxa-status:not([disabled]):hover,
|
||||
#PanelUI-fxa-status:not([disabled]):hover:active,
|
||||
#PanelUI-fxa-icon:not([disabled]):hover,
|
||||
#PanelUI-fxa-icon:not([disabled]):hover:active {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
#PanelUI-footer-fxa[fxastatus="error"] {
|
||||
background-color: hsl(42,94%,88%);
|
||||
border-top: 1px solid hsl(42,94%,70%);
|
||||
}
|
||||
|
||||
#PanelUI-footer-fxa[fxastatus="error"] > #PanelUI-fxa-status:hover {
|
||||
background-color: hsl(42,94%,85%);
|
||||
}
|
||||
|
||||
#PanelUI-footer-fxa[fxastatus="error"] > #PanelUI-fxa-status:hover:active {
|
||||
background-color: hsl(42,94%,82%);
|
||||
box-shadow: 0 1px 0 hsla(210,4%,10%,.05) inset;
|
||||
}
|
||||
|
||||
#PanelUI-update-status {
|
||||
color: black;
|
||||
}
|
||||
|
|
@ -1150,19 +906,16 @@ menuitem.panel-subview-footer@menuStateActive@,
|
|||
color: GrayText;
|
||||
}
|
||||
|
||||
#PanelUI-remotetabs-tabslist > toolbarbutton,
|
||||
#PanelUI-historyItems > toolbarbutton {
|
||||
list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.png");
|
||||
}
|
||||
|
||||
@media (min-resolution: 1.1dppx) {
|
||||
#PanelUI-remotetabs-tabslist > toolbarbutton,
|
||||
#PanelUI-historyItems > toolbarbutton {
|
||||
list-style-image: url("chrome://mozapps/skin/places/defaultFavicon@2x.png");
|
||||
}
|
||||
}
|
||||
|
||||
#PanelUI-remotetabs-tabslist > toolbarbutton > .toolbarbutton-icon,
|
||||
#PanelUI-recentlyClosedWindows > toolbarbutton > .toolbarbutton-icon,
|
||||
#PanelUI-recentlyClosedTabs > toolbarbutton > .toolbarbutton-icon,
|
||||
#PanelUI-historyItems > toolbarbutton > .toolbarbutton-icon {
|
||||
|
|
@ -1616,15 +1369,6 @@ menuitem[checked="true"].subviewbutton > .menu-iconic-left {
|
|||
list-style-image: url(chrome://branding/content/icon32.png);
|
||||
}
|
||||
|
||||
#PanelUI-fxa-label,
|
||||
#PanelUI-fxa-icon {
|
||||
list-style-image: url(chrome://browser/skin/sync-horizontalbar@2x.png);
|
||||
}
|
||||
|
||||
#PanelUI-fxa-icon[syncstatus="active"]:not([disabled]) {
|
||||
list-style-image: url(chrome://browser/skin/syncProgress-horizontalbar@2x.png);
|
||||
}
|
||||
|
||||
#PanelUI-customize {
|
||||
list-style-image: url(chrome://browser/skin/menuPanel-customize@2x.png);
|
||||
}
|
||||
|
|
@ -1641,8 +1385,6 @@ menuitem[checked="true"].subviewbutton > .menu-iconic-left {
|
|||
list-style-image: url(chrome://browser/skin/menuPanel-exit@2x.png);
|
||||
}
|
||||
|
||||
#PanelUI-fxa-label,
|
||||
#PanelUI-fxa-icon,
|
||||
#PanelUI-customize,
|
||||
#PanelUI-help,
|
||||
#PanelUI-quit {
|
||||
|
|
@ -1650,8 +1392,6 @@ menuitem[checked="true"].subviewbutton > .menu-iconic-left {
|
|||
}
|
||||
|
||||
#PanelUI-update-status > .toolbarbutton-icon,
|
||||
#PanelUI-fxa-label > .toolbarbutton-icon,
|
||||
#PanelUI-fxa-icon > .toolbarbutton-icon,
|
||||
#PanelUI-customize > .toolbarbutton-icon,
|
||||
#PanelUI-help > .toolbarbutton-icon,
|
||||
#PanelUI-quit > .toolbarbutton-icon {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue