Merge branch 'mozilla_main' into fork

issues/166-allow-fallback-location iceraven-1.2.1
Abhijit Valluri 4 years ago
commit 7a3cacf7f1

@ -115,6 +115,8 @@ To make it easier to triage, we have these issue requirements:
Please keep in mind that even though a feature you have in mind may seem like a small ask, as a small team, we have to prioritize our planned work and every new feature adds complexity and maintenance and may take up design, research, product, and engineering time. We appreciate everyones passion but we will not be able to incorporate every feature request or even fix every bug. That being said, just because we haven't replied, doesn't mean we don't care about the issue, please be patient with our response times as we're very busy. Please keep in mind that even though a feature you have in mind may seem like a small ask, as a small team, we have to prioritize our planned work and every new feature adds complexity and maintenance and may take up design, research, product, and engineering time. We appreciate everyones passion but we will not be able to incorporate every feature request or even fix every bug. That being said, just because we haven't replied, doesn't mean we don't care about the issue, please be patient with our response times as we're very busy.
## License
This Source Code Form is subject to the terms of the Mozilla Public This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this License, v. 2.0. If a copy of the MPL was not distributed with this

@ -14,7 +14,6 @@ import com.android.build.OutputFile
import groovy.json.JsonOutput import groovy.json.JsonOutput
import org.gradle.internal.logging.text.StyledTextOutput.Style import org.gradle.internal.logging.text.StyledTextOutput.Style
import org.gradle.internal.logging.text.StyledTextOutputFactory import org.gradle.internal.logging.text.StyledTextOutputFactory
import org.mozilla.fenix.gradle.tasks.LintUnitTestRunner
import static org.gradle.api.tasks.testing.TestResult.ResultType import static org.gradle.api.tasks.testing.TestResult.ResultType
@ -617,8 +616,6 @@ task buildTranslationArray {
android.defaultConfig.buildConfigField "String[]", "SUPPORTED_LOCALE_ARRAY", foundLocalesString android.defaultConfig.buildConfigField "String[]", "SUPPORTED_LOCALE_ARRAY", foundLocalesString
} }
tasks.register('lintUnitTestRunner', LintUnitTestRunner)
afterEvaluate { afterEvaluate {
// Format test output. Ported from AC #2401 // Format test output. Ported from AC #2401

@ -42,7 +42,7 @@ class HistoryRobot {
fun verifyVisitedTimeTitle() { fun verifyVisitedTimeTitle() {
mDevice.waitNotNull( mDevice.waitNotNull(
Until.findObject( Until.findObject(
By.text("Last 24 hours") By.text("Today")
), ),
waitingTime waitingTime
) )
@ -99,7 +99,7 @@ class HistoryRobot {
} }
fun openThreeDotMenu(interact: ThreeDotMenuHistoryItemRobot.() -> Unit): fun openThreeDotMenu(interact: ThreeDotMenuHistoryItemRobot.() -> Unit):
ThreeDotMenuHistoryItemRobot.Transition { ThreeDotMenuHistoryItemRobot.Transition {
threeDotMenu().click() threeDotMenu().click()
@ -143,7 +143,7 @@ private fun assertEmptyHistoryView() =
.check(matches(withText("No history here"))) .check(matches(withText("No history here")))
private fun assertVisitedTimeTitle() = private fun assertVisitedTimeTitle() =
onView(withId(R.id.header_title)).check(matches(withText("Last 24 hours"))) onView(withId(R.id.header_title)).check(matches(withText("Today")))
private fun assertTestPageTitle(title: String) = testPageTitle() private fun assertTestPageTitle(title: String) = testPageTitle()
.check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE))) .check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))

@ -88,4 +88,8 @@ public class Leanplum {
public static void track(String event, double value, String info) { public static void track(String event, double value, String info) {
} }
public static String getDeviceId() { return "stub"; }
public static String getUserId() { return "stub"; }
} }

@ -32,7 +32,6 @@ import kotlinx.android.synthetic.main.activity_home.*
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Dispatchers.IO import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.Dispatchers.Main
import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
@ -281,16 +280,6 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
} }
settings().wasDefaultBrowserOnLastResume = settings().isDefaultBrowser() settings().wasDefaultBrowserOnLastResume = settings().isDefaultBrowser()
if (!settings().manuallyCloseTabs) {
val toClose = components.core.store.state.tabs.filter {
(System.currentTimeMillis() - it.lastAccess) > settings().getTabTimeout()
}
// Removal needs to happen on the main thread.
lifecycleScope.launch(Main) {
toClose.forEach { components.useCases.tabsUseCases.removeTab(it.id) }
}
}
} }
} }

@ -18,7 +18,6 @@ import org.mozilla.fenix.Config
import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.R import org.mozilla.fenix.R
import org.mozilla.fenix.ReleaseChannel import org.mozilla.fenix.ReleaseChannel
import org.mozilla.fenix.StrictModeManager
import org.mozilla.fenix.components.metrics.AdjustMetricsService import org.mozilla.fenix.components.metrics.AdjustMetricsService
import org.mozilla.fenix.components.metrics.GleanMetricsService import org.mozilla.fenix.components.metrics.GleanMetricsService
import org.mozilla.fenix.components.metrics.LeanplumMetricsService import org.mozilla.fenix.components.metrics.LeanplumMetricsService
@ -35,8 +34,7 @@ import org.mozilla.geckoview.BuildConfig.MOZ_UPDATE_CHANNEL
*/ */
@Mockable @Mockable
class Analytics( class Analytics(
private val context: Context, private val context: Context
strictMode: StrictModeManager
) { ) {
val crashReporter: CrashReporter by lazy { val crashReporter: CrashReporter by lazy {
val services = mutableListOf<CrashReporterService>() val services = mutableListOf<CrashReporterService>()
@ -86,10 +84,7 @@ class Analytics(
) )
} }
val leanplumMetricsService by lazy { LeanplumMetricsService( val leanplumMetricsService by lazy { LeanplumMetricsService(context as Application) }
context as Application,
strictMode
) }
val metrics: MetricController by lazy { val metrics: MetricController by lazy {
MetricController.create( MetricController.create(

@ -30,7 +30,11 @@ import java.util.concurrent.TimeUnit
private const val DAY_IN_MINUTES = 24 * 60L private const val DAY_IN_MINUTES = 24 * 60L
/** /**
* Provides access to all components. * Provides access to all components. This class is an implementation of the Service Locator
* pattern, which helps us manage the dependencies in our app.
*
* Note: these aren't just "components" from "android-components": they're any "component" that
* can be considered a building block of our app.
*/ */
@Mockable @Mockable
class Components(private val context: Context) { class Components(private val context: Context) {
@ -116,7 +120,7 @@ class Components(private val context: Context) {
addonCollectionProvider.setCollectionName(addonsCollection) addonCollectionProvider.setCollectionName(addonsCollection)
} }
val analytics by lazy { Analytics(context, strictMode) } val analytics by lazy { Analytics(context) }
val publicSuffixList by lazy { PublicSuffixList(context) } val publicSuffixList by lazy { PublicSuffixList(context) }
val clipboardHandler by lazy { ClipboardHandler(context) } val clipboardHandler by lazy { ClipboardHandler(context) }
val migrationStore by lazy { MigrationStore() } val migrationStore by lazy { MigrationStore() }

@ -77,6 +77,7 @@ import java.util.concurrent.TimeUnit
* Component group for all core browser functionality. * Component group for all core browser functionality.
*/ */
@Mockable @Mockable
@Suppress("LargeClass")
class Core( class Core(
private val context: Context, private val context: Context,
private val crashReporter: CrashReporting, private val crashReporter: CrashReporting,
@ -218,6 +219,18 @@ class Core(
.periodicallyInForeground(interval = 30, unit = TimeUnit.SECONDS) .periodicallyInForeground(interval = 30, unit = TimeUnit.SECONDS)
.whenGoingToBackground() .whenGoingToBackground()
.whenSessionsChange() .whenSessionsChange()
// Now that we have restored our previous state (if there's one) let's remove timed out tabs
if (!context.settings().manuallyCloseTabs) {
store.state.tabs.filter {
(System.currentTimeMillis() - it.lastAccess) > context.settings().getTabTimeout()
}.forEach {
val session = sessionManager.findSessionById(it.id)
if (session != null) {
sessionManager.remove(session)
}
}
}
} }
WebNotificationFeature( WebNotificationFeature(
@ -272,11 +285,13 @@ class Core(
val bookmarksStorage by lazy { lazyBookmarksStorage.value } val bookmarksStorage by lazy { lazyBookmarksStorage.value }
val passwordsStorage by lazy { lazyPasswordsStorage.value } val passwordsStorage by lazy { lazyPasswordsStorage.value }
val tabCollectionStorage by lazy { TabCollectionStorage( val tabCollectionStorage by lazy {
context, TabCollectionStorage(
sessionManager, context,
strictMode sessionManager,
) } strictMode
)
}
/** /**
* A storage component for persisting thumbnail images of tabs. * A storage component for persisting thumbnail images of tabs.

@ -5,11 +5,8 @@
package org.mozilla.fenix.components.metrics package org.mozilla.fenix.components.metrics
import android.app.Application import android.app.Application
import android.content.Context.MODE_PRIVATE
import android.net.Uri import android.net.Uri
import android.os.StrictMode
import android.util.Log import android.util.Log
import androidx.annotation.VisibleForTesting
import com.leanplum.Leanplum import com.leanplum.Leanplum
import com.leanplum.LeanplumActivityHelper import com.leanplum.LeanplumActivityHelper
import com.leanplum.annotations.Parser import com.leanplum.annotations.Parser
@ -22,7 +19,6 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import mozilla.components.support.locale.LocaleManager import mozilla.components.support.locale.LocaleManager
import org.mozilla.fenix.BuildConfig import org.mozilla.fenix.BuildConfig
import org.mozilla.fenix.StrictModeManager
import org.mozilla.fenix.components.metrics.MozillaProductDetector.MozillaProducts import org.mozilla.fenix.components.metrics.MozillaProductDetector.MozillaProducts
import org.mozilla.fenix.ext.settings import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.home.intent.DeepLinkIntentProcessor import org.mozilla.fenix.home.intent.DeepLinkIntentProcessor
@ -57,9 +53,7 @@ private val Event.name: String?
} }
class LeanplumMetricsService( class LeanplumMetricsService(
private val application: Application, private val application: Application
strictMode: StrictModeManager,
private val deviceIdGenerator: () -> String = { randomUUID().toString() }
) : MetricsService, DeepLinkIntentProcessor.DeepLinkVerifier { ) : MetricsService, DeepLinkIntentProcessor.DeepLinkVerifier {
val scope = CoroutineScope(Dispatchers.IO) val scope = CoroutineScope(Dispatchers.IO)
var leanplumJob: Job? = null var leanplumJob: Job? = null
@ -84,22 +78,6 @@ class LeanplumMetricsService(
override val type = MetricServiceType.Marketing override val type = MetricServiceType.Marketing
private val token = Token(LeanplumId, LeanplumToken) private val token = Token(LeanplumId, LeanplumToken)
private val preferences = strictMode.resetAfter(StrictMode.allowThreadDiskReads()) {
application.getSharedPreferences(PREFERENCE_NAME, MODE_PRIVATE)
}
@VisibleForTesting
internal val deviceId by lazy {
var deviceId = preferences.getString(DEVICE_ID_KEY, null)
if (deviceId == null) {
deviceId = deviceIdGenerator.invoke()
preferences.edit().putString(DEVICE_ID_KEY, deviceId).apply()
}
deviceId
}
@Suppress("ComplexMethod") @Suppress("ComplexMethod")
override fun start() { override fun start() {
@ -107,7 +85,7 @@ class LeanplumMetricsService(
Leanplum.setIsTestModeEnabled(false) Leanplum.setIsTestModeEnabled(false)
Leanplum.setApplicationContext(application) Leanplum.setApplicationContext(application)
Leanplum.setDeviceId(deviceId) Leanplum.setDeviceId(randomUUID().toString())
Parser.parseVariables(application) Parser.parseVariables(application)
leanplumJob = scope.launch { leanplumJob = scope.launch {
@ -171,6 +149,8 @@ class LeanplumMetricsService(
LeanplumInternal.setCalledStart(true) LeanplumInternal.setCalledStart(true)
LeanplumInternal.setHasStarted(true) LeanplumInternal.setHasStarted(true)
LeanplumInternal.setStartedInBackground(true) LeanplumInternal.setStartedInBackground(true)
Log.i(LOGTAG, "Started Leanplum with deviceId ${Leanplum.getDeviceId()}" +
" and userId ${Leanplum.getUserId()}")
} }
} }
} }
@ -185,7 +165,7 @@ class LeanplumMetricsService(
// We compare the local Leanplum device ID against the "uid" query parameter and only // We compare the local Leanplum device ID against the "uid" query parameter and only
// accept deep links where both values match. // accept deep links where both values match.
val uid = deepLink.getQueryParameter("uid") val uid = deepLink.getQueryParameter("uid")
return uid == deviceId return uid == Leanplum.getDeviceId()
} }
override fun stop() { override fun stop() {

@ -11,7 +11,7 @@ import kotlinx.android.extensions.LayoutContainer
import kotlinx.android.synthetic.main.download_dialog_layout.view.* import kotlinx.android.synthetic.main.download_dialog_layout.view.*
import mozilla.components.browser.state.state.content.DownloadState import mozilla.components.browser.state.state.content.DownloadState
import mozilla.components.feature.downloads.AbstractFetchDownloadService import mozilla.components.feature.downloads.AbstractFetchDownloadService
import mozilla.components.feature.downloads.toMegabyteString import mozilla.components.feature.downloads.toMegabyteOrKilobyteString
import org.mozilla.fenix.R import org.mozilla.fenix.R
import org.mozilla.fenix.components.metrics.Event import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.ext.metrics import org.mozilla.fenix.ext.metrics
@ -86,7 +86,7 @@ class DynamicDownloadDialog(
} else { } else {
val titleText = container.context.getString( val titleText = container.context.getString(
R.string.mozac_feature_downloads_completed_notification_text2 R.string.mozac_feature_downloads_completed_notification_text2
) + " (${downloadState.contentLength?.toMegabyteString()})" ) + " (${downloadState.contentLength?.toMegabyteOrKilobyteString()})"
view.download_dialog_title.text = titleText view.download_dialog_title.text = titleText

@ -622,7 +622,8 @@ class HomeFragment : Fragment() {
dialog.cancel() dialog.cancel()
} }
setPositiveButton(R.string.tab_collection_dialog_positive) { dialog: DialogInterface, _ -> setPositiveButton(R.string.tab_collection_dialog_positive) { dialog: DialogInterface, _ ->
viewLifecycleOwner.lifecycleScope.launch(IO) { // Use fragment's lifecycle; the view may be gone by the time dialog is interacted with.
lifecycleScope.launch(IO) {
context.components.core.tabCollectionStorage.removeCollection(tabCollection) context.components.core.tabCollectionStorage.removeCollection(tabCollection)
context.components.analytics.metrics.track(Event.CollectionRemoved) context.components.analytics.metrics.track(Event.CollectionRemoved)
}.invokeOnCompletion { }.invokeOnCompletion {

@ -6,6 +6,7 @@ package org.mozilla.fenix.library.bookmarks
import android.content.DialogInterface import android.content.DialogInterface
import android.os.Bundle import android.os.Bundle
import android.text.SpannableString
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.Menu import android.view.Menu
import android.view.MenuInflater import android.view.MenuInflater
@ -49,6 +50,7 @@ import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.minus import org.mozilla.fenix.ext.minus
import org.mozilla.fenix.ext.nav import org.mozilla.fenix.ext.nav
import org.mozilla.fenix.ext.requireComponents import org.mozilla.fenix.ext.requireComponents
import org.mozilla.fenix.ext.setTextColor
import org.mozilla.fenix.ext.toShortUrl import org.mozilla.fenix.ext.toShortUrl
import org.mozilla.fenix.library.LibraryPageFragment import org.mozilla.fenix.library.LibraryPageFragment
import org.mozilla.fenix.utils.allowUndo import org.mozilla.fenix.utils.allowUndo
@ -185,6 +187,11 @@ class BookmarkFragment : LibraryPageFragment<BookmarkNode>(), UserInteractionHan
inflater.inflate(R.menu.bookmarks_select_multi_not_item, menu) inflater.inflate(R.menu.bookmarks_select_multi_not_item, menu)
} else { } else {
inflater.inflate(R.menu.bookmarks_select_multi, menu) inflater.inflate(R.menu.bookmarks_select_multi, menu)
menu.findItem(R.id.delete_bookmarks_multi_select).title =
SpannableString(getString(R.string.bookmark_menu_delete_button)).apply {
setTextColor(requireContext(), R.attr.destructive)
}
} }
} }
} }
@ -365,7 +372,8 @@ class BookmarkFragment : LibraryPageFragment<BookmarkNode>(), UserInteractionHan
pendingBookmarkDeletionJob = getDeleteOperation(Event.RemoveBookmarkFolder) pendingBookmarkDeletionJob = getDeleteOperation(Event.RemoveBookmarkFolder)
dialog.dismiss() dialog.dismiss()
val snackbarMessage = getRemoveBookmarksSnackBarMessage(selected, containsFolders = true) val snackbarMessage = getRemoveBookmarksSnackBarMessage(selected, containsFolders = true)
viewLifecycleOwner.lifecycleScope.allowUndo( // Use fragment's lifecycle; the view may be gone by the time dialog is interacted with.
lifecycleScope.allowUndo(
requireView(), requireView(),
snackbarMessage, snackbarMessage,
getString(R.string.bookmark_undo_deletion), getString(R.string.bookmark_undo_deletion),

@ -182,7 +182,8 @@ class EditBookmarkFragment : Fragment(R.layout.fragment_edit_bookmark) {
dialog.cancel() dialog.cancel()
} }
setPositiveButton(R.string.tab_collection_dialog_positive) { dialog: DialogInterface, _ -> setPositiveButton(R.string.tab_collection_dialog_positive) { dialog: DialogInterface, _ ->
viewLifecycleOwner.lifecycleScope.launch(IO) { // Use fragment's lifecycle; the view may be gone by the time dialog is interacted with.
lifecycleScope.launch(IO) {
requireComponents.core.bookmarksStorage.deleteNode(args.guidToEdit) requireComponents.core.bookmarksStorage.deleteNode(args.guidToEdit)
requireComponents.analytics.metrics.track(Event.RemoveBookmark) requireComponents.analytics.metrics.track(Event.RemoveBookmark)

@ -8,12 +8,12 @@ import android.view.View
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.synthetic.main.download_list_item.view.* import kotlinx.android.synthetic.main.download_list_item.view.*
import kotlinx.android.synthetic.main.library_site_item.view.* import kotlinx.android.synthetic.main.library_site_item.view.*
import mozilla.components.feature.downloads.toMegabyteOrKilobyteString
import org.mozilla.fenix.R import org.mozilla.fenix.R
import org.mozilla.fenix.ext.hideAndDisable import org.mozilla.fenix.ext.hideAndDisable
import org.mozilla.fenix.library.SelectionHolder import org.mozilla.fenix.library.SelectionHolder
import org.mozilla.fenix.library.downloads.DownloadInteractor import org.mozilla.fenix.library.downloads.DownloadInteractor
import org.mozilla.fenix.library.downloads.DownloadItem import org.mozilla.fenix.library.downloads.DownloadItem
import mozilla.components.feature.downloads.toMegabyteString
import org.mozilla.fenix.ext.getIcon import org.mozilla.fenix.ext.getIcon
class DownloadsListItemViewHolder( class DownloadsListItemViewHolder(
@ -29,7 +29,7 @@ class DownloadsListItemViewHolder(
) { ) {
itemView.download_layout.visibility = View.VISIBLE itemView.download_layout.visibility = View.VISIBLE
itemView.download_layout.titleView.text = item.fileName itemView.download_layout.titleView.text = item.fileName
itemView.download_layout.urlView.text = item.size.toLong().toMegabyteString() itemView.download_layout.urlView.text = item.size.toLong().toMegabyteOrKilobyteString()
itemView.download_layout.setSelectionInteractor(item, selectionHolder, downloadInteractor) itemView.download_layout.setSelectionInteractor(item, selectionHolder, downloadInteractor)
itemView.download_layout.changeSelected(item in selectionHolder.selectedItems) itemView.download_layout.changeSelected(item in selectionHolder.selectedItems)

@ -17,10 +17,11 @@ import java.util.Calendar
import java.util.Date import java.util.Date
enum class HistoryItemTimeGroup { enum class HistoryItemTimeGroup {
Today, ThisWeek, ThisMonth, Older; Today, Yesterday, ThisWeek, ThisMonth, Older;
fun humanReadable(context: Context): String = when (this) { fun humanReadable(context: Context): String = when (this) {
Today -> context.getString(R.string.history_24_hours) Today -> context.getString(R.string.history_today)
Yesterday -> context.getString(R.string.history_yesterday)
ThisWeek -> context.getString(R.string.history_7_days) ThisWeek -> context.getString(R.string.history_7_days)
ThisMonth -> context.getString(R.string.history_30_days) ThisMonth -> context.getString(R.string.history_30_days)
Older -> context.getString(R.string.history_older) Older -> context.getString(R.string.history_older)
@ -81,11 +82,14 @@ class HistoryAdapter(private val historyInteractor: HistoryInteractor) :
companion object { companion object {
private const val zeroDays = 0 private const val zeroDays = 0
private const val oneDay = 1
private const val sevenDays = 7 private const val sevenDays = 7
private const val thirtyDays = 30 private const val thirtyDays = 30
private val oneDayAgo = getDaysAgo(zeroDays).time private val zeroDaysAgo = getDaysAgo(zeroDays).time
private val oneDayAgo = getDaysAgo(oneDay).time
private val sevenDaysAgo = getDaysAgo(sevenDays).time private val sevenDaysAgo = getDaysAgo(sevenDays).time
private val thirtyDaysAgo = getDaysAgo(thirtyDays).time private val thirtyDaysAgo = getDaysAgo(thirtyDays).time
private val yesterdayRange = LongRange(oneDayAgo, zeroDaysAgo)
private val lastWeekRange = LongRange(sevenDaysAgo, oneDayAgo) private val lastWeekRange = LongRange(sevenDaysAgo, oneDayAgo)
private val lastMonthRange = LongRange(thirtyDaysAgo, sevenDaysAgo) private val lastMonthRange = LongRange(thirtyDaysAgo, sevenDaysAgo)
@ -99,6 +103,7 @@ class HistoryAdapter(private val historyInteractor: HistoryInteractor) :
private fun timeGroupForHistoryItem(item: HistoryItem): HistoryItemTimeGroup { private fun timeGroupForHistoryItem(item: HistoryItem): HistoryItemTimeGroup {
return when { return when {
DateUtils.isToday(item.visitedAt) -> HistoryItemTimeGroup.Today DateUtils.isToday(item.visitedAt) -> HistoryItemTimeGroup.Today
yesterdayRange.contains(item.visitedAt) -> HistoryItemTimeGroup.Yesterday
lastWeekRange.contains(item.visitedAt) -> HistoryItemTimeGroup.ThisWeek lastWeekRange.contains(item.visitedAt) -> HistoryItemTimeGroup.ThisWeek
lastMonthRange.contains(item.visitedAt) -> HistoryItemTimeGroup.ThisMonth lastMonthRange.contains(item.visitedAt) -> HistoryItemTimeGroup.ThisMonth
else -> HistoryItemTimeGroup.Older else -> HistoryItemTimeGroup.Older

@ -8,6 +8,7 @@ import android.content.ClipboardManager
import android.content.Context.CLIPBOARD_SERVICE import android.content.Context.CLIPBOARD_SERVICE
import android.content.DialogInterface import android.content.DialogInterface
import android.os.Bundle import android.os.Bundle
import android.text.SpannableString
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.Menu import android.view.Menu
import android.view.MenuInflater import android.view.MenuInflater
@ -42,6 +43,7 @@ import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.nav import org.mozilla.fenix.ext.nav
import org.mozilla.fenix.ext.requireComponents import org.mozilla.fenix.ext.requireComponents
import org.mozilla.fenix.ext.setTextColor
import org.mozilla.fenix.ext.showToolbar import org.mozilla.fenix.ext.showToolbar
import org.mozilla.fenix.ext.toShortUrl import org.mozilla.fenix.ext.toShortUrl
import org.mozilla.fenix.library.LibraryPageFragment import org.mozilla.fenix.library.LibraryPageFragment
@ -166,7 +168,13 @@ class HistoryFragment : LibraryPageFragment<HistoryItem>(), UserInteractionHandl
} }
inflater.inflate(menuRes, menu) inflater.inflate(menuRes, menu)
menu.findItem(R.id.share_history_multi_select)?.isVisible = true menu.findItem(R.id.share_history_multi_select)?.isVisible = true
menu.findItem(R.id.delete_history_multi_select)?.title =
SpannableString(getString(R.string.bookmark_menu_delete_button)).apply {
setTextColor(requireContext(), R.attr.destructive)
}
} }
override fun onOptionsItemSelected(item: MenuItem): Boolean = when (item.itemId) { override fun onOptionsItemSelected(item: MenuItem): Boolean = when (item.itemId) {
@ -267,7 +275,8 @@ class HistoryFragment : LibraryPageFragment<HistoryItem>(), UserInteractionHandl
} }
setPositiveButton(R.string.delete_browsing_data_prompt_allow) { dialog: DialogInterface, _ -> setPositiveButton(R.string.delete_browsing_data_prompt_allow) { dialog: DialogInterface, _ ->
historyStore.dispatch(HistoryFragmentAction.EnterDeletionMode) historyStore.dispatch(HistoryFragmentAction.EnterDeletionMode)
viewLifecycleOwner.lifecycleScope.launch(IO) { // Use fragment's lifecycle; the view may be gone by the time dialog is interacted with.
lifecycleScope.launch(IO) {
requireComponents.analytics.metrics.track(Event.HistoryAllItemsRemoved) requireComponents.analytics.metrics.track(Event.HistoryAllItemsRemoved)
requireComponents.core.store.dispatch(RecentlyClosedAction.RemoveAllClosedTabAction) requireComponents.core.store.dispatch(RecentlyClosedAction.RemoveAllClosedTabAction)
requireComponents.core.historyStorage.deleteEverything() requireComponents.core.historyStorage.deleteEverything()

@ -233,7 +233,8 @@ class AccountSettingsFragment : PreferenceFragmentCompat() {
setNegativeButton(getString(R.string.logins_warning_dialog_later)) { _: DialogInterface, _ -> setNegativeButton(getString(R.string.logins_warning_dialog_later)) { _: DialogInterface, _ ->
SyncEnginesStorage(context).setStatus(SyncEngine.Passwords, newValue) SyncEnginesStorage(context).setStatus(SyncEngine.Passwords, newValue)
viewLifecycleOwner.lifecycleScope.launch { // Use fragment's lifecycle; the view may be gone by the time dialog is interacted with.
lifecycleScope.launch {
context.components.backgroundServices.accountManager.syncNow(SyncReason.EngineChange) context.components.backgroundServices.accountManager.syncNow(SyncReason.EngineChange)
} }
} }

@ -142,7 +142,7 @@ class DeleteBrowsingDataFragment : Fragment(R.layout.fragment_delete_browsing_da
private fun deleteSelected() { private fun deleteSelected() {
startDeletion() startDeletion()
viewLifecycleOwner.lifecycleScope.launch(IO) { lifecycleScope.launch(IO) {
getCheckboxes().mapIndexed { i, v -> getCheckboxes().mapIndexed { i, v ->
if (v.isChecked) { if (v.isChecked) {
when (i) { when (i) {

@ -30,7 +30,7 @@ import org.mozilla.fenix.settings.logins.mapToSavedLogin
*/ */
open class SavedLoginsStorageController( open class SavedLoginsStorageController(
private val passwordsStorage: SyncableLoginsStorage, private val passwordsStorage: SyncableLoginsStorage,
private val viewLifecycleScope: CoroutineScope, private val lifecycleScope: CoroutineScope,
private val navController: NavController, private val navController: NavController,
private val loginsFragmentStore: LoginsFragmentStore, private val loginsFragmentStore: LoginsFragmentStore,
private val ioDispatcher: CoroutineDispatcher = Dispatchers.IO private val ioDispatcher: CoroutineDispatcher = Dispatchers.IO
@ -40,7 +40,7 @@ open class SavedLoginsStorageController(
fun delete(loginId: String) { fun delete(loginId: String) {
var deleteLoginJob: Deferred<Boolean>? = null var deleteLoginJob: Deferred<Boolean>? = null
val deleteJob = viewLifecycleScope.launch(ioDispatcher) { val deleteJob = lifecycleScope.launch(ioDispatcher) {
deleteLoginJob = async { deleteLoginJob = async {
passwordsStorage.delete(loginId) passwordsStorage.delete(loginId)
} }
@ -58,7 +58,7 @@ open class SavedLoginsStorageController(
fun save(loginId: String, usernameText: String, passwordText: String) { fun save(loginId: String, usernameText: String, passwordText: String) {
var saveLoginJob: Deferred<Unit>? = null var saveLoginJob: Deferred<Unit>? = null
viewLifecycleScope.launch(ioDispatcher) { lifecycleScope.launch(ioDispatcher) {
saveLoginJob = async { saveLoginJob = async {
// must retrieve from storage to get the httpsRealm and formActionOrigin // must retrieve from storage to get the httpsRealm and formActionOrigin
val oldLogin = passwordsStorage.get(loginId) val oldLogin = passwordsStorage.get(loginId)
@ -124,7 +124,7 @@ open class SavedLoginsStorageController(
fun findPotentialDuplicates(loginId: String) { fun findPotentialDuplicates(loginId: String) {
var deferredLogin: Deferred<List<Login>>? = null var deferredLogin: Deferred<List<Login>>? = null
val fetchLoginJob = viewLifecycleScope.launch(ioDispatcher) { val fetchLoginJob = lifecycleScope.launch(ioDispatcher) {
deferredLogin = async { deferredLogin = async {
val login = getLogin(loginId) val login = getLogin(loginId)
passwordsStorage.getPotentialDupesIgnoringUsername(login!!) passwordsStorage.getPotentialDupesIgnoringUsername(login!!)
@ -150,7 +150,7 @@ open class SavedLoginsStorageController(
fun fetchLoginDetails(loginId: String) { fun fetchLoginDetails(loginId: String) {
var deferredLogin: Deferred<List<Login>>? = null var deferredLogin: Deferred<List<Login>>? = null
val fetchLoginJob = viewLifecycleScope.launch(ioDispatcher) { val fetchLoginJob = lifecycleScope.launch(ioDispatcher) {
deferredLogin = async { deferredLogin = async {
passwordsStorage.list() passwordsStorage.list()
} }
@ -178,7 +178,7 @@ open class SavedLoginsStorageController(
fun handleLoadAndMapLogins() { fun handleLoadAndMapLogins() {
var deferredLogins: Deferred<List<Login>>? = null var deferredLogins: Deferred<List<Login>>? = null
val fetchLoginsJob = viewLifecycleScope.launch(ioDispatcher) { val fetchLoginsJob = lifecycleScope.launch(ioDispatcher) {
deferredLogins = async { deferredLogins = async {
passwordsStorage.list() passwordsStorage.list()
} }

@ -76,7 +76,7 @@ class EditLoginFragment : Fragment(R.layout.fragment_edit_login) {
interactor = EditLoginInteractor( interactor = EditLoginInteractor(
SavedLoginsStorageController( SavedLoginsStorageController(
passwordsStorage = requireContext().components.core.passwordsStorage, passwordsStorage = requireContext().components.core.passwordsStorage,
viewLifecycleScope = viewLifecycleOwner.lifecycleScope, lifecycleScope = lifecycleScope,
navController = findNavController(), navController = findNavController(),
loginsFragmentStore = loginsFragmentStore loginsFragmentStore = loginsFragmentStore
) )

@ -86,7 +86,7 @@ class LoginDetailFragment : Fragment(R.layout.fragment_login_detail) {
interactor = LoginDetailInteractor( interactor = LoginDetailInteractor(
SavedLoginsStorageController( SavedLoginsStorageController(
passwordsStorage = requireContext().components.core.passwordsStorage, passwordsStorage = requireContext().components.core.passwordsStorage,
viewLifecycleScope = viewLifecycleOwner.lifecycleScope, lifecycleScope = lifecycleScope,
navController = findNavController(), navController = findNavController(),
loginsFragmentStore = savedLoginsStore loginsFragmentStore = savedLoginsStore
) )

@ -16,6 +16,8 @@ import android.provider.Settings.ACTION_SECURITY_SETTINGS
import android.util.Log import android.util.Log
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.biometric.BiometricManager import androidx.biometric.BiometricManager
import androidx.biometric.BiometricManager.Authenticators.BIOMETRIC_WEAK
import androidx.biometric.BiometricManager.Authenticators.DEVICE_CREDENTIAL
import androidx.biometric.BiometricPrompt import androidx.biometric.BiometricPrompt
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.content.getSystemService import androidx.core.content.getSystemService
@ -98,7 +100,7 @@ class SavedLoginsAuthFragment : PreferenceFragmentCompat() {
promptInfo = BiometricPrompt.PromptInfo.Builder() promptInfo = BiometricPrompt.PromptInfo.Builder()
.setTitle(getString(R.string.logins_biometric_prompt_message)) .setTitle(getString(R.string.logins_biometric_prompt_message))
.setDeviceCredentialAllowed(true) .setAllowedAuthenticators(BIOMETRIC_WEAK or DEVICE_CREDENTIAL)
.build() .build()
} }
@ -154,7 +156,7 @@ class SavedLoginsAuthFragment : PreferenceFragmentCompat() {
private fun canUseBiometricPrompt(context: Context): Boolean { private fun canUseBiometricPrompt(context: Context): Boolean {
return if (SDK_INT >= M) { return if (SDK_INT >= M) {
val manager = BiometricManager.from(context) val manager = BiometricManager.from(context)
val canAuthenticate = manager.canAuthenticate() val canAuthenticate = manager.canAuthenticate(BIOMETRIC_WEAK)
val hardwareUnavailable = canAuthenticate == BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE || val hardwareUnavailable = canAuthenticate == BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE ||
canAuthenticate == BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE canAuthenticate == BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE

@ -92,7 +92,7 @@ class SavedLoginsFragment : Fragment() {
savedLoginsStorageController = savedLoginsStorageController =
SavedLoginsStorageController( SavedLoginsStorageController(
passwordsStorage = requireContext().components.core.passwordsStorage, passwordsStorage = requireContext().components.core.passwordsStorage,
viewLifecycleScope = viewLifecycleOwner.lifecycleScope, lifecycleScope = viewLifecycleOwner.lifecycleScope,
navController = findNavController(), navController = findNavController(),
loginsFragmentStore = savedLoginsStore loginsFragmentStore = savedLoginsStore
) )

@ -92,7 +92,8 @@ class SitePermissionsDetailsExceptionsFragment : PreferenceFragmentCompat() {
} }
private fun clearSitePermissions() { private fun clearSitePermissions() {
viewLifecycleOwner.lifecycleScope.launch(IO) { // Use fragment's lifecycle; the view may be gone by the time dialog is interacted with.
lifecycleScope.launch(IO) {
requireContext().components.core.permissionStorage.deleteSitePermissions(sitePermissions) requireContext().components.core.permissionStorage.deleteSitePermissions(sitePermissions)
withContext(Main) { withContext(Main) {
requireView().findNavController().popBackStack() requireView().findNavController().popBackStack()

@ -423,7 +423,7 @@ class TabTrayDialogFragment : AppCompatDialogFragment(), UserInteractionHandler
AlertDialog.Builder(it).setTitle(R.string.tab_tray_add_new_collection) AlertDialog.Builder(it).setTitle(R.string.tab_tray_add_new_collection)
.setView(customLayout).setPositiveButton(android.R.string.ok) { dialog, _ -> .setView(customLayout).setPositiveButton(android.R.string.ok) { dialog, _ ->
viewLifecycleOwner.lifecycleScope.launch(Dispatchers.IO) { lifecycleScope.launch(Dispatchers.IO) {
tabCollectionStorage.createCollection( tabCollectionStorage.createCollection(
collectionNameEditText.text.toString(), collectionNameEditText.text.toString(),
sessionList sessionList

@ -290,9 +290,15 @@ class TabTrayView(
tabTrayItemMenu = tabTrayItemMenu =
TabTrayItemMenu( TabTrayItemMenu(
view.context, context = view.context,
{ tabs.isNotEmpty() && view.tab_layout.selectedTabPosition == 0 }, shouldShowSaveToCollection = { tabs.isNotEmpty() && view.tab_layout.selectedTabPosition == 0 },
{ tabs.isNotEmpty() }) { hasOpenTabs = {
if (isPrivateModeSelected) {
view.context.components.core.store.state.privateTabs.isNotEmpty()
} else {
view.context.components.core.store.state.normalTabs.isNotEmpty()
}
}) {
when (it) { when (it) {
is TabTrayItemMenu.Item.ShareAllTabs -> interactor.onShareTabsClicked( is TabTrayItemMenu.Item.ShareAllTabs -> interactor.onShareTabsClicked(
isPrivateModeSelected isPrivateModeSelected

@ -111,6 +111,7 @@
android:id="@+id/tab_layout" android:id="@+id/tab_layout"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="80dp" android:layout_height="80dp"
app:tabMaxWidth="0dp"
android:background="@color/foundation_normal_theme" android:background="@color/foundation_normal_theme"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"

@ -143,6 +143,8 @@
<string name="browser_menu_install_on_homescreen">Instalar</string> <string name="browser_menu_install_on_homescreen">Instalar</string>
<!-- Menu option on the toolbar that takes you to synced tabs page--> <!-- Menu option on the toolbar that takes you to synced tabs page-->
<string name="synced_tabs">Pestanyas sincronizadas</string> <string name="synced_tabs">Pestanyas sincronizadas</string>
<!-- Content description (not visible, for screen readers etc.) for the Resync tabs button -->
<string name="resync_button_content_description">Resincronizar</string>
<!-- Browser menu button that opens the find in page menu --> <!-- Browser menu button that opens the find in page menu -->
<string name="browser_menu_find_in_page">Mirar en a pachina</string> <string name="browser_menu_find_in_page">Mirar en a pachina</string>
<!-- Browser menu button that creates a private tab --> <!-- Browser menu button that creates a private tab -->
@ -466,6 +468,11 @@
<!-- Preference for using the dynamic toolbar --> <!-- Preference for using the dynamic toolbar -->
<string name="preference_gestures_dynamic_toolbar">Desplazar pa amagar la barra de ferramientas</string> <string name="preference_gestures_dynamic_toolbar">Desplazar pa amagar la barra de ferramientas</string>
<!-- Preference for switching tabs by swiping horizontally on the toolbar -->
<string name="preference_gestures_swipe_toolbar_switch_tabs">Eslizar la barra de ferramientas enta los costaus pa cambiar de pestanya</string>
<!-- Preference for showing the opened tabs by swiping up on the toolbar-->
<string name="preference_gestures_swipe_toolbar_show_tabs">Eslizar la barra de ferramientas enta alto pa ubrir las pestanyas</string>
<!-- Library --> <!-- Library -->
<!-- Option in Library to open Sessions page --> <!-- Option in Library to open Sessions page -->
<string name="library_sessions">Sesions</string> <string name="library_sessions">Sesions</string>
@ -1351,8 +1358,12 @@
<string name="logins_site_copied">Puesto copiau a lo portafuellas</string> <string name="logins_site_copied">Puesto copiau a lo portafuellas</string>
<!-- Content Description (for screenreaders etc) read for the button to copy a password in logins--> <!-- Content Description (for screenreaders etc) read for the button to copy a password in logins-->
<string name="saved_logins_copy_password">Copiar clau</string> <string name="saved_logins_copy_password">Copiar clau</string>
<!-- Content Description (for screenreaders etc) read for the button to clear a password while editing a login-->
<string name="saved_logins_clear_password">Borrar la clau</string>
<!-- Content Description (for screenreaders etc) read for the button to copy a username in logins --> <!-- Content Description (for screenreaders etc) read for the button to copy a username in logins -->
<string name="saved_login_copy_username">Copiar nombre dusuario</string> <string name="saved_login_copy_username">Copiar nombre dusuario</string>
<!-- Content Description (for screenreaders etc) read for the button to clear a username while editing a login -->
<string name="saved_login_clear_username">Borrar lo nombre d\'usuario</string>
<!-- Content Description (for screenreaders etc) read for the button to copy a site in logins --> <!-- Content Description (for screenreaders etc) read for the button to copy a site in logins -->
<string name="saved_login_copy_site">Copiar puesto</string> <string name="saved_login_copy_site">Copiar puesto</string>
<!-- Content Description (for screenreaders etc) read for the button to open a site in logins --> <!-- Content Description (for screenreaders etc) read for the button to open a site in logins -->
@ -1523,6 +1534,8 @@
<!-- Top Sites --> <!-- Top Sites -->
<!-- Title text displayed in the dialog when top sites limit is reached. --> <!-- Title text displayed in the dialog when top sites limit is reached. -->
<string name="top_sites_max_limit_title">Sha arribau a lo limite de puestos principals.</string> <string name="top_sites_max_limit_title">Sha arribau a lo limite de puestos principals.</string>
<!-- Content description text displayed in the dialog when top sites limit is reached. -->
<string name="top_sites_max_limit_content_2">Pa anyadir un nuevo puesto principal, has de borrar-ne belatro. Toca y mantiene pretau lo puesto y tría borrar.</string>
<!-- Confirmation dialog button text when top sites limit is reached. --> <!-- Confirmation dialog button text when top sites limit is reached. -->
<string name="top_sites_max_limit_confirmation_button">Vale, entendiu</string> <string name="top_sites_max_limit_confirmation_button">Vale, entendiu</string>
<!-- Label for the show most visited sites preference --> <!-- Label for the show most visited sites preference -->

@ -405,6 +405,8 @@
<string name="preferences_marketing_data_description">Comparte los datos tocante a les carauterístiques qu\'uses en %1$s con Leanplum, el nuesu fornidor de marketing móvil.</string> <string name="preferences_marketing_data_description">Comparte los datos tocante a les carauterístiques qu\'uses en %1$s con Leanplum, el nuesu fornidor de marketing móvil.</string>
<!-- Title for experiments preferences --> <!-- Title for experiments preferences -->
<string name="preference_experiments">Esperimentos</string> <string name="preference_experiments">Esperimentos</string>
<!-- Summary for experiments preferences -->
<string name="preference_experiments_summary">Permite que Mozilla instale y recueya datos pa carauterístiques esperimentales</string>
<!-- Preference switch for crash reporter --> <!-- Preference switch for crash reporter -->
<string name="preferences_crash_reporter">Informador de casques</string> <string name="preferences_crash_reporter">Informador de casques</string>
@ -1079,6 +1081,8 @@
<string name="sign_in_with_camera">Aniciu de sesión cola cámara</string> <string name="sign_in_with_camera">Aniciu de sesión cola cámara</string>
<!-- Text shown for settings option for sign with email --> <!-- Text shown for settings option for sign with email -->
<string name="sign_in_with_email">Usar una direición de corréu</string> <string name="sign_in_with_email">Usar una direición de corréu</string>
<!-- Text shown for settings option for create new account text.'Firefox' intentionally hardcoded here.-->
<string name="sign_in_create_account_text"><![CDATA[¿Nun tienes cuenta? <u>Crea una</u> pa sincronizar Firefox ente preseos.]]></string>
<!-- Text shown in confirmation dialog to sign out of account --> <!-- Text shown in confirmation dialog to sign out of account -->
<string name="sign_out_confirmation_message">Firefox va dexar de sincronizase cola to cuenta mas nun va desaniciar nengún datu d\'esti preséu.</string> <string name="sign_out_confirmation_message">Firefox va dexar de sincronizase cola to cuenta mas nun va desaniciar nengún datu d\'esti preséu.</string>
<!-- Text shown in confirmation dialog to sign out of account. The first parameter is the name of the app (e.g. Firefox Preview) --> <!-- Text shown in confirmation dialog to sign out of account. The first parameter is the name of the app (e.g. Firefox Preview) -->
@ -1187,6 +1191,12 @@
The first parameter is the app name --> The first parameter is the app name -->
<string name="open_source_licenses_title">%s | Biblioteques OSS</string> <string name="open_source_licenses_title">%s | Biblioteques OSS</string>
<!-- Category of trackers (redirect trackers) that can be blocked by Enhanced Tracking Protection -->
<string name="etp_redirect_trackers_title">Redireiciones de rastrexadores</string>
<!-- Description of redirect tracker cookies that can be blocked by Enhanced Tracking Protection -->
<string name="etp_redirect_trackers_description">Llimpia les cookies creaes poles redireiciones a sitios web conocíos que rastrexen.</string>
<!-- About page link text to open support link --> <!-- About page link text to open support link -->
<string name="about_support">Sofitu</string> <string name="about_support">Sofitu</string>
<!-- About page link text to list of past crashes (like about:crashes on desktop) --> <!-- About page link text to list of past crashes (like about:crashes on desktop) -->
@ -1465,6 +1475,9 @@
<!-- Text displayed on a button in the synced tabs screen to link users to sign in when a user is not signed in to Firefox Sync --> <!-- Text displayed on a button in the synced tabs screen to link users to sign in when a user is not signed in to Firefox Sync -->
<string name="synced_tabs_sign_in_button">Aniciar sesión pa sincronizar</string> <string name="synced_tabs_sign_in_button">Aniciar sesión pa sincronizar</string>
<!-- The text displayed when a synced device has no tabs to show in the list of Synced Tabs. -->
<string name="synced_tabs_no_open_tabs">Nun hai llingüetes abiertes</string>
<!-- Top Sites --> <!-- Top Sites -->
<!-- Title text displayed in the dialog when top sites limit is reached. --> <!-- Title text displayed in the dialog when top sites limit is reached. -->
<string name="top_sites_max_limit_title">Algamóse la llende de sitios destacaos</string> <string name="top_sites_max_limit_title">Algamóse la llende de sitios destacaos</string>

@ -423,6 +423,9 @@
<!-- Preference switch for Mozilla location service --> <!-- Preference switch for Mozilla location service -->
<string name="preferences_mozilla_location_service">Служба месцазнаходжання Mozilla</string> <string name="preferences_mozilla_location_service">Служба месцазнаходжання Mozilla</string>
<!-- Preference switch for app health report. The first parameter is the name of the application (For example: Fenix) -->
<string name="preferences_fenix_health_report">Справаздача аб здароўі %s</string>
<!-- Turn On Sync Preferences --> <!-- Turn On Sync Preferences -->
<!-- Header of the Turn on Sync preference view --> <!-- Header of the Turn on Sync preference view -->
<string name="preferences_sync">Уключыць сінхранізацыю</string> <string name="preferences_sync">Уключыць сінхранізацыю</string>
@ -469,6 +472,9 @@
<!-- Preference for switching tabs by swiping horizontally on the toolbar --> <!-- Preference for switching tabs by swiping horizontally on the toolbar -->
<string name="preference_gestures_swipe_toolbar_switch_tabs">Пасуньце ўбок панэль інструментаў, каб пераключыць карткі</string> <string name="preference_gestures_swipe_toolbar_switch_tabs">Пасуньце ўбок панэль інструментаў, каб пераключыць карткі</string>
<!-- Preference for showing the opened tabs by swiping up on the toolbar-->
<string name="preference_gestures_swipe_toolbar_show_tabs">Пасуньце ўверх панэль інструментаў, каб адкрыць карткі</string>
<!-- Library --> <!-- Library -->
<!-- Option in Library to open Sessions page --> <!-- Option in Library to open Sessions page -->
<string name="library_sessions">Сеансы</string> <string name="library_sessions">Сеансы</string>
@ -1142,6 +1148,8 @@
<string name="sign_in_with_camera">Увайдзіце з дапамогай камеры</string> <string name="sign_in_with_camera">Увайдзіце з дапамогай камеры</string>
<!-- Text shown for settings option for sign with email --> <!-- Text shown for settings option for sign with email -->
<string name="sign_in_with_email">Выкарыстаць электронную пошту</string> <string name="sign_in_with_email">Выкарыстаць электронную пошту</string>
<!-- Text shown for settings option for create new account text.'Firefox' intentionally hardcoded here.-->
<string name="sign_in_create_account_text"><![CDATA[Не маеце ўліковага запісу? <u> Стварыце яго, </u> каб сінхранізаваць Firefox паміж прыладамі.]]></string>
<!-- Text shown in confirmation dialog to sign out of account --> <!-- Text shown in confirmation dialog to sign out of account -->
<string name="sign_out_confirmation_message">Firefox спыніць сінхранізацыю з вашым уліковым запісам, але не выдаліць дадзеныя аглядання на гэтай прыладзе.</string> <string name="sign_out_confirmation_message">Firefox спыніць сінхранізацыю з вашым уліковым запісам, але не выдаліць дадзеныя аглядання на гэтай прыладзе.</string>
<!-- Text shown in confirmation dialog to sign out of account. The first parameter is the name of the app (e.g. Firefox Preview) --> <!-- Text shown in confirmation dialog to sign out of account. The first parameter is the name of the app (e.g. Firefox Preview) -->
@ -1424,6 +1432,8 @@
<!-- Text for the button to learn more about adding a custom search engine --> <!-- Text for the button to learn more about adding a custom search engine -->
<string name="search_add_custom_engine_learn_more_label">Падрабязней</string> <string name="search_add_custom_engine_learn_more_label">Падрабязней</string>
<!-- Accessibility description for the form in which details about the custom search engine are entered -->
<string name="search_add_custom_engine_form_description">Інфармацыя аб дададзенай пошукавай сістэме</string>
<!-- Accessibility description for the 'Learn more' link --> <!-- Accessibility description for the 'Learn more' link -->
<string name="search_add_custom_engine_learn_more_description">Спасылка на падрабязныя звесткі</string> <string name="search_add_custom_engine_learn_more_description">Спасылка на падрабязныя звесткі</string>
@ -1545,6 +1555,8 @@
<!-- Top Sites --> <!-- Top Sites -->
<!-- Title text displayed in the dialog when top sites limit is reached. --> <!-- Title text displayed in the dialog when top sites limit is reached. -->
<string name="top_sites_max_limit_title">Дасягнуты ліміт папулярных сайтаў</string> <string name="top_sites_max_limit_title">Дасягнуты ліміт папулярных сайтаў</string>
<!-- Content description text displayed in the dialog when top sites limit is reached. -->
<string name="top_sites_max_limit_content_2">Каб дадаць новы топ-сайт, выдаліце якісь іншы. Націсніце на сайт і ўтрымлівайце, пасля абярыце &quot;Выдаліць&quot;.</string>
<!-- Confirmation dialog button text when top sites limit is reached. --> <!-- Confirmation dialog button text when top sites limit is reached. -->
<string name="top_sites_max_limit_confirmation_button">OK, зразумела</string> <string name="top_sites_max_limit_confirmation_button">OK, зразумела</string>

@ -21,12 +21,44 @@
<!-- No Private Tabs Message Description --> <!-- No Private Tabs Message Description -->
<string name="no_private_tabs_description">Поверителните раздели ще бъдат показани тук.</string> <string name="no_private_tabs_description">Поверителните раздели ще бъдат показани тук.</string>
<!-- Message announced to the user when tab tray is selected with 1 tab -->
<string name="open_tab_tray_single">1 отворен раздел. Докоснете за превключване на раздели.</string>
<!-- Message announced to the user when tab tray is selected with 0 or 2+ tabs -->
<string name="open_tab_tray_plural">%1$s отворени раздели. Докоснете за превключване между тях.</string>
<!-- Tab tray multi select title in app bar. The first parameter is the number of tabs selected -->
<string name="tab_tray_multi_select_title">%1$d избрани</string>
<!-- Label of button in create collection dialog for creating a new collection -->
<string name="tab_tray_add_new_collection">Създаване на списък</string>
<!-- Label of editable text in create collection dialog for naming a new collection -->
<string name="tab_tray_add_new_collection_name">Име</string>
<!-- Label of button in save to collection dialog for selecting a current collection -->
<string name="tab_tray_select_collection">Избор на списък</string>
<!-- Content description for close button while in multiselect mode in tab tray -->
<string name="tab_tray_close_multiselect_content_description">Изход от режим на множествен избор</string>
<!-- Content description for save to collection button while in multiselect mode in tab tray -->
<string name="tab_tray_collection_button_multiselect_content_description">Запазване на избраните раздели в списък</string>
<!-- Content description for checkmark while tab is selected while in multiselect mode in tab tray. The first parameter is the title of the tab selected -->
<string name="tab_tray_item_selected_multiselect_content_description">Отментат %1$s</string>
<!-- Content description when tab is unselected while in multiselect mode in tab tray. The first parameter is the title of the tab unselected -->
<string name="tab_tray_item_unselected_multiselect_content_description">Неотментат %1$s</string>
<!-- Content description announcement when exiting multiselect mode in tab tray -->
<string name="tab_tray_exit_multiselect_content_description">Излизане от режим на множествен избор</string>
<!-- Content description announcement when entering multiselect mode in tab tray -->
<string name="tab_tray_enter_multiselect_content_description">Режим на множествен избор, изберете раздели за добавяне към списък</string>
<!-- Content description on checkmark while tab is selected in multiselect mode in tab tray -->
<string name="tab_tray_multiselect_selected_content_description">Избран</string>
<!-- About content. The first parameter is the name of the application. (For example: Fenix) --> <!-- About content. The first parameter is the name of the application. (For example: Fenix) -->
<string name="about_content">%1$s е произведен от @fork-maintainers.</string> <string name="about_content">%1$s е произведен от @fork-maintainers.</string>
<!-- Private Browsing --> <!-- Private Browsing -->
<!-- Title for private session option --> <!-- Title for private session option -->
<string name="private_browsing_title">Вие сте в поверителен прозорец</string> <string name="private_browsing_title">Вие сте в поверителен прозорец</string>
<!-- Explanation for private browsing displayed to users on home view when they first enable private mode
The first parameter is the name of the app defined in app_name (for example: Fenix) -->
<string name="private_browsing_placeholder_description_2">%1$s изчиства историята на търсенето и разглеждането, когато ги затворите или излезете от приложението. Въпреки че това не ви прави анонимни за уеб сайтовете или доставчиците на интернет услуги, улеснява запазването на анонимността на действия ви в мрежата, от останалите ползващи същото устройство.</string>
<string name="private_browsing_common_myths">Разпространени легенди относно поверителното разглеждане</string> <string name="private_browsing_common_myths">Разпространени легенди относно поверителното разглеждане</string>
<!-- Delete session button to erase your history in a private session --> <!-- Delete session button to erase your history in a private session -->
<string name="private_browsing_delete_session">Изтриване на сесията</string> <string name="private_browsing_delete_session">Изтриване на сесията</string>
@ -48,6 +80,26 @@
<!-- Text for the negative button --> <!-- Text for the negative button -->
<string name="search_widget_cfr_neg_button_text">Не сега</string> <string name="search_widget_cfr_neg_button_text">Не сега</string>
<!-- Open in App "contextual feature recommendation" (CFR) -->
<!-- Text for the info message. 'Firefox' intentionally hardcoded here.-->
<string name="open_in_app_cfr_info_message">Може да настроите Firefox автоматично да отваря препратки в приложения</string>
<!-- Text for the positive action button -->
<string name="open_in_app_cfr_positive_button_text">Към настройки</string>
<!-- Text for the negative action button -->
<string name="open_in_app_cfr_negative_button_text">Прекратяване</string>
<!-- Text for the positive action button to go to Android Settings to grant permissions. -->
<string name="camera_permissions_needed_positive_button_text">Към настройки</string>
<!-- Text for the negative action button to dismiss the dialog. -->
<string name="camera_permissions_needed_negative_button_text">Прекратяване</string>
<!-- Text for the banner message to tell users about our auto close feature. -->
<string name="tab_tray_close_tabs_banner_message">Настройте отворените раздели да бъдат автоматично затваряни ако не са преглеждани през последния ден, седмица или месец.</string>
<!-- Text for the positive action button to go to Settings for auto close tabs. -->
<string name="tab_tray_close_tabs_banner_positive_button_text">Настройки</string>
<!-- Text for the negative action button to dismiss the Close Tabs Banner. -->
<string name="tab_tray_close_tabs_banner_negative_button_text">Прекратяване</string>
<!-- Home screen icons - Long press shortcuts --> <!-- Home screen icons - Long press shortcuts -->
<!-- Shortcut action to open new tab --> <!-- Shortcut action to open new tab -->
<string name="home_screen_shortcut_open_new_tab_2">Нов раздел</string> <string name="home_screen_shortcut_open_new_tab_2">Нов раздел</string>
@ -98,7 +150,7 @@
<!-- Browser menu button that creates a new tab --> <!-- Browser menu button that creates a new tab -->
<string name="browser_menu_new_tab">Нов раздел</string> <string name="browser_menu_new_tab">Нов раздел</string>
<!-- Browser menu button that saves the current tab to a collection --> <!-- Browser menu button that saves the current tab to a collection -->
<string name="browser_menu_save_to_collection_2">Добавяне в списък</string> <string name="browser_menu_save_to_collection_2">Добавяне към списък</string>
<!-- Browser menu button that open a share menu to share the current site --> <!-- Browser menu button that open a share menu to share the current site -->
<string name="browser_menu_share">Споделяне</string> <string name="browser_menu_share">Споделяне</string>
<!-- Share menu title, displayed when a user is sharing their current site --> <!-- Share menu title, displayed when a user is sharing their current site -->
@ -140,14 +192,12 @@
<!-- Search Fragment --> <!-- Search Fragment -->
<!-- Button in the search view that lets a user search by scanning a QR code --> <!-- Button in the search view that lets a user search by scanning a QR code -->
<string name="search_scan_button">Сканиране</string> <string name="search_scan_button">Сканиране</string>
<!-- Button in the search view that lets a user search by using a shortcut --> <!-- Button in the search view that lets a user change their search engine -->
<string name="search_shortcuts_button">Преки пътища</string> <string name="search_engine_button">Търсеща машина</string>
<!-- Button in the search view when shortcuts are displayed that takes a user to the search engine settings --> <!-- Button in the search view when shortcuts are displayed that takes a user to the search engine settings -->
<string name="search_shortcuts_engine_settings">Настройки на търсачките</string> <string name="search_shortcuts_engine_settings">Настройки на търсачките</string>
<!-- DEPRECATED: Header displayed when selecting a shortcut search engine -->
<string name="search_shortcuts_search_with">Търсене с</string>
<!-- Header displayed when selecting a shortcut search engine --> <!-- Header displayed when selecting a shortcut search engine -->
<string name="search_shortcuts_search_with_2">Този път търсете с:</string> <string name="search_engines_search_with">Този път търсете с:</string>
<!-- Button in the search view that lets a user navigate to the site in their clipboard --> <!-- Button in the search view that lets a user navigate to the site in their clipboard -->
<string name="awesomebar_clipboard_title">Използване на препратка от буфера</string> <string name="awesomebar_clipboard_title">Използване на препратка от буфера</string>
<!-- Button in the search suggestions onboarding that allows search suggestions in private sessions --> <!-- Button in the search suggestions onboarding that allows search suggestions in private sessions -->
@ -202,7 +252,7 @@
<!-- Preference for settings related to saved credit cards and addresses --> <!-- Preference for settings related to saved credit cards and addresses -->
<string name="preferences_credit_cards_addresses">Банкови карти и адреси</string> <string name="preferences_credit_cards_addresses">Банкови карти и адреси</string>
<!-- Preference for settings related to changing the default browser --> <!-- Preference for settings related to changing the default browser -->
<string name="preferences_set_as_default_browser">Задаване като стандартен четец</string> <string name="preferences_set_as_default_browser">Четец по подразбиране</string>
<!-- Preference category for advanced settings --> <!-- Preference category for advanced settings -->
<string name="preferences_category_advanced">Разширени</string> <string name="preferences_category_advanced">Разширени</string>
@ -216,13 +266,19 @@
<!-- Preference for private browsing options --> <!-- Preference for private browsing options -->
<string name="preferences_private_browsing_options">Поверително разглеждане</string> <string name="preferences_private_browsing_options">Поверително разглеждане</string>
<!-- Preference for opening links in a private tab--> <!-- Preference for opening links in a private tab-->
<string name="preferences_open_links_in_a_private_tab">Отваряне препратките в поверителен раздел</string> <string name="preferences_open_links_in_a_private_tab">Отваряне препратки в поверителен раздел</string>
<!-- Preference for allowing screenshots to be taken while in a private tab--> <!-- Preference for allowing screenshots to be taken while in a private tab-->
<string name="preferences_allow_screenshots_in_private_mode">Снимки на екрана в поверителен режим</string> <string name="preferences_allow_screenshots_in_private_mode">Снимки на екрана в поверителен режим</string>
<!-- Will inform the user of the risk of activating Allow screenshots in private browsing option -->
<string name="preferences_screenshots_in_private_mode_disclaimer">Ако е включено, поверителните раздели ще са видими от отворените приложения</string>
<!-- Preference for adding private browsing shortcut --> <!-- Preference for adding private browsing shortcut -->
<string name="preferences_add_private_browsing_shortcut">Добавяне на икона за поверителен режим</string> <string name="preferences_add_private_browsing_shortcut">Добавяне на икона за поверителен режим</string>
<!-- Preference for accessibility --> <!-- Preference for accessibility -->
<string name="preferences_accessibility">Достъпност</string> <string name="preferences_accessibility">Достъпност</string>
<!-- Preference to override the Firefox Account server -->
<string name="preferences_override_fxa_server">Личен сървър за Firefox Account</string>
<!-- Preference to override the Sync token server -->
<string name="preferences_override_sync_tokenserver">Личен сървър за Sync</string>
<!-- Preference category for account information --> <!-- Preference category for account information -->
<string name="preferences_category_account">Сметка</string> <string name="preferences_category_account">Сметка</string>
<!-- Preference shown on banner to sign into account --> <!-- Preference shown on banner to sign into account -->
@ -231,8 +287,12 @@
<string name="preferences_toolbar">Лента с инструменти</string> <string name="preferences_toolbar">Лента с инструменти</string>
<!-- Preference for changing default theme to dark or light mode --> <!-- Preference for changing default theme to dark or light mode -->
<string name="preferences_theme">Тема</string> <string name="preferences_theme">Тема</string>
<!-- Preference for customizing the home screen -->
<string name="preferences_home">Начален екран</string>
<!-- Preference for gestures based actions -->
<string name="preferences_gestures">Жестове</string>
<!-- Preference for settings related to visual options --> <!-- Preference for settings related to visual options -->
<string name="preferences_customize">Персонализиране</string> <string name="preferences_customize">Външен вид</string>
<!-- Preference description for banner about signing in --> <!-- Preference description for banner about signing in -->
<string name="preferences_sign_in_description">Синхронизирайте отметки, пароли и други с вашия Firefox Account</string> <string name="preferences_sign_in_description">Синхронизирайте отметки, пароли и други с вашия Firefox Account</string>
<!-- Preference shown instead of account display name while account profile information isn't available yet. --> <!-- Preference shown instead of account display name while account profile information isn't available yet. -->
@ -251,27 +311,36 @@
<string name="developer_tools_category">Развойни инструменти</string> <string name="developer_tools_category">Развойни инструменти</string>
<!-- Preference for developers --> <!-- Preference for developers -->
<string name="preferences_remote_debugging">Отдалечено отстраняване на дефекти през USB</string> <string name="preferences_remote_debugging">Отдалечено отстраняване на дефекти през USB</string>
<!-- Preference title for switch preference to show search shortcuts --> <!-- Preference title for switch preference to show search engines -->
<string name="preferences_show_search_shortcuts">Преки пътища за търсене</string> <string name="preferences_show_search_engines">Показване на търсещи машини</string>
<!-- Preference title for switch preference to show search suggestions --> <!-- Preference title for switch preference to show search suggestions -->
<string name="preferences_show_search_suggestions">Показване на предложения</string> <string name="preferences_show_search_suggestions">Показване на предложения</string>
<!-- Preference title for switch preference to show voice search button --> <!-- Preference title for switch preference to show voice search button -->
<string name="preferences_show_voice_search">Показване на гласово търсене</string> <string name="preferences_show_voice_search">Показване на гласово търсене</string>
<!-- Preference title for switch preference to show search suggestions also in private mode --> <!-- Preference title for switch preference to show search suggestions also in private mode -->
<string name="preferences_show_search_suggestions_in_private">Показване в поверителен режим</string> <string name="preferences_show_search_suggestions_in_private">В поверителен режим също</string>
<!-- Preference title for switch preference to show a clipboard suggestion when searching --> <!-- Preference title for switch preference to show a clipboard suggestion when searching -->
<string name="preferences_show_clipboard_suggestions">Показване на предложения от буфера</string> <string name="preferences_show_clipboard_suggestions">Предложения от буфера</string>
<!-- Preference title for switch preference to suggest browsing history when searching --> <!-- Preference title for switch preference to suggest browsing history when searching -->
<string name="preferences_search_browsing_history">Търсене на историята на разглеждане</string> <string name="preferences_search_browsing_history">В история на разглеждане</string>
<!-- Preference title for switch preference to suggest bookmarks when searching --> <!-- Preference title for switch preference to suggest bookmarks when searching -->
<string name="preferences_search_bookmarks">Търсене в отметките</string> <string name="preferences_search_bookmarks">В отметките</string>
<!-- Preference title for switch preference to suggest synced tabs when searching -->
<string name="preferences_search_synced_tabs">В синхронизираните раздели</string>
<!-- Preference for account settings --> <!-- Preference for account settings -->
<string name="preferences_account_settings">Настройки на сметката</string> <string name="preferences_account_settings">Настройки на сметката</string>
<!-- Preference for enabling url autocomplete-->
<string name="preferences_enable_autocomplete_urls">Автоматично довършване на адреси</string>
<!-- Preference for open links in third party apps --> <!-- Preference for open links in third party apps -->
<string name="preferences_open_links_in_apps">Отваряне на препратки в приложения</string> <string name="preferences_open_links_in_apps">Отваряне на препратки в приложения</string>
<!-- Preference for open download with an external download manager app -->
<string name="preferences_external_download_manager">Външно приложение за изтегляния</string>
<!-- Preference for add_ons --> <!-- Preference for add_ons -->
<string name="preferences_addons">Добавки</string> <string name="preferences_addons">Добавки</string>
<!-- Preference for notifications -->
<string name="preferences_notifications">Известия</string>
<!-- Account Preferences --> <!-- Account Preferences -->
<!-- Preference for triggering sync --> <!-- Preference for triggering sync -->
<string name="preferences_sync_now">Синхронизиране</string> <string name="preferences_sync_now">Синхронизиране</string>
@ -347,8 +416,12 @@
<string name="preferences_usage_data_description">Споделя данни за използването, производителността, хардуера, настройките на четеца с Mozilla, за да ни помогне да направим %1$s по-добър</string> <string name="preferences_usage_data_description">Споделя данни за използването, производителността, хардуера, настройките на четеца с Mozilla, за да ни помогне да направим %1$s по-добър</string>
<!-- Preference switch for marketing data collection --> <!-- Preference switch for marketing data collection -->
<string name="preferences_marketing_data">Маркетингови данни</string> <string name="preferences_marketing_data">Маркетингови данни</string>
<!-- Preference description for marketing data collection, parameter is the app name (e.g. Firefox) -->
<string name="preferences_marketing_data_description">Споделя данни за използваните от вас възможности на %1$s чрез Leanplum, нашият партньор за мобилен маркетинг.</string>
<!-- Title for experiments preferences --> <!-- Title for experiments preferences -->
<string name="preference_experiments">Експерименти</string> <string name="preference_experiments">Експерименти</string>
<!-- Summary for experiments preferences -->
<string name="preference_experiments_summary">Позволява на Mozilla да инсталира експериментални възможности и да събира данни за тях</string>
<!-- Preference switch for crash reporter --> <!-- Preference switch for crash reporter -->
<string name="preferences_crash_reporter">Доклади за срив</string> <string name="preferences_crash_reporter">Доклади за срив</string>
<!-- Preference switch for Mozilla location service --> <!-- Preference switch for Mozilla location service -->
@ -374,7 +447,7 @@
<string name="pair_instructions_2"><![CDATA[Сканирайте кода на QR, показан на <b>firefox.com/pair</b>]]></string> <string name="pair_instructions_2"><![CDATA[Сканирайте кода на QR, показан на <b>firefox.com/pair</b>]]></string>
<!-- Button to open camera for pairing --> <!-- Button to open camera for pairing -->
<string name="pair_open_camera">Отваряне на камерата</string> <string name="pair_open_camera">Отваряне на камера</string>
<!-- Button to cancel pairing --> <!-- Button to cancel pairing -->
<string name="pair_cancel">Отказ</string> <string name="pair_cancel">Отказ</string>
@ -391,10 +464,14 @@
<string name="preference_dark_theme">Тъмна</string> <string name="preference_dark_theme">Тъмна</string>
<!-- Preference for using using dark or light theme automatically set by battery --> <!-- Preference for using using dark or light theme automatically set by battery -->
<string name="preference_auto_battery_theme">Зададена от приложението за пестене на батерия</string> <string name="preference_auto_battery_theme">Зададена от приложение за пестене на батерия</string>
<!-- Preference for using following device theme --> <!-- Preference for using following device theme -->
<string name="preference_follow_device_theme">Следва темата на устройството</string> <string name="preference_follow_device_theme">Следва темата на устройството</string>
<!-- Gestures Preferences-->
<!-- Preferences for using pull to refresh in a webpage -->
<string name="preference_gestures_website_pull_to_refresh">Издърпайте за презареждане</string>
<!-- Library --> <!-- Library -->
<!-- Option in Library to open Sessions page --> <!-- Option in Library to open Sessions page -->
<string name="library_sessions">Сесии</string> <string name="library_sessions">Сесии</string>
@ -427,6 +504,32 @@
<!-- Content description (not visible, for screen readers etc.): "Close button for library settings" --> <!-- Content description (not visible, for screen readers etc.): "Close button for library settings" -->
<string name="content_description_close_button">Затваряне</string> <string name="content_description_close_button">Затваряне</string>
<!-- Option in library for Recently Closed Tabs -->
<string name="library_recently_closed_tabs">Последно затворени раздели</string>
<!-- Option in library to open Recently Closed Tabs page -->
<string name="recently_closed_show_full_history">Цялата история</string>
<!-- Text to show users they have multiple tabs saved in the Recently Closed Tabs section of history.
%d is a placeholder for the number of tabs selected. -->
<string name="recently_closed_tabs">%d раздела</string>
<!-- Text to show users they have one tab saved in the Recently Closed Tabs section of history.
%d is a placeholder for the number of tabs selected. -->
<string name="recently_closed_tab">%d раздел</string>
<!-- Recently closed tabs screen message when there are no recently closed tabs -->
<string name="recently_closed_empty_message">Няма затворени раздели</string>
<!-- Tab Management -->
<!-- Title of preference that allows a user to auto close tabs after a specified amount of time -->
<string name="preferences_close_tabs">Затваряне на раздели</string>
<!-- Option for auto closing tabs that will never auto close tabs, always allows user to manually close tabs -->
<string name="close_tabs_manually">Ръчно</string>
<!-- Option for auto closing tabs that will auto close tabs after one day -->
<string name="close_tabs_after_one_day">След един ден</string>
<!-- Option for auto closing tabs that will auto close tabs after one week -->
<string name="close_tabs_after_one_week">След една седмица</string>
<!-- Option for auto closing tabs that will auto close tabs after one month -->
<string name="close_tabs_after_one_month">След един месец</string>
<!-- Sessions --> <!-- Sessions -->
<!-- Title for the list of tabs --> <!-- Title for the list of tabs -->
<string name="tab_header_label">Отворени раздели</string> <string name="tab_header_label">Отворени раздели</string>
@ -443,9 +546,13 @@
<!-- Text shown as the title of the open tab tray --> <!-- Text shown as the title of the open tab tray -->
<string name="tab_tray_title">Отворени раздели</string> <string name="tab_tray_title">Отворени раздели</string>
<!-- Text shown in the menu for saving tabs to a collection --> <!-- Text shown in the menu for saving tabs to a collection -->
<string name="tab_tray_menu_item_save">Добавяне в списък</string> <string name="tab_tray_menu_item_save">Добавяне към списък</string>
<!-- Text shown in the menu for sharing all tabs --> <!-- Text shown in the menu for sharing all tabs -->
<string name="tab_tray_menu_item_share">Споделяне на всички раздели</string> <string name="tab_tray_menu_item_share">Споделяне на всички раздели</string>
<!-- Text shown in the menu to view recently closed tabs -->
<string name="tab_tray_menu_recently_closed">Последно затворени раздели</string>
<!-- Text shown in the menu to view tab settings -->
<string name="tab_tray_menu_tab_settings">Настройки на раздели</string>
<!-- Text shown in the menu for closing all tabs --> <!-- Text shown in the menu for closing all tabs -->
<string name="tab_tray_menu_item_close">Затваряне на всички раздели</string> <string name="tab_tray_menu_item_close">Затваряне на всички раздели</string>
<!-- Shortcut action to open new tab --> <!-- Shortcut action to open new tab -->
@ -481,17 +588,242 @@
<!-- Content description (not visible, for screen readers etc.): Title icon for current session menu --> <!-- Content description (not visible, for screen readers etc.): Title icon for current session menu -->
<string name="current_session_image">Заглавна пиктограма на текущото меню на сесия</string> <string name="current_session_image">Заглавна пиктограма на текущото меню на сесия</string>
<!-- Button to save the current set of tabs into a collection -->
<string name="save_to_collection">Добавяне към списък</string>
<!-- Text for the menu button to delete a collection -->
<string name="collection_delete">Изтриване на списък</string>
<!-- Text for the menu button to rename a collection -->
<string name="collection_rename">Преименуване на списък</string>
<!-- Text for the button to open tabs of the selected collection -->
<string name="collection_open_tabs">Отваряне на раздели</string>
<!-- Text for the menu button to remove a top site -->
<string name="remove_top_site">Премахване</string>
<!-- Text for the menu button to delete a top site from history -->
<string name="delete_from_history">Премахване от историята</string>
<!-- Postfix for private WebApp titles, placeholder is replaced with app name -->
<string name="pwa_site_controls_title_private">%1$s (поверителен режим)</string>
<!-- Button in the current tab tray header in multiselect mode. Saved the selected tabs to a collection when pressed. -->
<string name="tab_tray_save_to_collection">Запазване</string>
<!-- History -->
<!-- Text for the button to clear all history -->
<string name="history_delete_all">Изчистване на история</string>
<!-- Text for the dialog to confirm clearing all history -->
<string name="history_delete_all_dialog">Сигурни ли сте, че желаете да изтриете историята на разглеждане?</string>
<!-- Text for the snackbar to confirm that multiple browsing history items has been deleted -->
<string name="history_delete_multiple_items_snackbar">Историята е изчистена</string>
<!-- Text for the snackbar to confirm that a single browsing history item has been deleted. The first parameter is the shortened URL of the deleted history item. -->
<string name="history_delete_single_item_snackbar">Изтрито %1$s</string>
<!-- Text for positive action to delete history in deleting history dialog -->
<string name="history_clear_dialog">Изчистване</string>
<!-- History overflow menu copy button -->
<string name="history_menu_copy_button">Копиране</string>
<!-- History overflow menu share button -->
<string name="history_menu_share_button">Споделяне</string>
<!-- History overflow menu open in new tab button -->
<string name="history_menu_open_in_new_tab_button">Отваряне в раздел</string>
<!-- History overflow menu open in private tab button -->
<string name="history_menu_open_in_private_tab_button">Отваряне в поверителен раздел</string>
<!-- Text for the button to delete a single history item -->
<string name="history_delete_item">Изтриване</string>
<!-- History multi select title in app bar
The first parameter is the number of bookmarks selected -->
<string name="history_multi_select_title">%1$d избрани</string>
<!-- Text for the button to clear selected history items. The first parameter
is a digit showing the number of items you have selected -->
<string name="history_delete_some">Изтриване на %1$d записа</string>
<!-- Text for the header that groups the history for last 24 hours -->
<string name="history_24_hours">Последните 24 часа</string>
<!-- Text for the header that groups the history the past 7 days -->
<string name="history_7_days">Последните 7 дни</string>
<!-- Text for the header that groups the history the past 30 days -->
<string name="history_30_days">Последните 30 дни</string>
<!-- Text for the header that groups the history older than the last month -->
<string name="history_older">По-стари</string>
<!-- Text shown when no history exists -->
<string name="history_empty_message">Липсва история</string>
<!-- Downloads -->
<!-- Text shown when no download exists -->
<string name="download_empty_message">Няма изтегляния</string>
<!-- History multi select title in app bar
The first parameter is the number of downloads selected -->
<string name="download_multi_select_title">%1$d избрани</string>
<!-- Crashes -->
<!-- Title text displayed on the tab crash page. This first parameter is the name of the application (For example: Fenix) -->
<string name="tab_crash_title_2">Извинете. %1$s не можа да зареди страницата.</string>
<!-- Description text displayed on the tab crash page -->
<string name="tab_crash_description">Oпитайте да възстановите или затворите раздела.</string>
<!-- Send crash report checkbox text on the tab crash page -->
<string name="tab_crash_send_report">Изпращане на доклад за срива до Mozilla</string>
<!-- Close tab button text on the tab crash page -->
<string name="tab_crash_close">Затваряне на раздел</string>
<!-- Restore tab button text on the tab crash page -->
<string name="tab_crash_restore">Възстановяване на раздел</string>
<!-- Content Description for session item menu button -->
<string name="content_description_session_menu">Настройки на сесия</string>
<!-- Content Description for session item share button -->
<string name="content_description_session_share">Споделяне на сесия</string>
<!-- Bookmarks -->
<!-- Content description for bookmarks library menu -->
<string name="bookmark_menu_content_description">Меню отметки</string>
<!-- Screen title for editing bookmarks -->
<string name="bookmark_edit">Промяна на отметка</string>
<!-- Screen title for selecting a bookmarks folder -->
<string name="bookmark_select_folder">Избор на папка</string>
<!-- Confirmation message for a dialog confirming if the user wants to delete the selected folder -->
<string name="bookmark_delete_folder_confirmation_dialog">Наистина ли искате да изтриете папката?</string>
<!-- Confirmation message for a dialog confirming if the user wants to delete multiple items including folders. Parameter will be replaced by app name. -->
<string name="bookmark_delete_multiple_folders_confirmation_dialog">%s ще изтрие избраните елементи.</string>
<!-- Snackbar title shown after a folder has been deleted. This first parameter is the name of the deleted folder -->
<string name="bookmark_delete_folder_snackbar">Изтрита %1$s</string>
<!-- Screen title for adding a bookmarks folder -->
<string name="bookmark_add_folder">Добавяне на папка</string>
<!-- deprecated: Snackbar title shown after a bookmark has been created. -->
<string name="bookmark_created_snackbar">Отметката е създадена.</string>
<!-- Snackbar title shown after a bookmark has been created. -->
<string name="bookmark_saved_snackbar">Отметката е запазена!</string>
<!-- Snackbar edit button shown after a bookmark has been created. -->
<string name="edit_bookmark_snackbar_action">ПРОМЕНЯНЕ</string>
<!-- Bookmark overflow menu edit button -->
<string name="bookmark_menu_edit_button">Променяне</string>
<!-- Bookmark overflow menu select button -->
<string name="bookmark_menu_select_button">Избиране</string>
<!-- Bookmark overflow menu copy button -->
<string name="bookmark_menu_copy_button">Копиране</string>
<!-- Bookmark overflow menu share button -->
<string name="bookmark_menu_share_button">Споделяне</string>
<!-- Bookmark overflow menu open in new tab button -->
<string name="bookmark_menu_open_in_new_tab_button">Отваряне в нов раздел</string>
<!-- Bookmark overflow menu open in private tab button -->
<string name="bookmark_menu_open_in_private_tab_button">Отваряне в поверителен раздел</string>
<!-- Bookmark overflow menu delete button -->
<string name="bookmark_menu_delete_button">Изтриване</string>
<!--Bookmark overflow menu save button -->
<string name="bookmark_menu_save_button">Запазване</string>
<!-- Bookmark multi select title in app bar
The first parameter is the number of bookmarks selected -->
<string name="bookmarks_multi_select_title">%1$d избрани</string>
<!-- Bookmark editing screen title -->
<string name="edit_bookmark_fragment_title">Промяна на отметка</string>
<!-- Bookmark folder editing screen title -->
<string name="edit_bookmark_folder_fragment_title">Промяна на папка</string>
<!-- Bookmark sign in button message -->
<string name="bookmark_sign_in_button">Влезте, за да видите синхронизираните отметки</string>
<!-- Bookmark URL editing field label -->
<string name="bookmark_url_label">URL</string>
<!-- Bookmark FOLDER editing field label -->
<string name="bookmark_folder_label">ПАПКА</string>
<!-- Bookmark NAME editing field label -->
<string name="bookmark_name_label">ИМЕ</string>
<!-- Bookmark add folder screen title -->
<string name="bookmark_add_folder_fragment_label">Добавяне на папка</string>
<!-- Bookmark select folder screen title -->
<string name="bookmark_select_folder_fragment_label">Избиране на папка</string>
<!-- Bookmark editing error missing title -->
<string name="bookmark_empty_title_error">Заглавието е задължително</string>
<!-- Bookmark editing error missing or improper URL -->
<string name="bookmark_invalid_url_error">Неправилен адрес</string>
<!-- Bookmark screen message for empty bookmarks folder -->
<string name="bookmarks_empty_message">Липсват отметки</string>
<!-- Bookmark snackbar message on deletion
The first parameter is the host part of the URL of the bookmark deleted, if any -->
<string name="bookmark_deletion_snackbar_message">Изтрита %1$s</string>
<!-- Bookmark snackbar message on deleting multiple bookmarks not including folders-->
<string name="bookmark_deletion_multiple_snackbar_message_2">Отметките са изтрити</string>
<!-- Bookmark snackbar message on deleting multiple bookmarks including folders-->
<string name="bookmark_deletion_multiple_snackbar_message_3">Изтриване на избраните папки</string>
<!-- Bookmark undo button for deletion snackbar action -->
<string name="bookmark_undo_deletion">ОТМЕНЯНЕ</string>
<!-- Site Permissions -->
<!-- Site permissions preferences header -->
<string name="permissions_header">Права</string>
<!-- Button label that take the user to the Android App setting -->
<string name="phone_feature_go_to_settings">Към настройките</string>
<!-- Content description (not visible, for screen readers etc.): Quick settings sheet <!-- Content description (not visible, for screen readers etc.): Quick settings sheet
to give users access to site specific information / settings. For example: to give users access to site specific information / settings. For example:
Secure settings status and a button to modify site permissions --> Secure settings status and a button to modify site permissions -->
<string name="quick_settings_sheet">Списък с бързи настройки</string> <string name="quick_settings_sheet">Списък с бързи настройки</string>
<!-- Label that indicates that this option it the recommended one -->
<string name="phone_feature_recommended">Препоръчително</string>
<!-- button that allows editing site permissions settings -->
<string name="quick_settings_sheet_manage_site_permissions">Управление на права на страница</string>
<!-- Button label for clearing all the information of site permissions-->
<string name="clear_permissions">Изчистване на правата</string>
<!-- Button label for clearing a site permission-->
<string name="clear_permission">Изчистване на правото</string>
<!-- Button label for clearing all the information on all sites-->
<string name="clear_permissions_on_all_sites">Изчистване на правата на всички страници</string>
<!-- Preference for altering video and audio autoplay for all websites -->
<string name="preference_browser_feature_autoplay">Автоматично възпроизвеждане</string>
<!-- Preference for altering the camera access for all websites -->
<string name="preference_phone_feature_camera">Камера</string>
<!-- Preference for altering the microphone access for all websites -->
<string name="preference_phone_feature_microphone">Микрофон</string>
<!-- Preference for altering the location access for all websites -->
<string name="preference_phone_feature_location">Местоположение</string>
<!-- Preference for altering the notification access for all websites -->
<string name="preference_phone_feature_notification">Известие</string>
<!-- Label that indicates that a permission must be asked always -->
<string name="preference_option_phone_feature_ask_to_allow">Винаги да пита</string>
<!-- Label that indicates that a permission must be blocked -->
<string name="preference_option_phone_feature_blocked">Забраняване</string>
<!-- Label that indicates that a permission must be allowed -->
<string name="preference_option_phone_feature_allowed">Разрешаване</string>
<!--Label that indicates a permission is by the Android OS-->
<string name="phone_feature_blocked_by_android">Забранено от Android</string>
<!-- Preference for showing a list of websites that the default configurations won't apply to them -->
<string name="preference_exceptions">Изключения</string>
<!-- Summary of tracking protection preference if tracking protection is set to on -->
<string name="tracking_protection_on">Включено</string>
<!-- Summary of tracking protection preference if tracking protection is set to off -->
<string name="tracking_protection_off">Изключено</string>
<!-- Label that indicates that all video and audio autoplay is allowed -->
<string name="preference_option_autoplay_allowed2">Разрешаване на звук и видео</string>
<!-- Summary of delete browsing data on quit preference if it is set to on -->
<string name="delete_browsing_data_quit_on">Включено</string>
<!-- Summary of delete browsing data on quit preference if it is set to off -->
<string name="delete_browsing_data_quit_off">Изключено</string>
<!-- Collections -->
<!-- Collections header on home fragment -->
<string name="collections_header">Списъци</string>
<!-- Content description (not visible, for screen readers etc.): Opens the collection menu when pressed --> <!-- Content description (not visible, for screen readers etc.): Opens the collection menu when pressed -->
<string name="collection_menu_button_content_description">Меню Списъци</string> <string name="collection_menu_button_content_description">Меню Списъци</string>
<!-- Label to describe what collections are to a new user without any collections -->
<string name="no_collections_description2">Съберете важните за вас неща.\nГрупирайте търсения, страници и раздели за бърз достъп по-късно.</string>
<!-- Title for the "select tabs" step of the collection creator -->
<string name="create_collection_select_tabs">Избиране на раздели</string>
<!-- Button to add new collection for the "select collection" step of the collection creator -->
<string name="create_collection_add_new_collection">Създаване на списък</string>
<!-- Button to select all tabs in the "select tabs" step of the collection creator --> <!-- Button to select all tabs in the "select tabs" step of the collection creator -->
<string name="create_collection_select_all">Избиране на всички</string> <string name="create_collection_select_all">Избиране на всички</string>
<!-- Button to deselect all tabs in the "select tabs" step of the collection creator -->
<string name="create_collection_deselect_all">Отменяне всички</string>
<!-- Text to prompt users to select the tabs to save in the "select tabs" step of the collection creator -->
<string name="create_collection_save_to_collection_empty">Изберете раздели за запазване</string>
<!-- Text to show users how many tabs they have selected in the "select tabs" step of the collection creator.
%d is a placeholder for the number of tabs selected. -->
<string name="create_collection_save_to_collection_tabs_selected">%d раздела избрани</string>
<!-- Text to show users they have one tab selected in the "select tabs" step of the collection creator.
%d is a placeholder for the number of tabs selected. -->
<string name="create_collection_save_to_collection_tab_selected">%d раздел избран</string>
<!-- Text shown in snackbar when multiple tabs have been saved in a collection --> <!-- Text shown in snackbar when multiple tabs have been saved in a collection -->
<string name="create_collection_tabs_saved">Разделите са запазени!</string> <string name="create_collection_tabs_saved">Разделите са запазени!</string>
<!-- Text shown in snackbar when one or multiple tabs have been saved in a new collection -->
<string name="create_collection_tabs_saved_new_collection">Колекция запазена!</string>
<!-- Text shown in snackbar when one tab has been saved in a collection --> <!-- Text shown in snackbar when one tab has been saved in a collection -->
<string name="create_collection_tab_saved">Разделът е запазен!</string> <string name="create_collection_tab_saved">Разделът е запазен!</string>
<!-- Content description (not visible, for screen readers etc.): button to close the collection creator --> <!-- Content description (not visible, for screen readers etc.): button to close the collection creator -->
@ -499,14 +831,112 @@
<!-- Button to save currently selected tabs in the "select tabs" step of the collection creator--> <!-- Button to save currently selected tabs in the "select tabs" step of the collection creator-->
<string name="create_collection_save">Запазване</string> <string name="create_collection_save">Запазване</string>
<!-- Snackbar action to view the collection the user just created or updated -->
<string name="create_collection_view">Преглед</string>
<!-- Default name for a new collection in "name new collection" step of the collection creator. %d is a placeholder for the number of collections-->
<string name="create_collection_default_name">Списък %d</string>
<!-- Share -->
<!-- Share screen header -->
<string name="share_header">Изпращане и споделяне</string>
<!-- Share screen header -->
<string name="share_header_2">Споделяне</string>
<!-- Content description (not visible, for screen readers etc.): <!-- Content description (not visible, for screen readers etc.):
"Share" button. Opens the share menu when pressed. --> "Share" button. Opens the share menu when pressed. -->
<string name="share_button_content_description">Споделяне</string> <string name="share_button_content_description">Споделяне</string>
<!-- Sub-header in the dialog to share a link to another app -->
<string name="share_link_subheader">Споделяне на препратка</string>
<!-- Sub-header in the dialog to share a link to an app from the full list -->
<string name="share_link_all_apps_subheader">Всички действия</string>
<!-- Sub-header in the dialog to share a link to an app from the most-recent sorted list -->
<string name="share_link_recent_apps_subheader">Последно използвани</string>
<!-- An option from the share dialog to sign into sync -->
<string name="sync_sign_in">Вписване в Sync</string>
<!-- An option from the share dialog to send link to all other sync devices -->
<string name="sync_send_to_all">Изпращане до всички устройства</string>
<!-- An option from the share dialog to reconnect to sync -->
<string name="sync_reconnect">Повторно свързване със Sync</string>
<!-- Text displayed when sync is offline and cannot be accessed -->
<string name="sync_offline">Без мрежа</string>
<!-- An option to connect additional devices -->
<string name="sync_connect_device">Добавяне на устройство</string>
<!-- The dialog text shown when additional devices are not available -->
<string name="sync_connect_device_dialog">За да изпращате раздели е необходимо да бъдете вписани във Firefox на поне едно устройство.</string>
<!-- Confirmation dialog button -->
<string name="sync_confirmation_button">Разбрах</string>
<!-- Share error message -->
<string name="share_error_snackbar">Невъзможно е споделяне с това приложение</string>
<!-- Add new device screen title -->
<string name="sync_add_new_device_title">Изпращане към устройство</string>
<!-- Text for the warning message on the Add new device screen -->
<string name="sync_add_new_device_message">Няма свързани устройства</string>
<!-- Text for the button to learn about sending tabs -->
<string name="sync_add_new_device_learn_button">Повече за изпращане на раздели…</string>
<!-- Text for the button to connect another device -->
<string name="sync_add_new_device_connect_button">Добавяне на устройство…</string>
<!-- Notifications -->
<!-- The user visible name of the "notification channel" (Android 8+ feature) for the ongoing notification shown while a browsing session is active. -->
<string name="notification_pbm_channel_name">Поверителна сесия</string>
<!-- Text shown in the notification that pops up to remind the user that a private browsing session is active. -->
<string name="notification_pbm_delete_text">Изчистване на поверителни раздели</string>
<!-- Text shown in the notification that pops up to remind the user that a private browsing session is active. -->
<string name="notification_pbm_delete_text_2">Затваряне на поверителни раздели</string>
<!-- Notification action to open Fenix and resume the current browsing session. -->
<string name="notification_pbm_action_open">Отваряне</string>
<!-- Notification action to delete all current private browsing sessions AND switch to Fenix (bring it to the foreground) -->
<string name="notification_pbm_action_delete_and_open">Изчистване и отваряне</string>
<!-- QR code scanner prompt which appears after scanning a code, but before navigating to it <!-- QR code scanner prompt which appears after scanning a code, but before navigating to it
First parameter is the name of the app, second parameter is the URL or text scanned--> First parameter is the name of the app, second parameter is the URL or text scanned-->
<string name="qr_scanner_confirmation_dialog_message">Разрешете %1$s да отвори %2$s</string> <string name="qr_scanner_confirmation_dialog_message">Разрешете %1$s да отвори %2$s</string>
<!-- Collection and tab deletion prompt dialog title. Placeholder will be replaced with the collection name. This will show when the last tab from a collection is deleted -->
<string name="delete_tab_and_collection_dialog_title">Изтриване на %1$s?</string>
<!-- Tab collection deletion prompt dialog option to delete the collection -->
<string name="tab_collection_dialog_positive">Изтриване</string>
<!-- Tab collection deletion prompt dialog option to cancel deleting the collection -->
<string name="tab_collection_dialog_negative">Отказ</string>
<!-- Text displayed in a notification when the user enters full screen mode -->
<string name="full_screen_notification">Режим на цял екран</string>
<!-- Message for copying the URL via long press on the toolbar -->
<string name="url_copied">Адресът е копиран</string>
<!-- Title for the tabs item in Delete browsing data -->
<string name="preferences_delete_browsing_data_tabs_title_2">Отворени раздели</string>
<!-- Subtitle for the tabs item in Delete browsing data, parameter will be replaced with the number of open tabs -->
<string name="preferences_delete_browsing_data_tabs_subtitle">%d раздела</string>
<!-- Subtitle for the data and history items in delete browsing data, parameter will be replaced with the
number of history items the user has -->
<string name="preferences_delete_browsing_data_browsing_data_subtitle">%d адреса</string>
<!-- Title for history items in Delete browsing data -->
<string name="preferences_delete_browsing_data_browsing_history_title">История</string>
<!-- Subtitle for the history items in delete browsing data, parameter will be replaced with the
number of history pages the user has -->
<string name="preferences_delete_browsing_data_browsing_history_subtitle">%d страници</string>
<!-- Title for the cookies item in Delete browsing data -->
<string name="preferences_delete_browsing_data_cookies">Бисквитки</string>
<!-- Action item in menu for the Delete browsing data on quit feature -->
<string name="delete_browsing_data_on_quit_action">Изход</string>
<!-- Text for the cancel button for the data deletion dialog -->
<string name="delete_browsing_data_prompt_cancel">Отказ</string>
<!-- Text for the allow button for the data deletion dialog -->
<string name="delete_browsing_data_prompt_allow">Изтриване</string>
<!-- text for firefox preview moving tip button -->
<string name="tip_firefox_preview_moved_button_preview_installed">Преминете към новият Nightly</string>
<!-- text for firefox preview moving tip header. "Firefox Nightly" is intentionally hardcoded -->
<string name="tip_firefox_preview_moved_header_preview_not_installed">Firefox Nightly е преместен</string>
<!-- Onboarding -->
<!-- Text for onboarding welcome message
The first parameter is the name of the app (e.g. Firefox Preview) -->
<string name="onboarding_header">Здравейте от %s!</string>
<!-- text for the Firefox Preview feature section header <!-- text for the Firefox Preview feature section header
The first parameter is the name of the app (e.g. Firefox Preview) --> The first parameter is the name of the app (e.g. Firefox Preview) -->
<string name="onboarding_feature_section_header">Запознайте се с %s</string> <string name="onboarding_feature_section_header">Запознайте се с %s</string>
@ -517,17 +947,21 @@
<string name="onboarding_whats_new_description">Имате въпроси относно новия дизайн на %s? Искате ли да разберете какви са промените?</string> <string name="onboarding_whats_new_description">Имате въпроси относно новия дизайн на %s? Искате ли да разберете какви са промените?</string>
<!-- text for underlined clickable link that is part of "what's new" onboarding card description that links to an FAQ --> <!-- text for underlined clickable link that is part of "what's new" onboarding card description that links to an FAQ -->
<string name="onboarding_whats_new_description_linktext">Получете отговори тук</string> <string name="onboarding_whats_new_description_linktext">Получете отговори тук</string>
<!-- text for the firefox account onboarding card header <!-- text for the Firefox account onboarding sign in card header -->
The first parameter is the name of the app (e.g. Firefox Preview) --> <string name="onboarding_account_sign_in_header">Синхронизирайте отметки, пароли и други чрез вашата сметка във Firefox.</string>
<string name="onboarding_firefox_account_header">Извлечете максимума от %s</string> <!-- Text for the button to learn more about signing in to your Firefox account -->
<string name="onboarding_manual_sign_in_learn_more">Научете повече</string>
<!-- text for the automatic sign-in button while signing in is in process -->
<string name="onboarding_firefox_account_signing_in">Вписване…</string>
<!-- text for the button to manually sign into Firefox account. The word "Firefox" should not be translated -->
<string name="onboarding_firefox_account_sign_in">Вписване във Firefox</string>
<!-- text for the tracking protection onboarding card header --> <!-- text for the tracking protection onboarding card header -->
<string name="onboarding_tracking_protection_header_2">Автоматична поверителност</string> <string name="onboarding_tracking_protection_header_2">Автоматична поверителност</string>
<!-- text for the tracking protection card description <!-- text for the tracking protection card description
The first parameter is the name of the app (e.g. Firefox Preview) --> The first parameter is the name of the app (e.g. Firefox Preview) -->
<string name="onboarding_tracking_protection_description_2">Настройките за поверителност и сигурност спират проследяващ и злонамерен код, както и компании, които ви преследват.</string> <string name="onboarding_tracking_protection_description_2">Настройките за поверителност и сигурност спират проследяващ и злонамерен код, както и компании, които ви преследват.</string>
<!-- text for tracking protection radio button option for standard level of blocking --> <!-- text for tracking protection radio button option for standard level of blocking -->
<string name="onboarding_tracking_protection_standard_button_2">Стандартна (по подразбиране)</string> <string name="onboarding_tracking_protection_standard_button_2">Стандартна (подразбиране)</string>
<!-- text for standard blocking option button description --> <!-- text for standard blocking option button description -->
<string name="onboarding_tracking_protection_standard_button_description_2">Спира малко проследявания. Страниците зареждат нормално.</string> <string name="onboarding_tracking_protection_standard_button_description_2">Спира малко проследявания. Страниците зареждат нормално.</string>
<!-- text for tracking protection radio button option for strict level of blocking --> <!-- text for tracking protection radio button option for strict level of blocking -->
@ -536,42 +970,311 @@
<string name="onboarding_tracking_protection_strict_option">Строга</string> <string name="onboarding_tracking_protection_strict_option">Строга</string>
<!-- text for strict blocking option button description --> <!-- text for strict blocking option button description -->
<string name="onboarding_tracking_protection_strict_button_description_2">Спира повече проследявания, реклами и изскачащи прозорци. Страниците зареждат по-бързо, но може да не работят.</string> <string name="onboarding_tracking_protection_strict_button_description_2">Спира повече проследявания, реклами и изскачащи прозорци. Страниците зареждат по-бързо, но може да не работят.</string>
<!-- text for the toolbar position card header
In English this is an idiom for "choose a side as in an argument or fight"
but it is ok to make this more literally about "choosing a position in a physical space -->
<string name="onboarding_toolbar_position_header">Изберете страна</string>
<!-- text for the toolbar position card description -->
<string name="onboarding_toolbar_position_description">Изпробвайте работа с една ръка, с лента инструменти отдолу, или я преместете отгоре.</string>
<!-- text for the private browsing onboarding card header -->
<string name="onboarding_private_browsing_header">Разглеждайте поверително</string>
<!-- text for the private browsing onboarding card description
The first parameter is an icon that represents private browsing -->
<string name="onboarding_private_browsing_description1">За да отворите поверителен раздел: докоснете иконата %s.</string>
<!-- text for the private browsing onboarding card description, explaining how to always using private browsing -->
<string name="onboarding_private_browsing_always_description">За да се отваря поверителен раздел всеки път: променете настройките за поверително разглеждане.</string>
<!-- text for the private browsing onbording card button, that launches settings -->
<string name="onboarding_private_browsing_button">Отваряне на настройки</string>
<!-- text for the privacy notice onboarding card header -->
<string name="onboarding_privacy_notice_header">Поверителност</string>
<!-- text for the privacy notice onboarding card description
The first parameter is the name of the app (e.g. Firefox Preview) -->
<string name="onboarding_privacy_notice_description">Проектирали сме %s така, че да ви предоставя контрол върху това, което споделяте както онлайн, така и с нас.
</string>
<!-- Text for the button to read the privacy notice -->
<string name="onboarding_privacy_notice_read_button">Бележка за поверителността</string>
<!-- Content description (not visible, for screen readers etc.): Close onboarding screen --> <!-- Content description (not visible, for screen readers etc.): Close onboarding screen -->
<string name="onboarding_close">Затваряне</string> <string name="onboarding_close">Затваряне</string>
<!-- text for the button to finish onboarding -->
<string name="onboarding_finish">Започнете да разглеждате</string>
<!-- Onboarding theme --> <!-- Onboarding theme -->
<!-- text for the theme picker onboarding card header --> <!-- text for the theme picker onboarding card header -->
<string name="onboarding_theme_picker_header">Изберете тема</string> <string name="onboarding_theme_picker_header">Изберете тема</string>
<!-- text for the theme picker onboarding card description -->
<string name="onboarding_theme_picker_description1">Запазете батерия и зрението си с избиране на тъмна тема.</string>
<!-- Automatic theme setting (will follow device setting) -->
<string name="onboarding_theme_automatic_title">Автоматичнa</string>
<!-- Summary of automatic theme setting (will follow device setting) -->
<string name="onboarding_theme_automatic_summary">Приспособява се към настройките на устройството</string>
<!-- Theme setting for dark mode -->
<string name="onboarding_theme_dark_title">Тъмна тема</string>
<!-- Theme setting for light mode -->
<string name="onboarding_theme_light_title">Светла тема</string>
<!-- Text shown in snackbar when multiple tabs have been sent to device -->
<string name="sync_sent_tabs_snackbar">Разделите са изпратени!</string>
<!-- Text shown in snackbar when one tab has been sent to device -->
<string name="sync_sent_tab_snackbar">Разделът е изпратен!</string>
<!-- Text shown in snackbar for the "retry" action that the user has after sharing tabs failed -->
<string name="sync_sent_tab_error_snackbar_action">НОВ ОПИТ</string>
<!-- Title of QR Pairing Fragment -->
<string name="sync_scan_code">Сканиране на код</string>
<!-- Option to cancel signing out shown in confirmation dialog to sign out of account -->
<string name="sign_out_cancel">Отказ</string>
<!-- Enhanced Tracking Protection -->
<!-- Link displayed in enhanced tracking protection panel to access tracking protection settings -->
<string name="etp_settings">Настройки на защитата</string>
<!-- Preference title for enhanced tracking protection settings -->
<string name="preference_enhanced_tracking_protection">Подобрена защита от проследяване</string>
<!-- Title for the description of enhanced tracking protection --> <!-- Title for the description of enhanced tracking protection -->
<string name="preference_enhanced_tracking_protection_explanation_title">Преглеждайте без да бъдете следени</string> <string name="preference_enhanced_tracking_protection_explanation_title">Разглеждайте без да сте следени</string>
<!-- Description of enhanced tracking protection. The first parameter is the name of the application (For example: Fenix) --> <!-- Description of enhanced tracking protection. The first parameter is the name of the application (For example: Fenix) -->
<string name="preference_enhanced_tracking_protection_explanation">Пазете вашите данни само ваши. %s ви предпазва от много от най-разпространените проследявания, които следват вашите действия онлайн.</string> <string name="preference_enhanced_tracking_protection_explanation">Пазете вашите данни лични. %s ви предпазва от най-разпространените проследявания, които дебнат действията ви онлайн.</string>
<!-- Text displayed that links to website about enhanced tracking protection --> <!-- Text displayed that links to website about enhanced tracking protection -->
<string name="preference_enhanced_tracking_protection_explanation_learn_more">Научете повече</string> <string name="preference_enhanced_tracking_protection_explanation_learn_more">Научете повече</string>
<!-- Preference for enhanced tracking protection for the standard protection settings -->
<string name="preference_enhanced_tracking_protection_standard_default_1">Стандартна (подразбиране)</string>
<!-- Preference description for enhanced tracking protection for the standard protection settings -->
<string name="preference_enhanced_tracking_protection_standard_description_3">Спира малко проследявания. Страниците зареждат нормално.</string>
<!-- Preference for enhanced tracking protection for the strict protection settings -->
<string name="preference_enhanced_tracking_protection_strict">Строга</string>
<!-- Preference description for enhanced tracking protection for the strict protection settings -->
<string name="preference_enhanced_tracking_protection_strict_description_2">Спира повече проследявания, реклами и изскачащи прозорци. Страниците зареждат по-бързо, но може да не работят.</string>
<!-- Preference for enhanced tracking protection for the custom protection settings -->
<string name="preference_enhanced_tracking_protection_custom">По избор</string>
<!-- Preference description for enhanced tracking protection for the strict protection settings -->
<string name="preference_enhanced_tracking_protection_custom_description_2">Изберете какво проследяване и кои скриптове да спрете.</string>
<!-- Header for categories that are being blocked by current Enhanced Tracking Protection settings -->
<!-- Preference for enhanced tracking protection for the custom protection settings for cookies-->
<string name="preference_enhanced_tracking_protection_custom_cookies">Бисквитки</string>
<!-- Option for enhanced tracking protection for the custom protection settings for cookies-->
<string name="preference_enhanced_tracking_protection_custom_cookies_1">Проследяване в различни сайтове и социални медии</string>
<!-- Option for enhanced tracking protection for the custom protection settings for cookies-->
<string name="preference_enhanced_tracking_protection_custom_cookies_2">Бисквитки от непосетени страници</string>
<!-- Option for enhanced tracking protection for the custom protection settings for cookies-->
<string name="preference_enhanced_tracking_protection_custom_cookies_3">Всички бисквитки от трети страни (може наруши работата на страници)</string>
<!-- Option for enhanced tracking protection for the custom protection settings for cookies-->
<string name="preference_enhanced_tracking_protection_custom_cookies_4">Всички бисквитки (ще наруши работата на страници)</string>
<!-- Preference for enhanced tracking protection for the custom protection settings for tracking content -->
<string name="preference_enhanced_tracking_protection_custom_tracking_content">Проследяващо съдържание</string>
<!-- Option for enhanced tracking protection for the custom protection settings for tracking content-->
<string name="preference_enhanced_tracking_protection_custom_tracking_content_1">Във всички раздели</string>
<!-- Option for enhanced tracking protection for the custom protection settings for tracking content-->
<string name="preference_enhanced_tracking_protection_custom_tracking_content_2">Само в поверителни раздели</string>
<!-- Preference for enhanced tracking protection for the custom protection settings -->
<string name="preference_enhanced_tracking_protection_custom_cryptominers">Добиване на криптовалути</string>
<!-- Preference for enhanced tracking protection for the custom protection settings -->
<string name="preference_enhanced_tracking_protection_custom_fingerprinters">Снемане на цифров отпечатък</string>
<!-- Header for categories that are being not being blocked by current Enhanced Tracking Protection settings -->
<string name="enhanced_tracking_protection_allowed">Разрешено</string>
<!-- Category of trackers (social media trackers) that can be blocked by Enhanced Tracking Protection -->
<string name="etp_social_media_trackers_title">Проследяване от социални мрежи</string>
<!-- Description of social media trackers that can be blocked by Enhanced Tracking Protection -->
<string name="etp_social_media_trackers_description">Ограничава възможността социалните мрежи да проследяват вашата активност в Мрежата.</string>
<!-- Category of trackers (cross-site tracking cookies) that can be blocked by Enhanced Tracking Protection -->
<string name="etp_cookies_title">Бисквитки за следене в различни сайтове</string>
<!-- Description of cross-site tracking cookies that can be blocked by Enhanced Tracking Protection -->
<string name="etp_cookies_description">Спира бисквитки, които компаниите за реклама и анализ използват за събиране на ваши данни от посещения в множество страници.</string>
<!-- Category of trackers (cryptominers) that can be blocked by Enhanced Tracking Protection -->
<string name="etp_cryptominers_title">Добиване на криптовалути</string>
<!-- Description of cryptominers that can be blocked by Enhanced Tracking Protection -->
<string name="etp_cryptominers_description">Предотвратява зловредни скриптове, придобиващи достъп до устройството ви, с цел добив на цифрова валута.</string>
<!-- Category of trackers (fingerprinters) that can be blocked by Enhanced Tracking Protection -->
<string name="etp_fingerprinters_title">Снемане на цифров отпечатък</string>
<!-- Description of fingerprinters that can be blocked by Enhanced Tracking Protection -->
<string name="etp_fingerprinters_description">Предотвратява събирането на уникални данни за обратно установяване, които могат да бъдат използвани за проследяване. </string>
<!-- Category of trackers (tracking content) that can be blocked by Enhanced Tracking Protection -->
<string name="etp_tracking_content_title">Проследяващо съдържание</string>
<!-- Description of tracking content that can be blocked by Enhanced Tracking Protection -->
<string name="etp_tracking_content_description">Спира зареждането на външни реклами, видео и друго съдържание, съдържащо проследяващ код. Може да засегне някои страници.</string>
<!-- Enhanced Tracking Protection Onboarding Message shown in a dialog above the toolbar. The first parameter is the name of the application (For example: Fenix) -->
<string name="etp_onboarding_cfr_message">Всеки път, когато щитът е лилав, %s е спрял проследяване на сайт. Докоснете за повече информация.</string>
<!-- Enhanced Tracking Protection message that protection is currently on for this site -->
<string name="etp_panel_on">Защитите са ВКЛЮЧЕНИ за този сайт</string>
<!-- Enhanced Tracking Protection message that protection is currently off for this site -->
<string name="etp_panel_off">Защитите са ИЗКЛЮЧЕНИ за този сайт</string>
<!-- Header for exceptions list for which sites enhanced tracking protection is always off -->
<string name="enhanced_tracking_protection_exceptions">Подобрената защита от проследяване е изключена за тези сайтове</string>
<!-- Content description (not visible, for screen readers etc.): Navigate <!-- Content description (not visible, for screen readers etc.): Navigate
back from ETP details (Ex: Tracking content) --> back from ETP details (Ex: Tracking content) -->
<string name="etp_back_button_content_description">Връщане назад</string> <string name="etp_back_button_content_description">Връщане назад</string>
<!-- Open source licenses page title
The first parameter is the app name -->
<string name="open_source_licenses_title">%s | библиотеки с отворен код</string>
<!-- About page link text to open support link -->
<string name="about_support">Поддръжка</string>
<!-- About page link text to open privacy notice link -->
<string name="about_privacy_notice">Политика на поверителност</string>
<!-- About page link text to open know your rights link -->
<string name="about_know_your_rights">Знайте правата си</string>
<!-- About page link text to open licensing information link -->
<string name="about_licensing_information">Лицензна информация</string>
<!-- About page link text to open a screen with libraries that are used -->
<string name="about_other_open_source_libraries">Използвани библиотеки</string>
<!-- Toast shown to the user when they are activating the secret dev menu
The first parameter is number of long clicks left to enable the menu -->
<string name="about_debug_menu_toast_progress">Меню за отстраняване на грешки: %1$d оставащи натискания до включване</string>
<string name="about_debug_menu_toast_done">Меню за отстраняване на грешки включено</string>
<!-- Content description of the tab counter toolbar button when one tab is open -->
<string name="tab_counter_content_description_one_tab">1 раздел</string>
<!-- Content description of the tab counter toolbar button when multiple tabs are open. First parameter will be replaced with the number of tabs (always more than one) -->
<string name="tab_counter_content_description_multi_tab">%d раздела</string>
<!-- Browser long press popup menu -->
<!-- Copy the current url -->
<string name="browser_toolbar_long_press_popup_copy">Копиране</string>
<!-- Paste & go the text in the clipboard. '&amp;' is replaced with the ampersand symbol: & -->
<string name="browser_toolbar_long_press_popup_paste_and_go">Поставяне и посещаване</string>
<!-- Paste the text in the clipboard -->
<string name="browser_toolbar_long_press_popup_paste">Поставяне</string>
<!-- Snackbar message shown after an URL has been copied to clipboard. -->
<string name="browser_toolbar_url_copied_to_clipboard_snackbar">Адресът е копиран в системния буфер</string>
<!-- Title text for the Add To Homescreen dialog -->
<string name="add_to_homescreen_title">Добавяне към началния екран</string>
<!-- Cancel button text for the Add to Homescreen dialog -->
<string name="add_to_homescreen_cancel">Отказ</string>
<!-- Add button text for the Add to Homescreen dialog -->
<string name="add_to_homescreen_add">Добавяне</string>
<!-- Continue to website button text for the first-time Add to Homescreen dialog -->
<string name="add_to_homescreen_continue">Към страницата</string>
<!-- Placeholder text for the TextView in the Add to Homescreen dialog -->
<string name="add_to_homescreen_text_placeholder">Име на пряк път</string>
<!-- Preference for managing the settings for logins and passwords in Fenix -->
<string name="preferences_passwords_logins_and_passwords">Регистрации и пароли</string>
<!-- Preference for managing the saving of logins and passwords in Fenix -->
<string name="preferences_passwords_save_logins">Запазване на регистрации и пароли</string>
<!-- Preference option for asking to save passwords in Fenix -->
<string name="preferences_passwords_save_logins_ask_to_save">Питане за запазване</string>
<!-- Preference option for never saving passwords in Fenix -->
<string name="preferences_passwords_save_logins_never_save">Никога</string>
<!-- Preference for autofilling saved logins in Fenix -->
<string name="preferences_passwords_autofill">Автоматично попълване</string>
<!-- Preference for syncing saved logins in Fenix -->
<string name="preferences_passwords_sync_logins">Синхронизиране на регистрации</string>
<!-- Syncing saved logins in Fenix is on -->
<string name="preferences_passwords_sync_logins_on">Включено</string>
<!-- Syncing saved logins in Fenix is off -->
<string name="preferences_passwords_sync_logins_off">Изключено</string>
<!-- Syncing saved logins in Fenix needs reconnect to sync -->
<string name="preferences_passwords_sync_logins_reconnect">Повторно свързване</string>
<!-- Syncing saved logins in Fenix needs login -->
<string name="preferences_passwords_sync_logins_sign_in">Вписване в Sync</string>
<!-- Preference to access list of saved logins -->
<string name="preferences_passwords_saved_logins">Запазени регистрации</string>
<!-- Description of empty list of saved passwords. Placeholder is replaced with app name. -->
<string name="preferences_passwords_saved_logins_description_empty_text">Тук се показват нещата, които запазвате или синхронизирате във %s.</string>
<!-- Preference to access list of saved logins --> <!-- Preference to access list of saved logins -->
<string name="preferences_passwords_saved_logins_description_empty_learn_more_link">Научете повече за Sync.</string> <string name="preferences_passwords_saved_logins_description_empty_learn_more_link">Научете повече за Sync.</string>
<!-- Preference to access list of login exceptions that we never save logins for -->
<string name="preferences_passwords_exceptions">Изключения</string>
<!-- Empty description of list of login exceptions that we never save logins for -->
<string name="preferences_passwords_exceptions_description_empty">Тук се показват регистрации и пароли, които не са запазени.</string>
<!-- Hint for search box in logins list -->
<string name="preferences_passwords_saved_logins_search">Търсене на регистрация</string>
<!-- Option to sort logins list A-Z, alphabetically -->
<string name="preferences_passwords_saved_logins_alphabetically">Азбучен ред</string>
<!-- Option to sort logins list by most recently used -->
<string name="preferences_passwords_saved_logins_recently_used">Последно използвани</string>
<!-- The header for the site that a login is for -->
<string name="preferences_passwords_saved_logins_site">Страница</string>
<!-- The header for the username for a login -->
<string name="preferences_passwords_saved_logins_username">Потребителско име</string>
<!-- The header for the password for a login -->
<string name="preferences_passwords_saved_logins_password">Парола</string>
<!-- Message displayed in security prompt to reenter a secret pin to access saved logins -->
<string name="preferences_passwords_saved_logins_enter_pin">Въведете отново своя PIN</string>
<!-- Message displayed in security prompt to access saved logins -->
<string name="preferences_passwords_saved_logins_enter_pin_description">Отключете, за да видите запазените регистрации</string>
<!-- Message displayed when a connection is insecure and we detect the user is entering a password -->
<string name="logins_insecure_connection_warning">Връзката е незащитена. Въведените тук данни за вход могат да бъдат компрометирани.</string>
<!-- Learn more link that will link to a page with more information displayed when a connection is insecure and we detect the user is entering a password --> <!-- Learn more link that will link to a page with more information displayed when a connection is insecure and we detect the user is entering a password -->
<string name="logins_insecure_connection_warning_learn_more">Научете повече</string> <string name="logins_insecure_connection_warning_learn_more">Научете повече</string>
<!-- Content description (not visible, for screen readers etc.): Sort saved logins dropdown menu chevron icon --> <!-- Content description (not visible, for screen readers etc.): Sort saved logins dropdown menu chevron icon -->
<string name="saved_logins_menu_dropdown_chevron_icon_content_description">Меню за сортиране на регистрации</string> <string name="saved_logins_menu_dropdown_chevron_icon_content_description">Меню за сортиране на регистрации</string>
<!-- Title of the Add search engine screen -->
<string name="search_engine_add_custom_search_engine_title">Добавяне на търсеща машина</string>
<!-- Title of the Edit search engine screen -->
<string name="search_engine_edit_custom_search_engine_title">Промяна на търсеща машина</string>
<!-- Content description (not visible, for screen readers etc.): Title for the button to add a search engine in the action bar --> <!-- Content description (not visible, for screen readers etc.): Title for the button to add a search engine in the action bar -->
<string name="search_engine_add_button_content_description">Добавяне</string> <string name="search_engine_add_button_content_description">Добавяне</string>
<!-- Content description (not visible, for screen readers etc.): Title for the button to save a search engine in the action bar --> <!-- Content description (not visible, for screen readers etc.): Title for the button to save a search engine in the action bar -->
<string name="search_engine_add_custom_search_engine_edit_button_content_description">Запазване</string> <string name="search_engine_add_custom_search_engine_edit_button_content_description">Запазване</string>
<!-- Text for the menu button to edit a search engine -->
<string name="search_engine_edit">Променяне</string>
<!-- Text for the menu button to delete a search engine -->
<string name="search_engine_delete">Премахване</string>
<!-- Text for the button to create a custom search engine on the Add search engine screen -->
<string name="search_add_custom_engine_label_other">Друга</string>
<!-- Placeholder text shown in the Search Engine Name TextField before a user enters text -->
<string name="search_add_custom_engine_name_hint">Име</string>
<!-- Placeholder text shown in the Search String TextField before a user enters text -->
<string name="search_add_custom_engine_search_string_hint">Низ за търсене, който да се използва</string>
<!-- Description text for the Search String TextField. The %s is part of the string -->
<string name="search_add_custom_engine_search_string_example">Заменете заявката с „%s“. Пример:\nhttps://www.google.com/search?q=%s</string>
<!-- Text for the button to learn more about adding a custom search engine --> <!-- Text for the button to learn more about adding a custom search engine -->
<string name="search_add_custom_engine_learn_more_label">Научете повече</string> <string name="search_add_custom_engine_learn_more_label">Научете повече</string>
<!-- Accessibility description for the form in which details about the custom search engine are entered -->
<string name="search_add_custom_engine_form_description">Данни за търсещата машина на потребителя</string>
<!-- Accessibility description for the 'Learn more' link --> <!-- Accessibility description for the 'Learn more' link -->
<string name="search_add_custom_engine_learn_more_description">Препратка научете повече</string> <string name="search_add_custom_engine_learn_more_description">Препратка научете повече</string>
<!-- Text shown when a user leaves the name field empty -->
<string name="search_add_custom_engine_error_empty_name">Въведете име на търсещата машина</string>
<!-- Text shown when a user tries to add a search engine that already exists -->
<string name="search_add_custom_engine_error_existing_name">Търсеща машина с име „%s“ вече съществува.</string>
<!-- Text shown when a user leaves out the required template string -->
<string name="search_add_custom_engine_error_missing_template">Уверете се, че низът за търсене съвпада с примера</string>
<!-- Text shown when we aren't able to validate the custom search query. The first parameter is the url of the custom search engine -->
<string name="search_add_custom_engine_error_cannot_reach">Грешка при свързване с „%s“</string>
<!-- Text shown when a user creates a new search engine -->
<string name="search_add_custom_engine_success_message">%s е създадена</string>
<!-- Text shown when a user successfully edits a custom search engine -->
<string name="search_edit_custom_engine_success_message">%s е запазена</string>
<!-- Text shown when a user successfully deletes a custom search engine -->
<string name="search_delete_search_engine_success_message">%s е изтрита</string>
<!-- Title text shown for the migration screen to the new browser. Placeholder replaced with app name -->
<string name="migration_title">Добре дошли в един чисто нов %s</string>
<!-- Synced Tabs -->
<!-- Text displayed to ask user to connect another device as no devices found with account -->
<string name="synced_tabs_connect_another_device">Добавете друго на устройство.</string>
<!-- Text displayed when user has no tabs that have been synced -->
<string name="synced_tabs_no_tabs">Няма отворени раздели във Firefox на други ваши устройства.</string>
<!-- Text displayed in the synced tabs screen when a user is not signed in to Firefox Sync describing Synced Tabs -->
<string name="synced_tabs_sign_in_message">Вижте разделите от други ваши устройства.</string>
<!-- Text displayed on a button in the synced tabs screen to link users to sign in when a user is not signed in to Firefox Sync -->
<string name="synced_tabs_sign_in_button">Вписване в Sync</string>
<!-- The text displayed when a synced device has no tabs to show in the list of Synced Tabs. -->
<string name="synced_tabs_no_open_tabs">Няма отворени раздели</string>
<!-- Confirmation dialog button text when top sites limit is reached. -->
<string name="top_sites_max_limit_confirmation_button">Добре, разбрах</string>
<!-- Content description for close button in collection placeholder. -->
<string name="remove_home_collection_placeholder_content_description">Премахване</string>
<!-- Deprecated: text for the firefox account onboarding card header
The first parameter is the name of the app (e.g. Firefox Preview) -->
<string name="onboarding_firefox_account_header">Извлечете максимума от %s</string>
</resources> </resources>

@ -1175,7 +1175,7 @@
<!-- Text shown for settings option for sign with email --> <!-- Text shown for settings option for sign with email -->
<string name="sign_in_with_email">Impiegà piuttostu un messaghju elettronicu</string> <string name="sign_in_with_email">Impiegà piuttostu un messaghju elettronicu</string>
<!-- Text shown for settings option for create new account text.'Firefox' intentionally hardcoded here.--> <!-- Text shown for settings option for create new account text.'Firefox' intentionally hardcoded here.-->
<string name="sign_in_create_account_text"><![CDATA[Contu, ùn ne avete ? <u>Createne unu</u> per sincrunizà i vostri apparechji.]]></string> <string name="sign_in_create_account_text"><![CDATA[Contu, ùn ne avete ? <u>Createne unu</u> per sincrunizà Firefox trà i vostri apparechji.]]></string>
<!-- Text shown in confirmation dialog to sign out of account --> <!-- Text shown in confirmation dialog to sign out of account -->
<string name="sign_out_confirmation_message">Firefox ùn si sincruniserà più cù u vostru contu, ma ùn squasserà alcunu datu di navigazione nantà stapparechju.</string> <string name="sign_out_confirmation_message">Firefox ùn si sincruniserà più cù u vostru contu, ma ùn squasserà alcunu datu di navigazione nantà stapparechju.</string>
<!-- Text shown in confirmation dialog to sign out of account. The first parameter is the name of the app (e.g. Firefox Preview) --> <!-- Text shown in confirmation dialog to sign out of account. The first parameter is the name of the app (e.g. Firefox Preview) -->
@ -1284,7 +1284,7 @@
<string name="open_source_licenses_title">%s | Bibliuteche di fonte aperta</string> <string name="open_source_licenses_title">%s | Bibliuteche di fonte aperta</string>
<!-- Category of trackers (redirect trackers) that can be blocked by Enhanced Tracking Protection --> <!-- Category of trackers (redirect trackers) that can be blocked by Enhanced Tracking Protection -->
<string name="etp_redirect_trackers_title">Frattighjatori da ridirezzione</string> <string name="etp_redirect_trackers_title">Perseguitatori da ridirezzione</string>
<!-- Description of redirect tracker cookies that can be blocked by Enhanced Tracking Protection --> <!-- Description of redirect tracker cookies that can be blocked by Enhanced Tracking Protection -->
<string name="etp_redirect_trackers_description">Squasseghja i canistrelli definiti da ridirezzione ver di siti web cunnisciuti per u spiunagiu.</string> <string name="etp_redirect_trackers_description">Squasseghja i canistrelli definiti da ridirezzione ver di siti web cunnisciuti per u spiunagiu.</string>

@ -100,7 +100,7 @@
<!-- Text for the positive action button to go to Settings for auto close tabs. --> <!-- Text for the positive action button to go to Settings for auto close tabs. -->
<string name="tab_tray_close_tabs_banner_positive_button_text">Zobrazit možnosti</string> <string name="tab_tray_close_tabs_banner_positive_button_text">Zobrazit možnosti</string>
<!-- Text for the negative action button to dismiss the Close Tabs Banner. --> <!-- Text for the negative action button to dismiss the Close Tabs Banner. -->
<string name="tab_tray_close_tabs_banner_negative_button_text">Zavřít</string> <string name="tab_tray_close_tabs_banner_negative_button_text">Ne, děkuji</string>
<!-- Home screen icons - Long press shortcuts --> <!-- Home screen icons - Long press shortcuts -->
<!-- Shortcut action to open new tab --> <!-- Shortcut action to open new tab -->
@ -146,6 +146,8 @@
<string name="browser_menu_install_on_homescreen">Nainstalovat</string> <string name="browser_menu_install_on_homescreen">Nainstalovat</string>
<!-- Menu option on the toolbar that takes you to synced tabs page--> <!-- Menu option on the toolbar that takes you to synced tabs page-->
<string name="synced_tabs">Synchronizované panely</string> <string name="synced_tabs">Synchronizované panely</string>
<!-- Content description (not visible, for screen readers etc.) for the Resync tabs button -->
<string name="resync_button_content_description">Synchronizovat znovu</string>
<!-- Browser menu button that opens the find in page menu --> <!-- Browser menu button that opens the find in page menu -->
<string name="browser_menu_find_in_page">Najít na stránce</string> <string name="browser_menu_find_in_page">Najít na stránce</string>
<!-- Browser menu button that creates a private tab --> <!-- Browser menu button that creates a private tab -->
@ -272,6 +274,8 @@
<string name="preferences_open_links_in_a_private_tab">Otevírat odkazy v anonymních panelech</string> <string name="preferences_open_links_in_a_private_tab">Otevírat odkazy v anonymních panelech</string>
<!-- Preference for allowing screenshots to be taken while in a private tab--> <!-- Preference for allowing screenshots to be taken while in a private tab-->
<string name="preferences_allow_screenshots_in_private_mode">Povolit pořizování snímků obrazovky v anonymním prohlížení</string> <string name="preferences_allow_screenshots_in_private_mode">Povolit pořizování snímků obrazovky v anonymním prohlížení</string>
<!-- Will inform the user of the risk of activating Allow screenshots in private browsing option -->
<string name="preferences_screenshots_in_private_mode_disclaimer">Pokud toto povolíte, obsah panelů bude viditelný i v zobrazení otevřených aplikací</string>
<!-- Preference for adding private browsing shortcut --> <!-- Preference for adding private browsing shortcut -->
<string name="preferences_add_private_browsing_shortcut">Vytvořit zkratku pro anonymní prohlížení</string> <string name="preferences_add_private_browsing_shortcut">Vytvořit zkratku pro anonymní prohlížení</string>
<!-- Preference for accessibility --> <!-- Preference for accessibility -->
@ -328,6 +332,8 @@
<string name="preferences_search_browsing_history">Našeptávat z historie prohlížení</string> <string name="preferences_search_browsing_history">Našeptávat z historie prohlížení</string>
<!-- Preference title for switch preference to suggest bookmarks when searching --> <!-- Preference title for switch preference to suggest bookmarks when searching -->
<string name="preferences_search_bookmarks">Našeptávat ze záložek</string> <string name="preferences_search_bookmarks">Našeptávat ze záložek</string>
<!-- Preference title for switch preference to suggest synced tabs when searching -->
<string name="preferences_search_synced_tabs">Hledat v synchronizovaných panelech</string>
<!-- Preference for account settings --> <!-- Preference for account settings -->
<string name="preferences_account_settings">Nastavení účtu</string> <string name="preferences_account_settings">Nastavení účtu</string>
@ -1172,6 +1178,8 @@
<string name="sign_in_with_camera">Přihlásit se pomocí fotoaparátu</string> <string name="sign_in_with_camera">Přihlásit se pomocí fotoaparátu</string>
<!-- Text shown for settings option for sign with email --> <!-- Text shown for settings option for sign with email -->
<string name="sign_in_with_email">Použít raději e-mail</string> <string name="sign_in_with_email">Použít raději e-mail</string>
<!-- Text shown for settings option for create new account text.'Firefox' intentionally hardcoded here.-->
<string name="sign_in_create_account_text"><![CDATA[Ještě nemáte účet? <u>Vytvořte si ho</u> a synchronizujte svůj Firefox mezi zařízeními.]]></string>
<!-- Text shown in confirmation dialog to sign out of account --> <!-- Text shown in confirmation dialog to sign out of account -->
<string name="sign_out_confirmation_message">Firefox ukončí synchronizaci s vaším účtem, ale nesmaže z tohoto zařízení žádná vaše data.</string> <string name="sign_out_confirmation_message">Firefox ukončí synchronizaci s vaším účtem, ale nesmaže z tohoto zařízení žádná vaše data.</string>
<!-- Text shown in confirmation dialog to sign out of account. The first parameter is the name of the app (e.g. Firefox Preview) --> <!-- Text shown in confirmation dialog to sign out of account. The first parameter is the name of the app (e.g. Firefox Preview) -->
@ -1279,6 +1287,11 @@
The first parameter is the app name --> The first parameter is the app name -->
<string name="open_source_licenses_title">%s | OSS knihovny</string> <string name="open_source_licenses_title">%s | OSS knihovny</string>
<!-- Category of trackers (redirect trackers) that can be blocked by Enhanced Tracking Protection -->
<string name="etp_redirect_trackers_title">Sledující přesměrování</string>
<!-- Description of redirect tracker cookies that can be blocked by Enhanced Tracking Protection -->
<string name="etp_redirect_trackers_description">Maže cookies nastavené během přesměrování známými sledujícími servery.</string>
<!-- About page link text to open support link --> <!-- About page link text to open support link -->
<string name="about_support">Podpora</string> <string name="about_support">Podpora</string>
<!-- About page link text to list of past crashes (like about:crashes on desktop) --> <!-- About page link text to list of past crashes (like about:crashes on desktop) -->

@ -144,6 +144,8 @@
<string name="browser_menu_install_on_homescreen">Installer</string> <string name="browser_menu_install_on_homescreen">Installer</string>
<!-- Menu option on the toolbar that takes you to synced tabs page--> <!-- Menu option on the toolbar that takes you to synced tabs page-->
<string name="synced_tabs">Synkroniserede faneblade</string> <string name="synced_tabs">Synkroniserede faneblade</string>
<!-- Content description (not visible, for screen readers etc.) for the Resync tabs button -->
<string name="resync_button_content_description">Synkroniser igen</string>
<!-- Browser menu button that opens the find in page menu --> <!-- Browser menu button that opens the find in page menu -->
<string name="browser_menu_find_in_page">Find på siden</string> <string name="browser_menu_find_in_page">Find på siden</string>
<!-- Browser menu button that creates a private tab --> <!-- Browser menu button that creates a private tab -->
@ -265,6 +267,8 @@
<string name="preferences_open_links_in_a_private_tab">Åbn links i et privat faneblad</string> <string name="preferences_open_links_in_a_private_tab">Åbn links i et privat faneblad</string>
<!-- Preference for allowing screenshots to be taken while in a private tab--> <!-- Preference for allowing screenshots to be taken while in a private tab-->
<string name="preferences_allow_screenshots_in_private_mode">Tillad skærmbilleder i privat browsing</string> <string name="preferences_allow_screenshots_in_private_mode">Tillad skærmbilleder i privat browsing</string>
<!-- Will inform the user of the risk of activating Allow screenshots in private browsing option -->
<string name="preferences_screenshots_in_private_mode_disclaimer">Hvis du tillader det, vil private faneblade også være synlige, når flere apps er åbne</string>
<!-- Preference for adding private browsing shortcut --> <!-- Preference for adding private browsing shortcut -->
<string name="preferences_add_private_browsing_shortcut">Tilføj genvej til privat browsing</string> <string name="preferences_add_private_browsing_shortcut">Tilføj genvej til privat browsing</string>
<!-- Preference for accessibility --> <!-- Preference for accessibility -->
@ -285,6 +289,8 @@
<string name="preferences_theme">Tema</string> <string name="preferences_theme">Tema</string>
<!-- Preference for customizing the home screen --> <!-- Preference for customizing the home screen -->
<string name="preferences_home">Startside</string> <string name="preferences_home">Startside</string>
<!-- Preference for gestures based actions -->
<string name="preferences_gestures">Bevægelser</string>
<!-- Preference for settings related to visual options --> <!-- Preference for settings related to visual options -->
<string name="preferences_customize">Tilpas</string> <string name="preferences_customize">Tilpas</string>
<!-- Preference description for banner about signing in --> <!-- Preference description for banner about signing in -->
@ -319,8 +325,12 @@
<string name="preferences_search_browsing_history">Søg i browserhistorik</string> <string name="preferences_search_browsing_history">Søg i browserhistorik</string>
<!-- Preference title for switch preference to suggest bookmarks when searching --> <!-- Preference title for switch preference to suggest bookmarks when searching -->
<string name="preferences_search_bookmarks">Søg i bogmærker</string> <string name="preferences_search_bookmarks">Søg i bogmærker</string>
<!-- Preference title for switch preference to suggest synced tabs when searching -->
<string name="preferences_search_synced_tabs">Søg i synkroniserede faneblade</string>
<!-- Preference for account settings --> <!-- Preference for account settings -->
<string name="preferences_account_settings">Kontoindstillinger</string> <string name="preferences_account_settings">Kontoindstillinger</string>
<!-- Preference for enabling url autocomplete-->
<string name="preferences_enable_autocomplete_urls">Autofuldfør adresser</string>
<!-- Preference for open links in third party apps --> <!-- Preference for open links in third party apps -->
<string name="preferences_open_links_in_apps">Åbn links i apps</string> <string name="preferences_open_links_in_apps">Åbn links i apps</string>
<!-- Preference for open download with an external download manager app --> <!-- Preference for open download with an external download manager app -->
@ -456,6 +466,16 @@
<!-- Preference for using following device theme --> <!-- Preference for using following device theme -->
<string name="preference_follow_device_theme">Samme som enhedens tema</string> <string name="preference_follow_device_theme">Samme som enhedens tema</string>
<!-- Gestures Preferences-->
<!-- Preferences for using pull to refresh in a webpage -->
<string name="preference_gestures_website_pull_to_refresh">Træk for at genindlæse</string>
<!-- Preference for using the dynamic toolbar -->
<string name="preference_gestures_dynamic_toolbar">Scroll for at skjule værktøjslinje</string>
<!-- Preference for switching tabs by swiping horizontally on the toolbar -->
<string name="preference_gestures_swipe_toolbar_switch_tabs">Stryg værktøjslinje sidelæns for at skifte faneblade</string>
<!-- Preference for showing the opened tabs by swiping up on the toolbar-->
<string name="preference_gestures_swipe_toolbar_show_tabs">Stryg værktøjslinje op for at åbne faneblade</string>
<!-- Library --> <!-- Library -->
<!-- Option in Library to open Sessions page --> <!-- Option in Library to open Sessions page -->
<string name="library_sessions">Sessioner</string> <string name="library_sessions">Sessioner</string>
@ -1040,6 +1060,10 @@
<string name="onboarding_account_sign_in_header">Begynd at synkronisere bogmærker, adgangskoder m.m. med din Firefox-konto.</string> <string name="onboarding_account_sign_in_header">Begynd at synkronisere bogmærker, adgangskoder m.m. med din Firefox-konto.</string>
<!-- Text for the button to learn more about signing in to your Firefox account --> <!-- Text for the button to learn more about signing in to your Firefox account -->
<string name="onboarding_manual_sign_in_learn_more">Læs mere</string> <string name="onboarding_manual_sign_in_learn_more">Læs mere</string>
<!-- text for the firefox account onboarding card header when we detect you're already signed in to
another Firefox browser. (The word `Firefox` should not be translated)
The first parameter is the email of the detected user's account -->
<string name="onboarding_firefox_account_auto_signin_header_3">Du er logget ind som %s i en anden version af Firefox på denne enhed. Vil du logge ind med denne konto?</string>
<!-- text for the button to confirm automatic sign-in --> <!-- text for the button to confirm automatic sign-in -->
<string name="onboarding_firefox_account_auto_signin_confirm">Ja, log mig ind</string> <string name="onboarding_firefox_account_auto_signin_confirm">Ja, log mig ind</string>
<!-- text for the automatic sign-in button while signing in is in process --> <!-- text for the automatic sign-in button while signing in is in process -->
@ -1129,6 +1153,8 @@
<string name="sign_in_with_camera">Log in med dit kamera</string> <string name="sign_in_with_camera">Log in med dit kamera</string>
<!-- Text shown for settings option for sign with email --> <!-- Text shown for settings option for sign with email -->
<string name="sign_in_with_email">Brug mail i stedet</string> <string name="sign_in_with_email">Brug mail i stedet</string>
<!-- Text shown for settings option for create new account text.'Firefox' intentionally hardcoded here.-->
<string name="sign_in_create_account_text"><![CDATA[Ingen konto? <u>Opret en</u> for at synkronisere Firefox mellem enheder.]]></string>
<!-- Text shown in confirmation dialog to sign out of account --> <!-- Text shown in confirmation dialog to sign out of account -->
<string name="sign_out_confirmation_message">Firefox vil ikke længere synkronisere med din konto, men sletter ikke dine browserdata på denne enhed.</string> <string name="sign_out_confirmation_message">Firefox vil ikke længere synkronisere med din konto, men sletter ikke dine browserdata på denne enhed.</string>
<!-- Text shown in confirmation dialog to sign out of account. The first parameter is the name of the app (e.g. Firefox Preview) --> <!-- Text shown in confirmation dialog to sign out of account. The first parameter is the name of the app (e.g. Firefox Preview) -->
@ -1236,6 +1262,12 @@
The first parameter is the app name --> The first parameter is the app name -->
<string name="open_source_licenses_title">%s | OSS-biblioteker</string> <string name="open_source_licenses_title">%s | OSS-biblioteker</string>
<!-- Category of trackers (redirect trackers) that can be blocked by Enhanced Tracking Protection -->
<string name="etp_redirect_trackers_title">Sporing via omdirigeringer</string>
<!-- Description of redirect tracker cookies that can be blocked by Enhanced Tracking Protection -->
<string name="etp_redirect_trackers_description">Rydder cookies, der sættes af omdirigeringer til websteder, der er kendt for at spore deres brugere.</string>
<!-- About page link text to open support link --> <!-- About page link text to open support link -->
<string name="about_support">Hjælp</string> <string name="about_support">Hjælp</string>
<!-- About page link text to list of past crashes (like about:crashes on desktop) --> <!-- About page link text to list of past crashes (like about:crashes on desktop) -->
@ -1280,6 +1312,9 @@
<!-- Placeholder text for the TextView in the Add to Homescreen dialog --> <!-- Placeholder text for the TextView in the Add to Homescreen dialog -->
<string name="add_to_homescreen_text_placeholder">Genvejsnavn</string> <string name="add_to_homescreen_text_placeholder">Genvejsnavn</string>
<!-- Describes the add to homescreen functionality -->
<string name="add_to_homescreen_description_2">Du kan nemt føje dette websted til din enheds startskærm for at have hurtig adgang til det og browse hurtigere med en app-lignende oplevelse.</string>
<!-- Preference for managing the settings for logins and passwords in Fenix --> <!-- Preference for managing the settings for logins and passwords in Fenix -->
<string name="preferences_passwords_logins_and_passwords">Logins og adgangskoder</string> <string name="preferences_passwords_logins_and_passwords">Logins og adgangskoder</string>
<!-- Preference for managing the saving of logins and passwords in Fenix --> <!-- Preference for managing the saving of logins and passwords in Fenix -->
@ -1348,8 +1383,12 @@
<string name="logins_site_copied">Websted er kopieret til udklipsholder</string> <string name="logins_site_copied">Websted er kopieret til udklipsholder</string>
<!-- Content Description (for screenreaders etc) read for the button to copy a password in logins--> <!-- Content Description (for screenreaders etc) read for the button to copy a password in logins-->
<string name="saved_logins_copy_password">Kopier adgangskode</string> <string name="saved_logins_copy_password">Kopier adgangskode</string>
<!-- Content Description (for screenreaders etc) read for the button to clear a password while editing a login-->
<string name="saved_logins_clear_password">Ryd adgangskode</string>
<!-- Content Description (for screenreaders etc) read for the button to copy a username in logins --> <!-- Content Description (for screenreaders etc) read for the button to copy a username in logins -->
<string name="saved_login_copy_username">Kopier brugernavn</string> <string name="saved_login_copy_username">Kopier brugernavn</string>
<!-- Content Description (for screenreaders etc) read for the button to clear a username while editing a login -->
<string name="saved_login_clear_username">Ryd brugernavn</string>
<!-- Content Description (for screenreaders etc) read for the button to copy a site in logins --> <!-- Content Description (for screenreaders etc) read for the button to copy a site in logins -->
<string name="saved_login_copy_site">Kopier websted</string> <string name="saved_login_copy_site">Kopier websted</string>
<!-- Content Description (for screenreaders etc) read for the button to open a site in logins --> <!-- Content Description (for screenreaders etc) read for the button to open a site in logins -->
@ -1523,6 +1562,8 @@
<!-- Top Sites --> <!-- Top Sites -->
<!-- Title text displayed in the dialog when top sites limit is reached. --> <!-- Title text displayed in the dialog when top sites limit is reached. -->
<string name="top_sites_max_limit_title">Grænsen for Mest besøgte websider er nået</string> <string name="top_sites_max_limit_title">Grænsen for Mest besøgte websider er nået</string>
<!-- Content description text displayed in the dialog when top sites limit is reached. -->
<string name="top_sites_max_limit_content_2">Fjern en webside for at erstatte den med en ny. Tryk og hold på websiden, og vælg så Fjern.</string>
<!-- Confirmation dialog button text when top sites limit is reached. --> <!-- Confirmation dialog button text when top sites limit is reached. -->
<string name="top_sites_max_limit_confirmation_button">Ok, forstået</string> <string name="top_sites_max_limit_confirmation_button">Ok, forstået</string>

@ -41,12 +41,19 @@
<!-- Content description for save to collection button while in multiselect mode in tab tray --> <!-- Content description for save to collection button while in multiselect mode in tab tray -->
<string name="tab_tray_collection_button_multiselect_content_description">Αποθήκευση επιλεγμένων καρτελών στη συλλογή</string> <string name="tab_tray_collection_button_multiselect_content_description">Αποθήκευση επιλεγμένων καρτελών στη συλλογή</string>
<!-- Content description for checkmark while tab is selected while in multiselect mode in tab tray. The first parameter is the title of the tab selected -->
<string name="tab_tray_item_selected_multiselect_content_description">Επιλέχθηκε το &quot;%1$s&quot;</string>
<!-- Content description when tab is unselected while in multiselect mode in tab tray. The first parameter is the title of the tab unselected -->
<string name="tab_tray_item_unselected_multiselect_content_description">Αποεπιλέχθηκε το &quot;%1$s&quot;</string>
<!-- Content description announcement when exiting multiselect mode in tab tray --> <!-- Content description announcement when exiting multiselect mode in tab tray -->
<string name="tab_tray_exit_multiselect_content_description">Τέλος λειτουργίας πολλαπλής επιλογής</string> <string name="tab_tray_exit_multiselect_content_description">Τέλος λειτουργίας πολλαπλής επιλογής</string>
<!-- Content description announcement when entering multiselect mode in tab tray --> <!-- Content description announcement when entering multiselect mode in tab tray -->
<string name="tab_tray_enter_multiselect_content_description">Σε λειτουργία πολλαπλών επιλογών, επιλέξτε καρτέλες για αποθήκευση σε συλλογή</string> <string name="tab_tray_enter_multiselect_content_description">Σε λειτουργία πολλαπλών επιλογών, επιλέξτε καρτέλες για αποθήκευση σε συλλογή</string>
<!-- Content description on checkmark while tab is selected in multiselect mode in tab tray -->
<string name="tab_tray_multiselect_selected_content_description">Επιλέχθηκε</string>
<!-- About content. The first parameter is the name of the application. (For example: Fenix) --> <!-- About content. The first parameter is the name of the application. (For example: Fenix) -->
<string name="about_content">Το %1$s αναπτύσσεται από τη @fork-maintainers.</string> <string name="about_content">Το %1$s αναπτύσσεται από τη @fork-maintainers.</string>

@ -813,7 +813,7 @@
<!-- Summary of tracking protection preference if tracking protection is set to on --> <!-- Summary of tracking protection preference if tracking protection is set to on -->
<string name="tracking_protection_on">Activado</string> <string name="tracking_protection_on">Activado</string>
<!-- Summary of tracking protection preference if tracking protection is set to off --> <!-- Summary of tracking protection preference if tracking protection is set to off -->
<string name="tracking_protection_off">Desactivado</string> <string name="tracking_protection_off">Desactivada</string>
<!-- Label that indicates that all video and audio autoplay is allowed --> <!-- Label that indicates that all video and audio autoplay is allowed -->
<string name="preference_option_autoplay_allowed2">Permitir audio y video</string> <string name="preference_option_autoplay_allowed2">Permitir audio y video</string>
@ -828,7 +828,7 @@
<!-- Summary of delete browsing data on quit preference if it is set to on --> <!-- Summary of delete browsing data on quit preference if it is set to on -->
<string name="delete_browsing_data_quit_on">Activado</string> <string name="delete_browsing_data_quit_on">Activado</string>
<!-- Summary of delete browsing data on quit preference if it is set to off --> <!-- Summary of delete browsing data on quit preference if it is set to off -->
<string name="delete_browsing_data_quit_off">Desactivado</string> <string name="delete_browsing_data_quit_off">Desactivada</string>
<!-- Collections --> <!-- Collections -->
<!-- Collections header on home fragment --> <!-- Collections header on home fragment -->
@ -1220,7 +1220,7 @@
<!-- Accessibility text for the Strict protection information icon --> <!-- Accessibility text for the Strict protection information icon -->
<string name="preference_enhanced_tracking_protection_strict_info_button">Qué es lo que está bloqueado por la protección de rastreo estricta</string> <string name="preference_enhanced_tracking_protection_strict_info_button">Qué es lo que está bloqueado por la protección de rastreo estricta</string>
<!-- Preference for enhanced tracking protection for the custom protection settings --> <!-- Preference for enhanced tracking protection for the custom protection settings -->
<string name="preference_enhanced_tracking_protection_custom">Personalizado</string> <string name="preference_enhanced_tracking_protection_custom">Personalizada</string>
<!-- Preference description for enhanced tracking protection for the strict protection settings --> <!-- Preference description for enhanced tracking protection for the strict protection settings -->
<string name="preference_enhanced_tracking_protection_custom_description_2">Elegí qué rastreadores y secuencias de comandos querés bloquear.</string> <string name="preference_enhanced_tracking_protection_custom_description_2">Elegí qué rastreadores y secuencias de comandos querés bloquear.</string>
<!-- Accessibility text for the Strict protection information icon --> <!-- Accessibility text for the Strict protection information icon -->

@ -72,6 +72,8 @@
<!-- Text for the negative action button --> <!-- Text for the negative action button -->
<string name="open_in_app_cfr_negative_button_text">Descartar</string> <string name="open_in_app_cfr_negative_button_text">Descartar</string>
<!-- Text for the info dialog when camera permissions have been denied but user tries to access a camera feature. -->
<string name="camera_permissions_needed_message">Se necesita acceso a la cámara. Ve a los ajustes de Android, toca en permisos y luego en permitir.</string>
<!-- Text for the positive action button to go to Android Settings to grant permissions. --> <!-- Text for the positive action button to go to Android Settings to grant permissions. -->
<string name="camera_permissions_needed_positive_button_text">Ir a ajustes</string> <string name="camera_permissions_needed_positive_button_text">Ir a ajustes</string>
<!-- Text for the negative action button to dismiss the dialog. --> <!-- Text for the negative action button to dismiss the dialog. -->
@ -255,6 +257,8 @@
<string name="preferences_open_links_in_a_private_tab">Abrir enlaces en una pestaña privada</string> <string name="preferences_open_links_in_a_private_tab">Abrir enlaces en una pestaña privada</string>
<!-- Preference for allowing screenshots to be taken while in a private tab--> <!-- Preference for allowing screenshots to be taken while in a private tab-->
<string name="preferences_allow_screenshots_in_private_mode">Permitir capturas de pantalla en navegación privada</string> <string name="preferences_allow_screenshots_in_private_mode">Permitir capturas de pantalla en navegación privada</string>
<!-- Will inform the user of the risk of activating Allow screenshots in private browsing option -->
<string name="preferences_screenshots_in_private_mode_disclaimer">Si está permitido, las pestañas privadas también serán visibles cuando hayan varias aplicaciones abiertas</string>
<!-- Preference for adding private browsing shortcut --> <!-- Preference for adding private browsing shortcut -->
<string name="preferences_add_private_browsing_shortcut">Agregar acceso directo a la navegación privada</string> <string name="preferences_add_private_browsing_shortcut">Agregar acceso directo a la navegación privada</string>
<!-- Preference for accessibility --> <!-- Preference for accessibility -->
@ -545,6 +549,8 @@
<string name="tab_tray_menu_item_share">Compartir todas las pestañas</string> <string name="tab_tray_menu_item_share">Compartir todas las pestañas</string>
<!-- Text shown in the menu to view recently closed tabs --> <!-- Text shown in the menu to view recently closed tabs -->
<string name="tab_tray_menu_recently_closed">Pestañas cerradas recientemente</string> <string name="tab_tray_menu_recently_closed">Pestañas cerradas recientemente</string>
<!-- Text shown in the menu to view tab settings -->
<string name="tab_tray_menu_tab_settings">Ajustes de pestañas</string>
<!-- Text shown in the menu for closing all tabs --> <!-- Text shown in the menu for closing all tabs -->
<string name="tab_tray_menu_item_close">Cerrar todas las pestañas</string> <string name="tab_tray_menu_item_close">Cerrar todas las pestañas</string>
<!-- Shortcut action to open new tab --> <!-- Shortcut action to open new tab -->
@ -1562,6 +1568,8 @@
<!-- Top Sites --> <!-- Top Sites -->
<!-- Title text displayed in the dialog when top sites limit is reached. --> <!-- Title text displayed in the dialog when top sites limit is reached. -->
<string name="top_sites_max_limit_title">Límite de sitios frecuentes alcanzado</string> <string name="top_sites_max_limit_title">Límite de sitios frecuentes alcanzado</string>
<!-- Content description text displayed in the dialog when top sites limit is reached. -->
<string name="top_sites_max_limit_content_2">Para añadir un nuevo sitio frecuente, elimina uno. Toca y mantén presionado el sitio y selecciona eliminar.</string>
<!-- Confirmation dialog button text when top sites limit is reached. --> <!-- Confirmation dialog button text when top sites limit is reached. -->
<string name="top_sites_max_limit_confirmation_button">Vale, entendido</string> <string name="top_sites_max_limit_confirmation_button">Vale, entendido</string>

@ -481,11 +481,11 @@
<!-- Preferences for using pull to refresh in a webpage --> <!-- Preferences for using pull to refresh in a webpage -->
<string name="preference_gestures_website_pull_to_refresh">Trek om te vernieuwen</string> <string name="preference_gestures_website_pull_to_refresh">Trek om te vernieuwen</string>
<!-- Preference for using the dynamic toolbar --> <!-- Preference for using the dynamic toolbar -->
<string name="preference_gestures_dynamic_toolbar">Scroll om de werkbalk te verbergen</string> <string name="preference_gestures_dynamic_toolbar">Scrollen om de werkbalk te verbergen</string>
<!-- Preference for switching tabs by swiping horizontally on the toolbar --> <!-- Preference for switching tabs by swiping horizontally on the toolbar -->
<string name="preference_gestures_swipe_toolbar_switch_tabs">Veeg de werkbalk opzij om van tabblad te wisselen</string> <string name="preference_gestures_swipe_toolbar_switch_tabs">De werkbalk opzij vegen om van tabblad te wisselen</string>
<!-- Preference for showing the opened tabs by swiping up on the toolbar--> <!-- Preference for showing the opened tabs by swiping up on the toolbar-->
<string name="preference_gestures_swipe_toolbar_show_tabs">Veeg de werkbalk omhoog om tabbladen te openen</string> <string name="preference_gestures_swipe_toolbar_show_tabs">De werkbalk omhoog vegen om tabbladen te openen</string>
<!-- Library --> <!-- Library -->
<!-- Option in Library to open Sessions page --> <!-- Option in Library to open Sessions page -->

@ -1287,6 +1287,11 @@
The first parameter is the app name --> The first parameter is the app name -->
<string name="open_source_licenses_title">%s | OSS-bibliotek</string> <string name="open_source_licenses_title">%s | OSS-bibliotek</string>
<!-- Category of trackers (redirect trackers) that can be blocked by Enhanced Tracking Protection -->
<string name="etp_redirect_trackers_title">Omdirigeringssporarar</string>
<!-- Description of redirect tracker cookies that can be blocked by Enhanced Tracking Protection -->
<string name="etp_redirect_trackers_description">Fjernar infokapslar stilte inn av omdirigeringar til kjende sporingsnettstadar.</string>
<!-- About page link text to open support link --> <!-- About page link text to open support link -->
<string name="about_support">Brukarstøtte</string> <string name="about_support">Brukarstøtte</string>
<!-- About page link text to list of past crashes (like about:crashes on desktop) --> <!-- About page link text to list of past crashes (like about:crashes on desktop) -->

@ -77,6 +77,9 @@
<!-- Text for the negative button --> <!-- Text for the negative button -->
<string name="search_widget_cfr_neg_button_text">Pas ara</string> <string name="search_widget_cfr_neg_button_text">Pas ara</string>
<!-- Open in App "contextual feature recommendation" (CFR) -->
<!-- Text for the info message. 'Firefox' intentionally hardcoded here.-->
<string name="open_in_app_cfr_info_message">Podètz configurar Firefox per dobrir automaticament los ligams dins las aplicacions.</string>
<!-- Text for the positive action button --> <!-- Text for the positive action button -->
<string name="open_in_app_cfr_positive_button_text">Anar als paramètres</string> <string name="open_in_app_cfr_positive_button_text">Anar als paramètres</string>
<!-- Text for the negative action button --> <!-- Text for the negative action button -->
@ -321,6 +324,8 @@
<string name="preferences_search_browsing_history">Recercar dins listoric de navegacion</string> <string name="preferences_search_browsing_history">Recercar dins listoric de navegacion</string>
<!-- Preference title for switch preference to suggest bookmarks when searching --> <!-- Preference title for switch preference to suggest bookmarks when searching -->
<string name="preferences_search_bookmarks">Cercar dins los marcapaginas</string> <string name="preferences_search_bookmarks">Cercar dins los marcapaginas</string>
<!-- Preference title for switch preference to suggest synced tabs when searching -->
<string name="preferences_search_synced_tabs">Cercar dins los onglets sincronizats</string>
<!-- Preference for account settings --> <!-- Preference for account settings -->
<string name="preferences_account_settings">Paramètres del compte</string> <string name="preferences_account_settings">Paramètres del compte</string>
<!-- Preference for enabling url autocomplete--> <!-- Preference for enabling url autocomplete-->
@ -470,6 +475,11 @@
<!-- Preference for using the dynamic toolbar --> <!-- Preference for using the dynamic toolbar -->
<string name="preference_gestures_dynamic_toolbar">Desfilar per amagar la barra daisinas</string> <string name="preference_gestures_dynamic_toolbar">Desfilar per amagar la barra daisinas</string>
<!-- Preference for switching tabs by swiping horizontally on the toolbar -->
<string name="preference_gestures_swipe_toolbar_switch_tabs">Cambiar donglet en lisant la barra daisinas cap las costats</string>
<!-- Preference for showing the opened tabs by swiping up on the toolbar-->
<string name="preference_gestures_swipe_toolbar_show_tabs">Dobrir los ligams en lisant la barra daisina amont</string>
<!-- Library --> <!-- Library -->
<!-- Option in Library to open Sessions page --> <!-- Option in Library to open Sessions page -->
<string name="library_sessions">Sessions</string> <string name="library_sessions">Sessions</string>
@ -811,6 +821,8 @@
<string name="collections_header">Colleccions</string> <string name="collections_header">Colleccions</string>
<!-- Content description (not visible, for screen readers etc.): Opens the collection menu when pressed --> <!-- Content description (not visible, for screen readers etc.): Opens the collection menu when pressed -->
<string name="collection_menu_button_content_description">Menú de colleccion</string> <string name="collection_menu_button_content_description">Menú de colleccion</string>
<!-- Label to describe what collections are to a new user without any collections -->
<string name="no_collections_description2">Amassatz çò important per vos\nGropatz las recèrcas, los sites e onglets similars per i tornar mai tard.</string>
<!-- Title for the "select tabs" step of the collection creator --> <!-- Title for the "select tabs" step of the collection creator -->
<string name="create_collection_select_tabs">Seleccionar donglets</string> <string name="create_collection_select_tabs">Seleccionar donglets</string>
<!-- Title for the "select collection" step of the collection creator --> <!-- Title for the "select collection" step of the collection creator -->
@ -940,6 +952,8 @@
<string name="qr_scanner_dialog_negative">REFUSAR</string> <string name="qr_scanner_dialog_negative">REFUSAR</string>
<!-- Tab collection deletion prompt dialog message. Placeholder will be replaced with the collection name --> <!-- Tab collection deletion prompt dialog message. Placeholder will be replaced with the collection name -->
<string name="tab_collection_dialog_message">Volètz vertadièrament suprimir %1$s ?</string> <string name="tab_collection_dialog_message">Volètz vertadièrament suprimir %1$s ?</string>
<!-- Collection and tab deletion prompt dialog message. This will show when the last tab from a collection is deleted -->
<string name="delete_tab_and_collection_dialog_message">La supression daqueste onglet suprimirà tota la collecion. Podètz crear colleccions novèlas quand volgatz.</string>
<!-- Collection and tab deletion prompt dialog title. Placeholder will be replaced with the collection name. This will show when the last tab from a collection is deleted --> <!-- Collection and tab deletion prompt dialog title. Placeholder will be replaced with the collection name. This will show when the last tab from a collection is deleted -->
<string name="delete_tab_and_collection_dialog_title">Suprimir %1$s ?</string> <string name="delete_tab_and_collection_dialog_title">Suprimir %1$s ?</string>
<!-- Tab collection deletion prompt dialog option to delete the collection --> <!-- Tab collection deletion prompt dialog option to delete the collection -->
@ -992,6 +1006,8 @@
<string name="preferences_delete_browsing_data_on_quit">Suprimir las donadas de navegacion en quitant</string> <string name="preferences_delete_browsing_data_on_quit">Suprimir las donadas de navegacion en quitant</string>
<!-- Summary for the Delete browsing data on quit preference. "Quit" translation should match delete_browsing_data_on_quit_action translation. --> <!-- Summary for the Delete browsing data on quit preference. "Quit" translation should match delete_browsing_data_on_quit_action translation. -->
<string name="preference_summary_delete_browsing_data_on_quit">Suprimís automaticament las donadas de navegacion quand seleccionatz «Quitar» al menú principal</string> <string name="preference_summary_delete_browsing_data_on_quit">Suprimís automaticament las donadas de navegacion quand seleccionatz «Quitar» al menú principal</string>
<!-- Summary for the Delete browsing data on quit preference. "Quit" translation should match delete_browsing_data_on_quit_action translation. -->
<string name="preference_summary_delete_browsing_data_on_quit_2">Suprimís automaticament las donadas de navegacion quand seleccionatz «Quitar» al menú principal</string>
<!-- Action item in menu for the Delete browsing data on quit feature --> <!-- Action item in menu for the Delete browsing data on quit feature -->
<string name="delete_browsing_data_on_quit_action">Sortir</string> <string name="delete_browsing_data_on_quit_action">Sortir</string>

@ -1272,6 +1272,12 @@
The first parameter is the app name --> The first parameter is the app name -->
<string name="open_source_licenses_title">%s | Bibliotecas open source</string> <string name="open_source_licenses_title">%s | Bibliotecas open source</string>
<!-- Category of trackers (redirect trackers) that can be blocked by Enhanced Tracking Protection -->
<string name="etp_redirect_trackers_title">Fastizaders da renviament</string>
<!-- Description of redirect tracker cookies that can be blocked by Enhanced Tracking Protection -->
<string name="etp_redirect_trackers_description">Stizza cookies definids cun agid da renviaments a websites enconuschentas per fastizar.</string>
<!-- About page link text to open support link --> <!-- About page link text to open support link -->
<string name="about_support">Agid</string> <string name="about_support">Agid</string>
<!-- About page link text to list of past crashes (like about:crashes on desktop) --> <!-- About page link text to list of past crashes (like about:crashes on desktop) -->
@ -1317,6 +1323,9 @@
<!-- Placeholder text for the TextView in the Add to Homescreen dialog --> <!-- Placeholder text for the TextView in the Add to Homescreen dialog -->
<string name="add_to_homescreen_text_placeholder">Num da la scursanida</string> <string name="add_to_homescreen_text_placeholder">Num da la scursanida</string>
<!-- Describes the add to homescreen functionality -->
<string name="add_to_homescreen_description_2">Ti pos agiuntar a moda simpla questa website al visur da partenza da tes apparat per avair access direct e navigar pli svelt, sco sch\'i fiss ina app.</string>
<!-- Preference for managing the settings for logins and passwords in Fenix --> <!-- Preference for managing the settings for logins and passwords in Fenix -->
<string name="preferences_passwords_logins_and_passwords">Infurmaziuns d\'annunzia e pleds-clav</string> <string name="preferences_passwords_logins_and_passwords">Infurmaziuns d\'annunzia e pleds-clav</string>
<!-- Preference for managing the saving of logins and passwords in Fenix --> <!-- Preference for managing the saving of logins and passwords in Fenix -->
@ -1387,8 +1396,12 @@
<string name="logins_site_copied">Copià la pagina en l\'archiv provisoric</string> <string name="logins_site_copied">Copià la pagina en l\'archiv provisoric</string>
<!-- Content Description (for screenreaders etc) read for the button to copy a password in logins--> <!-- Content Description (for screenreaders etc) read for the button to copy a password in logins-->
<string name="saved_logins_copy_password">Copiar il pled-clav</string> <string name="saved_logins_copy_password">Copiar il pled-clav</string>
<!-- Content Description (for screenreaders etc) read for the button to clear a password while editing a login-->
<string name="saved_logins_clear_password">Stizzar il pled-clav</string>
<!-- Content Description (for screenreaders etc) read for the button to copy a username in logins --> <!-- Content Description (for screenreaders etc) read for the button to copy a username in logins -->
<string name="saved_login_copy_username">Copiar il num d\'utilisader</string> <string name="saved_login_copy_username">Copiar il num d\'utilisader</string>
<!-- Content Description (for screenreaders etc) read for the button to clear a username while editing a login -->
<string name="saved_login_clear_username">Stizzar il num d\'utilisader</string>
<!-- Content Description (for screenreaders etc) read for the button to copy a site in logins --> <!-- Content Description (for screenreaders etc) read for the button to copy a site in logins -->
<string name="saved_login_copy_site">Copiar la pagina</string> <string name="saved_login_copy_site">Copiar la pagina</string>
<!-- Content Description (for screenreaders etc) read for the button to open a site in logins --> <!-- Content Description (for screenreaders etc) read for the button to open a site in logins -->
@ -1565,6 +1578,8 @@
<!-- Top Sites --> <!-- Top Sites -->
<!-- Title text displayed in the dialog when top sites limit is reached. --> <!-- Title text displayed in the dialog when top sites limit is reached. -->
<string name="top_sites_max_limit_title">Cuntanschì la limita da paginas preferidas</string> <string name="top_sites_max_limit_title">Cuntanschì la limita da paginas preferidas</string>
<!-- Content description text displayed in the dialog when top sites limit is reached. -->
<string name="top_sites_max_limit_content_2">Per pudair agiuntar ina nova pagina preferida stos ti l\'emprim allontanar in\'autra. Tegna smatgà la pagina e tscherna «Allontanar».</string>
<!-- Confirmation dialog button text when top sites limit is reached. --> <!-- Confirmation dialog button text when top sites limit is reached. -->
<string name="top_sites_max_limit_confirmation_button">OK, chapì</string> <string name="top_sites_max_limit_confirmation_button">OK, chapì</string>

@ -246,8 +246,14 @@
<string name="preferences_private_browsing_options">Баррасии махфӣ</string> <string name="preferences_private_browsing_options">Баррасии махфӣ</string>
<!-- Preference for opening links in a private tab--> <!-- Preference for opening links in a private tab-->
<string name="preferences_open_links_in_a_private_tab">Кушодани пайвандҳо дар варақаи махфӣ</string> <string name="preferences_open_links_in_a_private_tab">Кушодани пайвандҳо дар варақаи махфӣ</string>
<!-- Preference for adding private browsing shortcut -->
<string name="preferences_add_private_browsing_shortcut">Илова кардани миёнбури тамошои махфӣ</string>
<!-- Preference for accessibility --> <!-- Preference for accessibility -->
<string name="preferences_accessibility">Қобилияти дастрасӣ</string> <string name="preferences_accessibility">Қобилияти дастрасӣ</string>
<!-- Preference to override the Firefox Account server -->
<string name="preferences_override_fxa_server">Сервери ҳисоби фармоишии Firefox</string>
<!-- Preference to override the Sync token server -->
<string name="preferences_override_sync_tokenserver">Сервери ҳамоҳангсозии фармоишӣ</string>
<!-- Preference category for account information --> <!-- Preference category for account information -->
<string name="preferences_category_account">Ҳисоб</string> <string name="preferences_category_account">Ҳисоб</string>
<!-- Preference shown on banner to sign into account --> <!-- Preference shown on banner to sign into account -->
@ -276,6 +282,8 @@
<string name="preferences_privacy_link">Огоҳиномаи махфият</string> <string name="preferences_privacy_link">Огоҳиномаи махфият</string>
<!-- Preference category for developer tools --> <!-- Preference category for developer tools -->
<string name="developer_tools_category">Абзорҳои барномасозӣ</string> <string name="developer_tools_category">Абзорҳои барномасозӣ</string>
<!-- Preference for developers -->
<string name="preferences_remote_debugging">Ислоҳкунии дурдасти хатоҳо тавассути USB</string>
<!-- Preference title for switch preference to show search engines --> <!-- Preference title for switch preference to show search engines -->
<string name="preferences_show_search_engines">Намоиш додани низомҳои ҷустуҷӯӣ</string> <string name="preferences_show_search_engines">Намоиш додани низомҳои ҷустуҷӯӣ</string>
<!-- Preference title for switch preference to show search suggestions --> <!-- Preference title for switch preference to show search suggestions -->
@ -696,6 +704,8 @@
<!-- Preference for altering the notification access for all websites --> <!-- Preference for altering the notification access for all websites -->
<string name="preference_phone_feature_notification">Огоҳинома</string> <string name="preference_phone_feature_notification">Огоҳинома</string>
<!-- Label that indicates that a permission must be asked always -->
<string name="preference_option_phone_feature_ask_to_allow">Дархости иҷозат</string>
<!-- Label that indicates that a permission must be blocked --> <!-- Label that indicates that a permission must be blocked -->
<string name="preference_option_phone_feature_blocked">Бояд манъ карда шавад</string> <string name="preference_option_phone_feature_blocked">Бояд манъ карда шавад</string>
<!-- Label that indicates that a permission must be allowed --> <!-- Label that indicates that a permission must be allowed -->
@ -721,6 +731,30 @@
<string name="collections_header">Маҷмӯаҳо</string> <string name="collections_header">Маҷмӯаҳо</string>
<!-- Content description (not visible, for screen readers etc.): Opens the collection menu when pressed --> <!-- Content description (not visible, for screen readers etc.): Opens the collection menu when pressed -->
<string name="collection_menu_button_content_description">Менюи маҷмӯаҳо</string> <string name="collection_menu_button_content_description">Менюи маҷмӯаҳо</string>
<!-- Title for the "select tabs" step of the collection creator -->
<string name="create_collection_select_tabs">Варақаҳоро интихоб намоед</string>
<!-- Title for the "select collection" step of the collection creator -->
<string name="create_collection_select_collection">Интихоб кардани маҷмӯа</string>
<!-- Title for the "name collection" step of the collection creator -->
<string name="create_collection_name_collection">Номи маҷмӯа</string>
<!-- Button to add new collection for the "select collection" step of the collection creator -->
<string name="create_collection_add_new_collection">Илова кардани маҷмӯаи нав</string>
<!-- Button to select all tabs in the "select tabs" step of the collection creator -->
<string name="create_collection_select_all">Ҳамаро интихоб кардан</string>
<!-- Text to prompt users to select the tabs to save in the "select tabs" step of the collection creator -->
<string name="create_collection_save_to_collection_empty">Варақаҳоро барои нигоҳ доштан интихоб намоед</string>
<!-- Text to show users how many tabs they have selected in the "select tabs" step of the collection creator.
%d is a placeholder for the number of tabs selected. -->
<string name="create_collection_save_to_collection_tabs_selected">%d варақа интихоб карда шуд</string>
<!-- Text to show users they have one tab selected in the "select tabs" step of the collection creator.
%d is a placeholder for the number of tabs selected. -->
<string name="create_collection_save_to_collection_tab_selected">%d варақа интихоб карда шуд</string>
<!-- Text shown in snackbar when multiple tabs have been saved in a collection -->
<string name="create_collection_tabs_saved">Варақаҳо нигоҳ дошта шудад!</string>
<!-- Text shown in snackbar when one or multiple tabs have been saved in a new collection -->
<string name="create_collection_tabs_saved_new_collection">Маҷмӯа нигоҳ дошта шуд!</string>
<!-- Text shown in snackbar when one tab has been saved in a collection -->
<string name="create_collection_tab_saved">Варақа нигоҳ дошта шуд!</string>
<!-- Content description (not visible, for screen readers etc.): button to close the collection creator --> <!-- Content description (not visible, for screen readers etc.): button to close the collection creator -->
<string name="create_collection_close">Пӯшидан</string> <string name="create_collection_close">Пӯшидан</string>
<!-- Button to save currently selected tabs in the "select tabs" step of the collection creator--> <!-- Button to save currently selected tabs in the "select tabs" step of the collection creator-->
@ -753,9 +787,16 @@
<string name="sync_reconnect">Барои ҳамоҳангсозӣ аз нав пайваст шавед</string> <string name="sync_reconnect">Барои ҳамоҳангсозӣ аз нав пайваст шавед</string>
<!-- Text displayed when sync is offline and cannot be accessed --> <!-- Text displayed when sync is offline and cannot be accessed -->
<string name="sync_offline">Офлайн</string> <string name="sync_offline">Офлайн</string>
<!-- An option to connect additional devices -->
<string name="sync_connect_device">Пайваст кардани дастгоҳи дигар</string>
<!-- Confirmation dialog button --> <!-- Confirmation dialog button -->
<string name="sync_confirmation_button">Фаҳмо</string> <string name="sync_confirmation_button">Фаҳмо</string>
<!-- Add new device screen title -->
<string name="sync_add_new_device_title">Фиристодан ба дастгоҳ</string>
<!-- Text for the warning message on the Add new device screen -->
<string name="sync_add_new_device_message">Ягон дастгоҳ пайваст нашуд</string>
<!-- Notifications --> <!-- Notifications -->
<!-- The user visible name of the "notification channel" (Android 8+ feature) for the ongoing notification shown while a browsing session is active. --> <!-- The user visible name of the "notification channel" (Android 8+ feature) for the ongoing notification shown while a browsing session is active. -->
<string name="notification_pbm_channel_name">Ҷаласаи баррасии махфӣ</string> <string name="notification_pbm_channel_name">Ҷаласаи баррасии махфӣ</string>
@ -835,6 +876,9 @@
<!-- Title for the Delete browsing data on quit preference --> <!-- Title for the Delete browsing data on quit preference -->
<string name="preferences_delete_browsing_data_on_quit">Нест кардани маълумоти баррасӣ ҳангоми баромад</string> <string name="preferences_delete_browsing_data_on_quit">Нест кардани маълумоти баррасӣ ҳангоми баромад</string>
<!-- Action item in menu for the Delete browsing data on quit feature -->
<string name="delete_browsing_data_on_quit_action">Баромадан</string>
<!-- Text for the cancel button for the data deletion dialog --> <!-- Text for the cancel button for the data deletion dialog -->
<string name="delete_browsing_data_prompt_cancel">Бекор кардан</string> <string name="delete_browsing_data_prompt_cancel">Бекор кардан</string>
<!-- Text for the allow button for the data deletion dialog --> <!-- Text for the allow button for the data deletion dialog -->
@ -844,14 +888,29 @@
<!-- Text for onboarding welcome message <!-- Text for onboarding welcome message
The first parameter is the name of the app (e.g. Firefox Preview) --> The first parameter is the name of the app (e.g. Firefox Preview) -->
<string name="onboarding_header">Хуш омадед ба %s!</string> <string name="onboarding_header">Хуш омадед ба %s!</string>
<!-- text for the Firefox Preview feature section header
The first parameter is the name of the app (e.g. Firefox Preview) -->
<string name="onboarding_feature_section_header">Бо %s шинос шавед</string>
<!-- text for the "What's New" onboarding card header -->
<string name="onboarding_whats_new_header1">Бинед, ки чӣ нав аст</string>
<!-- Text for the button to learn more about signing in to your Firefox account --> <!-- Text for the button to learn more about signing in to your Firefox account -->
<string name="onboarding_manual_sign_in_learn_more">Маълумоти бештар</string> <string name="onboarding_manual_sign_in_learn_more">Маълумоти бештар</string>
<!-- text for the button to confirm automatic sign-in -->
<string name="onboarding_firefox_account_auto_signin_confirm">Ҳа, маро ворид кунед</string>
<!-- text for the automatic sign-in button while signing in is in process -->
<string name="onboarding_firefox_account_signing_in">Ворид шуда истодааст…</string>
<!-- text for the button to manually sign into Firefox account. The word "Firefox" should not be translated -->
<string name="onboarding_firefox_account_sign_in">Ба Firefox ворид шавед</string>
<!-- text to display in the snackbar once account is signed-in --> <!-- text to display in the snackbar once account is signed-in -->
<string name="onboarding_firefox_account_sync_is_on">Ҳамоҳангсозӣ фаъол аст</string> <string name="onboarding_firefox_account_sync_is_on">Ҳамоҳангсозӣ фаъол аст</string>
<!-- text to display in the snackbar if automatic sign-in fails. user may try again --> <!-- text to display in the snackbar if automatic sign-in fails. user may try again -->
<string name="onboarding_firefox_account_automatic_signin_failed">Воридшавӣ иҷро нашуд</string> <string name="onboarding_firefox_account_automatic_signin_failed">Воридшавӣ иҷро нашуд</string>
<!-- text for the tracking protection onboarding card header --> <!-- text for the tracking protection onboarding card header -->
<string name="onboarding_tracking_protection_header_2">Махфияти худкор</string> <string name="onboarding_tracking_protection_header_2">Махфияти худкор</string>
<!-- text for tracking protection radio button option for standard level of blocking -->
<string name="onboarding_tracking_protection_standard_button_2">Стандартӣ (пешфарз)</string>
<!-- text for the private browsing onboarding card header -->
<string name="onboarding_private_browsing_header">Реҷаи тамошои махфӣ</string>
<!-- text for the private browsing onbording card button, that launches settings --> <!-- text for the private browsing onbording card button, that launches settings -->
<string name="onboarding_private_browsing_button">Кушодани танзимот</string> <string name="onboarding_private_browsing_button">Кушодани танзимот</string>
<!-- text for the privacy notice onboarding card header --> <!-- text for the privacy notice onboarding card header -->
@ -884,6 +943,8 @@
<string name="sync_sent_tab_error_snackbar">Ирсол ғайриимкон аст</string> <string name="sync_sent_tab_error_snackbar">Ирсол ғайриимкон аст</string>
<!-- Text shown in snackbar for the "retry" action that the user has after sharing tabs failed --> <!-- Text shown in snackbar for the "retry" action that the user has after sharing tabs failed -->
<string name="sync_sent_tab_error_snackbar_action">АЗ НАВ КӮШИШ КАРДАН</string> <string name="sync_sent_tab_error_snackbar_action">АЗ НАВ КӮШИШ КАРДАН</string>
<!-- Text shown for settings option for sign with pairing -->
<string name="sign_in_with_camera">Ворид шудан ба воситаи камера</string>
<!-- Option to continue signing out of account shown in confirmation dialog to sign out of account --> <!-- Option to continue signing out of account shown in confirmation dialog to sign out of account -->
<string name="sign_out_disconnect">Қатъ кардани пайваст</string> <string name="sign_out_disconnect">Қатъ кардани пайваст</string>
<!-- Option to cancel signing out shown in confirmation dialog to sign out of account --> <!-- Option to cancel signing out shown in confirmation dialog to sign out of account -->
@ -926,6 +987,10 @@
<string name="etp_fingerprinters_title">Хонандаи изи ангушт</string> <string name="etp_fingerprinters_title">Хонандаи изи ангушт</string>
<!-- Category of trackers (tracking content) that can be blocked by Enhanced Tracking Protection --> <!-- Category of trackers (tracking content) that can be blocked by Enhanced Tracking Protection -->
<string name="etp_tracking_content_title">Муҳтавои пайгирикунанда</string> <string name="etp_tracking_content_title">Муҳтавои пайгирикунанда</string>
<!-- Enhanced Tracking Protection message that protection is currently on for this site -->
<string name="etp_panel_on">Муҳофизат барои ин сомона фаъол аст</string>
<!-- Enhanced Tracking Protection message that protection is currently off for this site -->
<string name="etp_panel_off">Муҳофизат барои ин сомона ғайрифаъол аст</string>
<!-- About page Your rights link text --> <!-- About page Your rights link text -->
<string name="about_your_rights">Ҳуқуқҳои шумо</string> <string name="about_your_rights">Ҳуқуқҳои шумо</string>
<!-- About page link text to open open source licenses screen --> <!-- About page link text to open open source licenses screen -->
@ -1054,6 +1119,9 @@
<!-- Saved logins sorting strategy menu item -by name- (if selected, it will sort saved logins alphabetically) --> <!-- Saved logins sorting strategy menu item -by name- (if selected, it will sort saved logins alphabetically) -->
<string name="saved_logins_sort_strategy_alphabetically">Ном (А-Я)</string> <string name="saved_logins_sort_strategy_alphabetically">Ном (А-Я)</string>
<!-- Saved logins sorting strategy menu item -by last used- (if selected, it will sort saved logins by last used) -->
<string name="saved_logins_sort_strategy_last_used">Истифодашудаи охирин</string>
<!-- Title of the Add search engine screen --> <!-- Title of the Add search engine screen -->
<string name="search_engine_add_custom_search_engine_title">Илова кардани низоми ҷустуҷӯӣ</string> <string name="search_engine_add_custom_search_engine_title">Илова кардани низоми ҷустуҷӯӣ</string>
<!-- Title of the Edit search engine screen --> <!-- Title of the Edit search engine screen -->
@ -1076,6 +1144,8 @@
<!-- Accessibility description for the 'Learn more' link --> <!-- Accessibility description for the 'Learn more' link -->
<string name="search_add_custom_engine_learn_more_description">Пайванди «Маълумоти бештар»</string> <string name="search_add_custom_engine_learn_more_description">Пайванди «Маълумоти бештар»</string>
<!-- Text shown when a user leaves the search string field empty -->
<string name="search_add_custom_engine_error_empty_search_string">Сатри ҷустуҷӯро ворид кунед</string>
<!-- Text shown when a user creates a new search engine --> <!-- Text shown when a user creates a new search engine -->
<string name="search_add_custom_engine_success_message">%s эҷод карда шуд</string> <string name="search_add_custom_engine_success_message">%s эҷод карда шуд</string>
<!-- Text shown when a user successfully edits a custom search engine --> <!-- Text shown when a user successfully edits a custom search engine -->
@ -1083,6 +1153,8 @@
<!-- Text shown when a user successfully deletes a custom search engine --> <!-- Text shown when a user successfully deletes a custom search engine -->
<string name="search_delete_search_engine_success_message">%s нест карда шуд</string> <string name="search_delete_search_engine_success_message">%s нест карда шуд</string>
<!-- Text on the disabled button while in progress. Placeholder replaced with app name -->
<string name="migration_updating_app_button_text">%s нав шуда истодааст...</string>
<!-- Text on the enabled button. Placeholder replaced with app name--> <!-- Text on the enabled button. Placeholder replaced with app name-->
<string name="migration_update_app_button">Оғоз кардани %s</string> <string name="migration_update_app_button">Оғоз кардани %s</string>
<!-- Accessibility description text for a completed migration item --> <!-- Accessibility description text for a completed migration item -->
@ -1103,10 +1175,21 @@
<string name="quick_settings_sheet_secure_connection">Пайвасти боэътимод</string> <string name="quick_settings_sheet_secure_connection">Пайвасти боэътимод</string>
<!-- Label that indicates a site is using a insecure connection --> <!-- Label that indicates a site is using a insecure connection -->
<string name="quick_settings_sheet_insecure_connection">Пайвасти беэътимод</string> <string name="quick_settings_sheet_insecure_connection">Пайвасти беэътимод</string>
<!-- Confirmation message for a dialog confirming if the user wants to delete all the permissions for all sites-->
<string name="confirm_clear_permissions_on_all_sites">Шумо мутмаин ҳастед, ки мехоҳед ҳамаи иҷозатҳоро дар ҳамаи сомонаҳо тоза намоед?</string>
<!-- Confirmation message for a dialog confirming if the user wants to delete all the permissions for a site-->
<string name="confirm_clear_permissions_site">Шумо мутмаин ҳастед, ки мехоҳед ҳамаи иҷозатҳоро барои сомонаи ҷорӣ тоза намоед?</string>
<!-- Confirmation message for a dialog confirming if the user wants to set default value a permission for a site-->
<string name="confirm_clear_permission_site">Шумо мутмаин ҳастед, ки мехоҳед ин иҷозатҳоро барои сомонаи ҷорӣ тоза намоед?</string>
<!-- Label for the Pocket default top site --> <!-- Label for the Pocket default top site -->
<string name="pocket_top_articles">Мақолаҳои беҳтарин</string> <string name="pocket_top_articles">Мақолаҳои беҳтарин</string>
<!-- Bookmark deletion confirmation -->
<string name="bookmark_deletion_confirmation">Шумо мутмаин ҳастед, ки мехоҳед ин хатбаракро нест намоед?</string>
<!-- Browser menu button that adds a top site to the home fragment --> <!-- Browser menu button that adds a top site to the home fragment -->
<string name="browser_menu_add_to_top_sites">Илова кардан ба сомонаҳои беҳтарин</string> <string name="browser_menu_add_to_top_sites">Илова кардан ба сомонаҳои беҳтарин</string>
<!-- text shown before the issuer name to indicate who its verified by, parameter is the name of
the certificate authority that verified the ticket-->
<string name="certificate_info_verified_by">Тасдиқ аз ҷониби: %1$s</string>
<!-- Login overflow menu delete button --> <!-- Login overflow menu delete button -->
<string name="login_menu_delete_button">Нест кардан</string> <string name="login_menu_delete_button">Нест кардан</string>
<!-- Login overflow menu edit button --> <!-- Login overflow menu edit button -->
@ -1142,6 +1225,8 @@
<string name="synced_tabs_reauth">Лутфан, санҷиши ҳаққониятро аз нав такрор кунед</string> <string name="synced_tabs_reauth">Лутфан, санҷиши ҳаққониятро аз нав такрор кунед</string>
<!-- Text displayed when user has disabled tab syncing in Firefox Sync Account --> <!-- Text displayed when user has disabled tab syncing in Firefox Sync Account -->
<string name="synced_tabs_enable_tab_syncing">Лутфан ҳамоҳангсозии варақаҳоро фаъол кунед.</string> <string name="synced_tabs_enable_tab_syncing">Лутфан ҳамоҳангсозии варақаҳоро фаъол кунед.</string>
<!-- Text displayed on a button in the synced tabs screen to link users to sign in when a user is not signed in to Firefox Sync -->
<string name="synced_tabs_sign_in_button">Барои ҳамоҳангсозӣ ворид шавед</string>
<!-- The text displayed when a synced device has no tabs to show in the list of Synced Tabs. --> <!-- The text displayed when a synced device has no tabs to show in the list of Synced Tabs. -->
<string name="synced_tabs_no_open_tabs">Ягон варақаи кушодашуда нест</string> <string name="synced_tabs_no_open_tabs">Ягон варақаи кушодашуда нест</string>

@ -653,6 +653,10 @@
<!-- Text for the button to clear selected history items. The first parameter <!-- Text for the button to clear selected history items. The first parameter
is a digit showing the number of items you have selected --> is a digit showing the number of items you have selected -->
<string name="history_delete_some">Delete %1$d items</string> <string name="history_delete_some">Delete %1$d items</string>
<!-- Text for the header that groups the history for today -->
<string name="history_today">Today</string>
<!-- Text for the header that groups the history for yesterday -->
<string name="history_yesterday">Yesterday</string>
<!-- Text for the header that groups the history for last 24 hours --> <!-- Text for the header that groups the history for last 24 hours -->
<string name="history_24_hours">Last 24 hours</string> <string name="history_24_hours">Last 24 hours</string>
<!-- Text for the header that groups the history the past 7 days --> <!-- Text for the header that groups the history the past 7 days -->

@ -28,7 +28,7 @@ class TestComponents(private val context: Context) : Components(context) {
) )
} }
override val intentProcessors by lazy { mockk<IntentProcessors>(relaxed = true) } override val intentProcessors by lazy { mockk<IntentProcessors>(relaxed = true) }
override val analytics by lazy { Analytics(context, strictMode) } override val analytics by lazy { Analytics(context) }
override val clipboardHandler by lazy { ClipboardHandler(context) } override val clipboardHandler by lazy { ClipboardHandler(context) }

@ -1,51 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.fenix.components.metrics
import android.content.Context.MODE_PRIVATE
import io.mockk.mockk
import mozilla.components.support.test.robolectric.testContext
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNull
import org.junit.Test
import org.junit.runner.RunWith
import org.mozilla.fenix.ext.application
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
@RunWith(FenixRobolectricTestRunner::class)
class LeanplumMetricsServiceTest {
@Test
fun `deviceId is only generated on first run`() {
var callCount = 0
val idGenerator = {
callCount++
"TEST_DEVICE_ID"
}
val sharedPreferences = testContext.application.getSharedPreferences(
"LEANPLUM_PREFERENCES",
MODE_PRIVATE
)
assertNull(sharedPreferences.getString("LP_DEVICE_ID", null))
val leanplumMetricService = LeanplumMetricsService(
testContext.application,
mockk(relaxed = true),
idGenerator
)
assertEquals("TEST_DEVICE_ID", leanplumMetricService.deviceId)
val leanplumMetricService2 = LeanplumMetricsService(
testContext.application,
mockk(relaxed = true),
idGenerator
)
assertEquals("TEST_DEVICE_ID", leanplumMetricService2.deviceId)
assertEquals(1, callCount)
assertEquals("TEST_DEVICE_ID", sharedPreferences.getString("LP_DEVICE_ID", ""))
}
}

@ -8,20 +8,47 @@ import androidx.fragment.app.FragmentActivity
import androidx.preference.Preference import androidx.preference.Preference
import io.mockk.every import io.mockk.every
import io.mockk.mockk import io.mockk.mockk
import io.mockk.mockkObject
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.TestCoroutineDispatcher
import mozilla.components.support.test.robolectric.testContext
import mozilla.components.support.test.rule.MainCoroutineRule
import org.junit.Assert.assertFalse import org.junit.Assert.assertFalse
import org.junit.Assert.assertNotNull import org.junit.Assert.assertNotNull
import org.junit.Assert.assertTrue import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Rule
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
import org.mozilla.fenix.Config
import org.mozilla.fenix.R import org.mozilla.fenix.R
import org.mozilla.fenix.ReleaseChannel
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.getPreferenceKey import org.mozilla.fenix.ext.getPreferenceKey
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
import org.mozilla.fenix.utils.Settings import org.mozilla.fenix.utils.Settings
import org.robolectric.Robolectric import org.robolectric.Robolectric
import java.io.IOException
@ExperimentalCoroutinesApi
@RunWith(FenixRobolectricTestRunner::class) @RunWith(FenixRobolectricTestRunner::class)
class SettingsFragmentTest { class SettingsFragmentTest {
private val testDispatcher = TestCoroutineDispatcher()
@get:Rule
val coroutinesTestRule = MainCoroutineRule(testDispatcher)
@Before
fun setup() {
// Mock client for fetching account avatar
val client = testContext.components.core.client
every { client.fetch(any()) } throws IOException("test")
mockkObject(Config)
every { Config.channel } returns ReleaseChannel.Nightly
}
@Test @Test
fun `Add-on collection override pref is visible if debug menu active`() { fun `Add-on collection override pref is visible if debug menu active`() {
val settingsFragment = SettingsFragment() val settingsFragment = SettingsFragment()
@ -31,6 +58,8 @@ class SettingsFragmentTest {
.add(settingsFragment, "test") .add(settingsFragment, "test")
.commitNow() .commitNow()
testDispatcher.advanceUntilIdle()
val preferenceAmoCollectionOverride = settingsFragment.findPreference<Preference>( val preferenceAmoCollectionOverride = settingsFragment.findPreference<Preference>(
settingsFragment.getPreferenceKey(R.string.pref_key_override_amo_collection) settingsFragment.getPreferenceKey(R.string.pref_key_override_amo_collection)
) )
@ -54,6 +83,8 @@ class SettingsFragmentTest {
.add(settingsFragment, "test") .add(settingsFragment, "test")
.commitNow() .commitNow()
testDispatcher.advanceUntilIdle()
val preferenceAmoCollectionOverride = settingsFragment.findPreference<Preference>( val preferenceAmoCollectionOverride = settingsFragment.findPreference<Preference>(
settingsFragment.getPreferenceKey(R.string.pref_key_override_amo_collection) settingsFragment.getPreferenceKey(R.string.pref_key_override_amo_collection)
) )

@ -54,7 +54,7 @@ class SavedLoginsStorageControllerTest {
controller = SavedLoginsStorageController( controller = SavedLoginsStorageController(
passwordsStorage = passwordsStorage, passwordsStorage = passwordsStorage,
viewLifecycleScope = scope, lifecycleScope = scope,
navController = navController, navController = navController,
loginsFragmentStore = loginsFragmentStore, loginsFragmentStore = loginsFragmentStore,
ioDispatcher = ioDispatcher ioDispatcher = ioDispatcher

@ -179,7 +179,6 @@ tasks.register('ktlint', JavaExec) {
tasks.withType(io.gitlab.arturbosch.detekt.Detekt.class).configureEach { tasks.withType(io.gitlab.arturbosch.detekt.Detekt.class).configureEach {
exclude("**/resources/**") exclude("**/resources/**")
exclude("**/test/**")
exclude("**/tmp/**") exclude("**/tmp/**")
} }

@ -3,5 +3,5 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
object AndroidComponents { object AndroidComponents {
const val VERSION = "61.0.20200925190057" const val VERSION = "62.0.20201002143132"
} }

@ -13,7 +13,7 @@ object Versions {
const val detekt = "1.9.1" const val detekt = "1.9.1"
const val androidx_appcompat = "1.2.0-rc01" const val androidx_appcompat = "1.2.0-rc01"
const val androidx_biometric = "1.1.0-alpha01" const val androidx_biometric = "1.1.0-beta01"
const val androidx_coordinator_layout = "1.1.0-rc01" const val androidx_coordinator_layout = "1.1.0-rc01"
const val androidx_constraint_layout = "2.0.0" const val androidx_constraint_layout = "2.0.0"
const val androidx_preference = "1.1.0" const val androidx_preference = "1.1.0"
@ -22,8 +22,8 @@ object Versions {
const val androidx_lifecycle = "2.2.0" const val androidx_lifecycle = "2.2.0"
const val androidx_fragment = "1.2.5" const val androidx_fragment = "1.2.5"
const val androidx_navigation = "2.3.0" const val androidx_navigation = "2.3.0"
const val androidx_recyclerview = "1.2.0-alpha05" const val androidx_recyclerview = "1.2.0-alpha06"
const val androidx_core = "1.2.0" const val androidx_core = "1.3.2"
const val androidx_paging = "2.1.0" const val androidx_paging = "2.1.0"
const val androidx_transition = "1.3.0" const val androidx_transition = "1.3.0"
const val androidx_work = "2.2.0" const val androidx_work = "2.2.0"

@ -1,108 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.fenix.gradle.tasks
import org.gradle.api.DefaultTask
import org.gradle.api.GradleException
import org.gradle.api.tasks.TaskAction
import org.gradle.api.tasks.TaskExecutionException
import java.io.File
private val INVALID_TEST_RUNNERS = setOf(
// When updating this list, also update the violation message.
"AndroidJUnit4",
"RobolectricTestRunner"
)
/**
* A lint check that ensures unit tests do not specify an invalid test runner. See the error message
* and the suggested replacement class' kdoc for details.
*
* Performance note: AS indicates this task takes 50ms-100ms to run. This isn't too concerning because
* it's one task and it only runs for unit test compilation. However, if we add additional lint checks,
* we should considering aggregating them - e.g. this task reads the unit test file tree and we can
* combine all of our tasks such that the file tree only needs to be read once - or finding more
* optimal solutions - e.g. only running on changed files.
*/
open class LintUnitTestRunner : DefaultTask() {
init {
group = "Verification"
description = "Ensures unit tests do not specify an invalid test runner"
attachToCompilationTasks()
}
private fun attachToCompilationTasks() {
project.gradle.projectsEvaluated { project.tasks.let { tasks ->
// We make compile tasks, rather than assemble tasks, depend on us because some tools,
// such as AS' test runner, call the compile task directly rather than going through assemble.
val compileUnitTestTasks = tasks.filter {
it.name.startsWith("compile") && it.name.contains("UnitTest")
}
compileUnitTestTasks.forEach { it.dependsOn(this@LintUnitTestRunner) }
// To return feedback as early as possible, we run before all compile tasks including
// compiling the application.
val compileAllTasks = tasks.filter { it.name.startsWith("compile") }
compileAllTasks.forEach { it.mustRunAfter(this@LintUnitTestRunner) }
} }
}
@TaskAction
fun lint() {
val unitTestDir = File(project.projectDir, "/src/test")
check(unitTestDir.exists()) {
"Error in task impl: expected test directory - ${unitTestDir.absolutePath} - to exist"
}
val unitTestDirFileWalk = unitTestDir.walk().onEnter { true /* enter all dirs */ }.asSequence()
val kotlinFileWalk = unitTestDirFileWalk.filter { it.name.endsWith(".kt") && it.isFile }
check(kotlinFileWalk.count() > 0) { "Error in task impl: expected to walk > 0 test files" }
val violatingFiles = kotlinFileWalk.filter { file ->
file.useLines { lines -> lines.any(::isLineInViolation) }
}.sorted().toList()
if (violatingFiles.isNotEmpty()) {
throwViolation(violatingFiles)
}
}
private fun isLineInViolation(line: String): Boolean {
val trimmed = line.trimStart()
return INVALID_TEST_RUNNERS.any { invalid ->
trimmed.startsWith("@RunWith($invalid::class)")
}
}
private fun throwViolation(files: List<File>) {
val failureHeader = """Lint failure: saw unexpected unit test runners. The following code blocks:
|
| @RunWith(AndroidJUnit4::class)
| @Config(application = TestApplication::class)
|OR
| @RunWith(RobolectricTestRunner::class)
| @Config(application = TestApplication::class)
|
|should be replaced with:
|
| @RunWith(FenixRobolectricTestRunner::class)
|
|To reduce redundancy of setting @Config. No @Config specification is necessary because
|the FenixRobolectricTestRunner sets it automatically.
|
|Relatedly, adding robolectric to a test increases its runtime non-trivially so please
|ensure Robolectric is necessary before adding it.
|
|The following files were found to be in violation:
""".trimMargin()
val filesInViolation = files.map {
" ${it.relativeTo(project.rootDir)}"
}
val errorMsg = (listOf(failureHeader) + filesInViolation).joinToString("\n")
throw TaskExecutionException(this, GradleException(errorMsg))
}
}

@ -112,6 +112,8 @@ mozilla-detekt-rules:
# with the debuggable flag or not. Use a check for different build variants, # with the debuggable flag or not. Use a check for different build variants,
# instead. # instead.
bannedProperties: "BuildConfig.DEBUG" bannedProperties: "BuildConfig.DEBUG"
MozillaCorrectUnitTestRunner:
active: true
empty-blocks: empty-blocks:
active: true active: true

@ -14,7 +14,8 @@ class CustomRulesetProvider : RuleSetProvider {
override fun instance(config: Config): RuleSet = RuleSet( override fun instance(config: Config): RuleSet = RuleSet(
ruleSetId, ruleSetId,
listOf( listOf(
MozillaBannedPropertyAccess(config) MozillaBannedPropertyAccess(config),
MozillaCorrectUnitTestRunner(config)
) )
) )
} }

@ -0,0 +1,76 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.fenix.detektrules
import io.gitlab.arturbosch.detekt.api.CodeSmell
import io.gitlab.arturbosch.detekt.api.Config
import io.gitlab.arturbosch.detekt.api.Debt
import io.gitlab.arturbosch.detekt.api.Entity
import io.gitlab.arturbosch.detekt.api.Issue
import io.gitlab.arturbosch.detekt.api.Rule
import io.gitlab.arturbosch.detekt.api.Severity
import io.gitlab.arturbosch.detekt.api.internal.PathFilters
import org.jetbrains.kotlin.psi.KtAnnotationEntry
private val BANNED_TEST_RUNNERS = setOf(
// When updating this list, also update the violation message.
"AndroidJUnit4",
"RobolectricTestRunner"
)
// There is a change to how we output violations in a different PR so the formatting for message
// might be weird but it should still be readable.
private val VIOLATION_MSG = """The following code blocks:
|
| @RunWith(AndroidJUnit4::class)
| @Config(application = TestApplication::class)
| OR
| @RunWith(RobolectricTestRunner::class)
| @Config(application = TestApplication::class)
|
| should be replaced with:
|
| @RunWith(FenixRobolectricTestRunner::class)
|
| To reduce redundancy of setting @Config. No @Config specification is necessary because
| the FenixRobolectricTestRunner sets it automatically.
|
| Relatedly, adding robolectric to a test increases its runtime non-trivially so please
| ensure Robolectric is necessary before adding it.""".trimMargin()
/**
* Ensures we're using the correct Robolectric unit test runner.
*/
class MozillaCorrectUnitTestRunner(config: Config) : Rule(config) {
override val issue = Issue(
MozillaCorrectUnitTestRunner::class.simpleName!!,
Severity.Defect,
"Verifies we're using the correct Robolectric unit test runner",
Debt.FIVE_MINS
)
override val filters: PathFilters?
get() = PathFilters.of(
includes = listOf("**/test/**"), // unit tests only.
excludes = emptyList()
)
override fun visitAnnotationEntry(annotationEntry: KtAnnotationEntry) {
super.visitAnnotationEntry(annotationEntry)
// Example of an annotation: @RunWith(FenixRobolectricUnitTestRunner::class)
val annotationClassName = annotationEntry.shortName?.identifier
if (annotationClassName == "RunWith") {
// Example arg in parens: "(FenixRobolectricUnitTestRunner::class)"
val argInParens = annotationEntry.lastChild.node.chars
val argClassName = argInParens.substring(1 until argInParens.indexOf(":"))
val isInViolation = BANNED_TEST_RUNNERS.any { it == argClassName }
if (isInViolation) {
report(CodeSmell(issue, Entity.from(annotationEntry), VIOLATION_MSG))
}
}
}
}

@ -10,6 +10,9 @@ transforms:
- taskgraph.transforms.task:transforms - taskgraph.transforms.task:transforms
kind-dependencies: kind-dependencies:
# To work around a race condition where if this runs before
# push-apk, push-apk fails to verify chain of trust
- push-apk
- signing - signing
primary-dependency: signing primary-dependency: signing

Loading…
Cancel
Save