Backed out changeset 22901b9f9199 (bug 1434706) for browser-chrome failures browser_contextmenu_sendtab.js. CLOSED TREE

This commit is contained in:
Csoregi Natalia 2018-02-26 21:16:01 +02:00
Родитель c5b3bb6ce0
Коммит c8a2d994c8
18 изменённых файлов: 312 добавлений и 397 удалений

Просмотреть файл

@ -1416,10 +1416,6 @@ pref("browser.uiCustomization.debug", false);
// CustomizableUI state of the browser's user interface // CustomizableUI state of the browser's user interface
pref("browser.uiCustomization.state", ""); pref("browser.uiCustomization.state", "");
// If set to false, FxAccounts and Sync will be unavailable.
// A restart is mandatory after flipping that preference.
pref("identity.fxaccounts.enabled", true);
// The remote FxA root content URL. Must use HTTPS. // The remote FxA root content URL. Must use HTTPS.
pref("identity.fxaccounts.remote.root", "https://accounts.firefox.com/"); pref("identity.fxaccounts.remote.root", "https://accounts.firefox.com/");

Просмотреть файл

@ -263,13 +263,11 @@
label="&savePageCmd.label;" label="&savePageCmd.label;"
accesskey="&savePageCmd.accesskey2;" accesskey="&savePageCmd.accesskey2;"
oncommand="gContextMenu.savePageAs();"/> oncommand="gContextMenu.savePageAs();"/>
<menuseparator id="context-sep-sendpagetodevice" class="sync-ui-item" <menuseparator id="context-sep-sendpagetodevice" hidden="true"/>
hidden="true"/>
<menu id="context-sendpagetodevice" <menu id="context-sendpagetodevice"
class="sync-ui-item" label="&sendPageToDevice.label;"
label="&sendPageToDevice.label;" accesskey="&sendPageToDevice.accesskey;"
accesskey="&sendPageToDevice.accesskey;" hidden="true">
hidden="true">
<menupopup id="context-sendpagetodevice-popup" <menupopup id="context-sendpagetodevice-popup"
onpopupshowing="(() => { let browser = gBrowser || getPanelBrowser(); gSync.populateSendTabToDevicesMenu(event.target, browser.currentURI.spec, browser.contentTitle); })()"/> onpopupshowing="(() => { let browser = gBrowser || getPanelBrowser(); gSync.populateSendTabToDevicesMenu(event.target, browser.currentURI.spec, browser.contentTitle); })()"/>
</menu> </menu>
@ -312,13 +310,11 @@
oncommand="AddKeywordForSearchField();"/> oncommand="AddKeywordForSearchField();"/>
<menuitem id="context-searchselect" <menuitem id="context-searchselect"
oncommand="BrowserSearch.loadSearchFromContext(this.searchTerms);"/> oncommand="BrowserSearch.loadSearchFromContext(this.searchTerms);"/>
<menuseparator id="context-sep-sendlinktodevice" class="sync-ui-item" <menuseparator id="context-sep-sendlinktodevice" hidden="true"/>
hidden="true"/>
<menu id="context-sendlinktodevice" <menu id="context-sendlinktodevice"
class="sync-ui-item" label="&sendLinkToDevice.label;"
label="&sendLinkToDevice.label;" accesskey="&sendLinkToDevice.accesskey;"
accesskey="&sendLinkToDevice.accesskey;" hidden="true">
hidden="true">
<menupopup id="context-sendlinktodevice-popup" <menupopup id="context-sendlinktodevice-popup"
onpopupshowing="gSync.populateSendTabToDevicesMenu(event.target, gContextMenu.linkURL, gContextMenu.linkTextStr);"/> onpopupshowing="gSync.populateSendTabToDevicesMenu(event.target, gContextMenu.linkURL, gContextMenu.linkTextStr);"/>
</menu> </menu>

Просмотреть файл

@ -486,25 +486,21 @@
<!-- only one of sync-setup, sync-unverifieditem, sync-syncnowitem or sync-reauthitem will be showing at once --> <!-- only one of sync-setup, sync-unverifieditem, sync-syncnowitem or sync-reauthitem will be showing at once -->
<menuitem id="sync-setup" <menuitem id="sync-setup"
class="sync-ui-item"
label="&syncSignIn.label;" label="&syncSignIn.label;"
accesskey="&syncSignIn.accesskey;" accesskey="&syncSignIn.accesskey;"
observes="sync-setup-state" observes="sync-setup-state"
oncommand="gSync.openPrefs('menubar')"/> oncommand="gSync.openPrefs('menubar')"/>
<menuitem id="sync-unverifieditem" <menuitem id="sync-unverifieditem"
class="sync-ui-item"
label="&syncSignIn.label;" label="&syncSignIn.label;"
accesskey="&syncSignIn.accesskey;" accesskey="&syncSignIn.accesskey;"
observes="sync-unverified-state" observes="sync-unverified-state"
oncommand="gSync.openPrefs('menubar')"/> oncommand="gSync.openPrefs('menubar')"/>
<menuitem id="sync-syncnowitem" <menuitem id="sync-syncnowitem"
class="sync-ui-item"
label="&syncSyncNowItem.label;" label="&syncSyncNowItem.label;"
accesskey="&syncSyncNowItem.accesskey;" accesskey="&syncSyncNowItem.accesskey;"
observes="sync-syncnow-state" observes="sync-syncnow-state"
oncommand="gSync.doSync(event);"/> oncommand="gSync.doSync(event);"/>
<menuitem id="sync-reauthitem" <menuitem id="sync-reauthitem"
class="sync-ui-item"
label="&syncReAuthItem.label;" label="&syncReAuthItem.label;"
accesskey="&syncReAuthItem.accesskey;" accesskey="&syncReAuthItem.accesskey;"
observes="sync-reauth-state" observes="sync-reauth-state"

Просмотреть файл

@ -95,8 +95,6 @@ var gSync = {
}); });
XPCOMUtils.defineLazyPreferenceGetter(this, "PRODUCT_INFO_BASE_URL", XPCOMUtils.defineLazyPreferenceGetter(this, "PRODUCT_INFO_BASE_URL",
"app.productInfo.baseURL"); "app.productInfo.baseURL");
XPCOMUtils.defineLazyPreferenceGetter(this, "SYNC_ENABLED",
"identity.fxaccounts.enabled");
}, },
_maybeUpdateUIState() { _maybeUpdateUIState() {
@ -116,13 +114,6 @@ var gSync = {
return; return;
} }
this._definePrefGetters();
if (!this.SYNC_ENABLED) {
this.onSyncDisabled();
return;
}
// initial label for the sync buttons. // initial label for the sync buttons.
let statusBroadcaster = document.getElementById("sync-status"); let statusBroadcaster = document.getElementById("sync-status");
if (!statusBroadcaster) { if (!statusBroadcaster) {
@ -141,6 +132,7 @@ var gSync = {
} }
this._generateNodeGetters(); this._generateNodeGetters();
this._definePrefGetters();
this._maybeUpdateUIState(); this._maybeUpdateUIState();
@ -478,10 +470,6 @@ var gSync = {
// "Send Tab to Device" menu item // "Send Tab to Device" menu item
updateTabContextMenu(aPopupMenu, aTargetTab) { updateTabContextMenu(aPopupMenu, aTargetTab) {
if (!this.SYNC_ENABLED) {
// These items are hidden in onSyncDisabled(). No need to do anything.
return;
}
const enabled = !this.syncConfiguredAndLoading && const enabled = !this.syncConfiguredAndLoading &&
this.isSendableURI(aTargetTab.linkedBrowser.currentURI.spec); this.isSendableURI(aTargetTab.linkedBrowser.currentURI.spec);
@ -490,10 +478,6 @@ var gSync = {
// "Send Page to Device" and "Send Link to Device" menu items // "Send Page to Device" and "Send Link to Device" menu items
updateContentContextMenu(contextMenu) { updateContentContextMenu(contextMenu) {
if (!this.SYNC_ENABLED) {
// These items are hidden by default. No need to do anything.
return;
}
// showSendLink and showSendPage are mutually exclusive // showSendLink and showSendPage are mutually exclusive
const showSendLink = contextMenu.onSaveableLink || contextMenu.onPlainTextLink; const showSendLink = contextMenu.onSaveableLink || contextMenu.onPlainTextLink;
const showSendPage = !showSendLink const showSendPage = !showSendLink
@ -667,13 +651,6 @@ var gSync = {
} }
}, },
onSyncDisabled() {
const toHide = [...document.querySelectorAll(".sync-ui-item")];
for (const item of toHide) {
item.hidden = true;
}
},
QueryInterface: XPCOMUtils.generateQI([ QueryInterface: XPCOMUtils.generateQI([
Ci.nsIObserver, Ci.nsIObserver,
Ci.nsISupportsWeakReference Ci.nsISupportsWeakReference

Просмотреть файл

@ -97,9 +97,8 @@
accesskey="&moveToNewWindow.accesskey;" accesskey="&moveToNewWindow.accesskey;"
tbattr="tabbrowser-multiple" tbattr="tabbrowser-multiple"
oncommand="gBrowser.replaceTabWithWindow(TabContextMenu.contextTab);"/> oncommand="gBrowser.replaceTabWithWindow(TabContextMenu.contextTab);"/>
<menuseparator id="context_sendTabToDevice_separator" class="sync-ui-item"/> <menuseparator id="context_sendTabToDevice_separator"/>
<menu id="context_sendTabToDevice" label="&sendTabToDevice.label;" <menu id="context_sendTabToDevice" label="&sendTabToDevice.label;"
class="sync-ui-item"
accesskey="&sendTabToDevice.accesskey;"> accesskey="&sendTabToDevice.accesskey;">
<menupopup id="context_sendTabToDevicePopupMenu" <menupopup id="context_sendTabToDevicePopupMenu"
onpopupshowing="gSync.populateSendTabToDevicesMenu(event.target, TabContextMenu.contextTab.linkedBrowser.currentURI.spec, TabContextMenu.contextTab.linkedBrowser.contentTitle);"/> onpopupshowing="gSync.populateSendTabToDevicesMenu(event.target, TabContextMenu.contextTab.linkedBrowser.currentURI.spec, TabContextMenu.contextTab.linkedBrowser.contentTitle);"/>

Просмотреть файл

@ -7,8 +7,6 @@ const remoteClientsFixture = [ { id: 1, name: "Foo"}, { id: 2, name: "Bar"} ];
add_task(async function setup() { add_task(async function setup() {
await promiseSyncReady(); await promiseSyncReady();
// gSync.init() is called in a requestIdleCallback. Force its initialization.
gSync.init();
await BrowserTestUtils.openNewForegroundTab(gBrowser, "about:mozilla"); await BrowserTestUtils.openNewForegroundTab(gBrowser, "about:mozilla");
}); });
@ -30,7 +28,7 @@ add_task(async function test_page_contextmenu() {
sandbox.restore(); sandbox.restore();
}); });
add_task(async function test_page_contextmenu_no_remote_clients() { add_task(async function test_page_contextmenu_sendtab_no_remote_clients() {
const sandbox = setupSendTabMocks({ syncReady: true, clientsSynced: true, remoteClients: [], const sandbox = setupSendTabMocks({ syncReady: true, clientsSynced: true, remoteClients: [],
state: UIState.STATUS_SIGNED_IN, isSendableURI: true }); state: UIState.STATUS_SIGNED_IN, isSendableURI: true });
@ -48,7 +46,7 @@ add_task(async function test_page_contextmenu_no_remote_clients() {
sandbox.restore(); sandbox.restore();
}); });
add_task(async function test_page_contextmenu_one_remote_client() { add_task(async function test_page_contextmenu_sendtab_one_remote_client() {
const sandbox = setupSendTabMocks({ syncReady: true, clientsSynced: true, remoteClients: [{ id: 1, name: "Foo"}], const sandbox = setupSendTabMocks({ syncReady: true, clientsSynced: true, remoteClients: [{ id: 1, name: "Foo"}],
state: UIState.STATUS_SIGNED_IN, isSendableURI: true }); state: UIState.STATUS_SIGNED_IN, isSendableURI: true });
@ -177,16 +175,6 @@ add_task(async function test_page_contextmenu_login_failed() {
isSendableURI.restore(); isSendableURI.restore();
}); });
add_task(async function test_page_contextmenu_fxa_disabled() {
const getter = sinon.stub(gSync, "SYNC_ENABLED").get(() => false);
gSync.onSyncDisabled(); // Would have been called on gSync initialization if SYNC_ENABLED had been set.
await openContentContextMenu("#moztext");
is(document.getElementById("context-sendpagetodevice").hidden, true, "Send tab to device is hidden");
is(document.getElementById("context-sep-sendpagetodevice").hidden, true, "Separator is also hidden");
await hideContentContextMenu();
getter.restore();
});
// We are not going to bother testing the visibility of context-sendlinktodevice // We are not going to bother testing the visibility of context-sendlinktodevice
// since it uses the exact same code. // since it uses the exact same code.
// However, browser_contextmenu.js contains tests that verify its presence. // However, browser_contextmenu.js contains tests that verify its presence.

Просмотреть файл

@ -95,15 +95,3 @@ add_task(async function test_tab_contextmenu_sync_not_ready_other_state() {
sandbox.restore(); sandbox.restore();
}); });
add_task(async function test_tab_contextmenu_fxa_disabled() {
const getter = sinon.stub(gSync, "SYNC_ENABLED").get(() => false);
// Simulate onSyncDisabled() being called on window open.
gSync.onSyncDisabled();
updateTabContextMenu(testTab);
is(document.getElementById("context_sendTabToDevice").hidden, true, "Send tab to device is hidden");
is(document.getElementById("context_sendTabToDevice_separator").hidden, true, "Separator is also hidden");
getter.restore();
});

Просмотреть файл

@ -238,6 +238,252 @@ const CustomizableWidgets = [
panelview.appendChild(body); panelview.appendChild(body);
panelview.appendChild(footer); panelview.appendChild(footer);
} }
}, {
id: "sync-button",
label: "remotetabs-panelmenu.label",
tooltiptext: "remotetabs-panelmenu.tooltiptext2",
type: "view",
viewId: "PanelUI-remotetabs",
deckIndices: {
DECKINDEX_TABS: 0,
DECKINDEX_TABSDISABLED: 1,
DECKINDEX_FETCHING: 2,
DECKINDEX_NOCLIENTS: 3,
},
TABS_PER_PAGE: 25,
NEXT_PAGE_MIN_TABS: 5, // Minimum number of tabs displayed when we click "Show All"
onCreated(aNode) {
this._initialize(aNode);
},
_initialize(aNode) {
if (this._initialized) {
return;
}
// 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);
this._initialized = true;
},
onViewShowing(aEvent) {
this._initialize(aEvent.target);
let doc = aEvent.target.ownerDocument;
this._tabsList = doc.getElementById("PanelUI-remotetabs-tabslist");
Services.obs.addObserver(this, SyncedTabs.TOPIC_TABS_CHANGED);
if (SyncedTabs.isConfiguredToSyncTabs) {
if (SyncedTabs.hasSyncedThisSession) {
this.setDeckIndex(this.deckIndices.DECKINDEX_TABS);
} else {
// Sync hasn't synced tabs yet, so show the "fetching" panel.
this.setDeckIndex(this.deckIndices.DECKINDEX_FETCHING);
}
// force a background sync.
SyncedTabs.syncTabs().catch(ex => {
Cu.reportError(ex);
});
// show the current list - it will be updated by our observer.
this._showTabs();
} else {
// not configured to sync tabs, so no point updating the list.
this.setDeckIndex(this.deckIndices.DECKINDEX_TABSDISABLED);
}
},
onViewHiding() {
Services.obs.removeObserver(this, SyncedTabs.TOPIC_TABS_CHANGED);
this._tabsList = null;
},
_tabsList: null,
observe(subject, topic, data) {
switch (topic) {
case SyncedTabs.TOPIC_TABS_CHANGED:
this._showTabs();
break;
default:
break;
}
},
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(paginationInfo) {
this._showTabsPromise = this._showTabsPromise.then(() => {
return this.__showTabs(paginationInfo);
}, e => {
Cu.reportError(e);
});
},
// Return a new promise to update the tab list.
__showTabs(paginationInfo) {
if (!this._tabsList) {
// Closed between the previous `this._showTabsPromise`
// resolving and now.
return undefined;
}
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);
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);
}
if (paginationInfo && paginationInfo.clientId == client.id) {
this._appendClient(client, fragment, paginationInfo.maxTabs);
} else {
this._appendClient(client, fragment);
}
}
this._tabsList.appendChild(fragment);
PanelView.forNode(this._tabsList.closest("panelview"))
.descriptionHeightWorkaround();
}).catch(err => {
Cu.reportError(err);
}).then(() => {
// an observer for tests.
Services.obs.notifyObservers(null, "synced-tabs-menu:test:tabs-updated");
});
},
_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(client, attachFragment, maxTabs = this.TABS_PER_PAGE) {
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.gSync.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 {
// If this page will display all tabs, show no additional buttons.
// If the next page will display all the remaining tabs, show a "Show All" button
// Otherwise, show a "Shore More" button
let hasNextPage = client.tabs.length > maxTabs;
let nextPageIsLastPage = hasNextPage && maxTabs + this.TABS_PER_PAGE >= client.tabs.length;
if (nextPageIsLastPage) {
// When the user clicks "Show All", try to have at least NEXT_PAGE_MIN_TABS more tabs
// to display in order to avoid user frustration
maxTabs = Math.min(client.tabs.length - this.NEXT_PAGE_MIN_TABS, maxTabs);
}
if (hasNextPage) {
client.tabs = client.tabs.slice(0, maxTabs);
}
for (let tab of client.tabs) {
let tabEnt = this._createTabElement(doc, tab);
attachFragment.appendChild(tabEnt);
}
if (hasNextPage) {
let showAllEnt = this._createShowMoreElement(doc, client.id,
nextPageIsLastPage ?
Infinity :
maxTabs + this.TABS_PER_PAGE);
attachFragment.appendChild(showAllEnt);
}
}
},
_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);
if (doc.defaultView.whereToOpenLink(e) != "current") {
e.preventDefault();
e.stopPropagation();
} else {
CustomizableUI.hidePanelForNode(item);
}
BrowserUITelemetry.countSyncedTabEvent("open", "toolbarbutton-subview");
});
return item;
},
_createShowMoreElement(doc, clientId, showCount) {
let labelAttr, tooltipAttr;
if (showCount === Infinity) {
labelAttr = "showAllLabel";
tooltipAttr = "showAllTooltipText";
} else {
labelAttr = "showMoreLabel";
tooltipAttr = "showMoreTooltipText";
}
let showAllItem = doc.createElementNS(kNSXUL, "toolbarbutton");
showAllItem.setAttribute("itemtype", "showmorebutton");
showAllItem.setAttribute("class", "subviewbutton");
let label = this._tabsList.getAttribute(labelAttr);
showAllItem.setAttribute("label", label);
let tooltipText = this._tabsList.getAttribute(tooltipAttr);
showAllItem.setAttribute("tooltiptext", tooltipText);
showAllItem.addEventListener("click", e => {
e.preventDefault();
e.stopPropagation();
this._showTabs({ clientId, maxTabs: showCount });
});
return showAllItem;
}
}, { }, {
id: "privatebrowsing-button", id: "privatebrowsing-button",
shortcutId: "key_privatebrowsing", shortcutId: "key_privatebrowsing",
@ -628,256 +874,6 @@ const CustomizableWidgets = [
} }
}]; }];
if (Services.prefs.getBoolPref("identity.fxaccounts.enabled")) {
CustomizableWidgets.push({
id: "sync-button",
label: "remotetabs-panelmenu.label",
tooltiptext: "remotetabs-panelmenu.tooltiptext2",
type: "view",
viewId: "PanelUI-remotetabs",
deckIndices: {
DECKINDEX_TABS: 0,
DECKINDEX_TABSDISABLED: 1,
DECKINDEX_FETCHING: 2,
DECKINDEX_NOCLIENTS: 3,
},
TABS_PER_PAGE: 25,
NEXT_PAGE_MIN_TABS: 5, // Minimum number of tabs displayed when we click "Show All"
onCreated(aNode) {
this._initialize(aNode);
},
_initialize(aNode) {
if (this._initialized) {
return;
}
// 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);
this._initialized = true;
},
onViewShowing(aEvent) {
this._initialize(aEvent.target);
let doc = aEvent.target.ownerDocument;
this._tabsList = doc.getElementById("PanelUI-remotetabs-tabslist");
Services.obs.addObserver(this, SyncedTabs.TOPIC_TABS_CHANGED);
if (SyncedTabs.isConfiguredToSyncTabs) {
if (SyncedTabs.hasSyncedThisSession) {
this.setDeckIndex(this.deckIndices.DECKINDEX_TABS);
} else {
// Sync hasn't synced tabs yet, so show the "fetching" panel.
this.setDeckIndex(this.deckIndices.DECKINDEX_FETCHING);
}
// force a background sync.
SyncedTabs.syncTabs().catch(ex => {
Cu.reportError(ex);
});
// show the current list - it will be updated by our observer.
this._showTabs();
} else {
// not configured to sync tabs, so no point updating the list.
this.setDeckIndex(this.deckIndices.DECKINDEX_TABSDISABLED);
}
},
onViewHiding() {
Services.obs.removeObserver(this, SyncedTabs.TOPIC_TABS_CHANGED);
this._tabsList = null;
},
_tabsList: null,
observe(subject, topic, data) {
switch (topic) {
case SyncedTabs.TOPIC_TABS_CHANGED:
this._showTabs();
break;
default:
break;
}
},
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(paginationInfo) {
this._showTabsPromise = this._showTabsPromise.then(() => {
return this.__showTabs(paginationInfo);
}, e => {
Cu.reportError(e);
});
},
// Return a new promise to update the tab list.
__showTabs(paginationInfo) {
if (!this._tabsList) {
// Closed between the previous `this._showTabsPromise`
// resolving and now.
return undefined;
}
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);
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);
}
if (paginationInfo && paginationInfo.clientId == client.id) {
this._appendClient(client, fragment, paginationInfo.maxTabs);
} else {
this._appendClient(client, fragment);
}
}
this._tabsList.appendChild(fragment);
PanelView.forNode(this._tabsList.closest("panelview"))
.descriptionHeightWorkaround();
}).catch(err => {
Cu.reportError(err);
}).then(() => {
// an observer for tests.
Services.obs.notifyObservers(null, "synced-tabs-menu:test:tabs-updated");
});
},
_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(client, attachFragment, maxTabs = this.TABS_PER_PAGE) {
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.gSync.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 {
// If this page will display all tabs, show no additional buttons.
// If the next page will display all the remaining tabs, show a "Show All" button
// Otherwise, show a "Shore More" button
let hasNextPage = client.tabs.length > maxTabs;
let nextPageIsLastPage = hasNextPage && maxTabs + this.TABS_PER_PAGE >= client.tabs.length;
if (nextPageIsLastPage) {
// When the user clicks "Show All", try to have at least NEXT_PAGE_MIN_TABS more tabs
// to display in order to avoid user frustration
maxTabs = Math.min(client.tabs.length - this.NEXT_PAGE_MIN_TABS, maxTabs);
}
if (hasNextPage) {
client.tabs = client.tabs.slice(0, maxTabs);
}
for (let tab of client.tabs) {
let tabEnt = this._createTabElement(doc, tab);
attachFragment.appendChild(tabEnt);
}
if (hasNextPage) {
let showAllEnt = this._createShowMoreElement(doc, client.id,
nextPageIsLastPage ?
Infinity :
maxTabs + this.TABS_PER_PAGE);
attachFragment.appendChild(showAllEnt);
}
}
},
_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);
if (doc.defaultView.whereToOpenLink(e) != "current") {
e.preventDefault();
e.stopPropagation();
} else {
CustomizableUI.hidePanelForNode(item);
}
BrowserUITelemetry.countSyncedTabEvent("open", "toolbarbutton-subview");
});
return item;
},
_createShowMoreElement(doc, clientId, showCount) {
let labelAttr, tooltipAttr;
if (showCount === Infinity) {
labelAttr = "showAllLabel";
tooltipAttr = "showAllTooltipText";
} else {
labelAttr = "showMoreLabel";
tooltipAttr = "showMoreTooltipText";
}
let showAllItem = doc.createElementNS(kNSXUL, "toolbarbutton");
showAllItem.setAttribute("itemtype", "showmorebutton");
showAllItem.setAttribute("class", "subviewbutton");
let label = this._tabsList.getAttribute(labelAttr);
showAllItem.setAttribute("label", label);
let tooltipText = this._tabsList.getAttribute(tooltipAttr);
showAllItem.setAttribute("tooltiptext", tooltipText);
showAllItem.addEventListener("click", e => {
e.preventDefault();
e.stopPropagation();
this._showTabs({ clientId, maxTabs: showCount });
});
return showAllItem;
}
});
}
let preferencesButton = { let preferencesButton = {
id: "preferences-button", id: "preferences-button",
onCommand(aEvent) { onCommand(aEvent) {

Просмотреть файл

@ -177,7 +177,7 @@
oncommand="PanelUI._onBannerItemSelected(event)" oncommand="PanelUI._onBannerItemSelected(event)"
wrap="true" wrap="true"
hidden="true"/> hidden="true"/>
<toolbaritem id="appMenu-fxa-container" class="toolbaritem-combined-buttons sync-ui-item"> <toolbaritem id="appMenu-fxa-container" class="toolbaritem-combined-buttons">
<hbox id="appMenu-fxa-status" <hbox id="appMenu-fxa-status"
flex="1" flex="1"
defaultlabel="&fxaSignIn.label;" defaultlabel="&fxaSignIn.label;"
@ -201,7 +201,7 @@
<observes element="sync-status" attribute="tooltiptext"/> <observes element="sync-status" attribute="tooltiptext"/>
</toolbarbutton> </toolbarbutton>
</toolbaritem> </toolbaritem>
<toolbarseparator class="sync-ui-item"/> <toolbarseparator/>
<toolbarbutton id="appMenu-new-window-button" <toolbarbutton id="appMenu-new-window-button"
class="subviewbutton subviewbutton-iconic" class="subviewbutton subviewbutton-iconic"
label="&newNavigatorCmd.label;" label="&newNavigatorCmd.label;"
@ -637,7 +637,7 @@
closemenu="none" closemenu="none"
oncommand="DownloadsSubview.show(this);"/> oncommand="DownloadsSubview.show(this);"/>
<toolbarbutton id="appMenu-library-remotetabs-button" <toolbarbutton id="appMenu-library-remotetabs-button"
class="subviewbutton subviewbutton-iconic subviewbutton-nav sync-ui-item" class="subviewbutton subviewbutton-iconic subviewbutton-nav"
label="&appMenuRemoteTabs.label;" label="&appMenuRemoteTabs.label;"
closemenu="none" closemenu="none"
oncommand="PanelUI.showSubView('PanelUI-remotetabs', this)"/> oncommand="PanelUI.showSubView('PanelUI-remotetabs', this)"/>

Просмотреть файл

@ -467,11 +467,6 @@ var gMainPane = {
OS.File.stat(ignoreSeparateProfile).then(() => separateProfileModeCheckbox.checked = false, OS.File.stat(ignoreSeparateProfile).then(() => separateProfileModeCheckbox.checked = false,
() => separateProfileModeCheckbox.checked = true); () => separateProfileModeCheckbox.checked = true);
if (!Services.prefs.getBoolPref("identity.fxaccounts.enabled")) {
document.getElementById("sync-dev-edition-root").hidden = true;
return;
}
fxAccounts.getSignedInUser().then(data => { fxAccounts.getSignedInUser().then(data => {
document.getElementById("getStarted").selectedIndex = data ? 1 : 0; document.getElementById("getStarted").selectedIndex = data ? 1 : 0;
}) })

Просмотреть файл

@ -33,7 +33,7 @@
<vbox id="separateProfileBox"> <vbox id="separateProfileBox">
<checkbox id="separateProfileMode" <checkbox id="separateProfileMode"
label="&separateProfileMode.label;"/> label="&separateProfileMode.label;"/>
<hbox id="sync-dev-edition-root" align="center" class="indent"> <hbox align="center" class="indent">
<label id="useFirefoxSync">&useFirefoxSync.label;</label> <label id="useFirefoxSync">&useFirefoxSync.label;</label>
<deck id="getStarted"> <deck id="getStarted">
<label class="text-link">&getStarted.notloggedin.label;</label> <label class="text-link">&getStarted.notloggedin.label;</label>

Просмотреть файл

@ -55,10 +55,7 @@ function init_all() {
register_module("paneSearch", gSearchPane); register_module("paneSearch", gSearchPane);
register_module("panePrivacy", gPrivacyPane); register_module("panePrivacy", gPrivacyPane);
register_module("paneContainers", gContainersPane); register_module("paneContainers", gContainersPane);
if (Services.prefs.getBoolPref("identity.fxaccounts.enabled")) { register_module("paneSync", gSyncPane);
document.getElementById("category-sync").hidden = false;
register_module("paneSync", gSyncPane);
}
register_module("paneSearchResults", gSearchResultsPane); register_module("paneSearchResults", gSearchResultsPane);
gSearchResultsPane.init(); gSearchResultsPane.init();
gMainPane.preInit(); gMainPane.preInit();

Просмотреть файл

@ -172,7 +172,6 @@
<richlistitem id="category-sync" <richlistitem id="category-sync"
class="category" class="category"
hidden="true"
value="paneSync" value="paneSync"
helpTopic="prefs-weave" helpTopic="prefs-weave"
data-l10n-id="category-sync" data-l10n-id="category-sync"

3
browser/extensions/onboarding/bootstrap.js поставляемый
Просмотреть файл

@ -98,9 +98,6 @@ let syncTourChecker = {
}, },
init() { init() {
if (!Services.prefs.getBoolPref("identity.fxaccounts.enabled")) {
return;
}
// Check if we've already logged in at startup. // Check if we've already logged in at startup.
const state = UIState.get(); const state = UIState.get();
if (state.status != UIState.STATUS_NOT_CONFIGURED) { if (state.status != UIState.STATUS_NOT_CONFIGURED) {

Просмотреть файл

@ -479,12 +479,7 @@ class Onboarding {
_getTourIDList() { _getTourIDList() {
let tours = Services.prefs.getStringPref(`browser.onboarding.${this._tourType}tour`, ""); let tours = Services.prefs.getStringPref(`browser.onboarding.${this._tourType}tour`, "");
return tours.split(",").filter(tourId => { return tours.split(",").filter(tourId => tourId !== "").map(tourId => tourId.trim());
if (tourId === "sync" && !Services.prefs.getBoolPref("identity.fxaccounts.enabled")) {
return false;
}
return tourId !== "";
}).map(tourId => tourId.trim());
} }
_initPrefObserver() { _initPrefObserver() {

Просмотреть файл

@ -1218,11 +1218,8 @@ var gBuiltInActions = [
onCommand(event, buttonNode) { onCommand(event, buttonNode) {
browserPageActions(buttonNode).emailLink.onCommand(event, buttonNode); browserPageActions(buttonNode).emailLink.onCommand(event, buttonNode);
}, },
} },
];
if (Services.prefs.getBoolPref("identity.fxaccounts.enabled")) {
gBuiltInActions.push(
// send to device // send to device
{ {
id: "sendToDevice", id: "sendToDevice",
@ -1250,8 +1247,8 @@ if (Services.prefs.getBoolPref("identity.fxaccounts.enabled")) {
.onShowingSubview(panelViewNode); .onShowingSubview(panelViewNode);
}, },
}, },
}); }
} ];
/** /**

Просмотреть файл

@ -36,9 +36,6 @@ ChromeUtils.defineModuleGetter(this, "FxAccountsProfile",
ChromeUtils.defineModuleGetter(this, "Utils", ChromeUtils.defineModuleGetter(this, "Utils",
"resource://services-sync/util.js"); "resource://services-sync/util.js");
XPCOMUtils.defineLazyPreferenceGetter(this, "FXA_ENABLED",
"identity.fxaccounts.enabled", true);
// All properties exposed by the public FxAccounts API. // All properties exposed by the public FxAccounts API.
var publicProperties = [ var publicProperties = [
"accountStatus", "accountStatus",
@ -524,23 +521,20 @@ FxAccountsInternal.prototype = {
* } * }
* or null if no user is signed in. * or null if no user is signed in.
*/ */
async getSignedInUser() { getSignedInUser: function getSignedInUser() {
let currentState = this.currentAccountState; let currentState = this.currentAccountState;
const data = await currentState.getUserAccountData(); return currentState.getUserAccountData().then(data => {
if (!data) { if (!data) {
return currentState.resolve(null); return null;
} }
if (!FXA_ENABLED) { if (!this.isUserEmailVerified(data)) {
await this.signOut(); // If the email is not verified, start polling for verification,
return currentState.resolve(null); // but return null right away. We don't want to return a promise
} // that might not be fulfilled for a long time.
if (!this.isUserEmailVerified(data)) { this.startVerifiedCheck(data);
// If the email is not verified, start polling for verification, }
// but return null right away. We don't want to return a promise return data;
// that might not be fulfilled for a long time. }).then(result => currentState.resolve(result));
this.startVerifiedCheck(data);
}
return currentState.resolve(data);
}, },
/** /**
@ -564,32 +558,37 @@ FxAccountsInternal.prototype = {
* The promise resolves to null when the data is saved * The promise resolves to null when the data is saved
* successfully and is rejected on error. * successfully and is rejected on error.
*/ */
async setSignedInUser(credentials) { setSignedInUser: function setSignedInUser(credentials) {
if (!FXA_ENABLED) {
throw new Error("Cannot call setSignedInUser when FxA is disabled.");
}
log.debug("setSignedInUser - aborting any existing flows"); log.debug("setSignedInUser - aborting any existing flows");
const signedInUser = await this.getSignedInUser(); return this.getSignedInUser().then(signedInUser => {
if (signedInUser) { if (signedInUser) {
await this.deleteDeviceRegistration(signedInUser.sessionToken, signedInUser.deviceId); return this.deleteDeviceRegistration(signedInUser.sessionToken, signedInUser.deviceId);
} }
await this.abortExistingFlow(); return null;
let currentAccountState = this.currentAccountState = this.newAccountState( }).then(() =>
Cu.cloneInto(credentials, {}) // Pass a clone of the credentials object. this.abortExistingFlow()
); ).then(() => {
// This promise waits for storage, but not for verification. let currentAccountState = this.currentAccountState = this.newAccountState(
// We're telling the caller that this is durable now (although is that Cu.cloneInto(credentials, {}) // Pass a clone of the credentials object.
// really something we should commit to? Why not let the write happen in );
// the background? Already does for updateAccountData ;) // This promise waits for storage, but not for verification.
await currentAccountState.promiseInitialized; // We're telling the caller that this is durable now (although is that
// Starting point for polling if new user // really something we should commit to? Why not let the write happen in
if (!this.isUserEmailVerified(credentials)) { // the background? Already does for updateAccountData ;)
this.startVerifiedCheck(credentials); return currentAccountState.promiseInitialized.then(() => {
} // Starting point for polling if new user
await this.updateDeviceRegistration(); if (!this.isUserEmailVerified(credentials)) {
Services.telemetry.getHistogramById("FXA_CONFIGURED").add(1); this.startVerifiedCheck(credentials);
await this.notifyObservers(ONLOGIN_NOTIFICATION); }
return currentAccountState.resolve();
return this.updateDeviceRegistration();
}).then(() => {
Services.telemetry.getHistogramById("FXA_CONFIGURED").add(1);
return this.notifyObservers(ONLOGIN_NOTIFICATION);
}).then(() => {
return currentAccountState.resolve();
});
});
}, },
/** /**

Просмотреть файл

@ -117,13 +117,13 @@ WeaveService.prototype = {
/** /**
* Whether Sync appears to be enabled. * Whether Sync appears to be enabled.
* *
* This returns true if we have an associated FxA account and Sync is enabled. * This returns true if we have an associated FxA account
* *
* It does *not* perform a robust check to see if the client is working. * It does *not* perform a robust check to see if the client is working.
* For that, you'll want to check Weave.Status.checkSetup(). * For that, you'll want to check Weave.Status.checkSetup().
*/ */
get enabled() { get enabled() {
return !!syncUsername && Services.prefs.getBoolPref("identity.fxaccounts.enabled"); return !!syncUsername;
} }
}; };