mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-28 15:23:51 +00:00
Merge mozilla-central to mozilla-inbound a=merge on a CLOSED TREE
This commit is contained in:
commit
f3162b921c
@ -123,13 +123,6 @@ pref("app.update.log", false);
|
||||
// the failure.
|
||||
pref("app.update.backgroundMaxErrors", 10);
|
||||
|
||||
// Whether or not app updates are enabled
|
||||
#ifdef MOZ_UPDATER
|
||||
pref("app.update.enabled", true);
|
||||
#else
|
||||
pref("app.update.enabled", false);
|
||||
#endif
|
||||
|
||||
// Whether or not to use the doorhanger application update UI.
|
||||
pref("app.update.doorhanger", true);
|
||||
|
||||
@ -145,9 +138,8 @@ pref("app.update.download.promptMaxAttempts", 2);
|
||||
// download a fresh installer.
|
||||
pref("app.update.elevation.promptMaxAttempts", 2);
|
||||
|
||||
// If set to true, the Update Service will automatically download updates when
|
||||
// app updates are enabled per the app.update.enabled preference and if the user
|
||||
// can apply updates.
|
||||
// If set to true, the Update Service will automatically download updates if the
|
||||
// user can apply updates.
|
||||
pref("app.update.auto", true);
|
||||
|
||||
// If set to true, the Update Service will present no UI for any event.
|
||||
@ -434,7 +426,11 @@ pref("browser.link.open_newwindow.disabled_in_fullscreen", false);
|
||||
#endif
|
||||
|
||||
// Tabbed browser
|
||||
#if defined(NIGHTLY_BUILD)
|
||||
pref("browser.tabs.multiselect", true);
|
||||
#else
|
||||
pref("browser.tabs.multiselect", false);
|
||||
#endif
|
||||
pref("browser.tabs.20FpsThrobber", false);
|
||||
pref("browser.tabs.30FpsThrobber", false);
|
||||
pref("browser.tabs.closeTabByDblclick", false);
|
||||
|
@ -20,7 +20,7 @@ var gAppUpdater;
|
||||
|
||||
function onUnload(aEvent) {
|
||||
if (gAppUpdater.isChecking)
|
||||
gAppUpdater.checker.stopChecking(Ci.nsIUpdateChecker.CURRENT_CHECK);
|
||||
gAppUpdater.checker.stopCurrentCheck();
|
||||
// Safe to call even when there isn't a download in progress.
|
||||
gAppUpdater.removeDownloadListener();
|
||||
gAppUpdater = null;
|
||||
@ -60,8 +60,8 @@ function appUpdater(options = {}) {
|
||||
manualLink.href = manualURL;
|
||||
document.getElementById("failedLink").href = manualURL;
|
||||
|
||||
if (this.updateDisabledAndLocked) {
|
||||
this.selectPanel("adminDisabled");
|
||||
if (this.updateDisabledByPolicy) {
|
||||
this.selectPanel("policyDisabled");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -81,16 +81,6 @@ function appUpdater(options = {}) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Honor the "Never check for updates" option by not only disabling background
|
||||
// update checks, but also in the About dialog, by presenting a
|
||||
// "Check for updates" button.
|
||||
// If updates are found, the user is then asked if he wants to "Update to <version>".
|
||||
if (!this.updateEnabled ||
|
||||
Services.prefs.prefHasUserValue(PREF_APP_UPDATE_ELEVATE_NEVER)) {
|
||||
this.selectPanel("checkForUpdates");
|
||||
return;
|
||||
}
|
||||
|
||||
// That leaves the options
|
||||
// "Check for updates, but let me choose whether to install them", and
|
||||
// "Automatically install updates".
|
||||
@ -135,25 +125,14 @@ appUpdater.prototype =
|
||||
this.um.activeUpdate.state == "downloading";
|
||||
},
|
||||
|
||||
// true when updating is disabled by an administrator.
|
||||
get updateDisabledAndLocked() {
|
||||
return (!this.updateEnabled &&
|
||||
Services.prefs.prefIsLocked("app.update.enabled")) ||
|
||||
(Services.policies &&
|
||||
!Services.policies.isAllowed("appUpdate"));
|
||||
},
|
||||
|
||||
// true when updating is enabled.
|
||||
get updateEnabled() {
|
||||
try {
|
||||
return Services.prefs.getBoolPref("app.update.enabled");
|
||||
} catch (e) { }
|
||||
return true; // Firefox default is true
|
||||
// true when updating has been disabled by enterprise policy
|
||||
get updateDisabledByPolicy() {
|
||||
return Services.policies && !Services.policies.isAllowed("appUpdate");
|
||||
},
|
||||
|
||||
// true when updating in background is enabled.
|
||||
get backgroundUpdateEnabled() {
|
||||
return this.updateEnabled &&
|
||||
return !this.updateDisabledByPolicy &&
|
||||
gAppUpdater.aus.canStageUpdates;
|
||||
},
|
||||
|
||||
|
@ -93,7 +93,7 @@
|
||||
<hbox id="downloadFailed" align="center">
|
||||
<label>&update.failed.start;</label><label id="failedLink" class="text-link">&update.failed.linkText;</label><label>&update.failed.end;</label>
|
||||
</hbox>
|
||||
<hbox id="adminDisabled" align="center">
|
||||
<hbox id="policyDisabled" align="center">
|
||||
<label>&update.adminDisabled;</label>
|
||||
</hbox>
|
||||
<hbox id="noUpdatesFound" align="center">
|
||||
|
@ -227,12 +227,12 @@ var FeedHandler = {
|
||||
|
||||
get _feedMenuitem() {
|
||||
delete this._feedMenuitem;
|
||||
return this._feedMenuitem = document.getElementById("singleFeedMenuitemState");
|
||||
return this._feedMenuitem = document.getElementById("subscribeToPageMenuitem");
|
||||
},
|
||||
|
||||
get _feedMenupopup() {
|
||||
delete this._feedMenupopup;
|
||||
return this._feedMenupopup = document.getElementById("multipleFeedsMenuState");
|
||||
return this._feedMenupopup = document.getElementById("subscribeToPageMenupopup");
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -399,19 +399,20 @@
|
||||
observes="bookmarkThisPageBroadcaster"
|
||||
key="addBookmarkAsKb"/>
|
||||
<menuitem id="subscribeToPageMenuitem"
|
||||
disabled="true"
|
||||
#ifndef XP_MACOSX
|
||||
class="menuitem-iconic"
|
||||
#endif
|
||||
label="&subscribeToPageMenuitem.label;"
|
||||
oncommand="return FeedHandler.subscribeToFeed(null, event);"
|
||||
onclick="checkForMiddleClick(this, event);"
|
||||
observes="singleFeedMenuitemState"/>
|
||||
/>
|
||||
<menu id="subscribeToPageMenupopup"
|
||||
hidden="true"
|
||||
#ifndef XP_MACOSX
|
||||
class="menu-iconic"
|
||||
#endif
|
||||
label="&subscribeToPageMenupopup.label;"
|
||||
observes="multipleFeedsMenuState">
|
||||
label="&subscribeToPageMenupopup.label;">
|
||||
<menupopup id="subscribeToPageSubmenuMenupopup"
|
||||
onpopupshowing="return FeedHandler.buildFeedList(event.target);"
|
||||
oncommand="return FeedHandler.subscribeToFeed(null, event);"
|
||||
@ -511,8 +512,12 @@
|
||||
accesskey="&webDeveloperMenu.accesskey;">
|
||||
<menupopup id="menuWebDeveloperPopup">
|
||||
<menuitem id="menu_pageSource"
|
||||
observes="devtoolsMenuBroadcaster_PageSource"
|
||||
accesskey="&pageSourceCmd.accesskey;"/>
|
||||
label="&pageSourceCmd.label;"
|
||||
key="key_viewSource"
|
||||
command="View:PageSource"
|
||||
accesskey="&pageSourceCmd.accesskey;">
|
||||
<observes element="canViewSource" attribute="disabled"/>
|
||||
</menuitem>
|
||||
</menupopup>
|
||||
</menu>
|
||||
<menuitem id="menu_pageInfo"
|
||||
@ -609,14 +614,14 @@
|
||||
<menuitem id="menu_HelpPopup_reportPhishingtoolmenu"
|
||||
label="&reportDeceptiveSiteMenu.title;"
|
||||
accesskey="&reportDeceptiveSiteMenu.accesskey;"
|
||||
observes="reportPhishingBroadcaster"
|
||||
disabled="true"
|
||||
oncommand="openUILink(gSafeBrowsing.getReportURL('Phish'), event, {triggeringPrincipal: Services.scriptSecurityManager.createNullPrincipal({})});"
|
||||
onclick="checkForMiddleClick(this, event);"
|
||||
hidden="true"/>
|
||||
<menuitem id="menu_HelpPopup_reportPhishingErrortoolmenu"
|
||||
label="&safeb.palm.notdeceptive.label;"
|
||||
accesskey="&safeb.palm.notdeceptive.accesskey;"
|
||||
observes="reportPhishingErrorBroadcaster"
|
||||
disabled="true"
|
||||
oncommand="ReportFalseDeceptiveSite();"
|
||||
onclick="checkForMiddleClick(this, event);"
|
||||
hidden="true"/>
|
||||
|
@ -18,10 +18,10 @@ var gSafeBrowsing = {
|
||||
docURI && docURI.spec.startsWith("about:blocked?e=deceptiveBlocked");
|
||||
|
||||
// Show/hide the appropriate menu item.
|
||||
document.getElementById("menu_HelpPopup_reportPhishingtoolmenu")
|
||||
.hidden = isPhishingPage;
|
||||
document.getElementById("menu_HelpPopup_reportPhishingErrortoolmenu")
|
||||
.hidden = !isPhishingPage;
|
||||
const reportMenu = document.getElementById("menu_HelpPopup_reportPhishingtoolmenu");
|
||||
reportMenu.hidden = isPhishingPage;
|
||||
const reportErrorMenu = document.getElementById("menu_HelpPopup_reportPhishingErrortoolmenu");
|
||||
reportErrorMenu.hidden = !isPhishingPage;
|
||||
|
||||
// Now look at the currentURI to learn which page we were trying
|
||||
// to browse to.
|
||||
@ -30,18 +30,16 @@ var gSafeBrowsing = {
|
||||
|
||||
const disabledByPolicy = !Services.policies.isAllowed("feedbackCommands");
|
||||
|
||||
const reportBroadcaster = document.getElementById("reportPhishingBroadcaster");
|
||||
if (disabledByPolicy || isPhishingPage || !isReportablePage) {
|
||||
reportBroadcaster.setAttribute("disabled", "true");
|
||||
reportMenu.setAttribute("disabled", "true");
|
||||
} else {
|
||||
reportBroadcaster.removeAttribute("disabled");
|
||||
reportMenu.removeAttribute("disabled");
|
||||
}
|
||||
|
||||
const reportErrorBroadcaster = document.getElementById("reportPhishingErrorBroadcaster");
|
||||
if (disabledByPolicy || !isPhishingPage || !isReportablePage) {
|
||||
reportErrorBroadcaster.setAttribute("disabled", "true");
|
||||
reportErrorMenu.setAttribute("disabled", "true");
|
||||
} else {
|
||||
reportErrorBroadcaster.removeAttribute("disabled");
|
||||
reportErrorMenu.removeAttribute("disabled");
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -133,29 +133,9 @@
|
||||
label="&bookmarkThisPageCmd.label;"
|
||||
bookmarklabel="&bookmarkThisPageCmd.label;"
|
||||
editlabel="&editThisBookmarkCmd.label;"/>
|
||||
|
||||
<!-- popup blocking menu items -->
|
||||
<broadcaster id="blockedPopupAllowSite"
|
||||
accesskey="&allowPopups.accesskey;"
|
||||
oncommand="gPopupBlockerObserver.toggleAllowPopupsForSite(event);"/>
|
||||
<broadcaster id="blockedPopupEditSettings"
|
||||
#ifdef XP_WIN
|
||||
label="&editPopupSettings.label;"
|
||||
#else
|
||||
label="&editPopupSettingsUnix.label;"
|
||||
#endif
|
||||
accesskey="&editPopupSettings.accesskey;"
|
||||
oncommand="gPopupBlockerObserver.editPopupSettings();"/>
|
||||
<broadcaster id="blockedPopupDontShowMessage"
|
||||
accesskey="&dontShowMessage.accesskey;"
|
||||
type="checkbox"
|
||||
oncommand="gPopupBlockerObserver.dontShowMessage();"/>
|
||||
<broadcaster id="blockedPopupsSeparator"/>
|
||||
<broadcaster id="isImage"/>
|
||||
<broadcaster id="canViewSource"/>
|
||||
<broadcaster id="isFrameImage"/>
|
||||
<broadcaster id="singleFeedMenuitemState" disabled="true"/>
|
||||
<broadcaster id="multipleFeedsMenuState" hidden="true"/>
|
||||
|
||||
<!-- Sync broadcasters -->
|
||||
<!-- A broadcaster of a number of attributes suitable for "sync now" UI -
|
||||
@ -173,16 +153,6 @@
|
||||
sidebarurl="chrome://browser/content/syncedtabs/sidebar.xhtml"
|
||||
oncommand="SidebarUI.toggle('viewTabsSidebar');"/>
|
||||
<broadcaster id="workOfflineMenuitemState"/>
|
||||
|
||||
<broadcaster id="devtoolsMenuBroadcaster_PageSource"
|
||||
label="&pageSourceCmd.label;"
|
||||
key="key_viewSource"
|
||||
command="View:PageSource">
|
||||
<observes element="canViewSource" attribute="disabled"/>
|
||||
</broadcaster>
|
||||
<broadcaster id="reportPhishingBroadcaster" disabled="true"/>
|
||||
<broadcaster id="reportPhishingErrorBroadcaster" disabled="true"/>
|
||||
<broadcaster id="trackingProtectionBroadcaster" enabled="false"/>
|
||||
</broadcasterset>
|
||||
|
||||
<keyset id="mainKeyset">
|
||||
|
@ -41,7 +41,7 @@ var TrackingProtection = {
|
||||
this.animatedIcon = $("#tracking-protection-icon-animatable-image");
|
||||
this.animatedIcon.addEventListener("animationend", () => this.iconBox.removeAttribute("animate"));
|
||||
|
||||
this.broadcaster = $("#trackingProtectionBroadcaster");
|
||||
this.appMenuButton = $("#appMenu-tp-toggle");
|
||||
|
||||
this.enableTooltip =
|
||||
gNavigatorBundle.getString("trackingProtection.toggle.enable.tooltip");
|
||||
@ -131,14 +131,14 @@ var TrackingProtection = {
|
||||
this.content.setAttribute("enabled", this.enabled);
|
||||
|
||||
if (PrivateBrowsingUtils.isWindowPrivate(window)) {
|
||||
this.broadcaster.setAttribute("enabled", this.enabledInPrivateWindows);
|
||||
this.broadcaster.setAttribute("aria-pressed", this.enabledInPrivateWindows);
|
||||
this.broadcaster.setAttribute("tooltiptext", this.enabledInPrivateWindows ?
|
||||
this.appMenuButton.setAttribute("enabled", this.enabledInPrivateWindows);
|
||||
this.appMenuButton.setAttribute("aria-pressed", this.enabledInPrivateWindows);
|
||||
this.appMenuButton.setAttribute("tooltiptext", this.enabledInPrivateWindows ?
|
||||
this.disableTooltipPB : this.enableTooltipPB);
|
||||
} else {
|
||||
this.broadcaster.setAttribute("enabled", this.enabledGlobally);
|
||||
this.broadcaster.setAttribute("aria-pressed", this.enabledGlobally);
|
||||
this.broadcaster.setAttribute("tooltiptext", this.enabledGlobally ?
|
||||
this.appMenuButton.setAttribute("enabled", this.enabledGlobally);
|
||||
this.appMenuButton.setAttribute("aria-pressed", this.enabledGlobally);
|
||||
this.appMenuButton.setAttribute("tooltiptext", this.enabledGlobally ?
|
||||
this.disableTooltip : this.enableTooltip);
|
||||
}
|
||||
},
|
||||
|
@ -755,7 +755,7 @@ var gPopupBlockerObserver = {
|
||||
|
||||
onPopupHiding(aEvent) {
|
||||
let item = aEvent.target.lastChild;
|
||||
while (item && item.getAttribute("observes") != "blockedPopupsSeparator") {
|
||||
while (item && item.id != "blockedPopupsSeparator") {
|
||||
let next = item.previousSibling;
|
||||
item.remove();
|
||||
item = next;
|
||||
|
@ -404,10 +404,22 @@
|
||||
<menupopup id="blockedPopupOptions"
|
||||
onpopupshowing="gPopupBlockerObserver.fillPopupList(event);"
|
||||
onpopuphiding="gPopupBlockerObserver.onPopupHiding(event);">
|
||||
<menuitem observes="blockedPopupAllowSite"/>
|
||||
<menuitem observes="blockedPopupEditSettings"/>
|
||||
<menuitem observes="blockedPopupDontShowMessage"/>
|
||||
<menuseparator observes="blockedPopupsSeparator"/>
|
||||
<menuitem id="blockedPopupAllowSite"
|
||||
accesskey="&allowPopups.accesskey;"
|
||||
oncommand="gPopupBlockerObserver.toggleAllowPopupsForSite(event);"/>
|
||||
<menuitem
|
||||
#ifdef XP_WIN
|
||||
label="&editPopupSettings.label;"
|
||||
#else
|
||||
label="&editPopupSettingsUnix.label;"
|
||||
#endif
|
||||
accesskey="&editPopupSettings.accesskey;"
|
||||
oncommand="gPopupBlockerObserver.editPopupSettings();"/>
|
||||
<menuitem id="blockedPopupDontShowMessage"
|
||||
accesskey="&dontShowMessage.accesskey;"
|
||||
type="checkbox"
|
||||
oncommand="gPopupBlockerObserver.dontShowMessage();"/>
|
||||
<menuseparator id="blockedPopupsSeparator"/>
|
||||
</menupopup>
|
||||
|
||||
<menupopup id="autohide-context"
|
||||
|
@ -56,7 +56,7 @@ add_task(async function test_opening_blocked_popups() {
|
||||
gBrowser.tabContainer.addEventListener("TabOpen", onTabOpen);
|
||||
|
||||
// Press the button.
|
||||
let allow = menu.querySelector("[observes='blockedPopupAllowSite']");
|
||||
let allow = document.getElementById("blockedPopupAllowSite");
|
||||
allow.doCommand();
|
||||
await BrowserTestUtils.waitForCondition(() =>
|
||||
popupTabs.length == 2 &&
|
||||
|
@ -1,6 +1,10 @@
|
||||
const PREF_MULTISELECT_TABS = "browser.tabs.multiselect";
|
||||
|
||||
add_task(async function clickWithoutPrefSet() {
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [[PREF_MULTISELECT_TABS, false]]
|
||||
});
|
||||
|
||||
let tab = await addTab();
|
||||
let mSelectedTabs = gBrowser._multiSelectedTabsSet;
|
||||
|
||||
@ -22,11 +26,15 @@ add_task(async function clickWithoutPrefSet() {
|
||||
BrowserTestUtils.removeTab(tab);
|
||||
});
|
||||
|
||||
add_task(async function setPref() {
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [[PREF_MULTISELECT_TABS, true]]
|
||||
});
|
||||
});
|
||||
|
||||
add_task(async function clickWithPrefSet() {
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
[PREF_MULTISELECT_TABS, true]
|
||||
]
|
||||
set: [[PREF_MULTISELECT_TABS, true]]
|
||||
});
|
||||
|
||||
let mSelectedTabs = gBrowser._multiSelectedTabsSet;
|
||||
@ -48,12 +56,6 @@ add_task(async function clickWithPrefSet() {
|
||||
});
|
||||
|
||||
add_task(async function clearSelection() {
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
[PREF_MULTISELECT_TABS, true]
|
||||
]
|
||||
});
|
||||
|
||||
const tab1 = await addTab();
|
||||
const tab2 = await addTab();
|
||||
const tab3 = await addTab();
|
||||
|
@ -1,6 +1,10 @@
|
||||
const PREF_MULTISELECT_TABS = "browser.tabs.multiselect";
|
||||
|
||||
add_task(async function prefNotSet() {
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [[PREF_MULTISELECT_TABS, false]]
|
||||
});
|
||||
|
||||
let tab1 = await addTab();
|
||||
let tab2 = await addTab();
|
||||
let tab3 = await addTab();
|
||||
@ -30,9 +34,7 @@ add_task(async function prefNotSet() {
|
||||
|
||||
add_task(async function setPref() {
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
[PREF_MULTISELECT_TABS, true]
|
||||
]
|
||||
set: [[PREF_MULTISELECT_TABS, true]]
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -219,7 +219,7 @@
|
||||
<toolbarbutton id="appMenu-tp-toggle"
|
||||
closemenu="none"
|
||||
class="subviewkeynav"
|
||||
observes="trackingProtectionBroadcaster"
|
||||
enabled="false"
|
||||
oncommand="TrackingProtection.onGlobalToggleCommand();" />
|
||||
</toolbaritem>
|
||||
<toolbarseparator id="appMenu-tp-separator" hidden="true" />
|
||||
|
@ -11,6 +11,8 @@ var updateService = Cc["@mozilla.org/updates/update-service;1"].
|
||||
// policy is applied needs to occur in a different test since the policy does
|
||||
// not properly take effect unless it is applied during application startup.
|
||||
add_task(async function test_updates_pre_policy() {
|
||||
await SpecialPowers.pushPrefEnv({"set": [["app.update.disabledForTesting", false]]});
|
||||
|
||||
is(Services.policies.isAllowed("appUpdate"), true,
|
||||
"Since no policies have been set, appUpdate should be allowed by default");
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
[DEFAULT]
|
||||
prefs =
|
||||
app.update.enabled=true
|
||||
app.update.disabledForTesting=false
|
||||
app.update.auto=true
|
||||
browser.policies.alternatePath='<test-root>/browser/components/enterprisepolicies/tests/browser/disable_app_update/config_disable_app_update.json'
|
||||
support-files =
|
||||
|
@ -18,10 +18,8 @@ add_task(async function test_update_preferences_ui() {
|
||||
|
||||
await ContentTask.spawn(tab.linkedBrowser, null, async function() {
|
||||
let updateRadioGroup = content.document.getElementById("updateRadioGroup");
|
||||
is(updateRadioGroup.disabled, true,
|
||||
is(updateRadioGroup.hidden, true,
|
||||
"Update choices should be diabled when app update is locked by policy");
|
||||
is(updateRadioGroup.value, "manual",
|
||||
"Update choice should be set to \"manual\" when app update is disabled by policy");
|
||||
});
|
||||
|
||||
BrowserTestUtils.removeTab(tab);
|
||||
|
@ -771,7 +771,6 @@ BrowserGlue.prototype = {
|
||||
_checkForOldBuildUpdates() {
|
||||
// check for update if our build is old
|
||||
if (AppConstants.MOZ_UPDATER &&
|
||||
Services.prefs.getBoolPref("app.update.enabled") &&
|
||||
Services.prefs.getBoolPref("app.update.checkInstallTime")) {
|
||||
|
||||
let buildID = Services.appinfo.appBuildID;
|
||||
|
@ -228,7 +228,6 @@ if (AppConstants.platform === "win") {
|
||||
|
||||
if (AppConstants.MOZ_UPDATER) {
|
||||
Preferences.addAll([
|
||||
{ id: "app.update.enabled", type: "bool" },
|
||||
{ id: "app.update.auto", type: "bool" },
|
||||
{ id: "app.update.disable_button.showUpdateHistory", type: "bool" },
|
||||
]);
|
||||
@ -502,17 +501,35 @@ var gMainPane = {
|
||||
|
||||
if (AppConstants.MOZ_UPDATER) {
|
||||
gAppUpdater = new appUpdater();
|
||||
let onUnload = () => {
|
||||
window.removeEventListener("unload", onUnload);
|
||||
Services.prefs.removeObserver("app.update.", this);
|
||||
};
|
||||
window.addEventListener("unload", onUnload);
|
||||
Services.prefs.addObserver("app.update.", this);
|
||||
this.updateReadPrefs();
|
||||
setEventListener("updateRadioGroup", "command",
|
||||
gMainPane.updateWritePrefs);
|
||||
setEventListener("showUpdateHistory", "command",
|
||||
gMainPane.showUpdates);
|
||||
|
||||
if (Services.policies && !Services.policies.isAllowed("appUpdate")) {
|
||||
document.getElementById("updateAllowDescription").hidden = true;
|
||||
document.getElementById("updateRadioGroup").hidden = true;
|
||||
if (AppConstants.MOZ_MAINTENANCE_SERVICE) {
|
||||
document.getElementById("useService").hidden = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (AppConstants.MOZ_MAINTENANCE_SERVICE) {
|
||||
// Check to see if the maintenance service is installed.
|
||||
// If it isn't installed, don't show the preference at all.
|
||||
let installed;
|
||||
try {
|
||||
let wrk = Cc["@mozilla.org/windows-registry-key;1"]
|
||||
.createInstance(Ci.nsIWindowsRegKey);
|
||||
wrk.open(wrk.ROOT_KEY_LOCAL_MACHINE,
|
||||
"SOFTWARE\\Mozilla\\MaintenanceService",
|
||||
wrk.ACCESS_READ | wrk.WOW64_64);
|
||||
installed = wrk.readIntValue("Installed");
|
||||
wrk.close();
|
||||
} catch (e) {
|
||||
}
|
||||
if (installed != 1) {
|
||||
document.getElementById("useService").hidden = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Initilize Application section.
|
||||
@ -1175,111 +1192,6 @@ var gMainPane = {
|
||||
}
|
||||
},
|
||||
|
||||
/*
|
||||
* Preferences:
|
||||
*
|
||||
* app.update.enabled
|
||||
* - true if updates to the application are enabled, false otherwise
|
||||
* app.update.auto
|
||||
* - true if updates should be automatically downloaded and installed and
|
||||
* false if the user should be asked what he wants to do when an update is
|
||||
* available
|
||||
* extensions.update.enabled
|
||||
* - true if updates to extensions and themes are enabled, false otherwise
|
||||
* browser.search.update
|
||||
* - true if updates to search engines are enabled, false otherwise
|
||||
*/
|
||||
|
||||
/**
|
||||
* Selects the item of the radiogroup based on the pref values and locked
|
||||
* states.
|
||||
*
|
||||
* UI state matrix for update preference conditions
|
||||
*
|
||||
* UI Components: Preferences
|
||||
* Radiogroup i = app.update.enabled
|
||||
* ii = app.update.auto
|
||||
*
|
||||
* Disabled states:
|
||||
* Element pref value locked disabled
|
||||
* radiogroup i t/f f false
|
||||
* i t/f *t* *true*
|
||||
* ii t/f f false
|
||||
* ii t/f *t* *true*
|
||||
*/
|
||||
updateReadPrefs() {
|
||||
if (AppConstants.MOZ_UPDATER) {
|
||||
var enabledPref = Preferences.get("app.update.enabled");
|
||||
var autoPref = Preferences.get("app.update.auto");
|
||||
let disabledByPolicy = Services.policies &&
|
||||
!Services.policies.isAllowed("appUpdate");
|
||||
var radiogroup = document.getElementById("updateRadioGroup");
|
||||
|
||||
if (!enabledPref.value || disabledByPolicy) // Don't care for autoPref.value in this case.
|
||||
radiogroup.value = "manual"; // 3. Never check for updates.
|
||||
else if (autoPref.value) // enabledPref.value && autoPref.value
|
||||
radiogroup.value = "auto"; // 1. Automatically install updates
|
||||
else // enabledPref.value && !autoPref.value
|
||||
radiogroup.value = "checkOnly"; // 2. Check, but let me choose
|
||||
|
||||
var canCheck = Cc["@mozilla.org/updates/update-service;1"].
|
||||
getService(Ci.nsIApplicationUpdateService).
|
||||
canCheckForUpdates;
|
||||
// canCheck is false if the enabledPref is false and locked,
|
||||
// or the binary platform or OS version is not known.
|
||||
// A locked pref is sufficient to disable the radiogroup.
|
||||
radiogroup.disabled = !canCheck ||
|
||||
enabledPref.locked ||
|
||||
autoPref.locked ||
|
||||
disabledByPolicy;
|
||||
|
||||
if (AppConstants.MOZ_MAINTENANCE_SERVICE) {
|
||||
// Check to see if the maintenance service is installed.
|
||||
// If it is don't show the preference at all.
|
||||
var installed;
|
||||
try {
|
||||
var wrk = Cc["@mozilla.org/windows-registry-key;1"]
|
||||
.createInstance(Ci.nsIWindowsRegKey);
|
||||
wrk.open(wrk.ROOT_KEY_LOCAL_MACHINE,
|
||||
"SOFTWARE\\Mozilla\\MaintenanceService",
|
||||
wrk.ACCESS_READ | wrk.WOW64_64);
|
||||
installed = wrk.readIntValue("Installed");
|
||||
wrk.close();
|
||||
} catch (e) {
|
||||
}
|
||||
if (installed != 1) {
|
||||
document.getElementById("useService").hidden = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets the pref values based on the selected item of the radiogroup.
|
||||
*/
|
||||
updateWritePrefs() {
|
||||
let disabledByPolicy = Services.policies &&
|
||||
!Services.policies.isAllowed("appUpdate");
|
||||
if (AppConstants.MOZ_UPDATER && !disabledByPolicy) {
|
||||
var enabledPref = Preferences.get("app.update.enabled");
|
||||
var autoPref = Preferences.get("app.update.auto");
|
||||
var radiogroup = document.getElementById("updateRadioGroup");
|
||||
switch (radiogroup.value) {
|
||||
case "auto": // 1. Automatically install updates for Desktop only
|
||||
enabledPref.value = true;
|
||||
autoPref.value = true;
|
||||
break;
|
||||
case "checkOnly": // 2. Check, but let me choose
|
||||
enabledPref.value = true;
|
||||
autoPref.value = false;
|
||||
break;
|
||||
case "manual": // 3. Never check for updates.
|
||||
enabledPref.value = false;
|
||||
autoPref.value = false;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Displays the history of installed updates.
|
||||
*/
|
||||
@ -1337,9 +1249,6 @@ var gMainPane = {
|
||||
// the view when any of them changes.
|
||||
this._rebuildView();
|
||||
}
|
||||
if (AppConstants.MOZ_UPDATER) {
|
||||
this.updateReadPrefs();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -484,7 +484,7 @@
|
||||
accesskey="&update.checkForUpdatesButton.accesskey;"
|
||||
oncommand="gAppUpdater.checkForUpdates();"/>
|
||||
</hbox>
|
||||
<hbox id="adminDisabled" align="start">
|
||||
<hbox id="policyDisabled" align="start">
|
||||
<label>&update.adminDisabled;</label>
|
||||
<spacer flex="1"/>
|
||||
<button label="&update.checkForUpdatesButton.label;"
|
||||
@ -537,15 +537,13 @@
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_UPDATER
|
||||
<description data-l10n-id="update-application-allow-description"></description>
|
||||
<radiogroup id="updateRadioGroup">
|
||||
<description id="updateAllowDescription" data-l10n-id="update-application-allow-description"></description>
|
||||
<radiogroup id="updateRadioGroup" preference="app.update.auto">
|
||||
<radio id="autoDesktop"
|
||||
value="auto"
|
||||
value="true"
|
||||
data-l10n-id="update-application-auto"/>
|
||||
<radio value="checkOnly"
|
||||
<radio value="false"
|
||||
data-l10n-id="update-application-check-choose"/>
|
||||
<radio value="manual"
|
||||
data-l10n-id="update-application-manual"/>
|
||||
</radiogroup>
|
||||
#ifdef MOZ_MAINTENANCE_SERVICE
|
||||
<checkbox id="useService"
|
||||
|
111
browser/extensions/activity-stream/bin/locales.js
Normal file
111
browser/extensions/activity-stream/bin/locales.js
Normal file
@ -0,0 +1,111 @@
|
||||
exports.DEFAULT_LOCALE = "en-US";
|
||||
|
||||
// This locales list is to find any similar locales that we can reuse strings
|
||||
// instead of falling back to the default, e.g., use bn-BD strings for bn-IN.
|
||||
// https://hg.mozilla.org/mozilla-central/file/tip/browser/locales/l10n.toml
|
||||
exports.CENTRAL_LOCALES = [
|
||||
"ach",
|
||||
"af",
|
||||
"an",
|
||||
"ar",
|
||||
"as",
|
||||
"ast",
|
||||
"az",
|
||||
"be",
|
||||
"bg",
|
||||
"bn-BD",
|
||||
"bn-IN",
|
||||
"br",
|
||||
"bs",
|
||||
"ca",
|
||||
"cak",
|
||||
"crh",
|
||||
"cs",
|
||||
"cy",
|
||||
"da",
|
||||
"de",
|
||||
"dsb",
|
||||
"el",
|
||||
"en-CA",
|
||||
"en-GB",
|
||||
"en-ZA",
|
||||
"eo",
|
||||
"es-AR",
|
||||
"es-CL",
|
||||
"es-ES",
|
||||
"es-MX",
|
||||
"et",
|
||||
"eu",
|
||||
"fa",
|
||||
"ff",
|
||||
"fi",
|
||||
"fr",
|
||||
"fy-NL",
|
||||
"ga-IE",
|
||||
"gd",
|
||||
"gl",
|
||||
"gn",
|
||||
"gu-IN",
|
||||
"he",
|
||||
"hi-IN",
|
||||
"hr",
|
||||
"hsb",
|
||||
"hu",
|
||||
"hy-AM",
|
||||
"ia",
|
||||
"id",
|
||||
"is",
|
||||
"it",
|
||||
"ja",
|
||||
"ja-JP-mac",
|
||||
"ka",
|
||||
"kab",
|
||||
"kk",
|
||||
"km",
|
||||
"kn",
|
||||
"ko",
|
||||
"lij",
|
||||
"lo",
|
||||
"lt",
|
||||
"ltg",
|
||||
"lv",
|
||||
"mai",
|
||||
"mk",
|
||||
"ml",
|
||||
"mr",
|
||||
"ms",
|
||||
"my",
|
||||
"nb-NO",
|
||||
"ne-NP",
|
||||
"nl",
|
||||
"nn-NO",
|
||||
"oc",
|
||||
"or",
|
||||
"pa-IN",
|
||||
"pl",
|
||||
"pt-BR",
|
||||
"pt-PT",
|
||||
"rm",
|
||||
"ro",
|
||||
"ru",
|
||||
"si",
|
||||
"sk",
|
||||
"sl",
|
||||
"son",
|
||||
"sq",
|
||||
"sr",
|
||||
"sv-SE",
|
||||
"ta",
|
||||
"te",
|
||||
"th",
|
||||
"tl",
|
||||
"tr",
|
||||
"uk",
|
||||
"ur",
|
||||
"uz",
|
||||
"vi",
|
||||
"wo",
|
||||
"xh",
|
||||
"zh-CN",
|
||||
"zh-TW"
|
||||
];
|
@ -6,7 +6,7 @@ const path = require("path");
|
||||
// Note: this file is generated by webpack from content-src/activity-stream-prerender.jsx
|
||||
const {prerender} = require("./prerender");
|
||||
|
||||
const DEFAULT_LOCALE = "en-US";
|
||||
const {CENTRAL_LOCALES, DEFAULT_LOCALE} = require("./locales");
|
||||
|
||||
// Note: DEFAULT_OPTIONS.baseUrl should match BASE_URL in aboutNewTabService.js
|
||||
// in mozilla-central.
|
||||
@ -15,116 +15,6 @@ const DEFAULT_OPTIONS = {
|
||||
baseUrl: "resource://activity-stream/"
|
||||
};
|
||||
|
||||
// This locales list is to find any similar locales that we can reuse strings
|
||||
// instead of falling back to the default, e.g., use bn-BD strings for bn-IN.
|
||||
// https://hg.mozilla.org/mozilla-central/file/tip/browser/locales/l10n.toml
|
||||
const CENTRAL_LOCALES = [
|
||||
"ach",
|
||||
"af",
|
||||
"an",
|
||||
"ar",
|
||||
"as",
|
||||
"ast",
|
||||
"az",
|
||||
"be",
|
||||
"bg",
|
||||
"bn-BD",
|
||||
"bn-IN",
|
||||
"br",
|
||||
"bs",
|
||||
"ca",
|
||||
"cak",
|
||||
"crh",
|
||||
"cs",
|
||||
"cy",
|
||||
"da",
|
||||
"de",
|
||||
"dsb",
|
||||
"el",
|
||||
"en-CA",
|
||||
"en-GB",
|
||||
"en-ZA",
|
||||
"eo",
|
||||
"es-AR",
|
||||
"es-CL",
|
||||
"es-ES",
|
||||
"es-MX",
|
||||
"et",
|
||||
"eu",
|
||||
"fa",
|
||||
"ff",
|
||||
"fi",
|
||||
"fr",
|
||||
"fy-NL",
|
||||
"ga-IE",
|
||||
"gd",
|
||||
"gl",
|
||||
"gn",
|
||||
"gu-IN",
|
||||
"he",
|
||||
"hi-IN",
|
||||
"hr",
|
||||
"hsb",
|
||||
"hu",
|
||||
"hy-AM",
|
||||
"ia",
|
||||
"id",
|
||||
"is",
|
||||
"it",
|
||||
"ja",
|
||||
"ja-JP-mac",
|
||||
"ka",
|
||||
"kab",
|
||||
"kk",
|
||||
"km",
|
||||
"kn",
|
||||
"ko",
|
||||
"lij",
|
||||
"lo",
|
||||
"lt",
|
||||
"ltg",
|
||||
"lv",
|
||||
"mai",
|
||||
"mk",
|
||||
"ml",
|
||||
"mr",
|
||||
"ms",
|
||||
"my",
|
||||
"nb-NO",
|
||||
"ne-NP",
|
||||
"nl",
|
||||
"nn-NO",
|
||||
"oc",
|
||||
"or",
|
||||
"pa-IN",
|
||||
"pl",
|
||||
"pt-BR",
|
||||
"pt-PT",
|
||||
"rm",
|
||||
"ro",
|
||||
"ru",
|
||||
"si",
|
||||
"sk",
|
||||
"sl",
|
||||
"son",
|
||||
"sq",
|
||||
"sr",
|
||||
"sv-SE",
|
||||
"ta",
|
||||
"te",
|
||||
"th",
|
||||
"tl",
|
||||
"tr",
|
||||
"uk",
|
||||
"ur",
|
||||
"uz",
|
||||
"vi",
|
||||
"wo",
|
||||
"xh",
|
||||
"zh-CN",
|
||||
"zh-TW"
|
||||
];
|
||||
|
||||
// Locales that should be displayed RTL
|
||||
const RTL_LIST = ["ar", "he", "fa", "ur"];
|
||||
|
||||
|
@ -7,7 +7,7 @@ const fetch = require("node-fetch");
|
||||
/* globals cd, ls, mkdir, rm, ShellString */
|
||||
require("shelljs/global");
|
||||
|
||||
const DEFAULT_LOCALE = "en-US";
|
||||
const {CENTRAL_LOCALES, DEFAULT_LOCALE} = require("./locales");
|
||||
const L10N_CENTRAL = "https://hg.mozilla.org/l10n-central";
|
||||
const PROPERTIES_PATH = "raw-file/default/browser/chrome/browser/activity-stream/newtab.properties";
|
||||
const STRINGS_FILE = "strings.properties";
|
||||
@ -16,16 +16,21 @@ const STRINGS_FILE = "strings.properties";
|
||||
async function getLocales() {
|
||||
console.log(`Getting locales from ${L10N_CENTRAL}`);
|
||||
|
||||
// Add all non-test sub repository locales
|
||||
// Add sub repository locales that mozilla-central builds
|
||||
const locales = [];
|
||||
const unbuilt = [];
|
||||
const subrepos = await (await fetch(`${L10N_CENTRAL}?style=json`)).json();
|
||||
subrepos.entries.forEach(({name}) => {
|
||||
if (name !== "x-testing") {
|
||||
if (CENTRAL_LOCALES.includes(name)) {
|
||||
locales.push(name);
|
||||
} else {
|
||||
unbuilt.push(name);
|
||||
}
|
||||
});
|
||||
|
||||
console.log(`Got ${locales.length} locales: ${locales}`);
|
||||
console.log(`Got ${locales.length} mozilla-central locales: ${locales}`);
|
||||
console.log(`Skipped ${unbuilt.length} unbuilt locales: ${unbuilt}`);
|
||||
|
||||
return locales;
|
||||
}
|
||||
|
||||
@ -62,9 +67,17 @@ async function updateLocales() {
|
||||
}
|
||||
});
|
||||
|
||||
// Save the properties file for each locale in parallel
|
||||
const locales = await getLocales();
|
||||
const missing = (await Promise.all(locales.map(saveProperties))).filter(v => v);
|
||||
// Save the properties file for each locale one at a time to avoid too many
|
||||
// parallel connections (resulting in ECONNRESET / socket hang up)
|
||||
const missing = [];
|
||||
for (const locale of await getLocales()) {
|
||||
process.stdout.write(`${locale} `);
|
||||
if (await saveProperties(locale)) {
|
||||
missing.push(locale);
|
||||
}
|
||||
}
|
||||
|
||||
console.log("");
|
||||
console.log(`Skipped ${missing.length} locales without strings: ${missing.sort()}`);
|
||||
|
||||
console.log(`
|
||||
|
@ -21,7 +21,7 @@ export class ModalOverlay extends React.PureComponent {
|
||||
<h2> {title} </h2>
|
||||
{this.props.children}
|
||||
<div className="footer">
|
||||
<button onClick={this.props.onDoneButton} className="button primary modalButton"> {button_label} </button>
|
||||
<button tabIndex="2" onClick={this.props.onDoneButton} className="button primary modalButton"> {button_label} </button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -99,6 +99,12 @@
|
||||
height: 30px;
|
||||
padding: 4px 0 6px;
|
||||
font-size: 15px;
|
||||
|
||||
&:focus,
|
||||
&.active {
|
||||
box-shadow: $shadow-primary;
|
||||
transition: box-shadow 150ms;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ Field name | Type | Required | Description | Example / Note
|
||||
`publish_end` | `date` | No | When to stop showing the message | `1524474850876`
|
||||
`content` | `object` | Yes | An object containing all variables/props to be rendered in the template. Subset of allowed tags detailed below. | [See example below](#html-subset)
|
||||
`campaign` | `string` | No | Campaign id that the message belongs to | `RustWebAssembly`
|
||||
`targeting` | `string` `JEXL` | No | A [JEXL expression](http://normandy.readthedocs.io/en/latest/user/filter_expressions.html#jexl-basics) with all targeting information needed in order to decide if the message is shown | Not yet implemented, [some examples](http://normandy.readthedocs.io/en/latest/user/filter_expressions.html#examples)
|
||||
`targeting` | `string` `JEXL` | No | A [JEXL expression](http://normandy.readthedocs.io/en/latest/user/filter_expressions.html#jexl-basics) with all targeting information needed in order to decide if the message is shown | Not yet implemented, [Examples](#targeting-attributes)
|
||||
`trigger` | `string` | No | An event or condition upon which the message will be immediately shown. This can be combined with `targeting`. Messages that define a trigger will not be shown during non-trigger-based passive message rotation.
|
||||
|
||||
### Message example
|
||||
@ -43,3 +43,62 @@ Links cannot be rendered using regular anchor tags because [Fluent does not allo
|
||||
If a tag that is not on the allowed is used, the text content will be extracted and displayed.
|
||||
|
||||
Grouping multiple allowed elements is not possible, only the first level will be used: `<u><b>text</b></u>` will be interpreted as `<u>text</u>`.
|
||||
|
||||
### Targeting attributes
|
||||
For a more in-depth explanation of JEXL syntax you can read the [Normady project docs](https://normandy.readthedocs.io/en/stable/user/filters.html#jexl-basics).
|
||||
|
||||
Currently we expose the following targeting attributes that can be used by messages:
|
||||
|
||||
Name | Type | Example value | Description
|
||||
--- | --- | --- | ---
|
||||
`profileAgeCreated` | Number | `1522843725924` | Profile creation timestamp
|
||||
`profileAgeReset` | `Number` or `undefined` | `1522843725924` | When (if) the profile was reset
|
||||
`hasFxAccount` | `Boolean` | `true` | Does the user have a firefox account
|
||||
`addonsInfo` | `Object` | [example below](#addonsinfo-example) | Information about the addons the user has installed
|
||||
|
||||
#### addonsInfo Example
|
||||
|
||||
```javascript
|
||||
{
|
||||
"addons": {
|
||||
...
|
||||
"activity-stream@mozilla.org": {
|
||||
"version": "2018.07.06.1113-783442c0",
|
||||
"type": "extension",
|
||||
"isSystem": true,
|
||||
"isWebExtension": false,
|
||||
"name": "Activity Stream",
|
||||
"userDisabled": false,
|
||||
"installDate": "2018-03-10T03:41:06.000Z"
|
||||
}
|
||||
},
|
||||
"isFullData": true
|
||||
}
|
||||
```
|
||||
|
||||
#### Usage
|
||||
A message needs to contain the `targeting` property (JEXL string) which is evaluated against the provided attributes.
|
||||
Examples:
|
||||
|
||||
```javascript
|
||||
{
|
||||
"id": "7864",
|
||||
"content": {...},
|
||||
// simple equality check
|
||||
"targeting": "hasFxAccount == true"
|
||||
}
|
||||
|
||||
{
|
||||
"id": "7865",
|
||||
"content": {...},
|
||||
// using JEXL transforms and combining two attributes
|
||||
"targeting": "hasFxAccount == true && profileAgeCreated > '2018-01-07'|date"
|
||||
}
|
||||
|
||||
{
|
||||
"id": "7866",
|
||||
"content": {...},
|
||||
// targeting addon information
|
||||
"targeting": "addonsInfo.addons['activity-stream@mozilla.org'].name == 'Activity Stream'"
|
||||
}
|
||||
```
|
||||
|
@ -24,7 +24,7 @@ class OnboardingCard extends React.PureComponent {
|
||||
<p> {content.text} </p>
|
||||
</span>
|
||||
<span>
|
||||
<button className="button onboardingButton" onClick={this.onClick}> {content.button_label} </button>
|
||||
<button tabIndex="1" className="button onboardingButton" onClick={this.onClick}> {content.button_label} </button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -131,6 +131,12 @@
|
||||
float: none;
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
&:focus,
|
||||
&.active {
|
||||
box-shadow: $shadow-primary;
|
||||
transition: box-shadow 150ms;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
import {actionCreators as ac, actionTypes as at} from "common/Actions.jsm";
|
||||
import {FormattedMessage, injectIntl} from "react-intl";
|
||||
import {actionCreators as ac} from "common/Actions.jsm";
|
||||
import {connect} from "react-redux";
|
||||
import React from "react";
|
||||
|
||||
@ -15,8 +15,29 @@ export class _StartupOverlay extends React.PureComponent {
|
||||
|
||||
this.state = {
|
||||
emailInput: "",
|
||||
overlayRemoved: false
|
||||
overlayRemoved: false,
|
||||
flowId: "",
|
||||
flowBeginTime: 0
|
||||
};
|
||||
this.didFetch = false;
|
||||
}
|
||||
|
||||
async componentWillUpdate() {
|
||||
if (this.props.fxa_endpoint && !this.didFetch) {
|
||||
try {
|
||||
this.didFetch = true;
|
||||
const response = await fetch(`${this.props.fxa_endpoint}/metrics-flow`);
|
||||
if (response.status === 200) {
|
||||
const {flowId, flowBeginTime} = await response.json();
|
||||
this.setState({flowId, flowBeginTime});
|
||||
}
|
||||
} catch (error) {
|
||||
this.props.dispatch(ac.OnlyToMain({type: at.TELEMETRY_UNDESIRED_EVENT, data: {value: "FXA_METRICS_ERROR"}}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.initScene();
|
||||
}
|
||||
|
||||
@ -71,8 +92,9 @@ export class _StartupOverlay extends React.PureComponent {
|
||||
return null;
|
||||
}
|
||||
|
||||
let termsLink = (<a href="https://accounts.firefox.com/legal/terms" target="_blank" rel="noopener noreferrer"><FormattedMessage id="firstrun_terms_of_service" /></a>);
|
||||
let privacyLink = (<a href="https://accounts.firefox.com/legal/privacy" target="_blank" rel="noopener noreferrer"><FormattedMessage id="firstrun_privacy_notice" /></a>);
|
||||
let termsLink = (<a href={`${this.props.fxa_endpoint}/legal/terms`} target="_blank" rel="noopener noreferrer"><FormattedMessage id="firstrun_terms_of_service" /></a>);
|
||||
let privacyLink = (<a href={`${this.props.fxa_endpoint}/legal/privacy`} target="_blank" rel="noopener noreferrer"><FormattedMessage id="firstrun_privacy_notice" /></a>);
|
||||
|
||||
return (
|
||||
<div className={`overlay-wrapper ${this.state.show ? "show" : ""}`}>
|
||||
<div className="background" />
|
||||
@ -85,13 +107,15 @@ export class _StartupOverlay extends React.PureComponent {
|
||||
</div>
|
||||
<div className="firstrun-sign-in">
|
||||
<p className="form-header"><FormattedMessage id="firstrun_form_header" /><span className="sub-header"><FormattedMessage id="firstrun_form_sub_header" /></span></p>
|
||||
<form method="get" action="https://accounts.firefox.com" target="_blank" rel="noopener noreferrer" onSubmit={this.onSubmit}>
|
||||
<form method="get" action={this.props.fxa_endpoint} target="_blank" rel="noopener noreferrer" onSubmit={this.onSubmit}>
|
||||
<input name="service" type="hidden" value="sync" />
|
||||
<input name="action" type="hidden" value="email" />
|
||||
<input name="context" type="hidden" value="fx_desktop_v3" />
|
||||
<input name="entrypoint" type="hidden" value="activity-stream-firstrun" />
|
||||
<input name="utm_source" type="hidden" value="activity-stream" />
|
||||
<input name="utm_campaign" type="hidden" value="firstrun" />
|
||||
<input name="flow_id" type="hidden" value={this.state.flowId} />
|
||||
<input name="flow_begin_time" type="hidden" value={this.state.flowBeginTime} />
|
||||
<span className="error">{this.props.intl.formatMessage({id: "firstrun_invalid_input"})}</span>
|
||||
<input className="email-input" name="email" type="email" required="true" onInvalid={this.onInputInvalid} placeholder={this.props.intl.formatMessage({id: "firstrun_email_input_placeholder"})} onChange={this.onInputChange} />
|
||||
<div className="extra-links">
|
||||
@ -113,4 +137,5 @@ export class _StartupOverlay extends React.PureComponent {
|
||||
}
|
||||
}
|
||||
|
||||
export const StartupOverlay = connect()(injectIntl(_StartupOverlay));
|
||||
const getState = state => ({fxa_endpoint: state.Prefs.values.fxa_endpoint});
|
||||
export const StartupOverlay = connect(getState)(injectIntl(_StartupOverlay));
|
||||
|
@ -18,7 +18,8 @@ body {
|
||||
font-size: 16px;
|
||||
overflow-y: scroll;
|
||||
|
||||
&.hide-onboarding, &.hide-main > #onboarding-overlay-button {
|
||||
&.hide-onboarding > #onboarding-overlay-button,
|
||||
&.hide-main > #onboarding-overlay-button {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
|
@ -230,7 +230,8 @@ body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Ubuntu', 'Helvetica Neue', sans-serif;
|
||||
font-size: 16px;
|
||||
overflow-y: scroll; }
|
||||
body.hide-onboarding, body.hide-main > #onboarding-overlay-button {
|
||||
body.hide-onboarding > #onboarding-overlay-button,
|
||||
body.hide-main > #onboarding-overlay-button {
|
||||
display: none !important; }
|
||||
body.hide-main > #onboarding-notification-bar {
|
||||
display: none; }
|
||||
@ -1844,6 +1845,9 @@ a.firstrun-link {
|
||||
height: 30px;
|
||||
padding: 4px 0 6px;
|
||||
font-size: 15px; }
|
||||
.modalOverlayInner .footer .modalButton:focus, .modalOverlayInner .footer .modalButton.active {
|
||||
box-shadow: 0 0 0 5px var(--newtab-card-active-outline-color);
|
||||
transition: box-shadow 150ms; }
|
||||
|
||||
.SimpleSnippet.tall {
|
||||
padding: 27px 0; }
|
||||
@ -1976,6 +1980,9 @@ a.firstrun-link {
|
||||
.onboardingMessage .onboardingButton {
|
||||
float: none;
|
||||
margin-top: 30px; } }
|
||||
.onboardingMessage .onboardingButton:focus, .onboardingMessage .onboardingButton.active {
|
||||
box-shadow: 0 0 0 5px var(--newtab-card-active-outline-color);
|
||||
transition: box-shadow 150ms; }
|
||||
.onboardingMessage::before {
|
||||
content: '';
|
||||
height: 220px;
|
||||
|
File diff suppressed because one or more lines are too long
@ -233,7 +233,8 @@ body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Ubuntu', 'Helvetica Neue', sans-serif;
|
||||
font-size: 16px;
|
||||
overflow-y: scroll; }
|
||||
body.hide-onboarding, body.hide-main > #onboarding-overlay-button {
|
||||
body.hide-onboarding > #onboarding-overlay-button,
|
||||
body.hide-main > #onboarding-overlay-button {
|
||||
display: none !important; }
|
||||
body.hide-main > #onboarding-notification-bar {
|
||||
display: none; }
|
||||
@ -1847,6 +1848,9 @@ a.firstrun-link {
|
||||
height: 30px;
|
||||
padding: 4px 0 6px;
|
||||
font-size: 15px; }
|
||||
.modalOverlayInner .footer .modalButton:focus, .modalOverlayInner .footer .modalButton.active {
|
||||
box-shadow: 0 0 0 5px var(--newtab-card-active-outline-color);
|
||||
transition: box-shadow 150ms; }
|
||||
|
||||
.SimpleSnippet.tall {
|
||||
padding: 27px 0; }
|
||||
@ -1979,6 +1983,9 @@ a.firstrun-link {
|
||||
.onboardingMessage .onboardingButton {
|
||||
float: none;
|
||||
margin-top: 30px; } }
|
||||
.onboardingMessage .onboardingButton:focus, .onboardingMessage .onboardingButton.active {
|
||||
box-shadow: 0 0 0 5px var(--newtab-card-active-outline-color);
|
||||
transition: box-shadow 150ms; }
|
||||
.onboardingMessage::before {
|
||||
content: '';
|
||||
height: 220px;
|
||||
|
File diff suppressed because one or more lines are too long
@ -230,7 +230,8 @@ body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Ubuntu', 'Helvetica Neue', sans-serif;
|
||||
font-size: 16px;
|
||||
overflow-y: scroll; }
|
||||
body.hide-onboarding, body.hide-main > #onboarding-overlay-button {
|
||||
body.hide-onboarding > #onboarding-overlay-button,
|
||||
body.hide-main > #onboarding-overlay-button {
|
||||
display: none !important; }
|
||||
body.hide-main > #onboarding-notification-bar {
|
||||
display: none; }
|
||||
@ -1844,6 +1845,9 @@ a.firstrun-link {
|
||||
height: 30px;
|
||||
padding: 4px 0 6px;
|
||||
font-size: 15px; }
|
||||
.modalOverlayInner .footer .modalButton:focus, .modalOverlayInner .footer .modalButton.active {
|
||||
box-shadow: 0 0 0 5px var(--newtab-card-active-outline-color);
|
||||
transition: box-shadow 150ms; }
|
||||
|
||||
.SimpleSnippet.tall {
|
||||
padding: 27px 0; }
|
||||
@ -1976,6 +1980,9 @@ a.firstrun-link {
|
||||
.onboardingMessage .onboardingButton {
|
||||
float: none;
|
||||
margin-top: 30px; } }
|
||||
.onboardingMessage .onboardingButton:focus, .onboardingMessage .onboardingButton.active {
|
||||
box-shadow: 0 0 0 5px var(--newtab-card-active-outline-color);
|
||||
transition: box-shadow 150ms; }
|
||||
.onboardingMessage::before {
|
||||
content: '';
|
||||
height: 220px;
|
||||
|
File diff suppressed because one or more lines are too long
@ -4605,13 +4605,15 @@ const TopSiteList = Object(react_intl__WEBPACK_IMPORTED_MODULE_1__["injectIntl"]
|
||||
__webpack_require__.r(__webpack_exports__);
|
||||
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_StartupOverlay", function() { return _StartupOverlay; });
|
||||
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "StartupOverlay", function() { return StartupOverlay; });
|
||||
/* harmony import */ var react_intl__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(13);
|
||||
/* harmony import */ var react_intl__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react_intl__WEBPACK_IMPORTED_MODULE_0__);
|
||||
/* harmony import */ var common_Actions_jsm__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2);
|
||||
/* harmony import */ var common_Actions_jsm__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2);
|
||||
/* harmony import */ var react_intl__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(13);
|
||||
/* harmony import */ var react_intl__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react_intl__WEBPACK_IMPORTED_MODULE_1__);
|
||||
/* harmony import */ var react_redux__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(16);
|
||||
/* harmony import */ var react_redux__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(react_redux__WEBPACK_IMPORTED_MODULE_2__);
|
||||
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(5);
|
||||
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_3__);
|
||||
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
|
||||
|
||||
|
||||
|
||||
|
||||
@ -4629,8 +4631,33 @@ class _StartupOverlay extends react__WEBPACK_IMPORTED_MODULE_3___default.a.PureC
|
||||
|
||||
this.state = {
|
||||
emailInput: "",
|
||||
overlayRemoved: false
|
||||
overlayRemoved: false,
|
||||
flowId: "",
|
||||
flowBeginTime: 0
|
||||
};
|
||||
this.didFetch = false;
|
||||
}
|
||||
|
||||
componentWillUpdate() {
|
||||
var _this = this;
|
||||
|
||||
return _asyncToGenerator(function* () {
|
||||
if (_this.props.fxa_endpoint && !_this.didFetch) {
|
||||
try {
|
||||
_this.didFetch = true;
|
||||
const response = yield fetch(`${_this.props.fxa_endpoint}/metrics-flow`);
|
||||
if (response.status === 200) {
|
||||
const { flowId, flowBeginTime } = yield response.json();
|
||||
_this.setState({ flowId, flowBeginTime });
|
||||
}
|
||||
} catch (error) {
|
||||
_this.props.dispatch(common_Actions_jsm__WEBPACK_IMPORTED_MODULE_0__["actionCreators"].OnlyToMain({ type: common_Actions_jsm__WEBPACK_IMPORTED_MODULE_0__["actionTypes"].TELEMETRY_UNDESIRED_EVENT, data: { value: "FXA_METRICS_ERROR" } }));
|
||||
}
|
||||
}
|
||||
})();
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.initScene();
|
||||
}
|
||||
|
||||
@ -4661,12 +4688,12 @@ class _StartupOverlay extends react__WEBPACK_IMPORTED_MODULE_3___default.a.PureC
|
||||
}
|
||||
|
||||
onSubmit() {
|
||||
this.props.dispatch(common_Actions_jsm__WEBPACK_IMPORTED_MODULE_1__["actionCreators"].UserEvent({ event: "SUBMIT_EMAIL" }));
|
||||
this.props.dispatch(common_Actions_jsm__WEBPACK_IMPORTED_MODULE_0__["actionCreators"].UserEvent({ event: "SUBMIT_EMAIL" }));
|
||||
window.addEventListener("visibilitychange", this.removeOverlay);
|
||||
}
|
||||
|
||||
clickSkip() {
|
||||
this.props.dispatch(common_Actions_jsm__WEBPACK_IMPORTED_MODULE_1__["actionCreators"].UserEvent({ event: "SKIPPED_SIGNIN" }));
|
||||
this.props.dispatch(common_Actions_jsm__WEBPACK_IMPORTED_MODULE_0__["actionCreators"].UserEvent({ event: "SKIPPED_SIGNIN" }));
|
||||
this.removeOverlay();
|
||||
}
|
||||
|
||||
@ -4687,14 +4714,15 @@ class _StartupOverlay extends react__WEBPACK_IMPORTED_MODULE_3___default.a.PureC
|
||||
|
||||
let termsLink = react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement(
|
||||
"a",
|
||||
{ href: "https://accounts.firefox.com/legal/terms", target: "_blank", rel: "noopener noreferrer" },
|
||||
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement(react_intl__WEBPACK_IMPORTED_MODULE_0__["FormattedMessage"], { id: "firstrun_terms_of_service" })
|
||||
{ href: `${this.props.fxa_endpoint}/legal/terms`, target: "_blank", rel: "noopener noreferrer" },
|
||||
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement(react_intl__WEBPACK_IMPORTED_MODULE_1__["FormattedMessage"], { id: "firstrun_terms_of_service" })
|
||||
);
|
||||
let privacyLink = react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement(
|
||||
"a",
|
||||
{ href: "https://accounts.firefox.com/legal/privacy", target: "_blank", rel: "noopener noreferrer" },
|
||||
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement(react_intl__WEBPACK_IMPORTED_MODULE_0__["FormattedMessage"], { id: "firstrun_privacy_notice" })
|
||||
{ href: `${this.props.fxa_endpoint}/legal/privacy`, target: "_blank", rel: "noopener noreferrer" },
|
||||
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement(react_intl__WEBPACK_IMPORTED_MODULE_1__["FormattedMessage"], { id: "firstrun_privacy_notice" })
|
||||
);
|
||||
|
||||
return react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement(
|
||||
"div",
|
||||
{ className: `overlay-wrapper ${this.state.show ? "show" : ""}` },
|
||||
@ -4711,17 +4739,17 @@ class _StartupOverlay extends react__WEBPACK_IMPORTED_MODULE_3___default.a.PureC
|
||||
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement(
|
||||
"h1",
|
||||
{ className: "firstrun-title" },
|
||||
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement(react_intl__WEBPACK_IMPORTED_MODULE_0__["FormattedMessage"], { id: "firstrun_title" })
|
||||
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement(react_intl__WEBPACK_IMPORTED_MODULE_1__["FormattedMessage"], { id: "firstrun_title" })
|
||||
),
|
||||
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement(
|
||||
"p",
|
||||
{ className: "firstrun-content" },
|
||||
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement(react_intl__WEBPACK_IMPORTED_MODULE_0__["FormattedMessage"], { id: "firstrun_content" })
|
||||
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement(react_intl__WEBPACK_IMPORTED_MODULE_1__["FormattedMessage"], { id: "firstrun_content" })
|
||||
),
|
||||
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement(
|
||||
"a",
|
||||
{ className: "firstrun-link", href: "https://www.mozilla.org/firefox/features/sync/", target: "_blank", rel: "noopener noreferrer" },
|
||||
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement(react_intl__WEBPACK_IMPORTED_MODULE_0__["FormattedMessage"], { id: "firstrun_learn_more_link" })
|
||||
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement(react_intl__WEBPACK_IMPORTED_MODULE_1__["FormattedMessage"], { id: "firstrun_learn_more_link" })
|
||||
)
|
||||
),
|
||||
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement(
|
||||
@ -4730,22 +4758,24 @@ class _StartupOverlay extends react__WEBPACK_IMPORTED_MODULE_3___default.a.PureC
|
||||
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement(
|
||||
"p",
|
||||
{ className: "form-header" },
|
||||
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement(react_intl__WEBPACK_IMPORTED_MODULE_0__["FormattedMessage"], { id: "firstrun_form_header" }),
|
||||
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement(react_intl__WEBPACK_IMPORTED_MODULE_1__["FormattedMessage"], { id: "firstrun_form_header" }),
|
||||
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement(
|
||||
"span",
|
||||
{ className: "sub-header" },
|
||||
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement(react_intl__WEBPACK_IMPORTED_MODULE_0__["FormattedMessage"], { id: "firstrun_form_sub_header" })
|
||||
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement(react_intl__WEBPACK_IMPORTED_MODULE_1__["FormattedMessage"], { id: "firstrun_form_sub_header" })
|
||||
)
|
||||
),
|
||||
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement(
|
||||
"form",
|
||||
{ method: "get", action: "https://accounts.firefox.com", target: "_blank", rel: "noopener noreferrer", onSubmit: this.onSubmit },
|
||||
{ method: "get", action: this.props.fxa_endpoint, target: "_blank", rel: "noopener noreferrer", onSubmit: this.onSubmit },
|
||||
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement("input", { name: "service", type: "hidden", value: "sync" }),
|
||||
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement("input", { name: "action", type: "hidden", value: "email" }),
|
||||
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement("input", { name: "context", type: "hidden", value: "fx_desktop_v3" }),
|
||||
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement("input", { name: "entrypoint", type: "hidden", value: "activity-stream-firstrun" }),
|
||||
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement("input", { name: "utm_source", type: "hidden", value: "activity-stream" }),
|
||||
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement("input", { name: "utm_campaign", type: "hidden", value: "firstrun" }),
|
||||
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement("input", { name: "flow_id", type: "hidden", value: this.state.flowId }),
|
||||
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement("input", { name: "flow_begin_time", type: "hidden", value: this.state.flowBeginTime }),
|
||||
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement(
|
||||
"span",
|
||||
{ className: "error" },
|
||||
@ -4755,7 +4785,7 @@ class _StartupOverlay extends react__WEBPACK_IMPORTED_MODULE_3___default.a.PureC
|
||||
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement(
|
||||
"div",
|
||||
{ className: "extra-links" },
|
||||
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement(react_intl__WEBPACK_IMPORTED_MODULE_0__["FormattedMessage"], {
|
||||
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement(react_intl__WEBPACK_IMPORTED_MODULE_1__["FormattedMessage"], {
|
||||
id: "firstrun_extra_legal_links",
|
||||
values: {
|
||||
terms: termsLink,
|
||||
@ -4765,13 +4795,13 @@ class _StartupOverlay extends react__WEBPACK_IMPORTED_MODULE_3___default.a.PureC
|
||||
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement(
|
||||
"button",
|
||||
{ className: "continue-button", type: "submit" },
|
||||
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement(react_intl__WEBPACK_IMPORTED_MODULE_0__["FormattedMessage"], { id: "firstrun_continue_to_login" })
|
||||
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement(react_intl__WEBPACK_IMPORTED_MODULE_1__["FormattedMessage"], { id: "firstrun_continue_to_login" })
|
||||
)
|
||||
),
|
||||
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement(
|
||||
"button",
|
||||
{ className: "skip-button", disabled: !!this.state.emailInput, onClick: this.clickSkip },
|
||||
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement(react_intl__WEBPACK_IMPORTED_MODULE_0__["FormattedMessage"], { id: "firstrun_skip_login" })
|
||||
react__WEBPACK_IMPORTED_MODULE_3___default.a.createElement(react_intl__WEBPACK_IMPORTED_MODULE_1__["FormattedMessage"], { id: "firstrun_skip_login" })
|
||||
)
|
||||
)
|
||||
)
|
||||
@ -4780,7 +4810,8 @@ class _StartupOverlay extends react__WEBPACK_IMPORTED_MODULE_3___default.a.PureC
|
||||
}
|
||||
}
|
||||
|
||||
const StartupOverlay = Object(react_redux__WEBPACK_IMPORTED_MODULE_2__["connect"])()(Object(react_intl__WEBPACK_IMPORTED_MODULE_0__["injectIntl"])(_StartupOverlay));
|
||||
const getState = state => ({ fxa_endpoint: state.Prefs.values.fxa_endpoint });
|
||||
const StartupOverlay = Object(react_redux__WEBPACK_IMPORTED_MODULE_2__["connect"])(getState)(Object(react_intl__WEBPACK_IMPORTED_MODULE_1__["injectIntl"])(_StartupOverlay));
|
||||
|
||||
/***/ }),
|
||||
/* 37 */
|
||||
@ -8100,7 +8131,7 @@ class ModalOverlay_ModalOverlay extends external_React_default.a.PureComponent {
|
||||
{ className: "footer" },
|
||||
external_React_default.a.createElement(
|
||||
"button",
|
||||
{ onClick: this.props.onDoneButton, className: "button primary modalButton" },
|
||||
{ tabIndex: "2", onClick: this.props.onDoneButton, className: "button primary modalButton" },
|
||||
" ",
|
||||
button_label,
|
||||
" "
|
||||
@ -8161,7 +8192,7 @@ class OnboardingMessage_OnboardingCard extends external_React_default.a.PureComp
|
||||
null,
|
||||
external_React_default.a.createElement(
|
||||
"button",
|
||||
{ className: "button onboardingButton", onClick: this.onClick },
|
||||
{ tabIndex: "1", className: "button onboardingButton", onClick: this.onClick },
|
||||
" ",
|
||||
content.button_label,
|
||||
" "
|
||||
|
File diff suppressed because one or more lines are too long
@ -8,7 +8,7 @@
|
||||
<em:type>2</em:type>
|
||||
<em:bootstrap>true</em:bootstrap>
|
||||
<em:unpack>false</em:unpack>
|
||||
<em:version>2018.07.12.1202-ecc4456e</em:version>
|
||||
<em:version>2018.07.16.1239-6f362fbc</em:version>
|
||||
<em:name>Activity Stream</em:name>
|
||||
<em:description>A rich visual history feed and a reimagined home page make it easier than ever to find exactly what you're looking for in Firefox.</em:description>
|
||||
<em:multiprocessCompatible>true</em:multiprocessCompatible>
|
||||
|
@ -16,9 +16,6 @@ const INCOMING_MESSAGE_NAME = "ASRouter:child-to-parent";
|
||||
const OUTGOING_MESSAGE_NAME = "ASRouter:parent-to-child";
|
||||
const ONE_HOUR_IN_MS = 60 * 60 * 1000;
|
||||
const SNIPPETS_ENDPOINT_PREF = "browser.newtabpage.activity-stream.asrouter.snippetsUrl";
|
||||
// Note: currently a restart is required when this pref is changed, this will be fixed in Bug 1462114
|
||||
const SNIPPETS_ENDPOINT = Services.prefs.getStringPref(SNIPPETS_ENDPOINT_PREF,
|
||||
"https://activity-stream-icons.services.mozilla.com/v1/messages.json.br");
|
||||
// List of hosts for endpoints that serve router messages.
|
||||
// Key is allowed host, value is a name for the endpoint host.
|
||||
const WHITELIST_HOSTS = {
|
||||
@ -136,6 +133,35 @@ class _ASRouter {
|
||||
this.onMessage = this.onMessage.bind(this);
|
||||
}
|
||||
|
||||
_addASRouterPrefListener() {
|
||||
this.state.providers.forEach(provider => {
|
||||
if (provider.endpointPref) {
|
||||
Services.prefs.addObserver(provider.endpointPref, this);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Update provider endpoint and fetch new messages on pref change
|
||||
async observe(aSubject, aTopic, aPrefName) {
|
||||
await this.setState(prevState => {
|
||||
const providers = [...prevState.providers];
|
||||
this._updateProviderEndpointUrl(providers.find(p => p.endpointPref === aPrefName));
|
||||
return {providers};
|
||||
});
|
||||
|
||||
await this.loadMessagesFromAllProviders();
|
||||
}
|
||||
|
||||
_updateProviderEndpointUrl(provider) {
|
||||
if (provider && provider.endpointPref) {
|
||||
provider.url = Services.prefs.getStringPref(provider.endpointPref, "");
|
||||
// Reset provider update timestamp to force messages refresh
|
||||
provider.lastUpdated = undefined;
|
||||
}
|
||||
|
||||
return provider;
|
||||
}
|
||||
|
||||
get state() {
|
||||
return this._state;
|
||||
}
|
||||
@ -174,7 +200,7 @@ class _ASRouter {
|
||||
let newState = {messages: [], providers: []};
|
||||
for (const provider of this.state.providers) {
|
||||
if (needsUpdate.includes(provider)) {
|
||||
const {messages, lastUpdated} = await MessageLoaderUtils.loadMessagesForProvider(provider);
|
||||
const {messages, lastUpdated} = await MessageLoaderUtils.loadMessagesForProvider(this._updateProviderEndpointUrl(provider));
|
||||
newState.providers.push({...provider, lastUpdated});
|
||||
newState.messages = [...newState.messages, ...messages];
|
||||
} else {
|
||||
@ -199,6 +225,7 @@ class _ASRouter {
|
||||
async init(channel, storage) {
|
||||
this.messageChannel = channel;
|
||||
this.messageChannel.addMessageListener(INCOMING_MESSAGE_NAME, this.onMessage);
|
||||
this._addASRouterPrefListener();
|
||||
await this.loadMessagesFromAllProviders();
|
||||
this._storage = storage;
|
||||
|
||||
@ -212,6 +239,11 @@ class _ASRouter {
|
||||
this.messageChannel.sendAsyncMessage(OUTGOING_MESSAGE_NAME, {type: "CLEAR_ALL"});
|
||||
this.messageChannel.removeMessageListener(INCOMING_MESSAGE_NAME, this.onMessage);
|
||||
this.messageChannel = null;
|
||||
this.state.providers.forEach(provider => {
|
||||
if (provider.endpointPref) {
|
||||
Services.prefs.removeObserver(provider.endpointPref, this);
|
||||
}
|
||||
});
|
||||
this._resetInitialization();
|
||||
}
|
||||
|
||||
@ -453,7 +485,7 @@ this._ASRouter = _ASRouter;
|
||||
this.ASRouter = new _ASRouter({
|
||||
providers: [
|
||||
{id: "onboarding", type: "local", messages: OnboardingMessageProvider.getMessages()},
|
||||
{id: "snippets", type: "remote", url: SNIPPETS_ENDPOINT, updateCycleInMs: ONE_HOUR_IN_MS * 4}
|
||||
{id: "snippets", type: "remote", endpointPref: SNIPPETS_ENDPOINT_PREF, updateCycleInMs: ONE_HOUR_IN_MS * 4}
|
||||
]
|
||||
});
|
||||
|
||||
|
@ -168,7 +168,7 @@ const PREFS_CONFIG = new Map([
|
||||
}],
|
||||
["asrouter.snippetsUrl", {
|
||||
title: "A custom URL for the AS router snippets",
|
||||
value: ""
|
||||
value: "https://activity-stream-icons.services.mozilla.com/v1/messages.json.br"
|
||||
}]
|
||||
]);
|
||||
|
||||
|
@ -101,6 +101,10 @@ this.PrefsFeed = class PrefsFeed {
|
||||
values.isPrivateBrowsingEnabled = PrivateBrowsingUtils.enabled;
|
||||
values.platform = AppConstants.platform;
|
||||
|
||||
// Get the firefox accounts url for links and to send firstrun metrics to.
|
||||
values.fxa_endpoint = Services.prefs.getStringPref(
|
||||
"browser.newtabpage.activity-stream.fxaccounts.endpoint", "https://accounts.firefox.com");
|
||||
|
||||
// Set the initial state of all prefs in redux
|
||||
this.store.dispatch(ac.BroadcastToContent({type: at.PREFS_INITIAL_VALUES, data: values}));
|
||||
|
||||
|
@ -191,6 +191,8 @@ firstrun_form_sub_header=richin yatok pa Firefox Sync.
|
||||
|
||||
firstrun_email_input_placeholder=Taqoya'l
|
||||
|
||||
firstrun_invalid_input=Najowäx ütz chi taqoya'l
|
||||
|
||||
# LOCALIZATION NOTE (firstrun_extra_legal_links): {terms} is equal to firstrun_terms_of_service, and
|
||||
# {privacy} is equal to firstrun_privacy_notice. {terms} and {privacy} are clickable links.
|
||||
firstrun_extra_legal_links=Toq nasamajij qa, nawojqaj ri {terms} chuqa' {privacy}.
|
||||
|
@ -73,7 +73,7 @@ search_header=Αναζήτηση {search_engine_name}
|
||||
|
||||
# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
|
||||
# the user hasn't typed anything yet.
|
||||
search_web_placeholder=Αναζήτηση στον ιστό
|
||||
search_web_placeholder=Αναζήτηση στο διαδίκτυο
|
||||
|
||||
# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
|
||||
# the topstories section title to provide additional information about
|
||||
@ -95,7 +95,7 @@ prefs_home_description=Επιλέξτε τι περιεχόμενο θέλετε
|
||||
# plural forms used in a drop down of multiple row options (1 row, 2 rows).
|
||||
# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
|
||||
prefs_section_rows_option={num} σειρά;{num} σειρές
|
||||
prefs_search_header=Αναζήτηση ιστού
|
||||
prefs_search_header=Διαδικτυακή αναζήτηση
|
||||
prefs_topsites_description=Οι ιστοσελίδες που επισκέπτεστε περισσότερο
|
||||
prefs_topstories_description2=Εξαιρετικό περιεχόμενο από το διαδίκτυο, εξατομικευμένο για εσάς
|
||||
prefs_topstories_options_sponsored_label=Χορηγούμενες ιστορίες
|
||||
|
@ -191,6 +191,8 @@ firstrun_form_sub_header=por pluiri al Spegulado de Firefox.
|
||||
|
||||
firstrun_email_input_placeholder=Retpoŝta adreso
|
||||
|
||||
firstrun_invalid_input=Valida retpoŝta adreso postulata
|
||||
|
||||
# LOCALIZATION NOTE (firstrun_extra_legal_links): {terms} is equal to firstrun_terms_of_service, and
|
||||
# {privacy} is equal to firstrun_privacy_notice. {terms} and {privacy} are clickable links.
|
||||
firstrun_extra_legal_links=Se vi daŭrigas vi akceptas la {terms} kaj {privacy}.
|
||||
|
@ -49,6 +49,7 @@ menu_action_archive_pocket=पॉकेट में पुरालेख
|
||||
# found in the context menu of an item that has been downloaded. The intention behind
|
||||
# "this action" is that it will show where the downloaded file exists on the file system
|
||||
# for each operating system.
|
||||
menu_action_show_file_mac_os=फाइंडर में दिखाएँ
|
||||
menu_action_show_file_windows=संग्राहक फोल्डर खोलें
|
||||
menu_action_show_file_linux=संग्राहक फोल्डर खोलें
|
||||
menu_action_show_file_default=फ़ाइल दिखाएं
|
||||
@ -101,6 +102,7 @@ prefs_topstories_options_sponsored_label=प्रायोजित कहा
|
||||
prefs_topstories_sponsored_learn_more=अधिक जानें
|
||||
prefs_highlights_description=आपके द्वारा सहेजी गई या विज़िट की गई साइटों का चयन
|
||||
prefs_highlights_options_visited_label=देखे गए पृष्ठ
|
||||
prefs_highlights_options_download_label=सबसे हालिया डाउनलोड
|
||||
prefs_highlights_options_pocket_label=पॉकेट में सहेजे गए पृष्ठ
|
||||
prefs_snippets_description=Mozilla और Firefox से अद्यतन
|
||||
settings_pane_button_label=अपने नए टैब पृष्ठ को अनुकूलित करें
|
||||
|
@ -1,113 +0,0 @@
|
||||
|
||||
# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
|
||||
# of the corresponding content provider.
|
||||
|
||||
# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
|
||||
# the context menu button is focused/active. Title is the label or hostname of
|
||||
# the site.
|
||||
|
||||
# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
|
||||
# the section edit context menu button is focused/active.
|
||||
|
||||
# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
|
||||
# context on how the element is related to the user, e.g. type indicates that
|
||||
# the page is bookmarked, or is currently open on another device
|
||||
|
||||
# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
|
||||
# menu and are meant as a call to action for a given page.
|
||||
# LOCALIZATION NOTE (menu_action_bookmark): Bookmark is a verb, as in "Add to
|
||||
# bookmarks"
|
||||
menu_action_pin=Chita'an
|
||||
# LOCALIZATION NOTE (confirm_history_delete_notice_p2): this string is displayed in
|
||||
# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
|
||||
# page from history.
|
||||
|
||||
# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
|
||||
# found in the context menu of an item that has been downloaded. The intention behind
|
||||
# "this action" is that it will show where the downloaded file exists on the file system
|
||||
# for each operating system.
|
||||
menu_action_open_file=Kuna tutu
|
||||
|
||||
# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
|
||||
# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
|
||||
# link that belongs to this downloaded item"
|
||||
|
||||
# LOCALIZATION NOTE (search_button): This is screenreader only text for the
|
||||
# search button.
|
||||
search_button=Nduku
|
||||
|
||||
# LOCALIZATION NOTE (search_header): Displayed at the top of the panel
|
||||
# showing search suggestions. {search_engine_name} is replaced with the name of
|
||||
# the current default search engine. e.g. 'Google Search'
|
||||
search_header={search_engine_name} Nduku
|
||||
|
||||
# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
|
||||
# the user hasn't typed anything yet.
|
||||
search_web_placeholder=Nduku nu Web
|
||||
|
||||
# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
|
||||
# the topstories section title to provide additional information about
|
||||
# how the stories are selected.
|
||||
# LOCALIZATION NOTE (section_disclaimer_topstories_buttontext): The text of
|
||||
# the button used to acknowledge, and hide this disclaimer in the future.
|
||||
|
||||
# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
|
||||
# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
|
||||
# in English, while "Home" should be localized matching the about:preferences
|
||||
# sidebar mozilla-central string for the panel that has preferences related to
|
||||
# what is shown for the homepage, new windows, and new tabs.
|
||||
# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
|
||||
# plural forms used in a drop down of multiple row options (1 row, 2 rows).
|
||||
# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
|
||||
prefs_topstories_sponsored_learn_more=Skua'a kuakaa
|
||||
# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
|
||||
# traditionally on about:home. Alternative translation options: "Small Note" or
|
||||
# something that expresses the idea of "a small message, shortened from
|
||||
# something else, and non-essential but also not entirely trivial and useless."
|
||||
|
||||
# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
|
||||
# dialog.
|
||||
edit_topsites_button_text=Sama
|
||||
|
||||
# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
|
||||
topsites_form_url_label=URL
|
||||
# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
|
||||
topsites_form_add_button=Chikaa
|
||||
topsites_form_save_button=Chika vaà
|
||||
topsites_form_cancel_button=Kunchatu
|
||||
|
||||
# LOCALIZATION NOTE (pocket_read_more): This is shown at the bottom of the
|
||||
# trending stories section and precedes a list of links to popular topics.
|
||||
# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
|
||||
# end of the list of popular topic links.
|
||||
|
||||
# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
|
||||
# in the space that would have shown a few stories, this is shown instead.
|
||||
# {provider} is replaced by the name of the content provider for this section.
|
||||
|
||||
# LOCALIZATION NOTE (manual_migration_explanation2): This message is shown to encourage users to
|
||||
# import their browser profile from another browser they might be using.
|
||||
# LOCALIZATION NOTE (manual_migration_cancel_button): This message is shown on a button that cancels the
|
||||
# process of importing another browser’s profile into Firefox.
|
||||
# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
|
||||
# of importing another browser’s profile profile into Firefox.
|
||||
|
||||
# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
|
||||
# action link are shown in each section of UI that fails to render
|
||||
|
||||
# LOCALIZATION NOTE (section_menu_action_*). These strings are displayed in the section
|
||||
# context menu and are meant as a call to action for the given section.
|
||||
section_menu_action_move_up=Kanta kuchi
|
||||
section_menu_action_move_down=Kanta ninu
|
||||
|
||||
# LOCALIZATION NOTE (firstrun_*). These strings are displayed only once, on the
|
||||
# firstrun of the browser, they give an introduction to Firefox and Sync.
|
||||
|
||||
# LOCALIZATION NOTE (firstrun_form_header and firstrun_form_sub_header):
|
||||
# firstrun_form_sub_header is a continuation of firstrun_form_header, they are one sentence.
|
||||
# firstrun_form_header is displayed more boldly as the call to action.
|
||||
|
||||
|
||||
# LOCALIZATION NOTE (firstrun_extra_legal_links): {terms} is equal to firstrun_terms_of_service, and
|
||||
# {privacy} is equal to firstrun_privacy_notice. {terms} and {privacy} are clickable links.
|
||||
|
@ -190,6 +190,8 @@ firstrun_form_sub_header=per contunhar amb Firefox Sync.
|
||||
|
||||
firstrun_email_input_placeholder=Adreça electronica
|
||||
|
||||
firstrun_invalid_input=Cal una adreça electronica valida
|
||||
|
||||
# LOCALIZATION NOTE (firstrun_extra_legal_links): {terms} is equal to firstrun_terms_of_service, and
|
||||
# {privacy} is equal to firstrun_privacy_notice. {terms} and {privacy} are clickable links.
|
||||
firstrun_extra_legal_links=Se contunhatz, acceptatz las {terms} e l’{privacy}.
|
||||
|
@ -191,6 +191,8 @@ firstrun_form_sub_header=чтобы продолжить использоват
|
||||
|
||||
firstrun_email_input_placeholder=Эл. почта
|
||||
|
||||
firstrun_invalid_input=Введите действующий адрес электронной почты
|
||||
|
||||
# LOCALIZATION NOTE (firstrun_extra_legal_links): {terms} is equal to firstrun_terms_of_service, and
|
||||
# {privacy} is equal to firstrun_privacy_notice. {terms} and {privacy} are clickable links.
|
||||
firstrun_extra_legal_links=Продолжая, вы соглашаетесь с {terms} и {privacy}.
|
||||
|
@ -1,32 +1,24 @@
|
||||
newtab_page_title=නව ටැබය
|
||||
default_label_loading=පූරණය වෙමින්…
|
||||
|
||||
header_top_sites=ප්රමුඛ අඩවි
|
||||
header_stories=ප්රමුඛ පුවත්
|
||||
header_highlights=ඉස්මතු කිරීම්
|
||||
header_visit_again=යළි පිවිසෙන්න
|
||||
header_bookmarks=නැවුම් පිටු සලකුණු
|
||||
# LOCALIZATION NOTE(header_recommended_by): This is followed by the name
|
||||
# of the corresponding content provider.
|
||||
header_recommended_by={provider} විසින් නිර්දේශිතයි
|
||||
# LOCALIZATION NOTE(header_bookmarks_placeholder): This message is
|
||||
# meant to inform that section contains no information because
|
||||
# the user hasn't added any bookmarks.
|
||||
header_bookmarks_placeholder=ඔබ සතුව තවම පිටුසලකුණු නැත.
|
||||
# LOCALIZATION NOTE(header_stories_from): This is followed by a logo of the
|
||||
# corresponding content (stories) provider
|
||||
header_stories_from=සිට
|
||||
|
||||
# LOCALIZATION NOTE(context_menu_button_sr): This is for screen readers when
|
||||
# the context menu button is focused/active. Title is the label or hostname of
|
||||
# the site.
|
||||
|
||||
# LOCALIZATION NOTE(section_context_menu_button_sr): This is for screen readers when
|
||||
# the section edit context menu button is focused/active.
|
||||
|
||||
# LOCALIZATION NOTE (type_label_*): These labels are associated to pages to give
|
||||
# context on how the element is related to the user, e.g. type indicates that
|
||||
# the page is bookmarked, or is currently open on another device
|
||||
type_label_visited=ප්රවේශිත
|
||||
type_label_bookmarked=පිටු සලකුණු තැබූ
|
||||
type_label_synced=වෙනත් උපාංගයක් වෙතින් සමකාලීන කර ඇත
|
||||
# LOCALIZATION NOTE(type_label_open): Open is an adjective, as in "page is open"
|
||||
type_label_open=විවෘත
|
||||
type_label_topic=මාතෘකාව
|
||||
type_label_now=දැන්
|
||||
type_label_pocket=Pocket හි සුරකින ලදී
|
||||
|
||||
# LOCALIZATION NOTE (menu_action_*): These strings are displayed in a context
|
||||
# menu and are meant as a call to action for a given page.
|
||||
@ -34,8 +26,6 @@ type_label_now=දැන්
|
||||
# bookmarks"
|
||||
menu_action_bookmark=පිටු සලකුණ
|
||||
menu_action_remove_bookmark=පිටු සලකුණ ඉවත් කරන්න
|
||||
menu_action_copy_address=ලිපිනය පිටපත් කරන්න
|
||||
menu_action_email_link=විද්යුත් තැපැල් සබැඳි…
|
||||
menu_action_open_new_window=නව කවුළුවක විවෘත කරන්න
|
||||
menu_action_open_private_window=නව පුද්ගලික කවුළුවක විවෘත කරන්න
|
||||
menu_action_dismiss=ඉවත් කරන්න
|
||||
@ -47,12 +37,18 @@ confirm_history_delete_p1=ඔබට මෙම පිටුවට අදාල
|
||||
# the same dialog as confirm_history_delete_p1. "This action" refers to deleting a
|
||||
# page from history.
|
||||
confirm_history_delete_notice_p2=මෙම ක්රියාව අහෝසි කළ නොහැක.
|
||||
menu_action_save_to_pocket=Pocket හි සුරකින්න
|
||||
menu_action_delete_pocket=Pocket වෙතින් මකන්න
|
||||
menu_action_archive_pocket=Pocket හි සංරක්ෂණ කරන්න
|
||||
|
||||
# LOCALIZATION NOTE (search_for_something_with): {search_term} is a placeholder
|
||||
# for what the user has typed in the search input field, e.g. 'Search for ' +
|
||||
# search_term + 'with:' becomes 'Search for abc with:'
|
||||
# The search engine name is displayed as an icon and does not need a translation
|
||||
search_for_something_with={search_term} සදහා සෙවීමට භාවිත කළ යුත්තේ:
|
||||
# LOCALIZATION NOTE (menu_action_show_file_*): These are platform specific strings
|
||||
# found in the context menu of an item that has been downloaded. The intention behind
|
||||
# "this action" is that it will show where the downloaded file exists on the file system
|
||||
# for each operating system.
|
||||
|
||||
# LOCALIZATION NOTE (menu_action_copy_download_link, menu_action_go_to_download_page):
|
||||
# "Download" here, in both cases, is not a verb, it is a noun. As in, "Copy the
|
||||
# link that belongs to this downloaded item"
|
||||
|
||||
# LOCALIZATION NOTE (search_button): This is screenreader only text for the
|
||||
# search button.
|
||||
@ -66,13 +62,6 @@ search_header={search_engine_name} ෙසවුම
|
||||
# LOCALIZATION NOTE (search_web_placeholder): This is shown in the searchbox when
|
||||
# the user hasn't typed anything yet.
|
||||
search_web_placeholder=ජාලය තුළ සොයන්න
|
||||
search_settings=සෙවුම් සැකසුම් වෙනස් කරන්න
|
||||
|
||||
# LOCALIZATION NOTE (section_info_option): This is the screenreader text for the
|
||||
# (?) icon that would show a section's description with optional feedback link.
|
||||
section_info_option=තොරතුරු
|
||||
section_info_send_feedback=ප්රතිචාරය යවන්න
|
||||
section_info_privacy_notice=පෞද්ගලිකත්ව දැනුම්දීම්
|
||||
|
||||
# LOCALIZATION NOTE (section_disclaimer_topstories): This is shown below
|
||||
# the topstories section title to provide additional information about
|
||||
@ -82,55 +71,42 @@ section_disclaimer_topstories_linktext=එය ක්රියාකරන්
|
||||
# the button used to acknowledge, and hide this disclaimer in the future.
|
||||
section_disclaimer_topstories_buttontext=හරි, තේරුණා
|
||||
|
||||
# LOCALIZATION NOTE (welcome_*): This is shown as a modal dialog, typically on a
|
||||
# first-run experience when there's no data to display yet
|
||||
welcome_title=නව ටැබයට සාදරයෙන් පිළිගනිමු
|
||||
welcome_body=ඔබට පහසුවෙන් යළි භාවිතයට පහසු කරවීමට, Firefox මෙම ඉඩ ඔබට වඩාත් අදාල පිටු සළකුණු, ලිපි, විඩියෝ සහ ඔබ මෑතකදී පිවිසි පිටු පෙන්වීම සදහා භාවිත කරයි.
|
||||
welcome_label=ඔබේ ඉස්මතු කිරීම් හදුනාගනිමින්
|
||||
|
||||
# LOCALIZATION NOTE (time_label_*): {number} is a placeholder for a number which
|
||||
# represents a shortened timestamp format, e.g. '10m' means '10 minutes ago'.
|
||||
time_label_less_than_minute=<1m
|
||||
time_label_minute={number} මිනිත්තු
|
||||
time_label_hour={number}පැය
|
||||
time_label_day={number}දින
|
||||
|
||||
# LOCALIZATION NOTE (settings_pane_*): This is shown in the Settings Pane sidebar.
|
||||
# LOCALIZATION NOTE (prefs_*, settings_*): These are shown in about:preferences
|
||||
# for a "Firefox Home" section. "Firefox" should be treated as a brand and kept
|
||||
# in English, while "Home" should be localized matching the about:preferences
|
||||
# sidebar mozilla-central string for the panel that has preferences related to
|
||||
# what is shown for the homepage, new windows, and new tabs.
|
||||
prefs_home_header=Firefox මුල්පිටු අන්තර්ගතය
|
||||
prefs_home_description=Firefox මුල් පිටුවෙහි ඔබට අවැසි වන්නේ කුමන අන්තර්ගතයදැයි තෝරන්න.
|
||||
# LOCALIZATION NOTE (prefs_section_rows_option): This is a semi-colon list of
|
||||
# plural forms used in a drop down of multiple row options (1 row, 2 rows).
|
||||
# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals
|
||||
prefs_section_rows_option={num} තීරය;{num} තීර
|
||||
prefs_search_header=ජාල සෙවුම
|
||||
prefs_topsites_description=ඔබ වැඩිපුරම පිවිසෙන අඩවි
|
||||
prefs_topstories_sponsored_learn_more=තවත් දැනගන්න
|
||||
settings_pane_button_label=ඔබේ නව ටැබ පිටුව රුචිකරණය කරන්න
|
||||
settings_pane_header=නව ටැබ අභිප්රේත
|
||||
settings_pane_body2=මෙම පිටුවේ ඔබ දැකිය යුතු දේ තෝරන්න.
|
||||
settings_pane_search_header=සොයන්න
|
||||
settings_pane_search_body=ඔබේ නව ටැබයෙන් වෙබ් සෙවීම.
|
||||
settings_pane_topsites_header=ප්රමුඛ අඩවි
|
||||
settings_pane_topsites_body=ඔබ නිරතුරුව පිවිසෙන වෙබ් අඩවි වෙත ප්රවේශය.
|
||||
settings_pane_topsites_options_showmore=පේළි දෙකක් පෙන්වන්න
|
||||
settings_pane_bookmarks_header=නැවුම් පිටු සලකුණු
|
||||
settings_pane_bookmarks_body=ඔබේ නැවුම් පිටු සලකුණු එක් ස්ථානයක.
|
||||
settings_pane_visit_again_header=යළි පිවිසෙන්න
|
||||
settings_pane_highlights_header=ඉස්මතු කිරීම්
|
||||
settings_pane_highlights_options_bookmarks=පිටු සලකුණු
|
||||
settings_pane_highlights_options_visited=පිවිසුණු අඩවි
|
||||
# LOCALIZATION NOTE(settings_pane_snippets_header): For the "Snippets" feature
|
||||
# traditionally on about:home. Alternative translation options: "Small Note" or
|
||||
# something that expresses the idea of "a small message, shortened from
|
||||
# something else, and non-essential but also not entirely trivial and useless."
|
||||
settings_pane_topstories_options_sponsored=අනුග්රහක පුවත් පෙන්වන්න
|
||||
|
||||
# LOCALIZATION NOTE (edit_topsites_*): This is shown in the Edit Top Sites modal
|
||||
# dialog.
|
||||
edit_topsites_button_text=සැකසුම්
|
||||
edit_topsites_showmore_button=තවත් පෙන්වන්න
|
||||
edit_topsites_showless_button=අඩුවෙන් පෙන්වන්න
|
||||
edit_topsites_done_button=කළා
|
||||
edit_topsites_edit_button=මෙම අඩවිය සකසන්න
|
||||
edit_topsites_dismiss_button=මෙම අඩවිය ඉවත ලන්න
|
||||
edit_topsites_add_button=එක් කරන්න
|
||||
|
||||
# LOCALIZATION NOTE (topsites_form_*): This is shown in the New/Edit Topsite modal.
|
||||
topsites_form_add_header=නව ප්රමුඛ අඩවියක්
|
||||
topsites_form_edit_header=ප්රමුඛ අඩවිය සකසන්න
|
||||
topsites_form_title_label=මාතෘකාව
|
||||
topsites_form_title_placeholder=සිරස්තල එක් කරන්න
|
||||
topsites_form_url_label=URL
|
||||
topsites_form_url_placeholder=URL එකක් ඇතුළත් කරන්න
|
||||
# LOCALIZATION NOTE (topsites_form_*_button): These are verbs/actions.
|
||||
topsites_form_add_button=එක් කරන්න
|
||||
topsites_form_save_button=සුරකින්න
|
||||
topsites_form_cancel_button=අවලංගු කරන්න
|
||||
@ -142,10 +118,6 @@ pocket_read_more=ජනප්රිය මාතෘකා:
|
||||
# LOCALIZATION NOTE (pocket_read_even_more): This is shown as a link at the
|
||||
# end of the list of popular topic links.
|
||||
pocket_read_even_more=තවත් බොහෝ දැ
|
||||
# LOCALIZATION NOTE (pocket_feedback_header): This is shown as an introduction
|
||||
# to Pocket as part of the feedback form.
|
||||
# LOCALIZATION NOTE (pocket_description): This is shown in the settings pane and
|
||||
# below (pocket_feedback_header) to provide more information about Pocket.
|
||||
|
||||
# LOCALIZATION NOTE (topstories_empty_state): When there are no recommendations,
|
||||
# in the space that would have shown a few stories, this is shown instead.
|
||||
@ -160,3 +132,25 @@ manual_migration_cancel_button=එපා, ස්තුතියි
|
||||
# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
|
||||
# of importing another browser’s profile profile into Firefox.
|
||||
manual_migration_import_button=දැන් ආයාත කරන්න
|
||||
|
||||
# LOCALIZATION NOTE (error_fallback_default_*): This message and suggested
|
||||
# action link are shown in each section of UI that fails to render
|
||||
|
||||
# LOCALIZATION NOTE (section_menu_action_*). These strings are displayed in the section
|
||||
# context menu and are meant as a call to action for the given section.
|
||||
section_menu_action_move_up=ඉහළට ගෙනයන්න
|
||||
section_menu_action_move_down=පහළට ගෙනයන්න
|
||||
section_menu_action_privacy_notice=පෞද්ගලිකත්ව සටහන
|
||||
|
||||
# LOCALIZATION NOTE (firstrun_*). These strings are displayed only once, on the
|
||||
# firstrun of the browser, they give an introduction to Firefox and Sync.
|
||||
|
||||
# LOCALIZATION NOTE (firstrun_form_header and firstrun_form_sub_header):
|
||||
# firstrun_form_sub_header is a continuation of firstrun_form_header, they are one sentence.
|
||||
# firstrun_form_header is displayed more boldly as the call to action.
|
||||
|
||||
|
||||
|
||||
# LOCALIZATION NOTE (firstrun_extra_legal_links): {terms} is equal to firstrun_terms_of_service, and
|
||||
# {privacy} is equal to firstrun_privacy_notice. {terms} and {privacy} are clickable links.
|
||||
|
||||
|
@ -191,6 +191,8 @@ firstrun_form_sub_header=a používajte službu Firefox Sync.
|
||||
|
||||
firstrun_email_input_placeholder=E-mail
|
||||
|
||||
firstrun_invalid_input=Vyžaduje sa platná e-mailová adresa
|
||||
|
||||
# LOCALIZATION NOTE (firstrun_extra_legal_links): {terms} is equal to firstrun_terms_of_service, and
|
||||
# {privacy} is equal to firstrun_privacy_notice. {terms} and {privacy} are clickable links.
|
||||
firstrun_extra_legal_links=Pokračovaním súhlasíte s {terms} a {privacy}.
|
||||
|
@ -96,7 +96,7 @@ window.gActivityStreamStrings = {
|
||||
"firstrun_form_header": "Tatz'ib'aj ri ataqoya'l",
|
||||
"firstrun_form_sub_header": "richin yatok pa Firefox Sync.",
|
||||
"firstrun_email_input_placeholder": "Taqoya'l",
|
||||
"firstrun_invalid_input": "Valid email required",
|
||||
"firstrun_invalid_input": "Najowäx ütz chi taqoya'l",
|
||||
"firstrun_extra_legal_links": "Toq nasamajij qa, nawojqaj ri {terms} chuqa' {privacy}.",
|
||||
"firstrun_terms_of_service": "Kojqanem Samaj",
|
||||
"firstrun_privacy_notice": "Ichinan Na'oj",
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -34,14 +34,14 @@ window.gActivityStreamStrings = {
|
||||
"menu_action_remove_download": "Αφαίρεση από το ιστορικό",
|
||||
"search_button": "Αναζήτηση",
|
||||
"search_header": "Αναζήτηση {search_engine_name}",
|
||||
"search_web_placeholder": "Αναζήτηση στον ιστό",
|
||||
"search_web_placeholder": "Αναζήτηση στο διαδίκτυο",
|
||||
"section_disclaimer_topstories": "Οι πιο ενδιαφέρουσες ιστορίες στο διαδίκτυο, επιλεγμένες βάσει όσων διαβάζετε. Από το Pocket, πλέον μέλος της Mozilla.",
|
||||
"section_disclaimer_topstories_linktext": "Μάθετε πώς λειτουργεί.",
|
||||
"section_disclaimer_topstories_buttontext": "Εντάξει, το 'πιασα",
|
||||
"prefs_home_header": "Περιεχόμενο αρχικής σελίδας Firefox",
|
||||
"prefs_home_description": "Επιλέξτε τι περιεχόμενο θέλετε στην αρχική σελίδα του Firefox σας.",
|
||||
"prefs_section_rows_option": "{num} σειρά;{num} σειρές",
|
||||
"prefs_search_header": "Αναζήτηση ιστού",
|
||||
"prefs_search_header": "Διαδικτυακή αναζήτηση",
|
||||
"prefs_topsites_description": "Οι ιστοσελίδες που επισκέπτεστε περισσότερο",
|
||||
"prefs_topstories_description2": "Εξαιρετικό περιεχόμενο από το διαδίκτυο, εξατομικευμένο για εσάς",
|
||||
"prefs_topstories_options_sponsored_label": "Χορηγούμενες ιστορίες",
|
||||
|
@ -96,7 +96,7 @@ window.gActivityStreamStrings = {
|
||||
"firstrun_form_header": "Tajpu vian retpoŝtan adreson",
|
||||
"firstrun_form_sub_header": "por pluiri al Spegulado de Firefox.",
|
||||
"firstrun_email_input_placeholder": "Retpoŝta adreso",
|
||||
"firstrun_invalid_input": "Valid email required",
|
||||
"firstrun_invalid_input": "Valida retpoŝta adreso postulata",
|
||||
"firstrun_extra_legal_links": "Se vi daŭrigas vi akceptas la {terms} kaj {privacy}.",
|
||||
"firstrun_terms_of_service": "kondiĉojn de uzo",
|
||||
"firstrun_privacy_notice": "rimarkon pri privateco",
|
||||
|
@ -24,7 +24,7 @@ window.gActivityStreamStrings = {
|
||||
"menu_action_save_to_pocket": "Pocket में सहेजें",
|
||||
"menu_action_delete_pocket": "पॉकेट से हटाएं",
|
||||
"menu_action_archive_pocket": "पॉकेट में पुरालेख",
|
||||
"menu_action_show_file_mac_os": "Show in Finder",
|
||||
"menu_action_show_file_mac_os": "फाइंडर में दिखाएँ",
|
||||
"menu_action_show_file_windows": "संग्राहक फोल्डर खोलें",
|
||||
"menu_action_show_file_linux": "संग्राहक फोल्डर खोलें",
|
||||
"menu_action_show_file_default": "फ़ाइल दिखाएं",
|
||||
@ -48,7 +48,7 @@ window.gActivityStreamStrings = {
|
||||
"prefs_topstories_sponsored_learn_more": "अधिक जानें",
|
||||
"prefs_highlights_description": "आपके द्वारा सहेजी गई या विज़िट की गई साइटों का चयन",
|
||||
"prefs_highlights_options_visited_label": "देखे गए पृष्ठ",
|
||||
"prefs_highlights_options_download_label": "Most Recent Download",
|
||||
"prefs_highlights_options_download_label": "सबसे हालिया डाउनलोड",
|
||||
"prefs_highlights_options_pocket_label": "पॉकेट में सहेजे गए पृष्ठ",
|
||||
"prefs_snippets_description": "Mozilla और Firefox से अद्यतन",
|
||||
"settings_pane_button_label": "अपने नए टैब पृष्ठ को अनुकूलित करें",
|
||||
|
@ -96,7 +96,7 @@ window.gActivityStreamStrings = {
|
||||
"firstrun_form_header": "Picatz vòstra adreça electronica",
|
||||
"firstrun_form_sub_header": "per contunhar amb Firefox Sync.",
|
||||
"firstrun_email_input_placeholder": "Adreça electronica",
|
||||
"firstrun_invalid_input": "Valid email required",
|
||||
"firstrun_invalid_input": "Cal una adreça electronica valida",
|
||||
"firstrun_extra_legal_links": "Se contunhatz, acceptatz las {terms} e l’{privacy}.",
|
||||
"firstrun_terms_of_service": "Condicions d’utilizacion",
|
||||
"firstrun_privacy_notice": "Avís de privacitat",
|
||||
|
@ -96,7 +96,7 @@ window.gActivityStreamStrings = {
|
||||
"firstrun_form_header": "Введите ваш адрес электронной почты",
|
||||
"firstrun_form_sub_header": "чтобы продолжить использовать синхронизацию Firefox.",
|
||||
"firstrun_email_input_placeholder": "Эл. почта",
|
||||
"firstrun_invalid_input": "Valid email required",
|
||||
"firstrun_invalid_input": "Введите действующий адрес электронной почты",
|
||||
"firstrun_extra_legal_links": "Продолжая, вы соглашаетесь с {terms} и {privacy}.",
|
||||
"firstrun_terms_of_service": "условиями службы",
|
||||
"firstrun_privacy_notice": "политикой приватности",
|
||||
|
@ -9,7 +9,7 @@ window.gActivityStreamStrings = {
|
||||
"type_label_visited": "ප්රවේශිත",
|
||||
"type_label_bookmarked": "පිටු සලකුණු තැබූ",
|
||||
"type_label_recommended": "Trending",
|
||||
"type_label_pocket": "Saved to Pocket",
|
||||
"type_label_pocket": "Pocket හි සුරකින ලදී",
|
||||
"type_label_downloaded": "Downloaded",
|
||||
"menu_action_bookmark": "පිටු සලකුණ",
|
||||
"menu_action_remove_bookmark": "පිටු සලකුණ ඉවත් කරන්න",
|
||||
@ -21,9 +21,9 @@ window.gActivityStreamStrings = {
|
||||
"menu_action_unpin": "ඇමුණුම ඉවත් කරන්න",
|
||||
"confirm_history_delete_p1": "ඔබට මෙම පිටුවට අදාල සියලුම සිදුවීම් ඔබේ අතීතයන් මැකීමට අවශ්ය ද?",
|
||||
"confirm_history_delete_notice_p2": "මෙම ක්රියාව අහෝසි කළ නොහැක.",
|
||||
"menu_action_save_to_pocket": "Save to Pocket",
|
||||
"menu_action_delete_pocket": "Delete from Pocket",
|
||||
"menu_action_archive_pocket": "Archive in Pocket",
|
||||
"menu_action_save_to_pocket": "Pocket හි සුරකින්න",
|
||||
"menu_action_delete_pocket": "Pocket වෙතින් මකන්න",
|
||||
"menu_action_archive_pocket": "Pocket හි සංරක්ෂණ කරන්න",
|
||||
"menu_action_show_file_mac_os": "Show in Finder",
|
||||
"menu_action_show_file_windows": "Open Containing Folder",
|
||||
"menu_action_show_file_linux": "Open Containing Folder",
|
||||
@ -38,14 +38,14 @@ window.gActivityStreamStrings = {
|
||||
"section_disclaimer_topstories": "The most interesting stories on the web, selected based on what you read. From Pocket, now part of Mozilla.",
|
||||
"section_disclaimer_topstories_linktext": "එය ක්රියාකරන්නේ කෙසේදැයි අධ්යපනය කරන්න.",
|
||||
"section_disclaimer_topstories_buttontext": "හරි, තේරුණා",
|
||||
"prefs_home_header": "Firefox Home Content",
|
||||
"prefs_home_description": "Choose what content you want on your Firefox Home screen.",
|
||||
"prefs_section_rows_option": "{num} row;{num} rows",
|
||||
"prefs_search_header": "Web Search",
|
||||
"prefs_topsites_description": "The sites you visit most",
|
||||
"prefs_home_header": "Firefox මුල්පිටු අන්තර්ගතය",
|
||||
"prefs_home_description": "Firefox මුල් පිටුවෙහි ඔබට අවැසි වන්නේ කුමන අන්තර්ගතයදැයි තෝරන්න.",
|
||||
"prefs_section_rows_option": "{num} තීරය;{num} තීර",
|
||||
"prefs_search_header": "ජාල සෙවුම",
|
||||
"prefs_topsites_description": "ඔබ වැඩිපුරම පිවිසෙන අඩවි",
|
||||
"prefs_topstories_description2": "Great content from around the web, personalized for you",
|
||||
"prefs_topstories_options_sponsored_label": "Sponsored Stories",
|
||||
"prefs_topstories_sponsored_learn_more": "Learn more",
|
||||
"prefs_topstories_sponsored_learn_more": "තවත් දැනගන්න",
|
||||
"prefs_highlights_description": "A selection of sites that you’ve saved or visited",
|
||||
"prefs_highlights_options_visited_label": "Visited Pages",
|
||||
"prefs_highlights_options_download_label": "Most Recent Download",
|
||||
@ -60,7 +60,7 @@ window.gActivityStreamStrings = {
|
||||
"edit_topsites_edit_button": "මෙම අඩවිය සකසන්න",
|
||||
"topsites_form_add_header": "නව ප්රමුඛ අඩවියක්",
|
||||
"topsites_form_edit_header": "ප්රමුඛ අඩවිය සකසන්න",
|
||||
"topsites_form_title_label": "Title",
|
||||
"topsites_form_title_label": "මාතෘකාව",
|
||||
"topsites_form_title_placeholder": "සිරස්තල එක් කරන්න",
|
||||
"topsites_form_url_label": "URL",
|
||||
"topsites_form_image_url_label": "Custom Image URL",
|
||||
@ -87,9 +87,9 @@ window.gActivityStreamStrings = {
|
||||
"section_menu_action_manage_section": "Manage Section",
|
||||
"section_menu_action_manage_webext": "Manage Extension",
|
||||
"section_menu_action_add_topsite": "Add Top Site",
|
||||
"section_menu_action_move_up": "Move Up",
|
||||
"section_menu_action_move_down": "Move Down",
|
||||
"section_menu_action_privacy_notice": "Privacy Notice",
|
||||
"section_menu_action_move_up": "ඉහළට ගෙනයන්න",
|
||||
"section_menu_action_move_down": "පහළට ගෙනයන්න",
|
||||
"section_menu_action_privacy_notice": "පෞද්ගලිකත්ව සටහන",
|
||||
"firstrun_title": "Take Firefox with You",
|
||||
"firstrun_content": "Get your bookmarks, history, passwords and other settings on all your devices.",
|
||||
"firstrun_learn_more_link": "Learn more about Firefox Accounts",
|
||||
@ -101,45 +101,5 @@ window.gActivityStreamStrings = {
|
||||
"firstrun_terms_of_service": "Terms of Service",
|
||||
"firstrun_privacy_notice": "Privacy Notice",
|
||||
"firstrun_continue_to_login": "Continue",
|
||||
"firstrun_skip_login": "Skip this step",
|
||||
"default_label_loading": "පූරණය වෙමින්…",
|
||||
"header_stories": "ප්රමුඛ පුවත්",
|
||||
"header_visit_again": "යළි පිවිසෙන්න",
|
||||
"header_bookmarks": "නැවුම් පිටු සලකුණු",
|
||||
"header_bookmarks_placeholder": "ඔබ සතුව තවම පිටුසලකුණු නැත.",
|
||||
"header_stories_from": "සිට",
|
||||
"type_label_synced": "වෙනත් උපාංගයක් වෙතින් සමකාලීන කර ඇත",
|
||||
"type_label_open": "විවෘත",
|
||||
"type_label_topic": "මාතෘකාව",
|
||||
"type_label_now": "දැන්",
|
||||
"menu_action_copy_address": "ලිපිනය පිටපත් කරන්න",
|
||||
"menu_action_email_link": "විද්යුත් තැපැල් සබැඳි…",
|
||||
"search_for_something_with": "{search_term} සදහා සෙවීමට භාවිත කළ යුත්තේ:",
|
||||
"search_settings": "සෙවුම් සැකසුම් වෙනස් කරන්න",
|
||||
"section_info_option": "තොරතුරු",
|
||||
"section_info_send_feedback": "ප්රතිචාරය යවන්න",
|
||||
"section_info_privacy_notice": "පෞද්ගලිකත්ව දැනුම්දීම්",
|
||||
"welcome_title": "නව ටැබයට සාදරයෙන් පිළිගනිමු",
|
||||
"welcome_body": "ඔබට පහසුවෙන් යළි භාවිතයට පහසු කරවීමට, Firefox මෙම ඉඩ ඔබට වඩාත් අදාල පිටු සළකුණු, ලිපි, විඩියෝ සහ ඔබ මෑතකදී පිවිසි පිටු පෙන්වීම සදහා භාවිත කරයි.",
|
||||
"welcome_label": "ඔබේ ඉස්මතු කිරීම් හදුනාගනිමින්",
|
||||
"time_label_less_than_minute": "<1m",
|
||||
"time_label_minute": "{number} මිනිත්තු",
|
||||
"time_label_hour": "{number}පැය",
|
||||
"time_label_day": "{number}දින",
|
||||
"settings_pane_header": "නව ටැබ අභිප්රේත",
|
||||
"settings_pane_body2": "මෙම පිටුවේ ඔබ දැකිය යුතු දේ තෝරන්න.",
|
||||
"settings_pane_search_header": "සොයන්න",
|
||||
"settings_pane_search_body": "ඔබේ නව ටැබයෙන් වෙබ් සෙවීම.",
|
||||
"settings_pane_topsites_body": "ඔබ නිරතුරුව පිවිසෙන වෙබ් අඩවි වෙත ප්රවේශය.",
|
||||
"settings_pane_topsites_options_showmore": "පේළි දෙකක් පෙන්වන්න",
|
||||
"settings_pane_bookmarks_header": "නැවුම් පිටු සලකුණු",
|
||||
"settings_pane_bookmarks_body": "ඔබේ නැවුම් පිටු සලකුණු එක් ස්ථානයක.",
|
||||
"settings_pane_visit_again_header": "යළි පිවිසෙන්න",
|
||||
"settings_pane_highlights_options_visited": "පිවිසුණු අඩවි",
|
||||
"settings_pane_topstories_options_sponsored": "අනුග්රහක පුවත් පෙන්වන්න",
|
||||
"edit_topsites_showmore_button": "තවත් පෙන්වන්න",
|
||||
"edit_topsites_showless_button": "අඩුවෙන් පෙන්වන්න",
|
||||
"edit_topsites_done_button": "කළා",
|
||||
"edit_topsites_dismiss_button": "මෙම අඩවිය ඉවත ලන්න",
|
||||
"edit_topsites_add_button": "එක් කරන්න"
|
||||
"firstrun_skip_login": "Skip this step"
|
||||
};
|
||||
|
@ -96,7 +96,7 @@ window.gActivityStreamStrings = {
|
||||
"firstrun_form_header": "Zadajte e-mailovú adresu",
|
||||
"firstrun_form_sub_header": "a používajte službu Firefox Sync.",
|
||||
"firstrun_email_input_placeholder": "E-mail",
|
||||
"firstrun_invalid_input": "Valid email required",
|
||||
"firstrun_invalid_input": "Vyžaduje sa platná e-mailová adresa",
|
||||
"firstrun_extra_legal_links": "Pokračovaním súhlasíte s {terms} a {privacy}.",
|
||||
"firstrun_terms_of_service": "podmienkami používania služby",
|
||||
"firstrun_privacy_notice": "zásadami ochrany súkromia",
|
||||
|
@ -12,7 +12,6 @@ import {_ASRouter} from "lib/ASRouter.jsm";
|
||||
const FAKE_PROVIDERS = [FAKE_LOCAL_PROVIDER, FAKE_REMOTE_PROVIDER];
|
||||
const ALL_MESSAGE_IDS = [...FAKE_LOCAL_MESSAGES, ...FAKE_REMOTE_MESSAGES].map(message => message.id);
|
||||
const FAKE_BUNDLE = [FAKE_LOCAL_MESSAGES[1], FAKE_LOCAL_MESSAGES[2]];
|
||||
|
||||
// Creates a message object that looks like messages returned by
|
||||
// RemotePageManager listeners
|
||||
function fakeAsyncMessage(action) {
|
||||
@ -26,6 +25,8 @@ describe("ASRouter", () => {
|
||||
let blockList;
|
||||
let fetchStub;
|
||||
let clock;
|
||||
let getStringPrefStub;
|
||||
let addObserverStub;
|
||||
|
||||
function createFakeStorage() {
|
||||
return {
|
||||
@ -47,6 +48,10 @@ describe("ASRouter", () => {
|
||||
fetchStub = sandbox.stub(global, "fetch")
|
||||
.withArgs("http://fake.com/endpoint")
|
||||
.resolves({ok: true, status: 200, json: () => Promise.resolve({messages: FAKE_REMOTE_MESSAGES})});
|
||||
getStringPrefStub = sandbox.stub(global.Services.prefs, "getStringPref");
|
||||
getStringPrefStub.returns("http://fake.com/endpoint");
|
||||
addObserverStub = sandbox.stub(global.Services.prefs, "addObserver");
|
||||
|
||||
await createRouterAndInit();
|
||||
});
|
||||
afterEach(() => {
|
||||
@ -67,6 +72,10 @@ describe("ASRouter", () => {
|
||||
const [, listenerAdded] = channel.addMessageListener.firstCall.args;
|
||||
assert.isFunction(listenerAdded);
|
||||
});
|
||||
it("should add an observer for each provider with a defined endpointPref", () => {
|
||||
assert.calledOnce(addObserverStub);
|
||||
assert.calledWith(addObserverStub, "remotePref");
|
||||
});
|
||||
it("should set state.blockList to the block list in persistent storage", async () => {
|
||||
blockList = ["MESSAGE_ID"];
|
||||
|
||||
@ -85,6 +94,23 @@ describe("ASRouter", () => {
|
||||
assert.isArray(Router.state.messages);
|
||||
assert.lengthOf(Router.state.messages, FAKE_LOCAL_MESSAGES.length + FAKE_REMOTE_MESSAGES.length);
|
||||
});
|
||||
it("should call loadMessagesFromAllProviders on pref endpoint change", async () => {
|
||||
sandbox.spy(Router, "loadMessagesFromAllProviders");
|
||||
|
||||
await Router.observe();
|
||||
|
||||
assert.calledOnce(Router.loadMessagesFromAllProviders);
|
||||
});
|
||||
it("should update provider url on pref change", async () => {
|
||||
getStringPrefStub.withArgs("remotePref").returns("baz.com");
|
||||
const {length} = Router.state.providers;
|
||||
await Router.observe("", "", "remotePref");
|
||||
|
||||
const provider = Router.state.providers.find(p => p.url === "baz.com");
|
||||
|
||||
assert.lengthOf(Router.state.providers, length);
|
||||
assert.isDefined(provider);
|
||||
});
|
||||
});
|
||||
|
||||
describe("#loadMessagesFromAllProviders", () => {
|
||||
@ -95,6 +121,15 @@ describe("ASRouter", () => {
|
||||
}
|
||||
}
|
||||
|
||||
it("should load provider endpoint based on pref", async () => {
|
||||
getStringPrefStub.reset();
|
||||
getStringPrefStub.returns("example.com");
|
||||
await createRouterAndInit();
|
||||
|
||||
assert.calledOnce(getStringPrefStub);
|
||||
assert.calledWithExactly(getStringPrefStub, "remotePref", "");
|
||||
assert.isDefined(Router.state.providers.find(p => p.url === "example.com"));
|
||||
});
|
||||
it("should not trigger an update if not enough time has passed for a provider", async () => {
|
||||
await createRouterAndInit([
|
||||
{id: "remotey", type: "remote", url: "http://fake.com/endpoint", updateCycleInMs: 300}
|
||||
|
@ -73,7 +73,7 @@ describe("ASRouterFeed", () => {
|
||||
prefs[EXPERIMENT_PREF] = true;
|
||||
|
||||
// call .onAction with INIT
|
||||
feed.onAction({type: at.INIT});
|
||||
feed.onAction({type: at.INIT, data: {name: EXPERIMENT_PREF}});
|
||||
|
||||
assert.notCalled(Router.init);
|
||||
});
|
||||
|
@ -14,7 +14,7 @@ export const FAKE_LOCAL_PROVIDER = {id: "onboarding", type: "local", messages: F
|
||||
export const FAKE_REMOTE_MESSAGES = [
|
||||
{id: "qux", template: "simple_template", content: {title: "Qux", body: "hello world"}}
|
||||
];
|
||||
export const FAKE_REMOTE_PROVIDER = {id: "remotey", type: "remote", url: "http://fake.com/endpoint"};
|
||||
export const FAKE_REMOTE_PROVIDER = {id: "remotey", type: "remote", url: "http://fake.com/endpoint", endpointPref: "remotePref"};
|
||||
|
||||
// Stubs methods on RemotePageManager
|
||||
export class FakeRemotePageManager {
|
||||
|
@ -213,6 +213,26 @@ HOST_CXXFLAGS = $(COMPUTED_HOST_CXXFLAGS) $(_DEPEND_CFLAGS)
|
||||
HOST_C_LDFLAGS = $(COMPUTED_HOST_C_LDFLAGS)
|
||||
HOST_CXX_LDFLAGS = $(COMPUTED_HOST_CXX_LDFLAGS)
|
||||
|
||||
ifdef MOZ_LTO
|
||||
ifeq (Darwin,$(OS_TARGET))
|
||||
# When linking on macOS, debug info is not linked along with the final binary,
|
||||
# and the dwarf data stays in object files until they are "linked" with the
|
||||
# dsymutil tool.
|
||||
# With LTO, object files are temporary, and are not kept around, which
|
||||
# means there's no object file for dsymutil to do its job. Consequently,
|
||||
# there is no debug info for LTOed compilation units.
|
||||
# The macOS linker has however an option to explicitly keep those object
|
||||
# files, which dsymutil will then find.
|
||||
# The catch is that the linker uses sequential numbers for those object
|
||||
# files, and doesn't avoid conflicts from multiple linkers running at
|
||||
# the same time. So in directories with multiple binaries, object files
|
||||
# from the first linked binaries would be overwritten by those of the
|
||||
# last linked binary. So we use a subdirectory containing the name of the
|
||||
# linked binary.
|
||||
LDFLAGS += -Wl,-object_path_lto,$@.lto.o/
|
||||
endif
|
||||
endif
|
||||
|
||||
# We only add color flags if neither the flag to disable color
|
||||
# (e.g. "-fno-color-diagnostics" nor a flag to control color
|
||||
# (e.g. "-fcolor-diagnostics=never") is present.
|
||||
|
@ -392,7 +392,6 @@ class AnimationInspector {
|
||||
|
||||
await this.inspector.getCommonComponentProps()
|
||||
.setSelectedNode(nodeFront, { reason: "animation-panel" });
|
||||
await nodeFront.scrollIntoView();
|
||||
}
|
||||
|
||||
async setAnimationsCurrentTime(currentTime, shouldRefresh) {
|
||||
|
@ -271,7 +271,6 @@ subsuite = clipboard
|
||||
[browser_webconsole_context_menu_open_url.js]
|
||||
[browser_webconsole_context_menu_store_as_global.js]
|
||||
[browser_webconsole_csp_ignore_reflected_xss_message.js]
|
||||
skip-if = (e10s && debug) || (e10s && os == 'win') # Bug 1221499 enabled these on windows
|
||||
[browser_webconsole_csp_violation.js]
|
||||
[browser_webconsole_cspro.js]
|
||||
[browser_webconsole_document_focus.js]
|
||||
|
@ -63,6 +63,11 @@ function nextTest() {
|
||||
SimpleTest.executeSoon(runNextTest);
|
||||
}
|
||||
|
||||
var gHeadlessSkipList = [
|
||||
{ test: "file_fullscreen-plugins.html", reason: "bug 1409805" },
|
||||
{ test: "file_fullscreen-scrollbar.html", reason: "bug 1468648" },
|
||||
];
|
||||
|
||||
var gLinuxE10sSkipList = [
|
||||
{ "test": "file_fullscreen-plugins.html", "reason": "bug 1330553" },
|
||||
{ "test": "file_fullscreen-api.html", "reason": "bug 1332040" },
|
||||
@ -70,20 +75,25 @@ var gLinuxE10sSkipList = [
|
||||
];
|
||||
|
||||
function shouldSkipTest(test) {
|
||||
if (SpecialPowers.Cc["@mozilla.org/gfx/info;1"].getService(SpecialPowers.Ci.nsIGfxInfo).isHeadless &&
|
||||
test == "file_fullscreen-plugins.html") {
|
||||
todo(false, `${test} skipped due to bug 1409805`);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!SpecialPowers.isMainProcess() &&
|
||||
navigator.platform.includes('Linux')) {
|
||||
for (let item of gLinuxE10sSkipList) {
|
||||
function checkList(list) {
|
||||
for (let item of list) {
|
||||
if (item.test == test) {
|
||||
todo(false, `${test} skipped due to ${item.reason}`);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (SpecialPowers.Cc["@mozilla.org/gfx/info;1"].getService(SpecialPowers.Ci.nsIGfxInfo).isHeadless &&
|
||||
checkList(gHeadlessSkipList)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!SpecialPowers.isMainProcess() &&
|
||||
navigator.platform.includes('Linux') &&
|
||||
checkList(gLinuxE10sSkipList)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -19,15 +19,16 @@
|
||||
#include "mozilla/layers/WebRenderLayerManager.h"
|
||||
#include "mozilla/layers/WebRenderBridgeChild.h"
|
||||
#include "mozilla/TouchEvents.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsContainerFrame.h"
|
||||
#include "nsIScrollableFrame.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIDOMWindow.h"
|
||||
#include "nsIDOMWindowUtils.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
#include "nsIScrollableFrame.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
#include "nsPrintfCString.h"
|
||||
#include "nsRefreshDriver.h"
|
||||
#include "nsString.h"
|
||||
#include "nsView.h"
|
||||
@ -105,20 +106,38 @@ ScrollFrameTo(nsIScrollableFrame* aFrame, const FrameMetrics& aMetrics, bool& aS
|
||||
return geckoScrollPosition;
|
||||
}
|
||||
|
||||
// If this is the root content with overflow:hidden, then APZ should not
|
||||
// allow scrolling in such a way that moves the layout viewport.
|
||||
// If this frame is overflow:hidden, then the expectation is that it was
|
||||
// sized in a way that respects its scrollable boundaries. For the root
|
||||
// frame, this means that it cannot be scrolled in such a way that it moves
|
||||
// the layout viewport. For a non-root frame, this means that it cannot be
|
||||
// scrolled at all.
|
||||
//
|
||||
// If this is overflow:hidden, but not the root content, then
|
||||
// nsLayoutUtils::CalculateScrollableRectForFrame should have sized the
|
||||
// scrollable rect in a way that prevents APZ from scrolling it at all.
|
||||
// In either case, |targetScrollPosition| should be the same as
|
||||
// |geckoScrollPosition| here.
|
||||
//
|
||||
// In either case, targetScrollPosition should be the same as
|
||||
// geckoScrollPosition here.
|
||||
if (aFrame->GetScrollbarStyles().mVertical == NS_STYLE_OVERFLOW_HIDDEN) {
|
||||
MOZ_ASSERT(targetScrollPosition.y == geckoScrollPosition.y);
|
||||
// However, this is slightly racy. We query the overflow property of the
|
||||
// scroll frame at the time the repaint request arrives at the main thread
|
||||
// (i.e., right now), but APZ made the decision of whether or not to allow
|
||||
// scrolling based on the information it had at the time it processed the
|
||||
// scroll event. The overflow property could have changed at some time
|
||||
// between the two events and so APZ may have computed a scrollable region
|
||||
// that is larger than what is actually allowed.
|
||||
//
|
||||
// Currently, we allow the scroll position to change even though the frame is
|
||||
// overflow:hidden (that is, we take |targetScrollPosition|). If this turns
|
||||
// out to be problematic, an alternative solution would be to ignore the
|
||||
// scroll position change (that is, use |geckoScrollPosition|).
|
||||
if (aFrame->GetScrollbarStyles().mVertical == NS_STYLE_OVERFLOW_HIDDEN &&
|
||||
targetScrollPosition.y != geckoScrollPosition.y) {
|
||||
NS_WARNING(nsPrintfCString(
|
||||
"APZCCH: targetScrollPosition.y (%f) != geckoScrollPosition.y (%f)",
|
||||
targetScrollPosition.y, geckoScrollPosition.y).get());
|
||||
}
|
||||
if (aFrame->GetScrollbarStyles().mHorizontal == NS_STYLE_OVERFLOW_HIDDEN) {
|
||||
MOZ_ASSERT(targetScrollPosition.x == geckoScrollPosition.x);
|
||||
if (aFrame->GetScrollbarStyles().mHorizontal == NS_STYLE_OVERFLOW_HIDDEN &&
|
||||
targetScrollPosition.x != geckoScrollPosition.x) {
|
||||
NS_WARNING(nsPrintfCString(
|
||||
"APZCCH: targetScrollPosition.x (%f) != geckoScrollPosition.x (%f)",
|
||||
targetScrollPosition.x, geckoScrollPosition.x).get());
|
||||
}
|
||||
|
||||
// If the scrollable frame is currently in the middle of an async or smooth
|
||||
|
@ -1,4 +1,4 @@
|
||||
user_pref("app.update.enabled", false);
|
||||
user_pref("app.update.disabledForTesting", true);
|
||||
user_pref("browser.dom.window.dump.enabled", true);
|
||||
user_pref("browser.sessionstore.resume_from_crash", false);
|
||||
user_pref("browser.shell.checkDefaultBrowser", false);
|
||||
|
@ -353,6 +353,100 @@ AccumulateRectDifference(const nsRect& aR1, const nsRect& aR2, const nsRect& aBo
|
||||
aOut->Or(*aOut, r);
|
||||
}
|
||||
|
||||
static void
|
||||
AccumulateRoundedRectDifference(const DisplayItemClip::RoundedRect& aR1,
|
||||
const DisplayItemClip::RoundedRect& aR2,
|
||||
const nsRect& aBounds,
|
||||
const nsRect& aOtherBounds,
|
||||
nsRegion* aOut)
|
||||
{
|
||||
const nsRect& rect1 = aR1.mRect;
|
||||
const nsRect& rect2 = aR2.mRect;
|
||||
|
||||
// If the two rectangles are totally disjoint, just add them both - otherwise we'd
|
||||
// end up adding one big enclosing rect
|
||||
if (!rect1.Intersects(rect2) || memcmp(aR1.mRadii, aR2.mRadii, sizeof(aR1.mRadii))) {
|
||||
aOut->Or(*aOut, rect1.Intersect(aBounds));
|
||||
aOut->Or(*aOut, rect2.Intersect(aOtherBounds));
|
||||
return;
|
||||
}
|
||||
|
||||
nscoord lowestBottom = std::max(rect1.YMost(), rect2.YMost());
|
||||
nscoord highestTop = std::min(rect1.Y(), rect2.Y());
|
||||
nscoord maxRight = std::max(rect1.XMost(), rect2.XMost());
|
||||
nscoord minLeft = std::min(rect1.X(), rect2.X());
|
||||
|
||||
// At this point, we know that the radii haven't changed, and that the bounds
|
||||
// are different in some way. To explain how this works, consider the case
|
||||
// where the rounded rect has just been translated along the X direction.
|
||||
// | ______________________ _ _ _ _ _ _ |
|
||||
// | / / \ \ |
|
||||
// | | | |
|
||||
// | | aR1 | | aR2 | |
|
||||
// | | | |
|
||||
// | \ __________\___________ / _ _ _ _ _ / |
|
||||
// | |
|
||||
// The invalidation region will be as if we lopped off the left rounded part
|
||||
// of aR2, and the right rounded part of aR1, and XOR'd them:
|
||||
// | ______________________ _ _ _ _ _ _ |
|
||||
// | -/-----------/- -\-----------\- |
|
||||
// | |-------------- --|------------ |
|
||||
// | |-----aR1---|-- --|-----aR2---| |
|
||||
// | |-------------- --|------------ |
|
||||
// | -\ __________\-__________-/ _ _ _ _ _ /- |
|
||||
// | |
|
||||
// The logic below just implements this idea, but generalized to both the
|
||||
// X and Y dimensions. The "(...)Adjusted(...)" values represent the lopped
|
||||
// off sides.
|
||||
nscoord highestAdjustedBottom =
|
||||
std::min(rect1.YMost() - aR1.mRadii[eCornerBottomLeftY],
|
||||
std::min(rect1.YMost() - aR1.mRadii[eCornerBottomRightY],
|
||||
std::min(rect2.YMost() - aR2.mRadii[eCornerBottomLeftY],
|
||||
rect2.YMost() - aR2.mRadii[eCornerBottomRightY])));
|
||||
nscoord lowestAdjustedTop =
|
||||
std::max(rect1.Y() + aR1.mRadii[eCornerTopLeftY],
|
||||
std::max(rect1.Y() + aR1.mRadii[eCornerTopRightY],
|
||||
std::max(rect2.Y() + aR2.mRadii[eCornerTopLeftY],
|
||||
rect2.Y() + aR2.mRadii[eCornerTopRightY])));
|
||||
|
||||
nscoord minAdjustedRight =
|
||||
std::min(rect1.XMost() - aR1.mRadii[eCornerTopRightX],
|
||||
std::min(rect1.XMost() - aR1.mRadii[eCornerBottomRightX],
|
||||
std::min(rect2.XMost() - aR2.mRadii[eCornerTopRightX],
|
||||
rect2.XMost() - aR2.mRadii[eCornerBottomRightX])));
|
||||
nscoord maxAdjustedLeft =
|
||||
std::max(rect1.X() + aR1.mRadii[eCornerTopLeftX],
|
||||
std::max(rect1.X() + aR1.mRadii[eCornerBottomLeftX],
|
||||
std::max(rect2.X() + aR2.mRadii[eCornerTopLeftX],
|
||||
rect2.X() + aR2.mRadii[eCornerBottomLeftX])));
|
||||
|
||||
// We only want to add an invalidation rect if the bounds have changed. If we always
|
||||
// added all of the 4 rects below, we would always be invalidating a border around the
|
||||
// rects, even in cases where we just translated along the X or Y axis.
|
||||
nsRegion r;
|
||||
// First, or with the Y delta rects, wide along the X axis
|
||||
if (rect1.Y() != rect2.Y()) {
|
||||
r.Or(r, nsRect(minLeft, highestTop,
|
||||
maxRight - minLeft, lowestAdjustedTop - highestTop));
|
||||
}
|
||||
if (rect1.YMost() != rect2.YMost()) {
|
||||
r.Or(r, nsRect(minLeft, highestAdjustedBottom,
|
||||
maxRight - minLeft, lowestBottom - highestAdjustedBottom));
|
||||
}
|
||||
// Then, or with the X delta rects, narrow along the Y axis
|
||||
if (rect1.X() != rect2.X()) {
|
||||
r.Or(r, nsRect(minLeft, lowestAdjustedTop,
|
||||
maxAdjustedLeft - minLeft, highestAdjustedBottom - lowestAdjustedTop));
|
||||
}
|
||||
if (rect1.XMost() != rect2.XMost()) {
|
||||
r.Or(r, nsRect(minAdjustedRight, lowestAdjustedTop,
|
||||
maxRight - minAdjustedRight, highestAdjustedBottom - lowestAdjustedTop));
|
||||
}
|
||||
|
||||
r.And(r, aBounds.Union(aOtherBounds));
|
||||
aOut->Or(*aOut, r);
|
||||
}
|
||||
|
||||
void
|
||||
DisplayItemClip::AddOffsetAndComputeDifference(const nsPoint& aOffset,
|
||||
const nsRect& aBounds,
|
||||
@ -373,9 +467,11 @@ DisplayItemClip::AddOffsetAndComputeDifference(const nsPoint& aOffset,
|
||||
}
|
||||
for (uint32_t i = 0; i < mRoundedClipRects.Length(); ++i) {
|
||||
if (mRoundedClipRects[i] + aOffset != aOther.mRoundedClipRects[i]) {
|
||||
// The corners make it tricky so we'll just add both rects here.
|
||||
aDifference->Or(*aDifference, mRoundedClipRects[i].mRect.Intersect(aBounds));
|
||||
aDifference->Or(*aDifference, aOther.mRoundedClipRects[i].mRect.Intersect(aOtherBounds));
|
||||
AccumulateRoundedRectDifference(mRoundedClipRects[i] + aOffset,
|
||||
aOther.mRoundedClipRects[i],
|
||||
aBounds,
|
||||
aOtherBounds,
|
||||
aDifference);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1904,6 +1904,7 @@ const std::string kBasicAudioVideoOffer =
|
||||
"a=end-of-candidates" CRLF
|
||||
"a=ssrc:1111 foo" CRLF
|
||||
"a=ssrc:1111 foo:bar" CRLF
|
||||
"a=ssrc:1111 msid:1d0cdb4e-5934-4f0f-9f88-40392cb60d31 315b086a-5cb6-4221-89de-caf0b038c79d" CRLF
|
||||
"a=imageattr:120 send * recv *" CRLF
|
||||
"a=imageattr:121 send [x=640,y=480] recv [x=640,y=480]" CRLF
|
||||
"a=rid:bar recv pt=120;max-width=800;max-height=600" CRLF
|
||||
@ -2157,11 +2158,15 @@ TEST_P(NewSdpTest, CheckSsrc)
|
||||
ASSERT_TRUE(mSdp->GetMediaSection(1).GetAttributeList().HasAttribute(
|
||||
SdpAttribute::kSsrcAttribute));
|
||||
ssrcs = mSdp->GetMediaSection(1).GetAttributeList().GetSsrc().mSsrcs;
|
||||
ASSERT_EQ(2U, ssrcs.size());
|
||||
ASSERT_EQ(3U, ssrcs.size());
|
||||
ASSERT_EQ(1111U, ssrcs[0].ssrc);
|
||||
ASSERT_EQ("foo", ssrcs[0].attribute);
|
||||
ASSERT_EQ(1111U, ssrcs[1].ssrc);
|
||||
ASSERT_EQ("foo:bar", ssrcs[1].attribute);
|
||||
ASSERT_EQ(1111U, ssrcs[2].ssrc);
|
||||
ASSERT_EQ("msid:1d0cdb4e-5934-4f0f-9f88-40392cb60d31 "
|
||||
"315b086a-5cb6-4221-89de-caf0b038c79d",
|
||||
ssrcs[2].attribute);
|
||||
}
|
||||
|
||||
TEST_P(NewSdpTest, CheckRtpmap) {
|
||||
|
@ -1602,7 +1602,7 @@ fn parse_simulcast(to_parse: &str) -> Result<SdpAttribute, SdpParserInternalErro
|
||||
}
|
||||
|
||||
fn parse_ssrc(to_parse: &str) -> Result<SdpAttribute, SdpParserInternalError> {
|
||||
let mut tokens = to_parse.split_whitespace();
|
||||
let mut tokens = to_parse.splitn(2,' ');
|
||||
let ssrc_id = match tokens.next() {
|
||||
None => {
|
||||
return Err(SdpParserInternalError::Generic("Ssrc attribute is missing ssrc-id value"
|
||||
@ -2101,6 +2101,8 @@ fn test_parse_attribute_ssrc() {
|
||||
assert!(parse_attribute("ssrc:2655508255 foo").is_ok());
|
||||
assert!(parse_attribute("ssrc:2655508255 cname:{735484ea-4f6c-f74a-bd66-7425f8476c2e}")
|
||||
.is_ok());
|
||||
assert!(parse_attribute("ssrc:2082260239 msid:1d0cdb4e-5934-4f0f-9f88-40392cb60d31 315b086a-5cb6-4221-89de-caf0b038c79d")
|
||||
.is_ok());
|
||||
|
||||
assert!(parse_attribute("ssrc:").is_err());
|
||||
assert!(parse_attribute("ssrc:foo").is_err());
|
||||
|
@ -492,7 +492,6 @@ pref("app.update.url.android", "https://aus5.mozilla.org/update/4/%PRODUCT%/%VER
|
||||
|
||||
#ifdef MOZ_UPDATER
|
||||
/* prefs used specifically for updating the app */
|
||||
pref("app.update.enabled", false);
|
||||
pref("app.update.channel", "@MOZ_UPDATE_CHANNEL@");
|
||||
|
||||
#endif
|
||||
|
@ -226,6 +226,7 @@ DoTest_CreateRemoteThread_LoadLibrary(TgetArgsProc aGetArgsProc)
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(NIGHTLY_BUILD)
|
||||
TEST(TestInjectEject, CreateRemoteThread_LoadLibraryA)
|
||||
{
|
||||
DoTest_CreateRemoteThread_LoadLibrary([](const nsString& dllPath,
|
||||
@ -275,3 +276,4 @@ TEST(TestInjectEject, CreateRemoteThread_LoadLibraryExA)
|
||||
aThreadParam = (uintptr_t)dllPathC.get();
|
||||
});
|
||||
}
|
||||
#endif // defined(NIGHTLY_BUILD)
|
||||
|
@ -257,8 +257,8 @@ class OSXBootstrapper(BaseBootstrapper):
|
||||
if b'license' in e.output:
|
||||
xcodebuild = self.which('xcodebuild')
|
||||
try:
|
||||
subprocess.check_call([xcodebuild, '-license'],
|
||||
stderr=subprocess.STDOUT)
|
||||
self.check_output([xcodebuild, '-license'],
|
||||
stderr=subprocess.STDOUT)
|
||||
except subprocess.CalledProcessError as e:
|
||||
if b'requires admin privileges' in e.output:
|
||||
self.run_as_root([xcodebuild, '-license'])
|
||||
|
@ -33,11 +33,10 @@
|
||||
</groupbox>
|
||||
<groupbox>
|
||||
<description style="font-weight: bold;">&clientAuthAsk.message2;</description>
|
||||
<broadcaster id="certSelected" oncommand="onCertSelected();"/>
|
||||
<!-- The items in this menulist must never be sorted,
|
||||
but remain in the order filled by the application
|
||||
-->
|
||||
<menulist id="nicknames" observes="certSelected">
|
||||
<menulist id="nicknames" oncommand="onCertSelected();">
|
||||
<menupopup/>
|
||||
</menulist>
|
||||
<description>&clientAuthAsk.message3;</description>
|
||||
|
@ -122,6 +122,20 @@ OSXVersion::GetVersionNumber()
|
||||
return mOSXVersion;
|
||||
}
|
||||
|
||||
bool
|
||||
GetRealPath(std::string& aOutputPath, const char* aInputPath)
|
||||
{
|
||||
char* resolvedPath = realpath(aInputPath, nullptr);
|
||||
if (resolvedPath == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
aOutputPath = resolvedPath;
|
||||
free(resolvedPath);
|
||||
|
||||
return !aOutputPath.empty();
|
||||
}
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
bool StartMacSandbox(MacSandboxInfo const &aInfo, std::string &aErrorMessage)
|
||||
@ -132,7 +146,7 @@ bool StartMacSandbox(MacSandboxInfo const &aInfo, std::string &aErrorMessage)
|
||||
|
||||
// Used for the Flash sandbox. Declared here so that they
|
||||
// stay in scope until sandbox_init_with_parameters is called.
|
||||
std::string flashTempDir, flashPath;
|
||||
std::string flashCacheDir, flashTempDir, flashPath;
|
||||
|
||||
if (aInfo.type == MacSandboxType_Plugin &&
|
||||
aInfo.pluginInfo.type == MacSandboxPluginType_Flash) {
|
||||
@ -153,20 +167,28 @@ bool StartMacSandbox(MacSandboxInfo const &aInfo, std::string &aErrorMessage)
|
||||
params.push_back(getenv("HOME"));
|
||||
|
||||
params.push_back("PLUGIN_BINARY_PATH");
|
||||
flashPath = realpath(aInfo.pluginInfo.pluginBinaryPath.c_str(), nullptr);
|
||||
if (flashPath.empty()) {
|
||||
if (!GetRealPath(flashPath, aInfo.pluginInfo.pluginBinaryPath.c_str())) {
|
||||
return false;
|
||||
}
|
||||
params.push_back(flashPath.c_str());
|
||||
|
||||
// User temp dir
|
||||
params.push_back("DARWIN_USER_TEMP_DIR");
|
||||
char tempDir[PATH_MAX];
|
||||
if (!confstr(_CS_DARWIN_USER_TEMP_DIR, tempDir, sizeof(tempDir))) {
|
||||
// User cache dir
|
||||
params.push_back("DARWIN_USER_CACHE_DIR");
|
||||
char confStrBuf[PATH_MAX];
|
||||
if (!confstr(_CS_DARWIN_USER_CACHE_DIR, confStrBuf, sizeof(confStrBuf))) {
|
||||
return false;
|
||||
}
|
||||
flashTempDir = realpath(tempDir, nullptr);
|
||||
if (flashTempDir.empty()) {
|
||||
if (!GetRealPath(flashCacheDir, confStrBuf)) {
|
||||
return false;
|
||||
}
|
||||
params.push_back(flashCacheDir.c_str());
|
||||
|
||||
// User temp dir
|
||||
params.push_back("DARWIN_USER_TEMP_DIR");
|
||||
if (!confstr(_CS_DARWIN_USER_TEMP_DIR, confStrBuf, sizeof(confStrBuf))) {
|
||||
return false;
|
||||
}
|
||||
if (!GetRealPath(flashTempDir, confStrBuf)) {
|
||||
return false;
|
||||
}
|
||||
params.push_back(flashTempDir.c_str());
|
||||
|
@ -417,6 +417,7 @@ static const char flashPluginSandboxRules[] = R"SANDBOX_LITERAL(
|
||||
(define macosMinorVersion (string->number (param "MAC_OS_MINOR")))
|
||||
(define homeDir (param "HOME_PATH"))
|
||||
(define tempDir (param "DARWIN_USER_TEMP_DIR"))
|
||||
(define cacheDir (param "DARWIN_USER_CACHE_DIR"))
|
||||
(define pluginPath (param "PLUGIN_BINARY_PATH"))
|
||||
|
||||
(if (string=? shouldLog "TRUE")
|
||||
@ -571,6 +572,10 @@ static const char flashPluginSandboxRules[] = R"SANDBOX_LITERAL(
|
||||
(define (tempDir-regex tempDir-relative-regex)
|
||||
(regex (string-append "^" (regex-quote tempDir)) tempDir-relative-regex))
|
||||
|
||||
; Utility for allowing access to specific files within the cache dir
|
||||
(define (cache-literal cache-relative-literal)
|
||||
(literal (string-append cacheDir cache-relative-literal)))
|
||||
|
||||
; Read-only paths
|
||||
(allow file-read*
|
||||
(literal "/")
|
||||
@ -643,7 +648,9 @@ static const char flashPluginSandboxRules[] = R"SANDBOX_LITERAL(
|
||||
(global-name "com.apple.inputmethodkit.launcher")
|
||||
(global-name "com.apple.inputmethodkit.getxpcendpoint")
|
||||
(global-name "com.apple.decalog4.incoming")
|
||||
(global-name "com.apple.windowserver.active"))
|
||||
(global-name "com.apple.windowserver.active")
|
||||
(global-name "com.apple.trustd.agent")
|
||||
(global-name "com.apple.ocspd"))
|
||||
; bug 1475707
|
||||
(if (= macosMinorVersion 9)
|
||||
(allow mach-lookup (global-name "com.apple.xpcd")))
|
||||
@ -766,6 +773,19 @@ static const char flashPluginSandboxRules[] = R"SANDBOX_LITERAL(
|
||||
(home-library-literal "/PreferencePanes/Flash Player.prefPane")
|
||||
(home-library-regex "/Application Support/Macromedia/ss\.(cfg|cfn|sgn)$"))
|
||||
|
||||
(allow file-read*
|
||||
(literal "/Library/Preferences/com.apple.security.plist")
|
||||
(subpath "/private/var/db/mds"))
|
||||
; Tests revealed file-write-{data,create,flags} required for some encrypted
|
||||
; video playback. Allowing file-write* to match system profiles.
|
||||
(allow file-read* file-write*
|
||||
(cache-literal "/mds/mds.lock")
|
||||
(cache-literal "/mds/mdsDirectory.db_")
|
||||
(cache-literal "/mds/mdsDirectory.db_")
|
||||
(cache-literal "/mds/mdsObject.db")
|
||||
(cache-literal "/mds/mdsObject.db_")
|
||||
(require-all (vnode-type REGULAR-FILE)))
|
||||
|
||||
(allow network-bind (local ip))
|
||||
|
||||
(deny file-write-create (vnode-type SYMLINK))
|
||||
|
@ -16,6 +16,9 @@ lazy_static! {
|
||||
("app.update.auto", Pref::new(false)),
|
||||
|
||||
// Disable automatically upgrading Firefox
|
||||
("app.update.disabledForTesting", Pref::new(true)),
|
||||
// app.update.enabled is being removed. Once Firefox 62 becomes stable,
|
||||
// the line below can be removed as well.
|
||||
("app.update.enabled", Pref::new(false)),
|
||||
|
||||
// Enable the dump function, which sends messages to the system
|
||||
|
@ -504,6 +504,10 @@ class FennecInstance(GeckoInstance):
|
||||
class DesktopInstance(GeckoInstance):
|
||||
desktop_prefs = {
|
||||
# Disable application updates
|
||||
"app.update.disabledForTesting": True,
|
||||
"security.turn_off_all_security_so_that_viruses_can_take_over_this_computer": True,
|
||||
# app.update.enabled is being removed. Once Firefox 62 becomes stable,
|
||||
# the line below can be removed as well.
|
||||
"app.update.enabled": False,
|
||||
|
||||
# Enable output of dump()
|
||||
|
@ -66,7 +66,8 @@ const RECOMMENDED_PREFS = new Map([
|
||||
//
|
||||
// This should also be set in the profile prior to starting Firefox,
|
||||
// as it is picked up at runtime.
|
||||
["app.update.enabled", false],
|
||||
["app.update.disabledForTesting", true],
|
||||
["security.turn_off_all_security_so_that_viruses_can_take_over_this_computer", true],
|
||||
|
||||
// Increase the APZ content response timeout in tests to 1 minute.
|
||||
// This is to accommodate the fact that test environments tends to be
|
||||
|
@ -431,7 +431,8 @@ class FirefoxProfile(Profile):
|
||||
"""Specialized Profile subclass for Firefox"""
|
||||
|
||||
preferences = { # Don't automatically update the application
|
||||
'app.update.enabled': False,
|
||||
'app.update.disabledForTesting': True,
|
||||
'security.turn_off_all_security_so_that_viruses_can_take_over_this_computer': True,
|
||||
# Don't restore the last open set of tabs if the browser has crashed
|
||||
'browser.sessionstore.resume_from_crash': False,
|
||||
# Don't check for the default web browser during startup
|
||||
|
@ -1,6 +1,6 @@
|
||||
// Base preferences file used by both unittest and perf harnesses.
|
||||
/* globals user_pref */
|
||||
user_pref("app.update.enabled", false);
|
||||
user_pref("app.update.disabledForTesting", true);
|
||||
user_pref("browser.chrome.guess_favicon", false);
|
||||
user_pref("browser.dom.window.dump.enabled", true);
|
||||
// Use an empty list of sites to avoid fetching
|
||||
|
@ -22,15 +22,20 @@ def test_create_profile(options, app, get_prefs):
|
||||
if app != 'firefox':
|
||||
return
|
||||
|
||||
# This pref is set in mozprofile
|
||||
firefox_pref = 'user_pref("app.update.enabled", false);'
|
||||
# These prefs are set in mozprofile
|
||||
firefox_prefs = [
|
||||
'user_pref("app.update.disabledForTesting", true);',
|
||||
'user_pref("'
|
||||
'security.turn_off_all_security_so_that_viruses_can_take_over_this_computer", true);'
|
||||
]
|
||||
# This pref is set in raptor
|
||||
raptor_pref = 'user_pref("security.enable_java", false);'
|
||||
|
||||
prefs_file = os.path.join(raptor.profile.profile, 'user.js')
|
||||
with open(prefs_file, 'r') as fh:
|
||||
prefs = fh.read()
|
||||
assert firefox_pref in prefs
|
||||
for firefox_pref in firefox_prefs:
|
||||
assert firefox_pref in prefs
|
||||
assert raptor_pref in prefs
|
||||
|
||||
|
||||
|
@ -1 +1 @@
|
||||
{'deviceroot': '', 'dirs': {}, 'repository': 'http://hg.mozilla.org/releases/mozilla-release', 'buildid': '20131205075310', 'results_log': 'pathtoresults_log', 'symbols_path': None, 'bcontroller_config': 'pathtobcontroller', 'host': '', 'browser_name': 'Firefox', 'sourcestamp': '39faf812aaec', 'remote': False, 'child_process': 'plugin-container', 'branch_name': '', 'browser_version': '26.0', 'extra_args': '', 'develop': True, 'preferences': {'browser.display.overlaynavbuttons': False, 'extensions.getAddons.get.url': 'http://127.0.0.1/extensions-dummy/repositoryGetURL', 'dom.max_chrome_script_run_time': 0, 'network.proxy.type': 1, 'extensions.update.background.url': 'http://127.0.0.1/extensions-dummy/updateBackgroundURL', 'network.proxy.http': 'localhost', 'plugins.update.url': 'http://127.0.0.1/plugins-dummy/updateCheckURL', 'dom.max_script_run_time': 0, 'extensions.update.enabled': False, 'browser.safebrowsing.keyURL': 'http://127.0.0.1/safebrowsing-dummy/newkey', 'media.navigator.permission.disabled': True, 'app.update.enabled': False, 'extensions.blocklist.url': 'http://127.0.0.1/extensions-dummy/blocklistURL', 'browser.EULA.override': True, 'extensions.checkCompatibility': False, 'talos.logfile': 'pathtofile', 'browser.safebrowsing.gethashURL': 'http://127.0.0.1/safebrowsing-dummy/gethash', 'extensions.hotfix.url': 'http://127.0.0.1/extensions-dummy/hotfixURL', 'dom.disable_window_move_resize': True, 'network.proxy.http_port': 80, 'browser.dom.window.dump.enabled': True, 'extensions.update.url': 'http://127.0.0.1/extensions-dummy/updateURL', 'browser.chrome.dynamictoolbar': False, 'browser.link.open_newwindow': 2, 'browser.cache.disk.smart_size.first_run': False, 'security.turn_off_all_security_so_that_viruses_can_take_over_this_computer': True, 'dom.disable_open_during_load': False, 'extensions.getAddons.search.browseURL': 'http://127.0.0.1/extensions-dummy/repositoryBrowseURL', 'browser.cache.disk.smart_size.enabled': False, 'extensions.getAddons.getWithPerformance.url': 'http://127.0.0.1/extensions-dummy/repositoryGetWithPerformanceURL', 'hangmonitor.timeout': 0, 'dom.send_after_paint_to_content': True, 'security.fileuri.strict_origin_policy': False, 'media.capturestream_hints.enabled': True, 'extensions.update.notifyUser': False, 'extensions.blocklist.enabled': False, 'browser.bookmarks.max_backups': 0, 'browser.shell.checkDefaultBrowser': False, 'media.peerconnection.enabled': True, 'dom.disable_window_flip': True, 'security.enable_java': False, 'browser.warnOnQuit': False, 'media.navigator.enabled': True, 'browser.safebrowsing.updateURL': 'http://127.0.0.1/safebrowsing-dummy/update', 'dom.allow_scripts_to_close_windows': True, 'extensions.webservice.discoverURL': 'http://127.0.0.1/extensions-dummy/discoveryURL'}, 'test_timeout': 1200, 'title': 'qm-pxp01', 'error_filename': 'pathtoerrorfile', 'webserver': 'localhost:15707', 'browser_path':ffox_path, 'port': 20701, 'browser_log': 'browser_output.txt', 'process': 'firefox.exe', 'xperf_path': 'C:/Program Files/Microsoft Windows Performance Toolkit/xperf.exe', 'extensions': ['pathtopageloader'], 'fennecIDs': '', 'env': {'NO_EM_RESTART': '1'}, 'init_url': 'http://localhost:15707/getInfo.html', 'browser_wait': 5}
|
||||
{'deviceroot': '', 'dirs': {}, 'repository': 'http://hg.mozilla.org/releases/mozilla-release', 'buildid': '20131205075310', 'results_log': 'pathtoresults_log', 'symbols_path': None, 'bcontroller_config': 'pathtobcontroller', 'host': '', 'browser_name': 'Firefox', 'sourcestamp': '39faf812aaec', 'remote': False, 'child_process': 'plugin-container', 'branch_name': '', 'browser_version': '26.0', 'extra_args': '', 'develop': True, 'preferences': {'browser.display.overlaynavbuttons': False, 'extensions.getAddons.get.url': 'http://127.0.0.1/extensions-dummy/repositoryGetURL', 'dom.max_chrome_script_run_time': 0, 'network.proxy.type': 1, 'extensions.update.background.url': 'http://127.0.0.1/extensions-dummy/updateBackgroundURL', 'network.proxy.http': 'localhost', 'plugins.update.url': 'http://127.0.0.1/plugins-dummy/updateCheckURL', 'dom.max_script_run_time': 0, 'extensions.update.enabled': False, 'browser.safebrowsing.keyURL': 'http://127.0.0.1/safebrowsing-dummy/newkey', 'media.navigator.permission.disabled': True, 'app.update.disabledForTesting': True, 'extensions.blocklist.url': 'http://127.0.0.1/extensions-dummy/blocklistURL', 'browser.EULA.override': True, 'extensions.checkCompatibility': False, 'talos.logfile': 'pathtofile', 'browser.safebrowsing.gethashURL': 'http://127.0.0.1/safebrowsing-dummy/gethash', 'extensions.hotfix.url': 'http://127.0.0.1/extensions-dummy/hotfixURL', 'dom.disable_window_move_resize': True, 'network.proxy.http_port': 80, 'browser.dom.window.dump.enabled': True, 'extensions.update.url': 'http://127.0.0.1/extensions-dummy/updateURL', 'browser.chrome.dynamictoolbar': False, 'browser.link.open_newwindow': 2, 'browser.cache.disk.smart_size.first_run': False, 'security.turn_off_all_security_so_that_viruses_can_take_over_this_computer': True, 'dom.disable_open_during_load': False, 'extensions.getAddons.search.browseURL': 'http://127.0.0.1/extensions-dummy/repositoryBrowseURL', 'browser.cache.disk.smart_size.enabled': False, 'extensions.getAddons.getWithPerformance.url': 'http://127.0.0.1/extensions-dummy/repositoryGetWithPerformanceURL', 'hangmonitor.timeout': 0, 'dom.send_after_paint_to_content': True, 'security.fileuri.strict_origin_policy': False, 'media.capturestream_hints.enabled': True, 'extensions.update.notifyUser': False, 'extensions.blocklist.enabled': False, 'browser.bookmarks.max_backups': 0, 'browser.shell.checkDefaultBrowser': False, 'media.peerconnection.enabled': True, 'dom.disable_window_flip': True, 'security.enable_java': False, 'browser.warnOnQuit': False, 'media.navigator.enabled': True, 'browser.safebrowsing.updateURL': 'http://127.0.0.1/safebrowsing-dummy/update', 'dom.allow_scripts_to_close_windows': True, 'extensions.webservice.discoverURL': 'http://127.0.0.1/extensions-dummy/discoveryURL'}, 'test_timeout': 1200, 'title': 'qm-pxp01', 'error_filename': 'pathtoerrorfile', 'webserver': 'localhost:15707', 'browser_path':ffox_path, 'port': 20701, 'browser_log': 'browser_output.txt', 'process': 'firefox.exe', 'xperf_path': 'C:/Program Files/Microsoft Windows Performance Toolkit/xperf.exe', 'extensions': ['pathtopageloader'], 'fennecIDs': '', 'env': {'NO_EM_RESTART': '1'}, 'init_url': 'http://localhost:15707/getInfo.html', 'browser_wait': 5}
|
||||
|
@ -56,7 +56,8 @@ class TPSTestRunner(object):
|
||||
}
|
||||
|
||||
default_preferences = {
|
||||
'app.update.enabled': False,
|
||||
'app.update.disabledForTesting': True,
|
||||
'security.turn_off_all_security_so_that_viruses_can_take_over_this_computer': True,
|
||||
'browser.dom.window.dump.enabled': True,
|
||||
'browser.sessionstore.resume_from_crash': False,
|
||||
'browser.shell.checkDefaultBrowser': False,
|
||||
|
@ -1,3 +0,0 @@
|
||||
[update-and-send-events.html]
|
||||
disabled: https://bugzilla.mozilla.org/show_bug.cgi?id=1474811
|
||||
|
@ -186,24 +186,40 @@ promise_test(async t => {
|
||||
|
||||
let receivedEvents = [];
|
||||
anim.oncancel = event => receivedEvents.push(event);
|
||||
anim.onfinish = event => receivedEvents.push(event);
|
||||
div.ontransitionstart = event => receivedEvents.push(event);
|
||||
div.ontransitioncancel = event => receivedEvents.push(event);
|
||||
|
||||
await anim.ready;
|
||||
|
||||
anim.cancel();
|
||||
|
||||
await waitForAnimationFrames(1);
|
||||
|
||||
assert_array_equals(receivedEvents.map(event => event.type),
|
||||
[ 'cancel', 'transitioncancel' ],
|
||||
'Playback and CSS events for the same transition should be sorted by ' +
|
||||
'schedule event time and composite order');
|
||||
}, 'Sorts events for the same transition');
|
||||
|
||||
promise_test(async t => {
|
||||
const div = createDiv(t);
|
||||
const anim = div.animate(null, 100 * MS_PER_SEC);
|
||||
|
||||
let receivedEvents = [];
|
||||
anim.oncancel = event => receivedEvents.push(event);
|
||||
anim.onfinish = event => receivedEvents.push(event);
|
||||
|
||||
await anim.ready;
|
||||
|
||||
anim.finish();
|
||||
anim.cancel();
|
||||
|
||||
await waitForAnimationFrames(1);
|
||||
|
||||
assert_array_equals(receivedEvents.map(event => event.type),
|
||||
[ 'transitionstart',
|
||||
'finish',
|
||||
'cancel',
|
||||
'transitioncancel' ],
|
||||
'Playback and CSS events for the same transition should be sorted by ' +
|
||||
'schedule event time and composite order');
|
||||
}, 'Sorts events for the same transition');
|
||||
[ 'finish', 'cancel' ],
|
||||
'Calling finish() synchronously queues a finish event when updating the ' +
|
||||
'finish state so it should appear before the cancel event');
|
||||
}, 'Playback events with the same timeline retain the order in which they are' +
|
||||
'queued');
|
||||
|
||||
</script>
|
||||
|
@ -22,8 +22,7 @@ MainProcessSingleton.prototype = {
|
||||
engineURL = NetUtil.newURI(engineURL, null, pageURL);
|
||||
|
||||
let iconURL;
|
||||
let tabbrowser = browser.getTabBrowser();
|
||||
if (browser.mIconURL && (!tabbrowser || tabbrowser.shouldLoadFavIcon(pageURL)))
|
||||
if (browser.mIconURL && browser.mIconURL.startsWith("data:"))
|
||||
iconURL = NetUtil.newURI(browser.mIconURL);
|
||||
|
||||
try {
|
||||
@ -33,9 +32,6 @@ MainProcessSingleton.prototype = {
|
||||
if (!isWeb.includes(engineURL.scheme))
|
||||
throw "Unsupported search engine URL: " + engineURL.spec;
|
||||
|
||||
if (iconURL && !isWeb.includes(iconURL.scheme))
|
||||
throw "Unsupported search icon URL: " + iconURL.spec;
|
||||
|
||||
if (Services.policies &&
|
||||
!Services.policies.isAllowed("installSearchEngine")) {
|
||||
throw "Search Engine installation blocked by the Enterprise Policy Manager.";
|
||||
|
@ -5461,22 +5461,6 @@
|
||||
"releaseChannelCollection": "opt-out",
|
||||
"description": "Update: count of when the app.update.auto boolean preference is not the default value of true (true values are not submitted)"
|
||||
},
|
||||
"UPDATE_NOT_PREF_UPDATE_ENABLED_EXTERNAL": {
|
||||
"record_in_processes": ["main"],
|
||||
"alert_emails": ["application-update-telemetry-alerts@mozilla.com"],
|
||||
"expires_in_version": "never",
|
||||
"kind": "count",
|
||||
"releaseChannelCollection": "opt-out",
|
||||
"description": "Update: count of when the app.update.enabled boolean preference is not the default value of true (true values are not submitted)"
|
||||
},
|
||||
"UPDATE_NOT_PREF_UPDATE_ENABLED_NOTIFY": {
|
||||
"record_in_processes": ["main"],
|
||||
"alert_emails": ["application-update-telemetry-alerts@mozilla.com"],
|
||||
"expires_in_version": "never",
|
||||
"kind": "count",
|
||||
"releaseChannelCollection": "opt-out",
|
||||
"description": "Update: count of when the app.update.enabled boolean preference is not the default value of true (true values are not submitted)"
|
||||
},
|
||||
"UPDATE_NOT_PREF_UPDATE_STAGING_ENABLED_EXTERNAL": {
|
||||
"record_in_processes": ["main"],
|
||||
"alert_emails": ["application-update-telemetry-alerts@mozilla.com"],
|
||||
|
@ -187,7 +187,6 @@ const DEFAULT_ENVIRONMENT_PREFS = new Map([
|
||||
["accessibility.force_disabled", {what: RECORD_PREF_VALUE}],
|
||||
["app.shield.optoutstudies.enabled", {what: RECORD_PREF_VALUE}],
|
||||
["app.update.auto", {what: RECORD_PREF_VALUE}],
|
||||
["app.update.enabled", {what: RECORD_PREF_VALUE}],
|
||||
["app.update.interval", {what: RECORD_PREF_VALUE}],
|
||||
["app.update.service.enabled", {what: RECORD_PREF_VALUE}],
|
||||
["app.update.silent", {what: RECORD_PREF_VALUE}],
|
||||
@ -268,7 +267,6 @@ const PREF_DISTRIBUTOR = "app.distributor";
|
||||
const PREF_DISTRIBUTOR_CHANNEL = "app.distributor.channel";
|
||||
const PREF_APP_PARTNER_BRANCH = "app.partner.";
|
||||
const PREF_PARTNER_ID = "mozilla.partner.id";
|
||||
const PREF_UPDATE_ENABLED = "app.update.enabled";
|
||||
const PREF_UPDATE_AUTODOWNLOAD = "app.update.auto";
|
||||
const PREF_SEARCH_COHORT = "browser.search.cohort";
|
||||
|
||||
@ -1420,7 +1418,7 @@ EnvironmentCache.prototype = {
|
||||
locale: getBrowserLocale(),
|
||||
update: {
|
||||
channel: updateChannel,
|
||||
enabled: Services.prefs.getBoolPref(PREF_UPDATE_ENABLED, true),
|
||||
enabled: !Services.policies || Services.policies.isAllowed("appUpdate"),
|
||||
autoDownload: Services.prefs.getBoolPref(PREF_UPDATE_AUTODOWNLOAD, true),
|
||||
},
|
||||
userPrefs: this._getPrefData(),
|
||||
|
@ -1177,8 +1177,6 @@
|
||||
"UPDATE_LAST_NOTIFY_INTERVAL_DAYS_NOTIFY",
|
||||
"UPDATE_NOT_PREF_UPDATE_AUTO_EXTERNAL",
|
||||
"UPDATE_NOT_PREF_UPDATE_AUTO_NOTIFY",
|
||||
"UPDATE_NOT_PREF_UPDATE_ENABLED_EXTERNAL",
|
||||
"UPDATE_NOT_PREF_UPDATE_ENABLED_NOTIFY",
|
||||
"UPDATE_NOT_PREF_UPDATE_SERVICE_ENABLED_EXTERNAL",
|
||||
"UPDATE_NOT_PREF_UPDATE_SERVICE_ENABLED_NOTIFY",
|
||||
"UPDATE_NOT_PREF_UPDATE_STAGING_ENABLED_EXTERNAL",
|
||||
@ -1657,8 +1655,6 @@
|
||||
"UPDATE_INVALID_LASTUPDATETIME_NOTIFY",
|
||||
"UPDATE_NOT_PREF_UPDATE_AUTO_EXTERNAL",
|
||||
"UPDATE_NOT_PREF_UPDATE_AUTO_NOTIFY",
|
||||
"UPDATE_NOT_PREF_UPDATE_ENABLED_EXTERNAL",
|
||||
"UPDATE_NOT_PREF_UPDATE_ENABLED_NOTIFY",
|
||||
"UPDATE_NOT_PREF_UPDATE_SERVICE_ENABLED_EXTERNAL",
|
||||
"UPDATE_NOT_PREF_UPDATE_SERVICE_ENABLED_NOTIFY",
|
||||
"UPDATE_NOT_PREF_UPDATE_STAGING_ENABLED_EXTERNAL",
|
||||
|
@ -68,10 +68,6 @@ class TelemetryTestCase(PuppeteerMixin, MarionetteTestCase):
|
||||
# assert len(self.ping_list) == 1
|
||||
return self.ping_list.pop()
|
||||
|
||||
def toggle_update_pref(self):
|
||||
value = self.marionette.get_pref('app.update.enabled')
|
||||
self.marionette.enforce_gecko_prefs({'app.update.enabled': not value})
|
||||
|
||||
def restart_browser(self):
|
||||
"""Restarts browser while maintaining the same profile and session."""
|
||||
self.restart(clean=False, in_app=True)
|
||||
|
@ -46,17 +46,14 @@ var AUSTLMY = {
|
||||
CHK_IS_STAGED: 10,
|
||||
// An update is already downloaded (no notification)
|
||||
CHK_IS_DOWNLOADED: 11,
|
||||
// Background checks disabled by preference (no notification)
|
||||
CHK_PREF_DISABLED: 12,
|
||||
// Update checks disabled by admin locked preference (no notification)
|
||||
CHK_ADMIN_DISABLED: 13,
|
||||
// Note: codes 12-13 were removed along with the |app.update.enabled| pref.
|
||||
// Unable to check for updates per hasUpdateMutex() (no notification)
|
||||
CHK_NO_MUTEX: 14,
|
||||
// Unable to check for updates per gCanCheckForUpdates (no notification). This
|
||||
// should be covered by other codes and is recorded just in case.
|
||||
CHK_UNABLE_TO_CHECK: 15,
|
||||
// Background checks disabled for the current session (no notification)
|
||||
CHK_DISABLED_FOR_SESSION: 16,
|
||||
// Note: code 16 was removed when the feature for disabling updates for the
|
||||
// session was removed.
|
||||
// Unable to perform a background check while offline (no notification)
|
||||
CHK_OFFLINE: 17,
|
||||
// Note: codes 18 - 21 were removed along with the certificate checking code.
|
||||
@ -87,6 +84,8 @@ var AUSTLMY = {
|
||||
// User opted out of elevated updates for the available update version, OSX
|
||||
// only (no notification)
|
||||
CHK_ELEVATION_OPTOUT_FOR_VERSION: 36,
|
||||
// Update checks disabled by enterprise policy
|
||||
CHK_DISABLED_BY_POLICY: 37,
|
||||
|
||||
/**
|
||||
* Submit a telemetry ping for the update check result code or a telemetry
|
||||
|
@ -14,10 +14,10 @@ ChromeUtils.import("resource://gre/modules/UpdateTelemetry.jsm", this);
|
||||
|
||||
const XMLNS_XUL = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
|
||||
const PREF_APP_UPDATE_AUTO = "app.update.auto";
|
||||
const PREF_APP_UPDATE_BACKGROUNDERRORS = "app.update.backgroundErrors";
|
||||
const PREF_APP_UPDATE_CERT_ERRORS = "app.update.cert.errors";
|
||||
const PREF_APP_UPDATE_ELEVATE_NEVER = "app.update.elevate.never";
|
||||
const PREF_APP_UPDATE_ENABLED = "app.update.enabled";
|
||||
const PREF_APP_UPDATE_LOG = "app.update.log";
|
||||
const PREF_APP_UPDATE_NOTIFIEDUNSUPPORTED = "app.update.notifiedUnsupported";
|
||||
const PREF_APP_UPDATE_URL_MANUAL = "app.update.url.manual";
|
||||
@ -492,7 +492,7 @@ var gCheckingPage = {
|
||||
* Manager control, so stop checking for updates.
|
||||
*/
|
||||
onWizardCancel() {
|
||||
this._checker.stopChecking(Ci.nsIUpdateChecker.CURRENT_CHECK);
|
||||
this._checker.stopCurrentCheck();
|
||||
},
|
||||
|
||||
/**
|
||||
@ -561,8 +561,7 @@ var gNoUpdatesPage = {
|
||||
onPageShow() {
|
||||
LOG("gNoUpdatesPage", "onPageShow - could not select an appropriate " +
|
||||
"update. Either there were no updates or |selectUpdate| failed");
|
||||
|
||||
if (Services.prefs.getBoolPref(PREF_APP_UPDATE_ENABLED, true))
|
||||
if (Services.prefs.getBoolPref(PREF_APP_UPDATE_AUTO, true))
|
||||
document.getElementById("noUpdatesAutoEnabled").hidden = false;
|
||||
else
|
||||
document.getElementById("noUpdatesAutoDisabled").hidden = false;
|
||||
|
@ -275,30 +275,15 @@ interface nsIUpdateChecker : nsISupports
|
||||
* current value of the user's update settings. This is used by
|
||||
* any piece of UI that offers the user the imperative option to
|
||||
* check for updates now, regardless of their update settings.
|
||||
* force will not work if the system administrator has locked
|
||||
* the app.update.enabled preference.
|
||||
* However, if updates are disabled by policy, setting force to true
|
||||
* will not override the the policy.
|
||||
*/
|
||||
void checkForUpdates(in nsIUpdateCheckListener listener, in boolean force);
|
||||
|
||||
/**
|
||||
* Constants for the |stopChecking| function that tell the Checker how long
|
||||
* to stop checking:
|
||||
*
|
||||
* CURRENT_CHECK: Stops the current (active) check only
|
||||
* CURRENT_SESSION: Stops all checking for the current session
|
||||
* ANY_CHECKS: Stops all checking, any session from now on
|
||||
* (disables update checking preferences)
|
||||
*/
|
||||
const unsigned short CURRENT_CHECK = 1;
|
||||
const unsigned short CURRENT_SESSION = 2;
|
||||
const unsigned short ANY_CHECKS = 3;
|
||||
|
||||
/**
|
||||
* Ends any pending update check.
|
||||
* @param duration
|
||||
* A value representing the set of checks to stop doing.
|
||||
*/
|
||||
void stopChecking(in unsigned short duration);
|
||||
void stopCurrentCheck();
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -32,7 +32,7 @@ const PREF_APP_UPDATE_ELEVATE_NEVER = "app.update.elevate.never";
|
||||
const PREF_APP_UPDATE_ELEVATE_VERSION = "app.update.elevate.version";
|
||||
const PREF_APP_UPDATE_ELEVATE_ATTEMPTS = "app.update.elevate.attempts";
|
||||
const PREF_APP_UPDATE_ELEVATE_MAXATTEMPTS = "app.update.elevate.maxAttempts";
|
||||
const PREF_APP_UPDATE_ENABLED = "app.update.enabled";
|
||||
const PREF_APP_UPDATE_DISABLEDFORTESTING = "app.update.disabledForTesting";
|
||||
const PREF_APP_UPDATE_IDLETIME = "app.update.idletime";
|
||||
const PREF_APP_UPDATE_LOG = "app.update.log";
|
||||
const PREF_APP_UPDATE_NOTIFIEDUNSUPPORTED = "app.update.notifiedUnsupported";
|
||||
@ -519,40 +519,6 @@ function getCanStageUpdates() {
|
||||
return gCanStageUpdatesSession;
|
||||
}
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "gCanCheckForUpdates", function aus_gCanCheckForUpdates() {
|
||||
// If the administrator has disabled app update and locked the preference so
|
||||
// users can't check for updates. This preference check is ok in this lazy
|
||||
// getter since locked prefs don't change until the application is restarted.
|
||||
var enabled = Services.prefs.getBoolPref(PREF_APP_UPDATE_ENABLED, true);
|
||||
if (!enabled && Services.prefs.prefIsLocked(PREF_APP_UPDATE_ENABLED)) {
|
||||
LOG("gCanCheckForUpdates - unable to automatically check for updates, " +
|
||||
"the preference is disabled and admistratively locked.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Services.policies && !Services.policies.isAllowed("appUpdate")) {
|
||||
LOG("gCanCheckForUpdates - unable to automatically check for updates. " +
|
||||
"Functionality disabled by enterprise policy.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// If we don't know the binary platform we're updating, we can't update.
|
||||
if (!UpdateUtils.ABI) {
|
||||
LOG("gCanCheckForUpdates - unable to check for updates, unknown ABI");
|
||||
return false;
|
||||
}
|
||||
|
||||
// If we don't know the OS version we're updating, we can't update.
|
||||
if (!UpdateUtils.OSVersion) {
|
||||
LOG("gCanCheckForUpdates - unable to check for updates, unknown OS " +
|
||||
"version");
|
||||
return false;
|
||||
}
|
||||
|
||||
LOG("gCanCheckForUpdates - able to check for updates");
|
||||
return true;
|
||||
});
|
||||
|
||||
/**
|
||||
* Logs a string to the error console.
|
||||
* @param string
|
||||
@ -2016,11 +1982,6 @@ UpdateService.prototype = {
|
||||
// UPDATE_LAST_NOTIFY_INTERVAL_DAYS_NOTIFY
|
||||
AUSTLMY.pingLastUpdateTime(this._pingSuffix);
|
||||
// Histogram IDs:
|
||||
// UPDATE_NOT_PREF_UPDATE_ENABLED_EXTERNAL
|
||||
// UPDATE_NOT_PREF_UPDATE_ENABLED_NOTIFY
|
||||
AUSTLMY.pingBoolPref("UPDATE_NOT_PREF_UPDATE_ENABLED_" + this._pingSuffix,
|
||||
PREF_APP_UPDATE_ENABLED, true, true);
|
||||
// Histogram IDs:
|
||||
// UPDATE_NOT_PREF_UPDATE_AUTO_EXTERNAL
|
||||
// UPDATE_NOT_PREF_UPDATE_AUTO_NOTIFY
|
||||
AUSTLMY.pingBoolPref("UPDATE_NOT_PREF_UPDATE_AUTO_" + this._pingSuffix,
|
||||
@ -2098,14 +2059,12 @@ UpdateService.prototype = {
|
||||
} else if (!validUpdateURL) {
|
||||
AUSTLMY.pingCheckCode(this._pingSuffix,
|
||||
AUSTLMY.CHK_INVALID_DEFAULT_URL);
|
||||
} else if (!Services.prefs.getBoolPref(PREF_APP_UPDATE_ENABLED, true)) {
|
||||
AUSTLMY.pingCheckCode(this._pingSuffix, AUSTLMY.CHK_PREF_DISABLED);
|
||||
} else if (this.disabledByPolicy) {
|
||||
AUSTLMY.pingCheckCode(this._pingSuffix, AUSTLMY.CHK_DISABLED_BY_POLICY);
|
||||
} else if (!hasUpdateMutex()) {
|
||||
AUSTLMY.pingCheckCode(this._pingSuffix, AUSTLMY.CHK_NO_MUTEX);
|
||||
} else if (!gCanCheckForUpdates) {
|
||||
} else if (!this.canCheckForUpdates) {
|
||||
AUSTLMY.pingCheckCode(this._pingSuffix, AUSTLMY.CHK_UNABLE_TO_CHECK);
|
||||
} else if (!this.backgroundChecker._enabled) {
|
||||
AUSTLMY.pingCheckCode(this._pingSuffix, AUSTLMY.CHK_DISABLED_FOR_SESSION);
|
||||
}
|
||||
|
||||
this.backgroundChecker.checkForUpdates(this, false);
|
||||
@ -2251,8 +2210,7 @@ UpdateService.prototype = {
|
||||
return;
|
||||
}
|
||||
|
||||
var updateEnabled = Services.prefs.getBoolPref(PREF_APP_UPDATE_ENABLED, true);
|
||||
if (!updateEnabled) {
|
||||
if (this.disabledByPolicy) {
|
||||
AUSTLMY.pingCheckCode(this._pingSuffix, AUSTLMY.CHK_PREF_DISABLED);
|
||||
LOG("UpdateService:_selectAndInstallUpdate - not prompting because " +
|
||||
"update is disabled");
|
||||
@ -2344,11 +2302,48 @@ UpdateService.prototype = {
|
||||
return this._backgroundChecker;
|
||||
},
|
||||
|
||||
get disabledForTesting() {
|
||||
return Cu.isInAutomation &&
|
||||
Services.prefs.getBoolPref(PREF_APP_UPDATE_DISABLEDFORTESTING, false);
|
||||
},
|
||||
|
||||
get disabledByPolicy() {
|
||||
return (Services.policies && !Services.policies.isAllowed("appUpdate")) ||
|
||||
this.disabledForTesting;
|
||||
},
|
||||
|
||||
/**
|
||||
* See nsIUpdateService.idl
|
||||
*/
|
||||
get canCheckForUpdates() {
|
||||
return gCanCheckForUpdates && hasUpdateMutex();
|
||||
if (this.disabledByPolicy) {
|
||||
LOG("UpdateService.canCheckForUpdates - unable to automatically check " +
|
||||
"for updates, the option has been disabled by the administrator.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// If we don't know the binary platform we're updating, we can't update.
|
||||
if (!UpdateUtils.ABI) {
|
||||
LOG("UpdateService.canCheckForUpdates - unable to check for updates, " +
|
||||
"unknown ABI");
|
||||
return false;
|
||||
}
|
||||
|
||||
// If we don't know the OS version we're updating, we can't update.
|
||||
if (!UpdateUtils.OSVersion) {
|
||||
LOG("UpdateService.canCheckForUpdates - unable to check for updates, " +
|
||||
"unknown OS version");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!hasUpdateMutex()) {
|
||||
LOG("UpdateService.canCheckForUpdates - unable to check for updates, " +
|
||||
"unable to acquire update mutex");
|
||||
return false;
|
||||
}
|
||||
|
||||
LOG("UpdateService.canCheckForUpdates - able to check for updates");
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
@ -2964,7 +2959,13 @@ Checker.prototype = {
|
||||
throw Cr.NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
|
||||
if (!this.enabled && !force) {
|
||||
let UpdateServiceInstance = UpdateServiceFactory.createInstance();
|
||||
// |force| can override |canCheckForUpdates| since |force| indicates a
|
||||
// manual update check. But nothing should override enterprise policies.
|
||||
if (UpdateServiceInstance.disabledByPolicy) {
|
||||
return;
|
||||
}
|
||||
if (!UpdateServiceInstance.canCheckForUpdates && !force) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -3143,33 +3144,13 @@ Checker.prototype = {
|
||||
this._request = null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Whether or not we are allowed to do update checking.
|
||||
*/
|
||||
_enabled: true,
|
||||
get enabled() {
|
||||
return Services.prefs.getBoolPref(PREF_APP_UPDATE_ENABLED, true) &&
|
||||
gCanCheckForUpdates && hasUpdateMutex() && this._enabled;
|
||||
},
|
||||
|
||||
/**
|
||||
* See nsIUpdateService.idl
|
||||
*/
|
||||
stopChecking: function UC_stopChecking(duration) {
|
||||
stopCurrentCheck: function UC_stopCurrentCheck() {
|
||||
// Always stop the current check
|
||||
if (this._request)
|
||||
this._request.abort();
|
||||
|
||||
switch (duration) {
|
||||
case Ci.nsIUpdateChecker.CURRENT_SESSION:
|
||||
this._enabled = false;
|
||||
break;
|
||||
case Ci.nsIUpdateChecker.ANY_CHECKS:
|
||||
this._enabled = false;
|
||||
Services.prefs.setBoolPref(PREF_APP_UPDATE_ENABLED, this._enabled);
|
||||
break;
|
||||
}
|
||||
|
||||
this._callback = null;
|
||||
},
|
||||
|
||||
|
@ -120,7 +120,7 @@ function runUpdateTest(updateParams, checkAttempts, steps) {
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
[PREF_APP_UPDATE_DOWNLOADPROMPTATTEMPTS, 0],
|
||||
[PREF_APP_UPDATE_ENABLED, true],
|
||||
[PREF_APP_UPDATE_DISABLEDFORTESTING, false],
|
||||
[PREF_APP_UPDATE_IDLETIME, 0],
|
||||
[PREF_APP_UPDATE_URL_MANUAL, URL_MANUAL_UPDATE],
|
||||
[PREF_APP_UPDATE_LOG, DEBUG_AUS_TEST],
|
||||
@ -173,10 +173,10 @@ function runUpdateProcessingTest(updates, steps) {
|
||||
|
||||
setUpdateTimerPrefs();
|
||||
gEnv.set("MOZ_TEST_SKIP_UPDATE_STAGE", "1");
|
||||
SpecialPowers.pushPrefEnv({
|
||||
await SpecialPowers.pushPrefEnv({
|
||||
set: [
|
||||
[PREF_APP_UPDATE_DOWNLOADPROMPTATTEMPTS, 0],
|
||||
[PREF_APP_UPDATE_ENABLED, true],
|
||||
[PREF_APP_UPDATE_DISABLEDFORTESTING, false],
|
||||
[PREF_APP_UPDATE_IDLETIME, 0],
|
||||
[PREF_APP_UPDATE_URL_MANUAL, URL_MANUAL_UPDATE],
|
||||
[PREF_APP_UPDATE_LOG, DEBUG_AUS_TEST],
|
||||
|
@ -33,7 +33,7 @@ function runTest() {
|
||||
let url = URL_HTTP_UPDATE_XML + "?showDetails=1" + getVersionParams();
|
||||
setUpdateURL(url);
|
||||
|
||||
Services.prefs.setBoolPref(PREF_APP_UPDATE_ENABLED, true);
|
||||
Services.prefs.setBoolPref(PREF_APP_UPDATE_DISABLEDFORTESTING, false);
|
||||
Services.prefs.setBoolPref(PREF_APP_UPDATE_AUTO, false);
|
||||
|
||||
Services.io.offline = true;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user