Merge mozilla-central to mozilla-inbound a=merge on a CLOSED TREE

This commit is contained in:
Coroiu Cristina 2018-07-17 12:48:47 +03:00
commit f3162b921c
104 changed files with 993 additions and 881 deletions

View File

@ -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);

View File

@ -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;
},

View File

@ -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">

View File

@ -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");
},
/**

View File

@ -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"/>

View File

@ -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");
}
},

View File

@ -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">

View File

@ -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);
}
},

View File

@ -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;

View File

@ -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"

View File

@ -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 &&

View File

@ -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();

View File

@ -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]]
});
});

View File

@ -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" />

View File

@ -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");

View File

@ -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 =

View File

@ -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);

View File

@ -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;

View File

@ -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();
}
}
},

View File

@ -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"

View 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"
];

View File

@ -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"];

View File

@ -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(`

View File

@ -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>

View File

@ -99,6 +99,12 @@
height: 30px;
padding: 4px 0 6px;
font-size: 15px;
&:focus,
&.active {
box-shadow: $shadow-primary;
transition: box-shadow 150ms;
}
}
}
}

View File

@ -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'"
}
```

View File

@ -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>

View File

@ -131,6 +131,12 @@
float: none;
margin-top: 30px;
}
&:focus,
&.active {
box-shadow: $shadow-primary;
transition: box-shadow 150ms;
}
}

View File

@ -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));

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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>

View File

@ -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}
]
});

View File

@ -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"
}]
]);

View File

@ -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}));

View File

@ -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}.

View File

@ -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=Χορηγούμενες ιστορίες

View File

@ -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}.

View File

@ -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=अपने नए टैब पृष्ठ को अनुकूलित करें

View File

@ -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 browsers profile into Firefox.
# LOCALIZATION NOTE (manual_migration_import_button): This message is shown on a button that starts the process
# of importing another browsers 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.

View File

@ -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}.

View File

@ -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}.

View File

@ -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 browsers 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.

View File

@ -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}.

View File

@ -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",

View File

@ -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": "Χορηγούμενες ιστορίες",

View File

@ -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",

View File

@ -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": "अपने नए टैब पृष्ठ को अनुकूलित करें",

View File

@ -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 dutilizacion",
"firstrun_privacy_notice": "Avís de privacitat",

View File

@ -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": "политикой приватности",

View File

@ -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 youve 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"
};

View File

@ -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",

View File

@ -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}

View File

@ -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);
});

View File

@ -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 {

View File

@ -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.

View File

@ -392,7 +392,6 @@ class AnimationInspector {
await this.inspector.getCommonComponentProps()
.setSelectedNode(nodeFront, { reason: "animation-panel" });
await nodeFront.scrollIntoView();
}
async setAnimationsCurrentTime(currentTime, shouldRefresh) {

View File

@ -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]

View File

@ -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;
}

View File

@ -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

View File

@ -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);

View File

@ -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);
}
}
}

View File

@ -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) {

View File

@ -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());

View File

@ -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

View File

@ -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)

View File

@ -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'])

View File

@ -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>

View File

@ -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());

View File

@ -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))

View File

@ -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

View File

@ -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()

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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}

View File

@ -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,

View File

@ -1,3 +0,0 @@
[update-and-send-events.html]
disabled: https://bugzilla.mozilla.org/show_bug.cgi?id=1474811

View File

@ -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>

View File

@ -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.";

View File

@ -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"],

View File

@ -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(),

View File

@ -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",

View File

@ -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)

View File

@ -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

View File

@ -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;

View File

@ -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();
};
/**

View File

@ -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;
},

View File

@ -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],

View File

@ -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