--- a/browser/base/content/browser-sync.js
+++ b/browser/base/content/browser-sync.js
@@ -76,16 +76,32 @@ var gSync = {
delete this[prop];
this.__defineGetter__(prop, function() {
delete this[prop];
return this[prop] = document.getElementById("appMenu-fxa-" + suffix);
});
}
},
+ _definePrefGetters() {
+ XPCOMUtils.defineLazyPreferenceGetter(this, "UNSENDABLE_URL_REGEXP",
+ "services.sync.engine.tabs.filteredUrls", null, null, rx => {
+ try {
+ return new RegExp(rx, "i");
+ } catch (e) {
+ Cu.reportError(`Failed to build url filter regexp for send tab: ${e}`);
+ return null;
+ }
+ });
+ XPCOMUtils.defineLazyPreferenceGetter(this, "FXA_CONNECT_DEVICE_URI",
+ "identity.fxaccounts.remote.connectdevice.uri");
+ XPCOMUtils.defineLazyPreferenceGetter(this, "PRODUCT_INFO_BASE_URL",
+ "app.productInfo.baseURL");
+ },
+
_maybeUpdateUIState() {
// Update the UI.
if (UIState.isReady()) {
const state = UIState.get();
// If we are not configured, the UI is already in the right state when
// we open the window. We can avoid a repaint.
if (state.status != UIState.STATUS_NOT_CONFIGURED) {
this.updateAllUI(state);
@@ -98,16 +114,17 @@ var gSync = {
return;
}
for (let topic of this._obs) {
Services.obs.addObserver(this, topic, true);
}
this._generateNodeGetters();
+ this._definePrefGetters();
// initial label for the sync buttons.
let broadcaster = document.getElementById("sync-status");
broadcaster.setAttribute("label", this.syncStrings.GetStringFromName("syncnow.label"));
this._maybeUpdateUIState();
EnsureFxAccountsWebChannel();
@@ -272,23 +289,23 @@ var gSync = {
let url = await fxAccounts.promiseAccountsManageDevicesURI(entryPoint);
switchToTabHavingURI(url, true, {
replaceQueryString: true,
triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
});
},
openConnectAnotherDevice(entryPoint) {
- let url = new URL(Services.prefs.getCharPref("identity.fxaccounts.remote.connectdevice.uri"));
+ let url = new URL(this.FXA_CONNECT_DEVICE_URI);
url.searchParams.append("entrypoint", entryPoint);
openUILinkIn(url.href, "tab");
},
openSendToDevicePromo() {
- let url = Services.prefs.getCharPref("app.productInfo.baseURL");
+ let url = this.PRODUCT_INFO_BASE_URL;
url += "send-tabs/?utm_source=" + Services.appinfo.name.toLowerCase();
switchToTabHavingURI(url, true, { replaceQueryString: true });
},
sendTabToDevice(url, clientId, title) {
Weave.Service.clientsEngine.sendURIToClientForDisplay(url, clientId, title).catch(e => {
console.error("Could not send tab to device", e);
});
@@ -428,28 +445,24 @@ var gSync = {
isSendableURI(aURISpec) {
if (!aURISpec) {
return false;
}
// Disallow sending tabs with more than 65535 characters.
if (aURISpec.length > 65535) {
return false;
}
- try {
- // Filter out un-sendable URIs -- things like local files, object urls, etc.
- const unsendableRegexp = new RegExp(
- Services.prefs.getCharPref("services.sync.engine.tabs.filteredUrls"), "i");
- return !unsendableRegexp.test(aURISpec);
- } catch (e) {
- // The preference has been removed, or is an invalid regexp, so we log an
- // error and treat it as a valid URI -- and the more problematic case is
- // the length, which we've already addressed.
- Cu.reportError(`Failed to build url filter regexp for send tab: ${e}`);
- return true;
+ if (this.UNSENDABLE_URL_REGEXP) {
+ return !this.UNSENDABLE_URL_REGEXP.test(aURISpec);
}
+ // The preference has been removed, or is an invalid regexp, so we treat it
+ // as a valid URI. We've already logged an error when trying to construct
+ // the regexp, and the more problematic case is the length, which we've
+ // already addressed.
+ return true;
},
// "Send Tab to Device" menu item
updateTabContextMenu(aPopupMenu, aTargetTab) {
const enabled = !this.syncConfiguredAndLoading &&
this.isSendableURI(aTargetTab.linkedBrowser.currentURI.spec);
document.getElementById("context_sendTabToDevice").disabled = !enabled;