Merge pull request #149 from abhijitvalluri/mozilla_main

Pull latest mozilla commits + fix conflicts + fix bugs
pull/159/head
interfect 4 years ago committed by GitHub
commit f801c65d7b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -17,15 +17,17 @@ tasks:
$if: 'tasks_for in ["cron", "action"]'
then: '${tasks_for}@noreply.mozilla.org'
else:
$if: 'tasks_for == "github-push"'
then: '${event.pusher.email}'
# Assume Pull Request
$if: 'event.sender.login == "bors[bot]"'
then: 'skaspari+mozlando@mozilla.com' # It must match what's in bors.toml
else:
$if: 'tasks_for == "github-pull-request"'
then: '${event.pull_request.user.login}@users.noreply.github.com'
$if: 'tasks_for == "github-push"'
then: '${event.pusher.email}'
else:
$if: 'tasks_for == "github-release"'
then: '${event.sender.login}@users.noreply.github.com'
$if: 'tasks_for == "github-pull-request"'
then: '${event.pull_request.user.login}@users.noreply.github.com'
else:
$if: 'tasks_for == "github-release"'
then: '${event.sender.login}@users.noreply.github.com'
baseRepoUrl:
$if: 'tasks_for in ["github-push", "github-release"]'
then: '${event.repository.html_url}'
@ -101,7 +103,7 @@ tasks:
$if: >
tasks_for in ["action", "cron"]
|| (tasks_for == "github-pull-request" && pullRequestAction in ["opened", "reopened", "synchronize"])
|| (tasks_for == "github-push" && head_branch[:10] != "refs/tags/")
|| (tasks_for == "github-push" && head_branch[:10] != "refs/tags/") && (head_branch != "staging.tmp") && (head_branch != "trying.tmp")
|| (tasks_for == "github-release" && releaseAction == "published")
then:
$let:

@ -1,5 +1,6 @@
package org.mozilla.fenix.ui
import android.view.View
import androidx.test.espresso.IdlingRegistry
import org.mozilla.fenix.helpers.TestAssetHelper
@ -11,12 +12,12 @@ import okhttp3.mockwebserver.MockWebServer
import org.junit.Rule
import org.junit.Before
import org.junit.After
import org.junit.Ignore
import org.junit.Test
import org.mozilla.fenix.R
import org.mozilla.fenix.helpers.AndroidAssetDispatcher
import org.mozilla.fenix.helpers.HomeActivityTestRule
import org.mozilla.fenix.helpers.RecyclerViewIdlingResource
import org.mozilla.fenix.helpers.ViewVisibilityIdlingResource
import org.mozilla.fenix.ui.robots.homeScreen
import org.mozilla.fenix.ui.robots.navigationToolbar
@ -30,6 +31,7 @@ class SettingsAddonsTest {
private lateinit var mockWebServer: MockWebServer
private var addonsListIdlingResource: RecyclerViewIdlingResource? = null
private var addonContainerIdlingResource: ViewVisibilityIdlingResource? = null
@get:Rule
val activityTestRule = HomeActivityTestRule()
@ -49,6 +51,10 @@ class SettingsAddonsTest {
if (addonsListIdlingResource != null) {
IdlingRegistry.getInstance().unregister(addonsListIdlingResource!!)
}
if (addonContainerIdlingResource != null) {
IdlingRegistry.getInstance().unregister(addonContainerIdlingResource!!)
}
}
// Walks through settings add-ons menu to ensure all items are present
@ -89,7 +95,6 @@ class SettingsAddonsTest {
}
}
@Ignore("Failing intermittently on Firebase: https://github.com/mozilla-mobile/fenix/issues/13829")
// Opens the addons settings menu, installs an addon, then uninstalls
@Test
fun verifyAddonsCanBeUninstalled() {
@ -107,8 +112,13 @@ class SettingsAddonsTest {
clickInstallAddon(addonName)
acceptInstallAddon()
verifyDownloadAddonPrompt(addonName, activityTestRule)
IdlingRegistry.getInstance().unregister(addonsListIdlingResource!!)
}.openDetailedMenuForAddon(addonName) {
verifyCurrentAddonMenu()
addonContainerIdlingResource = ViewVisibilityIdlingResource(
activityTestRule.activity.findViewById(R.id.addon_container),
View.VISIBLE
)
IdlingRegistry.getInstance().register(addonContainerIdlingResource!!)
}.removeAddon {
}
}

@ -8,7 +8,6 @@ import androidx.test.platform.app.InstrumentationRegistry
import okhttp3.mockwebserver.MockWebServer
import org.junit.After
import org.junit.Before
import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.mozilla.fenix.ext.settings
@ -77,7 +76,6 @@ class StrictEnhancedTrackingProtectionTest {
}
}
@Ignore("Failing on AC 58 update: https://github.com/mozilla-mobile/fenix/issues/14524")
@Test
fun testStrictVisitContentNotification() {
val trackingProtectionTest =
@ -91,7 +89,6 @@ class StrictEnhancedTrackingProtectionTest {
}.closeNotificationPopup {}
}
@Ignore("Failing on AC 58 update: https://github.com/mozilla-mobile/fenix/issues/14524")
@Test
fun testStrictVisitContentShield() {
val trackingProtectionTest =
@ -109,7 +106,6 @@ class StrictEnhancedTrackingProtectionTest {
}
}
@Ignore("Failing on AC 58 update: https://github.com/mozilla-mobile/fenix/issues/14524")
@Test
fun testStrictVisitProtectionSheet() {
val trackingProtectionTest =
@ -129,7 +125,6 @@ class StrictEnhancedTrackingProtectionTest {
}
}
@Ignore("Failing on AC 58 update: https://github.com/mozilla-mobile/fenix/issues/14524")
@Test
fun testStrictVisitDisable() {
val trackingProtectionTest =
@ -161,7 +156,6 @@ class StrictEnhancedTrackingProtectionTest {
}
}
@Ignore("Failing on AC 58 update: https://github.com/mozilla-mobile/fenix/issues/14524")
@Test
fun testStrictVisitDisableExceptionToggle() {
val trackingProtectionTest =
@ -194,7 +188,6 @@ class StrictEnhancedTrackingProtectionTest {
}
}
@Ignore("Failing on AC 58 update: https://github.com/mozilla-mobile/fenix/issues/14524")
@Test
fun testStrictVisitSheetDetails() {
val trackingProtectionTest =

@ -16,8 +16,6 @@ import org.mozilla.fenix.helpers.click
class SettingsSubMenuAddonsManagerAddonDetailedMenuRobot {
fun verifyCurrentAddonMenu() = assertAddonMenuItems()
class Transition {
fun goBack(interact: SettingsSubMenuAddonsManagerRobot.() -> Unit): SettingsSubMenuAddonsManagerRobot.Transition {
fun goBackButton() = onView(allOf(withContentDescription("Navigate up")))
@ -28,33 +26,14 @@ class SettingsSubMenuAddonsManagerAddonDetailedMenuRobot {
}
fun removeAddon(interact: SettingsSubMenuAddonsManagerRobot.() -> Unit): SettingsSubMenuAddonsManagerRobot.Transition {
removeAddonButton().check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
removeAddonButton().click()
SettingsSubMenuAddonsManagerRobot().interact()
return SettingsSubMenuAddonsManagerRobot.Transition()
}
}
private fun assertAddonMenuItems() {
enableSwitchButton().check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
settingsButton().check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
detailsButton().check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
permissionsButton().check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
removeAddonButton().check(matches(withEffectiveVisibility(ViewMatchers.Visibility.VISIBLE)))
}
}
private fun enableSwitchButton() =
onView(withId(R.id.enable_switch))
private fun settingsButton() =
onView(withId(R.id.settings))
private fun detailsButton() =
onView(withId(R.id.details))
private fun permissionsButton() =
onView(withId(R.id.permissions))
private fun removeAddonButton() =
onView(withId(R.id.remove_add_on))

@ -45,4 +45,9 @@ object FeatureFlags {
* Enables swipe to delete in bookmarks
*/
val bookmarkSwipeToDelete = Config.channel.isNightlyOrDebug
/**
* Enables ETP cookie purging
*/
val etpCookiePurging = Config.channel.isNightlyOrDebug
}

@ -16,16 +16,24 @@ object StrictModeManager {
/***
* Enables strict mode for debug purposes. meant to be run only in the main process.
* @param setPenaltyDialog boolean value to decide setting the dialog box as a penalty.
* @param setPenaltyDeath boolean value to decide setting the penaltyDeath as a penalty.
* @param setPenaltyDialog boolean value to decide setting the dialog box as a penalty.
* Note: dialog penalty cannot be set with penaltyDeath
*/
fun enableStrictMode(setPenaltyDialog: Boolean) {
fun enableStrictMode(setPenaltyDeath: Boolean, setPenaltyDialog: Boolean = false) {
if (Config.channel.isDebug) {
val threadPolicy = StrictMode.ThreadPolicy.Builder()
.detectAll()
.penaltyLog()
if (setPenaltyDialog && Build.MANUFACTURER !in strictModeExceptionList) {
if (setPenaltyDeath && Build.MANUFACTURER !in strictModeExceptionList) {
threadPolicy.penaltyDeath()
}
// dialog penalty cannot be set with penaltyDeath
if (!setPenaltyDeath && setPenaltyDialog) {
threadPolicy.penaltyDialog()
}
StrictMode.setThreadPolicy(threadPolicy.build())
val builder = StrictMode.VmPolicy.Builder()
@ -39,7 +47,7 @@ object StrictModeManager {
builder.detectContentUriWithoutPermission()
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
if (setPenaltyDialog) {
if (setPenaltyDeath || setPenaltyDialog) {
builder.permitNonSdkApiUsage()
} else {
builder.detectNonSdkApiUsage()
@ -50,14 +58,15 @@ object StrictModeManager {
}
/**
* Revert strict mode to disable penalty dialog. Tied to fragment lifecycle since strict mode
* Revert strict mode to disable penalty. Tied to fragment lifecycle since strict mode
* needs to switch to penalty logs. Using the fragment life cycle allows decoupling from any
* specific fragment.
*/
fun changeStrictModePolicies(fragmentManager: FragmentManager) {
fragmentManager.registerFragmentLifecycleCallbacks(object : FragmentManager.FragmentLifecycleCallbacks() {
fragmentManager.registerFragmentLifecycleCallbacks(object :
FragmentManager.FragmentLifecycleCallbacks() {
override fun onFragmentResumed(fm: FragmentManager, f: Fragment) {
enableStrictMode(false)
enableStrictMode(setPenaltyDeath = false, setPenaltyDialog = false)
fm.unregisterFragmentLifecycleCallbacks(this)
}
}, false)

@ -255,7 +255,8 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Session
)
},
onCloseTab = { closedSession ->
val tab = store.state.findTab(closedSession.id) ?: return@DefaultBrowserToolbarController
val tab = store.state.findTab(closedSession.id)
?: return@DefaultBrowserToolbarController
val isSelected = tab.id == context.components.core.store.state.selectedTabId
val snackbarMessage = if (tab.content.private) {
@ -372,11 +373,6 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Session
view = view
)
val shouldForwardToThirdParties =
PreferenceManager.getDefaultSharedPreferences(context).getBoolean(
context.getPreferenceKey(R.string.pref_key_external_download_manager), false
)
val downloadFeature = DownloadsFeature(
context.applicationContext,
store = store,
@ -388,7 +384,11 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Session
store,
DownloadService::class
),
shouldForwardToThirdParties = { shouldForwardToThirdParties },
shouldForwardToThirdParties = {
PreferenceManager.getDefaultSharedPreferences(context).getBoolean(
context.getPreferenceKey(R.string.pref_key_external_download_manager), false
)
},
promptsStyling = DownloadsFeature.PromptsStyling(
gravity = Gravity.BOTTOM,
shouldWidthMatchParent = true,
@ -877,7 +877,11 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Session
}
override fun onBackLongPressed(): Boolean {
findNavController().navigate(R.id.action_global_tabHistoryDialogFragment)
findNavController().navigate(
NavGraphDirections.actionGlobalTabHistoryDialogFragment(
activeSessionId = customTabSessionId
)
)
return true
}
@ -1120,7 +1124,8 @@ abstract class BaseBrowserFragment : Fragment(), UserInteractionHandler, Session
private fun didFirstContentfulHappen() =
if (components.settings.waitToShowPageUntilFirstPaint) {
val tab = components.core.store.state.findTabOrCustomTabOrSelectedTab(customTabSessionId)
val tab =
components.core.store.state.findTabOrCustomTabOrSelectedTab(customTabSessionId)
tab?.content?.firstContentfulPaint ?: false
} else {
true

@ -36,10 +36,12 @@ class OpenInAppOnboardingObserver(
}
}
@Suppress("ComplexCondition")
override fun onLoadingStateChanged(session: Session, loading: Boolean) {
val appLink = appLinksUseCases.appLinkRedirect
if (!loading &&
!settings.openLinksInExternalApp &&
settings.shouldShowOpenInAppBanner &&
appLink(session.url).hasExternalApp()
) {

@ -12,8 +12,6 @@ import android.graphics.PointF
import android.graphics.Rect
import android.view.View
import android.view.ViewConfiguration
import androidx.annotation.Dimension
import androidx.annotation.Dimension.DP
import androidx.core.animation.doOnEnd
import androidx.core.graphics.contains
import androidx.core.graphics.toPoint
@ -21,8 +19,8 @@ import androidx.core.view.isVisible
import androidx.interpolator.view.animation.LinearOutSlowInInterpolator
import mozilla.components.browser.session.Session
import mozilla.components.browser.session.SessionManager
import mozilla.components.support.ktx.android.util.dpToPx
import mozilla.components.support.ktx.android.view.getRectWithViewLocation
import org.mozilla.fenix.R
import org.mozilla.fenix.ext.getRectWithScreenLocation
import org.mozilla.fenix.ext.getWindowInsets
import org.mozilla.fenix.ext.isKeyboardVisible
@ -57,7 +55,8 @@ class ToolbarGestureHandler(
private val windowWidth: Int
get() = activity.resources.displayMetrics.widthPixels
private val previewOffset = PREVIEW_OFFSET.dpToPx(activity.resources.displayMetrics)
private val previewOffset =
activity.resources.getDimensionPixelSize(R.dimen.browser_fragment_gesture_preview_offset)
private val touchSlop = ViewConfiguration.get(activity).scaledTouchSlop
private val minimumFlingVelocity = ViewConfiguration.get(activity).scaledMinimumFlingVelocity
@ -304,12 +303,6 @@ class ToolbarGestureHandler(
*/
private const val OVERSCROLL_HIDE_PERCENT = 0.20
/**
* The size of the gap between the tab preview and content layout.
*/
@Dimension(unit = DP)
private const val PREVIEW_OFFSET = 48
/**
* Animation duration when switching to another tab
*/

@ -119,8 +119,8 @@ class FenixSnackbar private constructor(
val callback = FenixSnackbarCallback(content)
val shouldUseBottomToolbar = view.context.settings().shouldUseBottomToolbar
val toolbarHeight = view.context.resources
.getDimensionPixelSize(R.dimen.browser_toolbar_height)
val toolbarHeight = view.resources.getDimensionPixelSize(R.dimen.browser_toolbar_height)
val dynamicToolbarEnabled = view.context.settings().isDynamicToolbarEnabled
return FenixSnackbar(parent, content, callback, isError).also {
it.duration = durationOrAccessibleDuration
@ -134,7 +134,7 @@ class FenixSnackbar private constructor(
// can't intelligently position the snackbar on the upper most view.
// Ideally we should not pass ContentFrameLayout in, but it's the only
// way to display snackbars through a fragment transition.
view is ContentFrameLayout
(view is ContentFrameLayout || !dynamicToolbarEnabled)
) {
toolbarHeight
} else {

@ -8,6 +8,7 @@ import androidx.annotation.VisibleForTesting
import mozilla.components.concept.engine.EngineSession.TrackingProtectionPolicy
import mozilla.components.concept.engine.EngineSession.TrackingProtectionPolicyForSessionTypes
import org.mozilla.fenix.Config
import org.mozilla.fenix.FeatureFlags
import org.mozilla.fenix.utils.Settings
/**
@ -102,6 +103,6 @@ internal fun TrackingProtectionPolicyForSessionTypes.adaptPolicyToChannel(): Tra
trackingCategories = trackingCategories,
cookiePolicy = cookiePolicy,
strictSocialTrackingProtection = strictSocialTrackingProtection,
cookiePurging = Config.channel.isNightlyOrDebug
cookiePurging = FeatureFlags.etpCookiePurging
)
}

@ -7,6 +7,7 @@ package org.mozilla.fenix.components.searchengine
import android.content.Context
import androidx.annotation.VisibleForTesting
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Deferred
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.async
@ -32,16 +33,15 @@ import java.util.Locale
open class FenixSearchEngineProvider(
private val context: Context
) : SearchEngineProvider, CoroutineScope by CoroutineScope(Job() + Dispatchers.IO) {
private val locationService = with(MozillaLocationService(
context,
context.components.core.client,
BuildConfig.MLS_TOKEN
)) {
if (Config.channel.isDebug || !this.hasRegionCached()) {
LocationService.dummy()
} else {
this
}
private val shouldMockMLS = Config.channel.isDebug || BuildConfig.MLS_TOKEN.isNullOrEmpty()
private val locationService: LocationService = if (shouldMockMLS) {
LocationService.dummy()
} else {
MozillaLocationService(
context,
context.components.core.client,
BuildConfig.MLS_TOKEN
)
}
// We have two search engine types: one based on MLS reported region, one based only on Locale.
@ -94,6 +94,17 @@ open class FenixSearchEngineProvider(
private var loadedSearchEngines = refreshAsync()
// https://github.com/mozilla-mobile/fenix/issues/9935
// Create new getter that will return the fallback SearchEngineList if
// the main one hasn't completed yet
private val searchEngines: Deferred<SearchEngineList>
get() =
if (isRegionCachedByLocationService) {
loadedSearchEngines
} else {
fallbackEngines
}
fun getDefaultEngine(context: Context): SearchEngine {
val engines = installedSearchEngines(context)
val selectedName = context.settings().defaultSearchEngineName
@ -107,7 +118,7 @@ open class FenixSearchEngineProvider(
*/
fun installedSearchEngines(context: Context): SearchEngineList = runBlocking {
val installedIdentifiers = installedSearchEngineIdentifiers(context)
val engineList = loadedSearchEngines.await()
val engineList = searchEngines.await()
engineList.copy(
list = engineList.list.filter {
@ -178,11 +189,7 @@ open class FenixSearchEngineProvider(
}
private fun refreshAsync() = async {
val engineList = if (isRegionCachedByLocationService) {
baseSearchEngines.await()
} else {
fallbackEngines.await()
}
val engineList = baseSearchEngines.await()
val bundledList = bundledSearchEngines.await().list
val customList = customSearchEngines.await().list

@ -87,7 +87,9 @@ class DefaultBrowserToolbarMenuController(
is ToolbarMenu.Item.Back -> {
if (item.viewHistory) {
navController.navigate(
BrowserFragmentDirections.actionGlobalTabHistoryDialogFragment()
BrowserFragmentDirections.actionGlobalTabHistoryDialogFragment(
activeSessionId = customTabSession?.id
)
)
} else {
sessionUseCases.goBack.invoke(currentSession)
@ -96,7 +98,9 @@ class DefaultBrowserToolbarMenuController(
is ToolbarMenu.Item.Forward -> {
if (item.viewHistory) {
navController.navigate(
BrowserFragmentDirections.actionGlobalTabHistoryDialogFragment()
BrowserFragmentDirections.actionGlobalTabHistoryDialogFragment(
activeSessionId = customTabSession?.id
)
)
} else {
sessionUseCases.goForward.invoke(currentSession)

@ -27,7 +27,6 @@ import mozilla.components.browser.state.state.ExternalAppType
import mozilla.components.browser.toolbar.BrowserToolbar
import mozilla.components.browser.toolbar.behavior.BrowserToolbarBottomBehavior
import mozilla.components.browser.toolbar.display.DisplayToolbar
import mozilla.components.support.ktx.android.util.dpToFloat
import mozilla.components.support.utils.URLStringUtils
import org.mozilla.fenix.R
import org.mozilla.fenix.customtabs.CustomTabToolbarIntegration
@ -111,7 +110,7 @@ class BrowserToolbarView(
view.apply {
setScrollFlags()
elevation = TOOLBAR_ELEVATION.dpToFloat(resources.displayMetrics)
elevation = resources.getDimension(R.dimen.browser_fragment_toolbar_elevation)
if (!isCustomTabSession) {
display.setUrlBackground(getDrawable(R.drawable.search_url_background))

@ -155,7 +155,7 @@ class TopSheetBehavior<V : View?>
a.hasValue(R.styleable.BottomSheetBehavior_Layout_shapeAppearance)
createMaterialShapeDrawable(context, attrs!!)
createShapeValueAnimator()
peekHeight = context.resources.displayMetrics.heightPixels * PEEK_HEIGHT_RATIO
peekHeight = (context.resources.displayMetrics.heightPixels * PEEK_HEIGHT_RATIO).toInt()
isHideable = a.getBoolean(
R.styleable.BottomSheetBehavior_Layout_behavior_hideable,
false
@ -821,7 +821,7 @@ class TopSheetBehavior<V : View?>
private const val CORNER_ANIMATION_DURATION = 500
private val DEF_STYLE_RES = R.style.Widget_Design_BottomSheet_Modal
private const val PEEK_HEIGHT_RATIO = 3 / 4
private const val PEEK_HEIGHT_RATIO = 0.75
private const val VELOCITY_UNITS = 1000
}
}

@ -8,6 +8,7 @@ import android.content.Context
import android.content.Intent
import android.os.SystemClock
import android.view.View
import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.core.view.isVisible
import androidx.navigation.fragment.navArgs
import kotlinx.android.synthetic.main.component_browser_top_toolbar.*
@ -81,7 +82,8 @@ class ExternalAppBrowserFragment : BaseBrowserFragment(), UserInteractionHandler
components.core.store,
customTabSessionId
) { uri ->
val intent = Intent.parseUri("${BuildConfig.DEEP_LINK_SCHEME}://open?url=$uri", 0)
val intent =
Intent.parseUri("${BuildConfig.DEEP_LINK_SCHEME}://open?url=$uri", 0)
if (intent.action == Intent.ACTION_VIEW) {
intent.addCategory(Intent.CATEGORY_BROWSABLE)
intent.component = null
@ -103,7 +105,12 @@ class ExternalAppBrowserFragment : BaseBrowserFragment(), UserInteractionHandler
) { toolbarVisible ->
browserToolbarView.view.isVisible = toolbarVisible
webAppToolbarShouldBeVisible = toolbarVisible
if (!toolbarVisible) { engineView.setDynamicToolbarMaxHeight(0) }
if (!toolbarVisible) {
engineView.setDynamicToolbarMaxHeight(0)
val browserEngine =
swipeRefresh.layoutParams as CoordinatorLayout.LayoutParams
browserEngine.bottomMargin = 0
}
},
owner = this,
view = toolbar

@ -9,10 +9,13 @@ import android.text.Spannable
import android.text.SpannableString
import android.text.style.AbsoluteSizeSpan
import android.text.style.ForegroundColorSpan
import androidx.annotation.AttrRes
import androidx.annotation.Dimension
import androidx.annotation.Dimension.DP
import mozilla.components.support.ktx.android.content.getColorFromAttr
import mozilla.components.support.ktx.android.util.dpToPx
fun SpannableString.setTextSize(context: Context, textSize: Int) =
fun SpannableString.setTextSize(context: Context, @Dimension(unit = DP) textSize: Int) =
this.setSpan(
AbsoluteSizeSpan(textSize.dpToPx(context.resources.displayMetrics)),
0,
@ -20,11 +23,9 @@ fun SpannableString.setTextSize(context: Context, textSize: Int) =
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
)
fun SpannableString.setTextColor(context: Context, colorResId: Int) =
fun SpannableString.setTextColor(context: Context, @AttrRes colorResId: Int) =
this.setSpan(
ForegroundColorSpan(
context.getColorFromAttr(colorResId)
),
ForegroundColorSpan(context.getColorFromAttr(colorResId)),
0,
this.length,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE

@ -11,9 +11,9 @@ import androidx.core.text.toSpannable
/**
* Adds an underline effect to the text displayed in the TextView.
*/
fun TextView.addUnderline() {
fun TextView.addUnderline(start: Int = 0, end: Int = this.text.length, flags: Int = 0) {
val currentText = text
text = currentText.toSpannable().apply {
setSpan(UnderlineSpan(), 0, currentText.length, 0)
setSpan(UnderlineSpan(), start, end, flags)
}
}

@ -9,11 +9,13 @@ import android.os.Build
import android.view.TouchDelegate
import android.view.View
import androidx.annotation.Dimension
import androidx.annotation.Dimension.DP
import androidx.annotation.VisibleForTesting
import androidx.core.view.WindowInsetsCompat
import mozilla.components.support.ktx.android.util.dpToPx
import org.mozilla.fenix.R
fun View.increaseTapArea(extraDps: Int) {
fun View.increaseTapArea(@Dimension(unit = DP) extraDps: Int) {
val dips = extraDps.dpToPx(resources.displayMetrics)
val parent = this.parent as View
parent.post {
@ -73,7 +75,7 @@ fun View.isKeyboardVisible(): Boolean {
val minimumKeyboardHeight = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
0
} else {
MINIMUM_KEYBOARD_HEIGHT.dpToPx(resources.displayMetrics)
resources.getDimensionPixelSize(R.dimen.minimum_keyboard_height)
}
return getKeyboardHeight() > minimumKeyboardHeight
}

@ -20,6 +20,7 @@ import android.widget.Button
import android.widget.LinearLayout
import android.widget.PopupWindow
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.content.res.AppCompatResources
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.constraintlayout.widget.ConstraintSet
import androidx.constraintlayout.widget.ConstraintSet.BOTTOM
@ -69,7 +70,7 @@ import mozilla.components.feature.top.sites.TopSitesConfig
import mozilla.components.feature.top.sites.TopSitesFeature
import mozilla.components.lib.state.ext.consumeFrom
import mozilla.components.support.base.feature.ViewBoundFeatureWrapper
import mozilla.components.support.ktx.android.util.dpToPx
import mozilla.components.support.ktx.android.content.res.resolveAttribute
import org.mozilla.fenix.BrowserDirection
import org.mozilla.fenix.FeatureFlags
import org.mozilla.fenix.HomeActivity
@ -313,13 +314,13 @@ class HomeFragment : Fragment() {
applyTo(view.toolbarLayout)
}
view.bottom_bar.background = resources.getDrawable(
ThemeManager.resolveAttribute(R.attr.bottomBarBackgroundTop, requireContext()),
null
view.bottom_bar.background = AppCompatResources.getDrawable(
view.context,
view.context.theme.resolveAttribute(R.attr.bottomBarBackgroundTop)
)
view.homeAppBar.updateLayoutParams<ViewGroup.MarginLayoutParams> {
topMargin = HEADER_MARGIN.dpToPx(resources.displayMetrics)
topMargin = resources.getDimensionPixelSize(R.dimen.home_fragment_top_toolbar_header_margin)
}
}
ToolbarPosition.BOTTOM -> {
@ -1002,8 +1003,5 @@ class HomeFragment : Fragment() {
private const val ANIM_SNACKBAR_DELAY = 100L
private const val CFR_WIDTH_DIVIDER = 1.7
private const val CFR_Y_OFFSET = -20
// Layout
private const val HEADER_MARGIN = 60
}
}

@ -46,7 +46,7 @@ sealed class AdapterItem(@LayoutRes val viewType: Int) {
data class TopSitePager(val topSites: List<TopSite>) : AdapterItem(TopSitePagerViewHolder.LAYOUT_ID) {
override fun sameAs(other: AdapterItem): Boolean {
val newTopSites = (other as? TopSitePager) ?: return false
return newTopSites.topSites == this.topSites
return newTopSites.topSites.size == this.topSites.size
}
override fun contentsSameAs(other: AdapterItem): Boolean {
@ -54,7 +54,7 @@ sealed class AdapterItem(@LayoutRes val viewType: Int) {
if (newTopSites.topSites.size != this.topSites.size) return false
val newSitesSequence = newTopSites.topSites.asSequence()
val oldTopSites = this.topSites.asSequence()
return newSitesSequence.zip(oldTopSites).all { (new, old) -> new.title == old.title }
return newSitesSequence.zip(oldTopSites).all { (new, old) -> new == old }
}
}

@ -18,7 +18,7 @@ class PrivateBrowsingDescriptionViewHolder(
) : RecyclerView.ViewHolder(view) {
init {
val resources = view.context.resources
val resources = view.resources
val appName = resources.getString(R.string.app_name)
view.private_session_description.text = resources.getString(
R.string.private_browsing_placeholder_description_2, appName

@ -11,14 +11,13 @@ import androidx.appcompat.content.res.AppCompatResources
import kotlinx.android.synthetic.main.list_element.*
import mozilla.components.feature.tab.collections.TabCollection
import mozilla.components.support.ktx.android.content.getColorFromAttr
import mozilla.components.support.ktx.android.util.dpToFloat
import org.mozilla.fenix.R
import org.mozilla.fenix.utils.view.ViewHolder
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.increaseTapArea
import org.mozilla.fenix.ext.loadIntoView
import org.mozilla.fenix.ext.toShortUrl
import org.mozilla.fenix.home.sessioncontrol.CollectionInteractor
import org.mozilla.fenix.utils.view.ViewHolder
import mozilla.components.feature.tab.collections.Tab as ComponentTab
class TabInCollectionViewHolder(
@ -42,7 +41,7 @@ class TabInCollectionViewHolder(
0,
view.width,
view.height,
FAV_ICON_BORDER_RADIUS_IN_DP.dpToFloat(view.context.resources.displayMetrics)
view.resources.getDimension(R.dimen.tab_tray_favicon_border_radius)
)
}
}

@ -44,7 +44,8 @@ class TopSitePagerViewHolder(
}
fun bind(topSites: List<TopSite>) {
topSitesPagerAdapter.updateData(topSites)
val chunkedTopSites = topSites.chunked(TOP_SITES_PER_PAGE)
topSitesPagerAdapter.submitList(chunkedTopSites)
// Don't show any page indicator if there is only 1 page.
val numPages = if (topSites.size > TOP_SITES_PER_PAGE) {

@ -6,21 +6,16 @@ package org.mozilla.fenix.home.sessioncontrol.viewholders.topsites
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import kotlinx.android.synthetic.main.component_top_sites.view.*
import mozilla.components.feature.top.sites.TopSite
import org.mozilla.fenix.home.sessioncontrol.TopSiteInteractor
import org.mozilla.fenix.home.sessioncontrol.viewholders.TopSiteViewHolder
class TopSitesPagerAdapter(
private val interactor: TopSiteInteractor
) : RecyclerView.Adapter<TopSiteViewHolder>() {
private var topSites: List<List<TopSite>> = listOf()
fun updateData(topSites: List<TopSite>) {
this.topSites = topSites.chunked(TOP_SITES_PER_PAGE)
notifyDataSetChanged()
}
) : ListAdapter<List<TopSite>, TopSiteViewHolder>(DiffCallback) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TopSiteViewHolder {
val view = LayoutInflater.from(parent.context)
@ -29,12 +24,17 @@ class TopSitesPagerAdapter(
}
override fun onBindViewHolder(holder: TopSiteViewHolder, position: Int) {
holder.bind(this.topSites[position])
val adapter = holder.itemView.top_sites_list.adapter as TopSitesAdapter
adapter.submitList(getItem(position))
}
override fun getItemCount(): Int = this.topSites.size
private object DiffCallback : DiffUtil.ItemCallback<List<TopSite>>() {
override fun areItemsTheSame(oldItem: List<TopSite>, newItem: List<TopSite>): Boolean {
return oldItem.size == newItem.size
}
companion object {
const val TOP_SITES_PER_PAGE = 8
override fun areContentsTheSame(oldItem: List<TopSite>, newItem: List<TopSite>): Boolean {
return newItem.zip(oldItem).all { (new, old) -> new == old }
}
}
}

@ -26,16 +26,30 @@ class BookmarkAdapter(private val emptyView: View, private val interactor: Bookm
private var isFirstRun = true
fun updateData(tree: BookmarkNode?, mode: BookmarkFragmentState.Mode) {
// Display folders above all other bookmarks.
val allNodes = tree?.children.orEmpty()
val folders: MutableList<BookmarkNode> = mutableListOf()
val notFolders: MutableList<BookmarkNode> = mutableListOf()
allNodes.forEach {
if (it.type == BookmarkNodeType.FOLDER) {
folders.add(it)
} else {
notFolders.add(it)
}
}
val newTree = folders + notFolders
val diffUtil = DiffUtil.calculateDiff(
BookmarkDiffUtil(
this.tree,
tree?.children.orEmpty(),
newTree,
this.mode,
mode
)
)
this.tree = tree?.children.orEmpty()
this.tree = newTree
isFirstRun = if (isFirstRun) false else {
emptyView.isVisible = this.tree.isEmpty()
false

@ -30,8 +30,12 @@ class BookmarkTouchCallback(
recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder
): Int {
// Swiping separators is currently not supported.
if (viewHolder is BookmarkSeparatorViewHolder) {
return 0
}
val item = (viewHolder as BookmarkNodeViewHolder).item
return if (viewHolder is BookmarkSeparatorViewHolder || item?.inRoots() == true) {
return if (item?.inRoots() == true) {
0
} else {
super.getSwipeDirs(recyclerView, viewHolder)
@ -72,7 +76,7 @@ class BookmarkTouchCallback(
R.drawable.swipe_delete_background
)!!
val margin =
SwipeToDeleteCallback.MARGIN.dpToPx(recyclerView.context.resources.displayMetrics)
SwipeToDeleteCallback.MARGIN.dpToPx(recyclerView.resources.displayMetrics)
val cellHeight = viewHolder.itemView.bottom - viewHolder.itemView.top
val iconTop = viewHolder.itemView.top + (cellHeight - icon.intrinsicHeight) / 2
val iconBottom = iconTop + icon.intrinsicHeight

@ -11,36 +11,15 @@ import org.mozilla.fenix.R
import org.mozilla.fenix.ext.components
class DesktopFolders(
context: Context,
private val context: Context,
private val showMobileRoot: Boolean
) {
private val bookmarksStorage = context.components.core.bookmarksStorage
private val bookmarksTitle = context.getString(R.string.library_bookmarks)
/**
* Map of [BookmarkNode.title] to translated strings.
*/
private val rootTitles: Map<String, String> = if (showMobileRoot) {
mapOf(
"root" to bookmarksTitle,
"mobile" to bookmarksTitle,
"menu" to context.getString(R.string.library_desktop_bookmarks_menu),
"toolbar" to context.getString(R.string.library_desktop_bookmarks_toolbar),
"unfiled" to context.getString(R.string.library_desktop_bookmarks_unfiled)
)
} else {
mapOf(
"root" to context.getString(R.string.library_desktop_bookmarks_root),
"menu" to context.getString(R.string.library_desktop_bookmarks_menu),
"toolbar" to context.getString(R.string.library_desktop_bookmarks_toolbar),
"unfiled" to context.getString(R.string.library_desktop_bookmarks_unfiled)
)
}
fun withRootTitle(node: BookmarkNode): BookmarkNode =
if (rootTitles.containsKey(node.title)) node.copy(title = rootTitles[node.title]) else node
private val rootTitles = rootTitles(context, showMobileRoot)
suspend fun withOptionalDesktopFolders(node: BookmarkNode): BookmarkNode {
return when (node.guid) {
@ -103,7 +82,7 @@ class DesktopFolders(
return listOf(
mobileRoot.copy(
children = mobileChildren,
title = bookmarksTitle
title = context.getString(R.string.library_bookmarks)
)
)
}

@ -0,0 +1,37 @@
/* 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.library.bookmarks
import android.content.Context
import mozilla.components.concept.storage.BookmarkNode
import org.mozilla.fenix.R
fun rootTitles(context: Context, withMobileRoot: Boolean): Map<String, String> = if (withMobileRoot) {
mapOf(
"root" to context.getString(R.string.library_bookmarks),
"mobile" to context.getString(R.string.library_bookmarks),
"menu" to context.getString(R.string.library_desktop_bookmarks_menu),
"toolbar" to context.getString(R.string.library_desktop_bookmarks_toolbar),
"unfiled" to context.getString(R.string.library_desktop_bookmarks_unfiled)
)
} else {
mapOf(
"root" to context.getString(R.string.library_desktop_bookmarks_root),
"menu" to context.getString(R.string.library_desktop_bookmarks_menu),
"toolbar" to context.getString(R.string.library_desktop_bookmarks_toolbar),
"unfiled" to context.getString(R.string.library_desktop_bookmarks_unfiled)
)
}
fun friendlyRootTitle(
context: Context,
node: BookmarkNode,
withMobileRoot: Boolean = true,
rootTitles: Map<String, String> = rootTitles(context, withMobileRoot)
) = when {
!node.inRoots() -> node.title
rootTitles.containsKey(node.title) -> rootTitles[node.title]
else -> node.title
}

@ -29,6 +29,7 @@ import org.mozilla.fenix.ext.nav
import org.mozilla.fenix.ext.requireComponents
import org.mozilla.fenix.ext.showToolbar
import org.mozilla.fenix.library.bookmarks.BookmarksSharedViewModel
import org.mozilla.fenix.library.bookmarks.friendlyRootTitle
/**
* Menu to create a new bookmark folder.
@ -58,19 +59,19 @@ class AddBookmarkFolderFragment : Fragment(R.layout.fragment_edit_bookmark) {
showToolbar(getString(R.string.bookmark_add_folder_fragment_label))
viewLifecycleOwner.lifecycleScope.launch(Main) {
val context = requireContext()
sharedViewModel.selectedFolder = withContext(IO) {
sharedViewModel.selectedFolder
?: requireComponents.core.bookmarksStorage.getTree(BookmarkRoot.Mobile.id)
?: requireComponents.core.bookmarksStorage.getBookmark(BookmarkRoot.Mobile.id)
}
bookmarkParentFolderSelector.text = sharedViewModel.selectedFolder!!.title
bookmarkParentFolderSelector.text = friendlyRootTitle(context, sharedViewModel.selectedFolder!!)
bookmarkParentFolderSelector.setOnClickListener {
nav(
R.id.bookmarkAddFolderFragment,
AddBookmarkFolderFragmentDirections
.actionBookmarkAddFolderFragmentToBookmarkSelectFolderFragment(
BookmarkRoot.Root.id,
true
allowCreatingNewFolder = true
)
)
}

@ -45,7 +45,7 @@ import org.mozilla.fenix.ext.requireComponents
import org.mozilla.fenix.ext.setToolbarColors
import org.mozilla.fenix.ext.toShortUrl
import org.mozilla.fenix.library.bookmarks.BookmarksSharedViewModel
import org.mozilla.fenix.library.bookmarks.DesktopFolders
import org.mozilla.fenix.library.bookmarks.friendlyRootTitle
/**
* Menu to edit the name, URL, and location of a bookmark item.
@ -58,6 +58,7 @@ class EditBookmarkFragment : Fragment(R.layout.fragment_edit_bookmark) {
}
private var bookmarkNode: BookmarkNode? = null
private var bookmarkParent: BookmarkNode? = null
private var initialParentGuid: String? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@ -71,14 +72,23 @@ class EditBookmarkFragment : Fragment(R.layout.fragment_edit_bookmark) {
viewLifecycleOwner.lifecycleScope.launch(Main) {
val context = requireContext()
val bookmarkNodeBeforeReload = bookmarkNode
val bookmarksStorage = context.components.core.bookmarksStorage
withContext(IO) {
val bookmarksStorage = context.components.core.bookmarksStorage
bookmarkNode = bookmarksStorage.getTree(args.guidToEdit)
bookmarkParent = sharedViewModel.selectedFolder
?: bookmarkNode?.parentGuid
?.let { bookmarksStorage.getTree(it) }
?.let { DesktopFolders(context, showMobileRoot = true).withRootTitle(it) }
bookmarkNode = withContext(IO) {
bookmarksStorage.getBookmark(args.guidToEdit)
}
if (initialParentGuid == null) {
initialParentGuid = bookmarkNode?.parentGuid
}
bookmarkParent = withContext(IO) {
// Use user-selected parent folder if it's set, or node's current parent otherwise.
if (sharedViewModel.selectedFolder != null) {
sharedViewModel.selectedFolder
} else {
bookmarkNode?.parentGuid?.let { bookmarksStorage.getBookmark(it) }
}
}
when (bookmarkNode?.type) {
@ -100,15 +110,23 @@ class EditBookmarkFragment : Fragment(R.layout.fragment_edit_bookmark) {
}
bookmarkParent?.let { node ->
bookmarkParentFolderSelector.text = node.title
bookmarkParentFolderSelector.setOnClickListener {
sharedViewModel.selectedFolder = null
nav(
R.id.bookmarkEditFragment,
EditBookmarkFragmentDirections
.actionBookmarkEditFragmentToBookmarkSelectFolderFragment(null)
)
}
bookmarkParentFolderSelector.text = friendlyRootTitle(context, node)
}
bookmarkParentFolderSelector.setOnClickListener {
sharedViewModel.selectedFolder = null
nav(
R.id.bookmarkEditFragment,
EditBookmarkFragmentDirections
.actionBookmarkEditFragmentToBookmarkSelectFolderFragment(
allowCreatingNewFolder = false,
// Don't allow moving folders into themselves.
hideFolderGuid = when (bookmarkNode!!.type) {
BookmarkNodeType.FOLDER -> bookmarkNode!!.guid
else -> null
}
)
)
}
view.bookmarkNameEdit.apply {
@ -209,14 +227,18 @@ class EditBookmarkFragment : Fragment(R.layout.fragment_edit_bookmark) {
if (title != bookmarkNode?.title || url != bookmarkNode?.url) {
components.analytics.metrics.track(Event.EditedBookmark)
}
if (sharedViewModel.selectedFolder != null) {
val parentGuid = sharedViewModel.selectedFolder?.guid ?: bookmarkNode!!.parentGuid
val parentChanged = initialParentGuid != parentGuid
// Only track the 'moved' event if new parent was selected.
if (parentChanged) {
components.analytics.metrics.track(Event.MovedBookmark)
}
components.core.bookmarksStorage.updateNode(
args.guidToEdit,
BookmarkInfo(
sharedViewModel.selectedFolder?.guid ?: bookmarkNode!!.parentGuid,
bookmarkNode?.position,
parentGuid,
// Setting position to 'null' is treated as a 'move to the end' by the storage API.
if (parentChanged) null else bookmarkNode?.position,
title,
if (bookmarkNode?.type == BookmarkNodeType.ITEM) url else null
)

@ -15,7 +15,6 @@ import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.extensions.LayoutContainer
import mozilla.components.concept.storage.BookmarkNode
import mozilla.components.concept.storage.BookmarkNodeType
import mozilla.components.support.ktx.android.util.dpToPx
import org.mozilla.fenix.R
import org.mozilla.fenix.library.LibrarySiteItemView
import org.mozilla.fenix.library.bookmarks.BookmarksSharedViewModel
@ -25,12 +24,19 @@ import org.mozilla.fenix.library.bookmarks.selectfolder.SelectBookmarkFolderAdap
class SelectBookmarkFolderAdapter(private val sharedViewModel: BookmarksSharedViewModel) :
ListAdapter<BookmarkNodeWithDepth, BookmarkFolderViewHolder>(DiffCallback) {
fun updateData(tree: BookmarkNode?) {
fun updateData(tree: BookmarkNode?, hideFolderGuid: String?) {
val updatedData = tree
?.convertToFolderDepthTree()
?.drop(1)
.orEmpty()
submitList(updatedData)
val filteredData = if (hideFolderGuid != null && updatedData.isNotEmpty()) {
updatedData.filter { it.node.guid != hideFolderGuid }
} else {
updatedData
}
submitList(filteredData)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BookmarkFolderViewHolder {
@ -85,8 +91,8 @@ class SelectBookmarkFolderAdapter(private val sharedViewModel: BookmarksSharedVi
view.setOnClickListener {
onSelect(folder.node)
}
val pxToIndent = dpsToIndent.dpToPx(view.context.resources.displayMetrics)
val padding = pxToIndent * if (folder.depth > maxDepth) maxDepth else folder.depth
val pxToIndent = view.resources.getDimensionPixelSize(R.dimen.bookmark_select_folder_indent)
val padding = pxToIndent * minOf(MAX_DEPTH, folder.depth)
view.updatePaddingRelative(start = padding)
}
@ -117,8 +123,7 @@ class SelectBookmarkFolderAdapter(private val sharedViewModel: BookmarksSharedVi
this == sharedViewModel.selectedFolder
companion object {
private const val maxDepth = 10
private const val dpsToIndent = 10
private const val MAX_DEPTH = 10
}
}

@ -50,6 +50,8 @@ class SelectBookmarkFolderFragment : Fragment() {
super.onResume()
showToolbar(getString(R.string.bookmark_select_folder_fragment_label))
val args: SelectBookmarkFolderFragmentArgs by navArgs()
viewLifecycleOwner.lifecycleScope.launch(Main) {
bookmarkNode = withContext(IO) {
val context = requireContext()
@ -59,13 +61,13 @@ class SelectBookmarkFolderFragment : Fragment() {
}
val adapter = SelectBookmarkFolderAdapter(sharedViewModel)
recylerViewBookmarkFolders.adapter = adapter
adapter.updateData(bookmarkNode)
adapter.updateData(bookmarkNode, args.hideFolderGuid)
}
}
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
val args: SelectBookmarkFolderFragmentArgs by navArgs()
if (!args.visitedAddBookmark) {
if (!args.allowCreatingNewFolder) {
inflater.inflate(R.menu.bookmarks_select_folder, menu)
}
}

@ -12,8 +12,10 @@ import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.SimpleItemAnimator
import kotlinx.android.synthetic.main.component_history.*
import kotlinx.android.synthetic.main.component_history.view.*
import kotlinx.android.synthetic.main.recently_closed_nav_item.*
import mozilla.components.support.base.feature.UserInteractionHandler
import org.mozilla.fenix.R
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.library.LibraryPageView
import org.mozilla.fenix.library.SelectionInteractor
import org.mozilla.fenix.theme.ThemeManager
@ -164,6 +166,19 @@ class HistoryView(
fun updateEmptyState(userHasHistory: Boolean) {
history_list.isVisible = userHasHistory
history_empty_view.isVisible = !userHasHistory
recently_closed_nav_empty.apply {
setOnClickListener {
interactor.onRecentlyClosedClicked()
}
val numRecentTabs = view.context.components.core.store.state.closedTabs.size
recently_closed_tabs_description.text = String.format(
view.context.getString(
if (numRecentTabs == 1)
R.string.recently_closed_tab else R.string.recently_closed_tabs
), numRecentTabs
)
isVisible = !userHasHistory
}
if (!userHasHistory) {
history_empty_view.announceForAccessibility(context.getString(R.string.history_empty_message))
}

@ -5,10 +5,12 @@
package org.mozilla.fenix.library.history.viewholders
import android.view.View
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.view.isVisible
import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.synthetic.main.history_list_item.view.*
import kotlinx.android.synthetic.main.library_site_item.view.*
import kotlinx.android.synthetic.main.recently_closed_nav_item.view.*
import org.mozilla.fenix.R
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.hideAndDisable
@ -41,7 +43,7 @@ class HistoryListItemViewHolder(
}
}
itemView.recently_closed.setOnClickListener {
itemView.findViewById<ConstraintLayout>(R.id.recently_closed_nav).setOnClickListener {
historyInteractor.onRecentlyClosedClicked()
}
}
@ -96,10 +98,11 @@ class HistoryListItemViewHolder(
showTopContent: Boolean,
isNormalMode: Boolean
) {
itemView.delete_button.isVisible = showTopContent
itemView.findViewById<ConstraintLayout>(R.id.recently_closed_nav).isVisible = showTopContent
if (showTopContent) {
itemView.delete_button.run {
visibility = View.VISIBLE
if (isNormalMode) {
isEnabled = true
alpha = 1f
@ -115,10 +118,15 @@ class HistoryListItemViewHolder(
R.string.recently_closed_tab else R.string.recently_closed_tabs
), numRecentTabs
)
itemView.recently_closed.isVisible = true
} else {
itemView.recently_closed.visibility = View.GONE
itemView.delete_button.visibility = View.GONE
itemView.findViewById<ConstraintLayout>(R.id.recently_closed_nav).run {
if (isNormalMode) {
isEnabled = true
alpha = 1f
} else {
isEnabled = false
alpha = DELETE_BUTTON_DISABLED_ALPHA
}
}
}
}

@ -19,6 +19,7 @@ import mozilla.components.feature.awesomebar.provider.SearchActionProvider
import mozilla.components.feature.awesomebar.provider.SearchSuggestionProvider
import mozilla.components.feature.awesomebar.provider.SessionSuggestionProvider
import mozilla.components.feature.search.SearchUseCases
import mozilla.components.feature.syncedtabs.DeviceIndicators
import mozilla.components.feature.session.SessionUseCases
import mozilla.components.feature.syncedtabs.SyncedTabsStorageSuggestionProvider
import mozilla.components.feature.tabs.TabsUseCases
@ -130,7 +131,12 @@ class AwesomeBarView(
SyncedTabsStorageSuggestionProvider(
components.backgroundServices.syncedTabsStorage,
components.useCases.tabsUseCases.addTab,
components.core.icons
components.core.icons,
DeviceIndicators(
getDrawable(activity, R.drawable.ic_search_results_device_desktop),
getDrawable(activity, R.drawable.ic_search_results_device_mobile),
getDrawable(activity, R.drawable.ic_search_results_device_tablet)
)
)
val searchBitmap = getDrawable(activity, R.drawable.ic_search)!!.apply {

@ -234,6 +234,8 @@ class SearchDialogFragment : AppCompatDialogFragment(), UserInteractionHandler {
}
fill_link_from_clipboard.setOnClickListener {
view.hideKeyboard()
toolbarView.view.clearFocus()
(activity as HomeActivity)
.openToBrowserAndLoad(
searchTermOrURL = requireContext().components.clipboardHandler.url ?: "",

@ -35,7 +35,6 @@ import mozilla.components.service.fxa.sync.SyncReason
import mozilla.components.service.fxa.sync.SyncStatusObserver
import mozilla.components.service.fxa.sync.getLastSynced
import mozilla.components.support.ktx.android.content.getColorFromAttr
import mozilla.components.support.ktx.android.util.dpToPx
import org.mozilla.fenix.R
import org.mozilla.fenix.components.FenixSnackbar
import org.mozilla.fenix.components.StoreProvider
@ -162,7 +161,7 @@ class AccountSettingsFragment : PreferenceFragmentCompat() {
}
setOnBindEditTextListener { editText ->
editText.filters = arrayOf(InputFilter.LengthFilter(DEVICE_NAME_MAX_LENGTH))
editText.minHeight = DEVICE_NAME_EDIT_TEXT_MIN_HEIGHT_DP.dpToPx(resources.displayMetrics)
editText.minHeight = resources.getDimensionPixelSize(R.dimen.account_settings_device_name_min_height)
}
}

@ -6,6 +6,7 @@ package org.mozilla.fenix.settings.account
import android.Manifest
import android.os.Bundle
import android.text.Spanned
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
@ -25,6 +26,7 @@ import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.R
import org.mozilla.fenix.components.FenixSnackbar
import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.ext.addUnderline
import org.mozilla.fenix.ext.requireComponents
import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.ext.showToolbar
@ -64,6 +66,10 @@ class TurnOnSyncFragment : Fragment(), AccountObserver {
requireComponents.analytics.metrics.track(Event.SyncAuthScanPairing)
}
private val createAccountClickListener = View.OnClickListener {
navigateToPairWithEmail()
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
requireComponents.analytics.metrics.track(Event.SyncAuthOpened)
@ -85,7 +91,8 @@ class TurnOnSyncFragment : Fragment(), AccountObserver {
override fun onResume() {
super.onResume()
if (pairWithEmailStarted ||
requireComponents.backgroundServices.accountManager.authenticatedAccount() != null) {
requireComponents.backgroundServices.accountManager.authenticatedAccount() != null
) {
findNavController().popBackStack()
return
@ -118,6 +125,20 @@ class TurnOnSyncFragment : Fragment(), AccountObserver {
DefaultSyncController(activity = activity as HomeActivity)
)
val createAccountActionText = getString(R.string.sign_in_create_account_link)
val fullText = getString(R.string.sign_in_create_account_text, createAccountActionText)
val spanStart = fullText.indexOf(createAccountActionText, 0, false)
val spanEnd = spanStart + createAccountActionText.length
view.createAccount.apply {
text = fullText
addUnderline(
spanStart,
spanEnd,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
)
setOnClickListener(createAccountClickListener)
}
return view
}

@ -17,7 +17,6 @@ import kotlinx.android.synthetic.main.view_synced_tabs_group.view.*
import kotlinx.android.synthetic.main.view_synced_tabs_title.view.*
import mozilla.components.concept.sync.DeviceType
import mozilla.components.feature.syncedtabs.view.SyncedTabsView
import mozilla.components.support.ktx.android.util.dpToPx
import org.mozilla.fenix.NavGraphDirections
import org.mozilla.fenix.R
import org.mozilla.fenix.sync.SyncedTabsAdapter.AdapterItem
@ -135,13 +134,8 @@ sealed class SyncedTabsViewHolder(itemView: View) : RecyclerView.ViewHolder(item
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT
)
val displayMetrics = itemView.context.resources.displayMetrics
val margin = ERROR_MARGIN.dpToPx(displayMetrics)
val margin = itemView.resources.getDimensionPixelSize(R.dimen.synced_tabs_error_margin)
lp.setMargins(margin, margin, margin, 0)
itemView.layoutParams = lp
}
companion object {
private const val ERROR_MARGIN = 20
}
}

@ -5,8 +5,8 @@
package org.mozilla.fenix.tabhistory
import androidx.navigation.NavController
import mozilla.components.browser.session.SessionManager
import mozilla.components.feature.session.SessionUseCases
import org.mozilla.fenix.R
interface TabHistoryController {
fun handleGoToHistoryItem(item: TabHistoryItem)
@ -14,11 +14,16 @@ interface TabHistoryController {
class DefaultTabHistoryController(
private val navController: NavController,
private val goToHistoryIndexUseCase: SessionUseCases.GoToHistoryIndexUseCase
private val goToHistoryIndexUseCase: SessionUseCases.GoToHistoryIndexUseCase,
private val customTabId: String? = null,
private val sessionManager: SessionManager
) : TabHistoryController {
override fun handleGoToHistoryItem(item: TabHistoryItem) {
navController.popBackStack(R.id.browserFragment, false)
goToHistoryIndexUseCase.invoke(item.index)
navController.navigateUp()
goToHistoryIndexUseCase.invoke(
item.index,
session = customTabId?.let { sessionManager.findSessionById(customTabId) }
?: sessionManager.selectedSession)
}
}

@ -12,10 +12,16 @@ import androidx.navigation.fragment.findNavController
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import kotlinx.android.synthetic.main.activity_home.*
import kotlinx.android.synthetic.main.fragment_tab_history_dialog.*
import kotlinx.coroutines.ExperimentalCoroutinesApi
import mozilla.components.lib.state.ext.consumeFrom
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.mapNotNull
import mozilla.components.browser.state.selector.findCustomTabOrSelectedTab
import mozilla.components.lib.state.ext.flowScoped
import mozilla.components.support.ktx.kotlinx.coroutines.flow.ifChanged
import org.mozilla.fenix.R
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.requireComponents
class TabHistoryDialogFragment : BottomSheetDialogFragment() {
@ -25,6 +31,8 @@ class TabHistoryDialogFragment : BottomSheetDialogFragment() {
setStyle(STYLE_NO_TITLE, R.style.BottomSheet)
}
var customTabSessionId: String? = null
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
@ -35,9 +43,13 @@ class TabHistoryDialogFragment : BottomSheetDialogFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
customTabSessionId = requireArguments().getString(EXTRA_SESSION_ID)
val controller = DefaultTabHistoryController(
navController = findNavController(),
goToHistoryIndexUseCase = requireComponents.useCases.sessionUseCases.goToHistoryIndex
goToHistoryIndexUseCase = requireComponents.useCases.sessionUseCases.goToHistoryIndex,
customTabId = customTabSessionId,
sessionManager = container.requireContext().components.core.sessionManager
)
val tabHistoryView = TabHistoryView(
container = tabHistoryLayout,
@ -45,12 +57,20 @@ class TabHistoryDialogFragment : BottomSheetDialogFragment() {
interactor = TabHistoryInteractor(controller)
)
consumeFrom(requireComponents.core.store) {
tabHistoryView.updateState(it)
requireComponents.core.store.flowScoped(viewLifecycleOwner) { flow ->
flow.mapNotNull { state -> state.findCustomTabOrSelectedTab(customTabSessionId)?.content?.history }
.ifChanged()
.collect { historyState ->
tabHistoryView.updateState(historyState)
}
}
}
private fun expand() {
(dialog as BottomSheetDialog).behavior.state = BottomSheetBehavior.STATE_EXPANDED
}
companion object {
const val EXTRA_SESSION_ID = "activeSessionId"
}
}

@ -11,8 +11,7 @@ import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.extensions.LayoutContainer
import kotlinx.android.synthetic.main.component_tabhistory.*
import mozilla.components.browser.state.selector.selectedTab
import mozilla.components.browser.state.state.BrowserState
import mozilla.components.browser.state.state.content.HistoryState
import org.mozilla.fenix.R
interface TabHistoryViewInteractor {
@ -66,18 +65,16 @@ class TabHistoryView(
tabHistoryRecyclerView.layoutManager = layoutManager
}
fun updateState(state: BrowserState) {
state.selectedTab?.content?.history?.let { historyState ->
currentIndex = historyState.currentIndex
val items = historyState.items.mapIndexed { index, historyItem ->
TabHistoryItem(
title = historyItem.title,
url = historyItem.uri,
index = index,
isSelected = index == historyState.currentIndex
)
}
adapter.submitList(items)
fun updateState(historyState: HistoryState) {
currentIndex = historyState.currentIndex
val items = historyState.items.mapIndexed { index, historyItem ->
TabHistoryItem(
title = historyItem.title,
url = historyItem.uri,
index = index,
isSelected = index == currentIndex
)
}
adapter.submitList(items)
}
}

@ -8,10 +8,10 @@ import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.CheckedTextView
import androidx.annotation.VisibleForTesting
import androidx.core.content.ContextCompat
import androidx.appcompat.content.res.AppCompatResources
import androidx.core.view.updatePaddingRelative
import androidx.recyclerview.widget.RecyclerView
import mozilla.components.support.ktx.android.util.dpToPx
import mozilla.components.support.ktx.android.view.putCompoundDrawablesRelativeWithIntrinsicBounds
import org.mozilla.fenix.R
internal class CollectionsAdapter(
@ -36,15 +36,17 @@ internal class CollectionsAdapter(
override fun onBindViewHolder(holder: CollectionItemViewHolder, position: Int) {
if (position == 0) {
val displayMetrics = holder.textView.context.resources.displayMetrics
holder.textView.updatePaddingRelative(start = NEW_COLLECTION_PADDING_START.dpToPx(displayMetrics))
val resources = holder.textView.resources
holder.textView.updatePaddingRelative(
start = resources.getDimensionPixelSize(R.dimen.tab_tray_new_collection_padding_start)
)
holder.textView.compoundDrawablePadding =
NEW_COLLECTION_DRAWABLE_PADDING.dpToPx(displayMetrics)
holder.textView.setCompoundDrawablesWithIntrinsicBounds(
ContextCompat.getDrawable(
resources.getDimensionPixelSize(R.dimen.tab_tray_new_collection_drawable_padding)
holder.textView.putCompoundDrawablesRelativeWithIntrinsicBounds(
start = AppCompatResources.getDrawable(
holder.textView.context,
R.drawable.ic_new
), null, null, null
)
)
} else {
holder.textView.isChecked = checkedPosition == position
@ -65,9 +67,4 @@ internal class CollectionsAdapter(
override fun getItemCount() = collections.size
fun getSelectedCollection() = checkedPosition - 1
companion object {
private const val NEW_COLLECTION_PADDING_START = 24
private const val NEW_COLLECTION_DRAWABLE_PADDING = 28
}
}

@ -54,7 +54,6 @@ import mozilla.components.browser.state.state.BrowserState
import mozilla.components.browser.tabstray.TabViewHolder
import mozilla.components.feature.syncedtabs.SyncedTabsFeature
import mozilla.components.support.base.feature.ViewBoundFeatureWrapper
import mozilla.components.support.ktx.android.util.dpToPx
import org.mozilla.fenix.R
import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.components.toolbar.TabCounter.Companion.INFINITE_CHAR_PADDING_BOTTOM
@ -568,20 +567,29 @@ class TabTrayView(
)
)
val displayMetrics = view.context.resources.displayMetrics
view.handle.updateLayoutParams<ViewGroup.MarginLayoutParams> {
height =
if (multiselect) MULTISELECT_HANDLE_HEIGHT.dpToPx(displayMetrics) else NORMAL_HANDLE_HEIGHT.dpToPx(
displayMetrics
)
height = view.resources.getDimensionPixelSize(
if (multiselect) {
R.dimen.tab_tray_multiselect_handle_height
} else {
R.dimen.tab_tray_normal_handle_height
}
)
if (useTopTabsTray) {
bottomMargin = if (multiselect) 0.dpToPx(displayMetrics) else NORMAL_BOTTOM_MARGIN.dpToPx(
displayMetrics
bottomMargin = view.resources.getDimensionPixelSize(
if (multiselect) {
R.dimen.tab_tray_multiselect_handle_bottom_margin
} else {
R.dimen.tab_tray_normal_handle_bottom_margin
}
)
} else {
topMargin = if (multiselect) 0.dpToPx(displayMetrics) else NORMAL_TOP_MARGIN.dpToPx(
displayMetrics
topMargin = view.resources.getDimensionPixelSize(
if (multiselect) {
R.dimen.tab_tray_multiselect_handle_top_margin
} else {
R.dimen.tab_tray_normal_handle_top_margin
}
)
}
}
@ -672,7 +680,7 @@ class TabTrayView(
val topOffset = if (landscape) {
0
} else {
view.context.resources.getDimension(R.dimen.tab_tray_top_offset).toInt()
view.context.resources.getDimensionPixelSize(R.dimen.tab_tray_top_offset)
}
if (!useTopTabsTray) {
@ -689,11 +697,11 @@ class TabTrayView(
if (private) {
fabView.new_tab_button.extend()
fabView.new_tab_button.contentDescription =
view.context.resources.getString(R.string.add_private_tab)
view.context.getString(R.string.add_private_tab)
} else {
fabView.new_tab_button.shrink()
fabView.new_tab_button.contentDescription =
view.context.resources.getString(R.string.add_tab)
view.context.getString(R.string.add_tab)
}
}
@ -734,10 +742,6 @@ class TabTrayView(
private const val EXPAND_AT_SIZE = 3
private const val SLIDE_OFFSET = 0
private const val SELECTION_DELAY = 500
private const val MULTISELECT_HANDLE_HEIGHT = 11
private const val NORMAL_HANDLE_HEIGHT = 3
private const val NORMAL_TOP_MARGIN = 8
private const val NORMAL_BOTTOM_MARGIN = 8
private const val NORMAL_HANDLE_PERCENT_WIDTH = 0.1F
private const val COLUMN_WIDTH_DP = 190
}

@ -80,7 +80,7 @@ class TouchCallback(
val iconLeft: Int
val iconRight: Int
val margin =
SwipeToDeleteCallback.MARGIN.dpToPx(recyclerView.context.resources.displayMetrics)
SwipeToDeleteCallback.MARGIN.dpToPx(recyclerView.resources.displayMetrics)
val iconWidth = icon.intrinsicWidth
val iconHeight = icon.intrinsicHeight
val cellHeight = itemView.bottom - itemView.top

@ -10,6 +10,7 @@ import androidx.core.view.isVisible
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.navArgs
import kotlinx.android.synthetic.main.fragment_tracking_protection_blocking.*
import org.mozilla.fenix.FeatureFlags
import org.mozilla.fenix.R
import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.ext.showToolbar
@ -22,6 +23,7 @@ class TrackingProtectionBlockingFragment :
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
category_redirect_trackers.isVisible = FeatureFlags.etpCookiePurging
when (args.protectionMode) {
TrackingProtectionMode.STANDARD -> {

@ -7,7 +7,6 @@ package org.mozilla.fenix.trackingprotection
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import androidx.appcompat.content.res.AppCompatResources
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.withStyledAttributes
import kotlinx.android.synthetic.main.tracking_protection_category.view.*
@ -27,11 +26,6 @@ class TrackingProtectionCategoryItem @JvmOverloads constructor(
defStyleAttr,
0
) {
val id = getResourceId(
R.styleable.TrackingProtectionCategory_categoryItemIcon,
R.drawable.ic_cryptominers
)
trackingProtectionCategoryIcon?.background = AppCompatResources.getDrawable(context, id)
trackingProtectionCategoryTitle?.text = resources.getString(
getResourceId(
R.styleable.TrackingProtectionCategory_categoryItemTitle,

@ -149,9 +149,14 @@ class TrackingProtectionPanelView(
}
}
/**
* Checks whether the permission was allowed or blocked when they were last used based on
* visibility, where "..._loaded" titles correspond to "Allowed" permissions and the other
* corresponds to "Blocked" permissions for each category.
*/
private fun getLastUsedCategoryView(categoryTitle: String) = when (categoryTitle) {
CROSS_SITE_TRACKING_COOKIES.name -> {
cross_site_tracking
if (cross_site_tracking.isGone) cross_site_tracking_loaded else cross_site_tracking
}
SOCIAL_MEDIA_TRACKERS.name -> {
if (social_media_trackers.isGone) social_media_trackers_loaded else social_media_trackers
@ -171,11 +176,14 @@ class TrackingProtectionPanelView(
private fun updateCategoryVisibility() {
cross_site_tracking.isGone =
bucketedTrackers.get(CROSS_SITE_TRACKING_COOKIES, true).isEmpty()
social_media_trackers.isGone = bucketedTrackers.get(SOCIAL_MEDIA_TRACKERS, true).isEmpty()
social_media_trackers.isGone =
bucketedTrackers.get(SOCIAL_MEDIA_TRACKERS, true).isEmpty()
fingerprinters.isGone = bucketedTrackers.get(FINGERPRINTERS, true).isEmpty()
tracking_content.isGone = bucketedTrackers.get(TRACKING_CONTENT, true).isEmpty()
cryptominers.isGone = bucketedTrackers.get(CRYPTOMINERS, true).isEmpty()
cross_site_tracking_loaded.isGone =
bucketedTrackers.get(CROSS_SITE_TRACKING_COOKIES, false).isEmpty()
social_media_trackers_loaded.isGone =
bucketedTrackers.get(SOCIAL_MEDIA_TRACKERS, false).isEmpty()
fingerprinters_loaded.isGone = bucketedTrackers.get(FINGERPRINTERS, false).isEmpty()
@ -189,6 +197,7 @@ class TrackingProtectionPanelView(
cross_site_tracking.setOnClickListener(this)
tracking_content.setOnClickListener(this)
cryptominers.setOnClickListener(this)
cross_site_tracking_loaded.setOnClickListener(this)
social_media_trackers_loaded.setOnClickListener(this)
fingerprinters_loaded.setOnClickListener(this)
tracking_content_loaded.setOnClickListener(this)
@ -251,7 +260,7 @@ class TrackingProtectionPanelView(
private fun getCategory(v: View) = when (v.id) {
R.id.social_media_trackers, R.id.social_media_trackers_loaded -> SOCIAL_MEDIA_TRACKERS
R.id.fingerprinters, R.id.fingerprinters_loaded -> FINGERPRINTERS
R.id.cross_site_tracking -> CROSS_SITE_TRACKING_COOKIES
R.id.cross_site_tracking, R.id.cross_site_tracking_loaded -> CROSS_SITE_TRACKING_COOKIES
R.id.tracking_content, R.id.tracking_content_loaded -> TRACKING_CONTENT
R.id.cryptominers, R.id.cryptominers_loaded -> CRYPTOMINERS
else -> null
@ -262,6 +271,7 @@ class TrackingProtectionPanelView(
*/
private fun isLoaded(v: View) = when (v.id) {
R.id.social_media_trackers_loaded,
R.id.cross_site_tracking_loaded,
R.id.fingerprinters_loaded,
R.id.tracking_content_loaded,
R.id.cryptominers_loaded -> true

@ -68,8 +68,7 @@ fun CoroutineScope.allowUndo(
}
val shouldUseBottomToolbar = view.context.settings().shouldUseBottomToolbar
val toolbarHeight = view.context.resources
.getDimensionPixelSize(R.dimen.browser_toolbar_height)
val toolbarHeight = view.resources.getDimensionPixelSize(R.dimen.browser_toolbar_height)
snackbar.view.updatePadding(
bottom = if (

@ -2,48 +2,58 @@
<!-- 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/. -->
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/history_wrapper"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/history_wrapper"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ProgressBar
android:id="@+id/progress_bar"
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
android:indeterminate="true"
android:layout_width="match_parent"
android:layout_height="8dp"
android:translationY="-3dp"
android:visibility="gone"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent" />
android:id="@+id/progress_bar"
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="8dp"
android:indeterminate="true"
android:translationY="-3dp"
android:visibility="gone"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<include
android:id="@+id/recently_closed_nav_empty"
layout="@layout/recently_closed_nav_item"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="@id/progress_bar" />
<TextView
android:id="@+id/history_empty_view"
android:layout_width="0dp"
android:layout_height="0dp"
android:gravity="center"
android:text="@string/history_empty_message"
android:textColor="?secondaryText"
android:textSize="16sp"
android:visibility="gone"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
android:id="@+id/history_empty_view"
android:layout_width="0dp"
android:layout_height="0dp"
android:gravity="center"
android:text="@string/history_empty_message"
android:textColor="?secondaryText"
android:textSize="16sp"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/recently_closed_nav_empty" />
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swipe_refresh"
android:layout_width="match_parent"
android:layout_height="match_parent" >
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="@id/recently_closed_nav_empty">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/history_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical"
tools:listitem="@layout/history_list_item"/>
android:visibility="gone"
tools:listitem="@layout/history_list_item" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

@ -61,7 +61,6 @@
android:layout_height="@dimen/tracking_protection_item_height"
android:text="@string/etp_cookies_title"
android:visibility="gone"
app:drawableStartCompat="@drawable/ic_cookies"
app:layout_constraintTop_toBottomOf="@id/blocking_header" />
<TextView
@ -71,7 +70,6 @@
android:layout_height="@dimen/tracking_protection_item_height"
android:text="@string/etp_fingerprinters_title"
android:visibility="gone"
app:drawableStartCompat="@drawable/ic_fingerprinters"
app:layout_constraintTop_toBottomOf="@id/cross_site_tracking" />
<TextView
@ -81,7 +79,6 @@
android:layout_height="@dimen/tracking_protection_item_height"
android:text="@string/etp_cryptominers_title"
android:visibility="gone"
app:drawableStartCompat="@drawable/ic_cryptominers"
app:layout_constraintTop_toBottomOf="@id/fingerprinters" />
<TextView
@ -91,7 +88,6 @@
android:layout_height="@dimen/tracking_protection_item_height"
android:text="@string/etp_social_media_trackers_title"
android:visibility="gone"
app:drawableStartCompat="@drawable/ic_social_media_trackers"
app:layout_constraintTop_toBottomOf="@id/cryptominers" />
<TextView
@ -101,7 +97,6 @@
android:layout_height="@dimen/tracking_protection_item_height"
android:text="@string/etp_tracking_content_title"
android:visibility="gone"
app:drawableStartCompat="@drawable/ic_tracking_content"
app:layout_constraintTop_toBottomOf="@id/social_media_trackers" />
<TextView
@ -117,6 +112,15 @@
app:layout_constraintTop_toBottomOf="@id/tracking_content"
tools:targetApi="p" />
<TextView
android:id="@+id/cross_site_tracking_loaded"
style="@style/QuickSettingsLargeText.Icon"
android:layout_width="match_parent"
android:layout_height="@dimen/tracking_protection_item_height"
android:text="@string/etp_cookies_title"
android:visibility="gone"
app:layout_constraintTop_toBottomOf="@id/not_blocking_header" />
<TextView
android:id="@+id/fingerprinters_loaded"
style="@style/QuickSettingsLargeText.Icon"
@ -124,8 +128,7 @@
android:layout_height="@dimen/tracking_protection_item_height"
android:text="@string/etp_fingerprinters_title"
android:visibility="gone"
app:drawableStartCompat="@drawable/ic_fingerprinters"
app:layout_constraintTop_toBottomOf="@id/not_blocking_header" />
app:layout_constraintTop_toBottomOf="@id/cross_site_tracking_loaded" />
<TextView
android:id="@+id/cryptominers_loaded"
@ -134,7 +137,6 @@
android:layout_height="@dimen/tracking_protection_item_height"
android:text="@string/etp_cryptominers_title"
android:visibility="gone"
app:drawableStartCompat="@drawable/ic_cryptominers"
app:layout_constraintTop_toBottomOf="@id/fingerprinters_loaded" />
<TextView
@ -144,7 +146,6 @@
android:layout_height="@dimen/tracking_protection_item_height"
android:text="@string/etp_social_media_trackers_title"
android:visibility="gone"
app:drawableStartCompat="@drawable/ic_social_media_trackers"
app:layout_constraintTop_toBottomOf="@id/cryptominers_loaded" />
<TextView
@ -154,7 +155,6 @@
android:layout_height="@dimen/tracking_protection_item_height"
android:text="@string/etp_tracking_content_title"
android:visibility="gone"
app:drawableStartCompat="@drawable/ic_tracking_content"
app:layout_constraintTop_toBottomOf="@id/social_media_trackers_loaded" />
<View

@ -31,7 +31,6 @@
android:clickable="true"
android:focusable="true"
app:categoryItemDescription="@string/etp_social_media_trackers_description"
app:categoryItemIcon="@drawable/ic_social_media_trackers"
app:categoryItemTitle="@string/etp_social_media_trackers_title" />
<org.mozilla.fenix.trackingprotection.TrackingProtectionCategoryItem
@ -42,7 +41,6 @@
android:clickable="true"
android:focusable="true"
app:categoryItemDescription="@string/etp_cookies_description"
app:categoryItemIcon="@drawable/ic_cookies"
app:categoryItemTitle="@string/etp_cookies_title" />
<org.mozilla.fenix.trackingprotection.TrackingProtectionCategoryItem
@ -53,7 +51,6 @@
android:clickable="true"
android:focusable="true"
app:categoryItemDescription="@string/etp_cryptominers_description"
app:categoryItemIcon="@drawable/ic_cryptominers"
app:categoryItemTitle="@string/etp_cryptominers_title" />
<org.mozilla.fenix.trackingprotection.TrackingProtectionCategoryItem
@ -64,7 +61,6 @@
android:clickable="true"
android:focusable="true"
app:categoryItemDescription="@string/etp_fingerprinters_description"
app:categoryItemIcon="@drawable/ic_fingerprinters"
app:categoryItemTitle="@string/etp_fingerprinters_title" />
<org.mozilla.fenix.trackingprotection.TrackingProtectionCategoryItem
@ -75,7 +71,17 @@
android:clickable="true"
android:focusable="true"
app:categoryItemDescription="@string/etp_tracking_content_description"
app:categoryItemIcon="@drawable/ic_tracking_content"
app:categoryItemTitle="@string/etp_tracking_content_title" />
<org.mozilla.fenix.trackingprotection.TrackingProtectionCategoryItem
android:id="@+id/category_redirect_trackers"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?android:attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"
android:visibility="gone"
app:categoryItemDescription="@string/etp_redirect_trackers_description"
app:categoryItemTitle="@string/etp_redirect_trackers_title" />
</LinearLayout>
</ScrollView>

@ -71,7 +71,19 @@
android:layout_margin="0dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/signInScanButton" />
app:layout_constraintTop_toBottomOf="@id/signInScanButton"
app:layout_constraintBottom_toTopOf="@id/createAccount"/>
<TextView
android:id="@+id/createAccount"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:gravity="center"
android:textAppearance="@style/Body14TextStyle"
app:layout_constraintTop_toBottomOf="@id/signInEmailButton"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
tools:text="@string/sign_in_create_account_text"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>

@ -3,7 +3,6 @@
- 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/. -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -16,63 +15,7 @@
android:text="@string/history_delete_all"
android:visibility="gone" />
<androidx.constraintlayout.widget.ConstraintLayout
android:visibility="gone"
android:id="@+id/recently_closed"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:background="?android:attr/selectableItemBackground"
android:minHeight="@dimen/library_item_height">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/icon"
android:layout_width="@dimen/history_favicon_width_height"
android:layout_height="@dimen/history_favicon_width_height"
android:layout_marginStart="20dp"
android:importantForAccessibility="no"
android:padding="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_multiple_tabs" />
<TextView
android:id="@+id/recently_closed_tabs_header"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:ellipsize="end"
android:singleLine="true"
android:text="@string/library_recently_closed_tabs"
android:textAlignment="viewStart"
android:textColor="?primaryText"
android:textSize="18sp"
app:layout_constraintBottom_toTopOf="@+id/recently_closed_tabs_description"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/icon"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed"
app:layout_goneMarginEnd="@dimen/library_item_icon_margin_horizontal" />
<TextView
android:id="@+id/recently_closed_tabs_description"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:ellipsize="end"
android:singleLine="true"
android:textAlignment="viewStart"
android:textColor="?secondaryText"
android:textSize="12sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/icon"
app:layout_constraintTop_toBottomOf="@id/recently_closed_tabs_header"
app:layout_goneMarginEnd="@dimen/library_item_icon_margin_horizontal"
tools:text="2 tabs" />
</androidx.constraintlayout.widget.ConstraintLayout>
<include layout="@layout/recently_closed_nav_item" />
<TextView
android:id="@+id/header_title"

@ -0,0 +1,66 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 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/. -->
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/recently_closed_nav"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:background="?android:attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"
android:minHeight="@dimen/library_item_height"
android:visibility="gone"
app:layout_constraintTop_toTopOf="parent">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/icon"
android:layout_width="@dimen/history_favicon_width_height"
android:layout_height="@dimen/history_favicon_width_height"
android:layout_marginStart="20dp"
android:importantForAccessibility="no"
android:padding="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/ic_multiple_tabs" />
<TextView
android:id="@+id/recently_closed_tabs_header"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:ellipsize="end"
android:singleLine="true"
android:text="@string/library_recently_closed_tabs"
android:textAlignment="viewStart"
android:textColor="?primaryText"
android:textSize="18sp"
app:layout_constraintBottom_toTopOf="@+id/recently_closed_tabs_description"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/icon"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed"
app:layout_goneMarginEnd="@dimen/library_item_icon_margin_horizontal" />
<TextView
android:id="@+id/recently_closed_tabs_description"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:ellipsize="end"
android:singleLine="true"
android:textAlignment="viewStart"
android:textColor="?secondaryText"
android:textSize="12sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/icon"
app:layout_constraintTop_toBottomOf="@id/recently_closed_tabs_header"
app:layout_goneMarginEnd="@dimen/library_item_icon_margin_horizontal"
tools:text="2 tabs" />
</androidx.constraintlayout.widget.ConstraintLayout>

@ -22,7 +22,6 @@
android:contentDescription="@string/content_description_close_button"
android:padding="12dp"
app:iconTint="@color/neutral_text"
app:layout_constraintEnd_toStartOf="@id/title"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/mozac_ic_close" />

@ -9,25 +9,11 @@
android:layout_height="wrap_content"
tools:parentTag="androidx.constraintlayout.widget.ConstraintLayout">
<ImageView
android:id="@+id/trackingProtectionCategoryIcon"
android:layout_width="@dimen/preference_icon_drawable_size"
android:layout_height="@dimen/preference_icon_drawable_size"
android:layout_marginStart="@dimen/library_item_icon_margin_horizontal"
android:layout_marginTop="@dimen/library_item_icon_margin_vertical"
android:layout_marginEnd="@dimen/library_item_icon_margin_horizontal"
android:layout_marginBottom="@dimen/library_item_icon_margin_vertical"
android:background="@drawable/ic_cryptominers"
android:clickable="false"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/trackingProtectionCategoryTitle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/radio_button_drawable_padding"
android:layout_marginStart="@dimen/top_bar_alignment_margin_start"
android:layout_marginTop="@dimen/about_list_margin_top"
android:layout_marginEnd="@dimen/library_item_icon_margin_horizontal"
android:clickable="false"
@ -36,15 +22,14 @@
app:layout_constraintBottom_toTopOf="@+id/trackingProtectionCategoryItemDescription"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@id/trackingProtectionCategoryIcon"
app:layout_constraintTop_toTopOf="parent"
tools:text="@tools:sample/lorem" />
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/trackingProtectionCategoryItemDescription"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/radio_button_drawable_padding"
android:layout_marginStart="@dimen/top_bar_alignment_margin_start"
android:layout_marginEnd="@dimen/library_item_icon_margin_horizontal"
android:layout_marginBottom="@dimen/tracking_protection_item_margin_bottom"
android:clickable="false"
@ -52,7 +37,6 @@
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@id/trackingProtectionCategoryIcon"
app:layout_constraintTop_toBottomOf="@+id/trackingProtectionCategoryTitle"
tools:text="@tools:sample/lorem/random" />
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/trackingProtectionCategoryTitle" />
</merge>

@ -298,10 +298,6 @@
android:name="org.mozilla.fenix.library.bookmarks.selectfolder.SelectBookmarkFolderFragment"
android:label="@string/bookmark_select_folder_fragment_label"
tools:layout="@layout/fragment_select_bookmark_folder">
<argument
android:name="folderGuid"
app:argType="string"
app:nullable="true" />
<action
android:id="@+id/action_bookmarkSelectFolderFragment_self"
app:destination="@id/bookmarkSelectFolderFragment" />
@ -309,9 +305,14 @@
android:id="@+id/action_bookmarkSelectFolderFragment_to_bookmarkAddFolderFragment"
app:destination="@id/bookmarkAddFolderFragment" />
<argument
android:name="visitedAddBookmark"
android:name="allowCreatingNewFolder"
android:defaultValue="false"
app:argType="boolean" />
<argument
android:name="hideFolderGuid"
android:defaultValue="@null"
app:nullable="true"
app:argType="string" />
</fragment>
<fragment
@ -835,7 +836,12 @@
<dialog
android:id="@+id/tabHistoryDialogFragment"
android:name="org.mozilla.fenix.tabhistory.TabHistoryDialogFragment"
tools:layout="@layout/fragment_tab_history_dialog" />
tools:layout="@layout/fragment_tab_history_dialog">
<argument
android:name="activeSessionId"
app:argType="string"
app:nullable="true" />
</dialog>
<navigation
android:id="@+id/site_permissions_exceptions_graph"

@ -262,6 +262,8 @@
<string name="preferences_open_links_in_a_private_tab">Ubrir vinclos en una pestanya privada</string>
<!-- 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>
<!-- Will inform the user of the risk of activating Allow screenshots in private browsing option -->
<string name="preferences_screenshots_in_private_mode_disclaimer">Si ye permitiu, las pestanyas privadas seran visibles quan multiples aplicacions sigan ubiertas</string>
<!-- Preference for adding private browsing shortcut -->
<string name="preferences_add_private_browsing_shortcut">Adhibir acceso directo a navegación privada</string>
<!-- Preference for accessibility -->
@ -282,6 +284,8 @@
<string name="preferences_theme">Tema</string>
<!-- Preference for customizing the home screen -->
<string name="preferences_home">Inicio</string>
<!-- Preference for gestures based actions -->
<string name="preferences_gestures">Cenyos</string>
<!-- Preference for settings related to visual options -->
<string name="preferences_customize">Personalizar</string>
<!-- Preference description for banner about signing in -->
@ -316,8 +320,12 @@
<string name="preferences_search_browsing_history">Buscar historial de navegación</string>
<!-- Preference title for switch preference to suggest bookmarks when searching -->
<string name="preferences_search_bookmarks">Buscar marcapachinas</string>
<!-- Preference title for switch preference to suggest synced tabs when searching -->
<string name="preferences_search_synced_tabs">Mirar en pestanyas sincronizadas</string>
<!-- Preference for account settings -->
<string name="preferences_account_settings">Achustes da cuenta</string>
<!-- Preference for enabling url autocomplete-->
<string name="preferences_enable_autocomplete_urls">Autocompletar URLs</string>
<!-- Preference for open links in third party apps -->
<string name="preferences_open_links_in_apps">Ubrir vinclos en aplicacions</string>
<!-- Preference for open download with an external download manager app -->
@ -452,6 +460,12 @@
<!-- Preference for using following device theme -->
<string name="preference_follow_device_theme">Seguir tema do dispositivo</string>
<!-- Gestures Preferences-->
<!-- Preferences for using pull to refresh in a webpage -->
<string name="preference_gestures_website_pull_to_refresh">Estirar pa refrescar</string>
<!-- Preference for using the dynamic toolbar -->
<string name="preference_gestures_dynamic_toolbar">Desplazar pa amagar la barra de ferramientas</string>
<!-- Library -->
<!-- Option in Library to open Sessions page -->
<string name="library_sessions">Sesions</string>
@ -1031,10 +1045,6 @@
<string name="onboarding_account_sign_in_header">Encomienza la sincronización d\'as adrezas d\'interés, las contrasenyas y muito mas con a tuya cuenta d\'o Firefox.</string>
<!-- Text for the button to learn more about signing in to your Firefox account -->
<string name="onboarding_manual_sign_in_learn_more">Saber-ne mas</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_2">Ya has iniciau sesión como %s en unatro navegador Firefox deste telefono. Quiers iniciar sesión con esta cuenta?</string>
<!-- text for the button to confirm automatic sign-in -->
<string name="onboarding_firefox_account_auto_signin_confirm">Sí, iniciar sesión</string>
<!-- text for the automatic sign-in button while signing in is in process -->
@ -1272,8 +1282,6 @@
<string name="add_to_homescreen_continue">Continar a lo puesto web</string>
<!-- Placeholder text for the TextView in the Add to Homescreen dialog -->
<string name="add_to_homescreen_text_placeholder">Nombre dacceso directo</string>
<!-- Describes the add to homescreen functionality -->
<string name="add_to_homescreen_description">Puetz anyadir facilment este puesto web a la tuya pachina dinicio pa tener-ie acceso instantanio y navegar rapidament como si estase una aplicación.</string>
<!-- Preference for managing the settings for logins and passwords in Fenix -->
<string name="preferences_passwords_logins_and_passwords">Inicios de sesión y claus</string>
@ -1496,7 +1504,7 @@
<string name="saved_login_duplicate">Ya existe un inicio de sesión con ixe nombre dusuario</string>
<!-- Synced Tabs -->
<!-- Text displayed to ask user to connect another device as no devices found with account -->
<!-- Text displayed to ask user to connect another device as no devices found with account -->
<string name="synced_tabs_connect_another_device">Connectar unatro dispositivo.</string>
<!-- Text displayed asking user to re-authenticate -->
<string name="synced_tabs_reauth">Per favor, torna a autentificar-te.</string>
@ -1515,8 +1523,6 @@
<!-- Top Sites -->
<!-- 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>
<!-- Content description text displayed in the dialog when top sites limit is reached. -->
<string name="top_sites_max_limit_content">Pa anyadir un nuevo puesto principal, has de borrar-ne belatro. Mantiene pretau lo puesto y selecciona borrar.</string>
<!-- Confirmation dialog button text when top sites limit is reached. -->
<string name="top_sites_max_limit_confirmation_button">Vale, entendiu</string>
<!-- Label for the show most visited sites preference -->
@ -1525,7 +1531,7 @@
<!-- Content description for close button in collection placeholder. -->
<string name="remove_home_collection_placeholder_content_description">Eliminar</string>
<!-- depcrecated: text for the firefox account onboarding card header
<!-- 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">Quita-le lo millor provecho a %s.</string>
@ -1533,4 +1539,9 @@
<string name="no_collections_header1">Colecciona las cosetas que timportan</string>
<!-- Deprecated: Label to describe what collections are to a new user without any collections -->
<string name="no_collections_description1">Agrupa busquedas, puestos y pestanyas semellants pa un acceso rapido mas tarde.</string>
<!-- Deprecated: text for the firefox account onboarding card header when we detect you're already signed in to -->
<string name="onboarding_firefox_account_auto_signin_header_2">Ya has iniciau sesión como %s en unatro navegador Firefox deste telefono. Quiers iniciar sesión con esta cuenta?</string>
<!-- Deprecated: Describes the add to homescreen functionality -->
<string name="add_to_homescreen_description">Puetz anyadir facilment este puesto web a la tuya pachina dinicio pa tener-ie acceso instantanio y navegar rapidament como si estase una aplicación.</string>
</resources>

@ -318,6 +318,8 @@
<string name="preferences_search_browsing_history">Buscar nel historial de restolar</string>
<!-- Preference title for switch preference to suggest bookmarks when searching -->
<string name="preferences_search_bookmarks">Buscar nos marcadores</string>
<!-- Preference title for switch preference to suggest synced tabs when searching -->
<string name="preferences_search_synced_tabs">Buscar llingüetes sincronizaes</string>
<!-- Preference for account settings -->
<string name="preferences_account_settings">Axustes de la cuenta</string>
<!-- Preference for open links in third party apps -->
@ -600,7 +602,7 @@
<!-- 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">Perdona pero %1$s nun pue cargar esa páxina.</string>
<string name="tab_crash_title_2">Perdona mas %1$s nun pue cargar esa páxina.</string>
<!-- Description text displayed on the tab crash page -->
<string name="tab_crash_description">Pues tentar de restaurar o zarrar esta llingüeta embaxo.</string>
@ -1012,7 +1014,7 @@
<!-- text for tracking protection radio button option for strict level of blocking -->
<string name="onboarding_tracking_protection_strict_option">Estricta</string>
<!-- text for strict blocking option button description -->
<string name="onboarding_tracking_protection_strict_button_description_2">Bloquia más rastrexadores, anuncios y ventanos emerxentes. Los páxines van cargar más rápido pero quiciabes dalgunes funcionalidaes nun funcionen.</string>
<string name="onboarding_tracking_protection_strict_button_description_2">Bloquia más rastrexadores, anuncios y ventanos emerxentes. Los páxines van cargar más rápido mas dalgunes funcionalidaes quiciabes nun funcionen.</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 -->
@ -1078,9 +1080,9 @@
<!-- Text shown for settings option for sign with email -->
<string name="sign_in_with_email">Usar una direición de corréu</string>
<!-- Text shown in confirmation dialog to sign out of account -->
<string name="sign_out_confirmation_message">Firefox va dexar de sincronizase cola to cuenta pero 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) -->
<string name="sign_out_confirmation_message_2">%s va dexar de sincronizase cola to cuenta pero nun va desaniciar nengún datu d\'esti preséu.</string>
<string name="sign_out_confirmation_message_2">%s va dexar de sincronizase cola to cuenta mas nun va desaniciar nengún datu d\'esti preséu.</string>
<!-- Option to continue signing out of account shown in confirmation dialog to sign out of account -->
<string name="sign_out_disconnect">Desconeutar</string>
@ -1110,7 +1112,7 @@
<!-- Preference for enhanced tracking protection for the strict protection settings -->
<string name="preference_enhanced_tracking_protection_strict">Estricta</string>
<!-- Preference description for enhanced tracking protection for the strict protection settings -->
<string name="preference_enhanced_tracking_protection_strict_description_2">Bloquia más rastrexadores, anuncios y ventanos emerxentes. Les páxines van cargar más rápido pero quiciabes dalgunes funcionalidaes nun funcionen.</string>
<string name="preference_enhanced_tracking_protection_strict_description_2">Bloquia más rastrexadores, anuncios y ventanos emerxentes. Les páxines van cargar más rápido mas dalgunes funcionalidaes quiciabes nun funcionen.</string>
<!-- Accessibility text for the Strict protection information icon -->
<string name="preference_enhanced_tracking_protection_strict_info_button">Lo que la proteición estricta escontra\'l rastrexu bloquia</string>
<!-- Preference for enhanced tracking protection for the custom protection settings -->
@ -1472,7 +1474,7 @@
<!-- Label for the show most visited sites preference -->
<string name="top_sites_toggle_top_frecent_sites">Amosar los sitios más visitaos</string>
<!-- depcrecated: text for the firefox account onboarding card header
<!-- 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">Aprovecha %s al máximu.</string>

@ -321,6 +321,8 @@
<string name="preferences_account_settings">Налады ўліковага запісу</string>
<!-- Preference for open links in third party apps -->
<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 -->
<string name="preferences_addons">Дадаткі</string>
@ -351,6 +353,8 @@
<string name="sync_syncing_in_progress">Сінхранізацыя…</string>
<!-- Label summary indicating that sync failed. The first parameter is the date stamp showing last time it succeeded -->
<string name="sync_failed_summary">Памылка сінхранізацыі. Апошняе паспяховае сінхранаванне: %s</string>
<!-- Label summary showing never synced -->
<string name="sync_failed_never_synced_summary">Памылка сінхранізацыі. Апошняе сінхранаванне: ніколі</string>
<!-- Label summary the date we last synced. The first parameter is date stamp showing last time synced -->
<string name="sync_last_synced_summary">Апошняя сінхранізацыя: %s</string>
<!-- Label summary showing never synced -->

@ -149,6 +149,8 @@
<string name="browser_menu_install_on_homescreen">Installà</string>
<!-- Menu option on the toolbar that takes you to synced tabs page-->
<string name="synced_tabs">Unghjette sincrunizate</string>
<!-- Content description (not visible, for screen readers etc.) for the Resync tabs button -->
<string name="resync_button_content_description">Risincrunizà</string>
<!-- Browser menu button that opens the find in page menu -->
<string name="browser_menu_find_in_page">Circà in a pagina</string>
<!-- Browser menu button that creates a private tab -->
@ -271,6 +273,8 @@
<string name="preferences_open_links_in_a_private_tab">Apre i liami in ununghjetta privata</string>
<!-- Preference for allowing screenshots to be taken while in a private tab-->
<string name="preferences_allow_screenshots_in_private_mode">Permette e catture di screnu durante a navigazione privata</string>
<!-- Will inform the user of the risk of activating Allow screenshots in private browsing option -->
<string name="preferences_screenshots_in_private_mode_disclaimer">Sella hè permessa, lunghjette private seranu ancu videvule quandu parechje appiecazioni sò aperte</string>
<!-- Preference for adding private browsing shortcut -->
<string name="preferences_add_private_browsing_shortcut">Aghjunghje un accurtatoghjiu per a navigazione privata</string>
<!-- Preference for accessibility -->
@ -291,6 +295,8 @@
<string name="preferences_theme">Tema</string>
<!-- Preference for customizing the home screen -->
<string name="preferences_home">Accolta</string>
<!-- Preference for gestures based actions -->
<string name="preferences_gestures">Mosse</string>
<!-- Preference for settings related to visual options -->
<string name="preferences_customize">Persunalizà</string>
<!-- Preference description for banner about signing in -->
@ -326,9 +332,13 @@
<!-- Preference title for switch preference to suggest bookmarks when searching -->
<string name="preferences_search_bookmarks">Circà in lindette</string>
<!-- Preference title for switch preference to suggest synced tabs when searching -->
<string name="preferences_search_synced_tabs">Ricercà in lunghjette sincrunizate</string>
<!-- Preference for account settings -->
<string name="preferences_account_settings">Preferenze di u contu</string>
<!-- Preference for enabling url autocomplete-->
<string name="preferences_enable_autocomplete_urls">Compie autumaticamente lURL</string>
<!-- Preference for open links in third party apps -->
<string name="preferences_open_links_in_apps">Apre i liami in appiecazioni</string>
@ -465,6 +475,17 @@
<!-- Preference for using following device theme -->
<string name="preference_follow_device_theme">Seguità u tema di lapparechju</string>
<!-- Gestures Preferences-->
<!-- Preferences for using pull to refresh in a webpage -->
<string name="preference_gestures_website_pull_to_refresh">Tirà per attualizà</string>
<!-- Preference for using the dynamic toolbar -->
<string name="preference_gestures_dynamic_toolbar">Sfilà per piattà a barra dattrezzi</string>
<!-- Preference for switching tabs by swiping horizontally on the toolbar -->
<string name="preference_gestures_swipe_toolbar_switch_tabs">Fà sfilà a barra dattrezzi lateralmente per cambià dunghjetta</string>
<!-- Preference for showing the opened tabs by swiping up on the toolbar-->
<string name="preference_gestures_swipe_toolbar_show_tabs">Fà sfilà a barra dattrezzi insù per apre unghjette</string>
<!-- Library -->
<!-- Option in Library to open Sessions page -->
<string name="library_sessions">Sessioni</string>
@ -1061,7 +1082,7 @@
<!-- 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_2">Site cunnettu cumè %s nantà un altru navigatore Firefox cù stu telefonu. Vulete cunnettavvi cù stu contu ?</string>
<string name="onboarding_firefox_account_auto_signin_header_3">Site cunnettu cumè %s nantà un altru navigatore Firefox cù stapparechju. Vulete cunnettavvi cù stu contu ?</string>
<!-- text for the button to confirm automatic sign-in -->
<string name="onboarding_firefox_account_auto_signin_confirm">Iè, cunnettatemi</string>
<!-- text for the automatic sign-in button while signing in is in process -->
@ -1306,7 +1327,7 @@
<string name="add_to_homescreen_text_placeholder">Nome di laccurtatoghju</string>
<!-- Describes the add to homescreen functionality -->
<string name="add_to_homescreen_description">Hè faciule daghjunghje stu situ nantà u screnu daccolta di u vostru telefonu per accedeci direttamente è navigà più prestu cumè sella fussi unappiecazione.</string>
<string name="add_to_homescreen_description_2">Hè faciule daghjunghje stu situ nantà u screnu daccolta di u vostru apparechju per accedeci direttamente è navigà più prestu cumè sella fussi unappiecazione.</string>
<!-- Preference for managing the settings for logins and passwords in Fenix -->
<string name="preferences_passwords_logins_and_passwords">Identificazioni è parolle dentrata</string>
@ -1378,8 +1399,12 @@
<string name="logins_site_copied">Situ cupiatu ver di u premepapei</string>
<!-- Content Description (for screenreaders etc) read for the button to copy a password in logins-->
<string name="saved_logins_copy_password">Cupià a parolla dentrata</string>
<!-- Content Description (for screenreaders etc) read for the button to clear a password while editing a login-->
<string name="saved_logins_clear_password">Squassà a parolla dentrata</string>
<!-- Content Description (for screenreaders etc) read for the button to copy a username in logins -->
<string name="saved_login_copy_username">Cupià u nome dutilizatore</string>
<!-- Content Description (for screenreaders etc) read for the button to clear a username while editing a login -->
<string name="saved_login_clear_username">Squassà u nome dutilizatore</string>
<!-- Content Description (for screenreaders etc) read for the button to copy a site in logins -->
<string name="saved_login_copy_site">Cupià u situ</string>
<!-- Content Description (for screenreaders etc) read for the button to open a site in logins -->
@ -1537,7 +1562,7 @@
<string name="saved_login_duplicate">Lidentificazione di cunnessione cù stu nome dutilizatore esiste dighjà</string>
<!-- Synced Tabs -->
<!-- Text displayed to ask user to connect another device as no devices found with account -->
<!-- Text displayed to ask user to connect another device as no devices found with account -->
<string name="synced_tabs_connect_another_device">Cunnettate un altru apparechju.</string>
<!-- Text displayed asking user to re-authenticate -->
<string name="synced_tabs_reauth">Ci vole à autenticassi torna.</string>
@ -1559,7 +1584,7 @@
<!-- Title text displayed in the dialog when top sites limit is reached. -->
<string name="top_sites_max_limit_title">Cunfina di siti principale tocca</string>
<!-- Content description text displayed in the dialog when top sites limit is reached. -->
<string name="top_sites_max_limit_content">Per aghjunghje un novu situ principale, ci vole à cacciane unu. Effettuate una longa incalcata nantà u situ è selezziunate Caccià.</string>
<string name="top_sites_max_limit_content_2">Per aghjunghje un novu situ principale, ci vole à cacciane unaltru. Effettuate una longa incalcata nantà u situ è selezziunate Caccià.</string>
<!-- Confirmation dialog button text when top sites limit is reached. -->
<string name="top_sites_max_limit_confirmation_button">Iè, aghju capitu</string>
@ -1569,7 +1594,7 @@
<!-- Content description for close button in collection placeholder. -->
<string name="remove_home_collection_placeholder_content_description">Caccià</string>
<!-- depcrecated: text for the firefox account onboarding card header
<!-- 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">Ottene u più bellu da %s.</string>
@ -1577,4 +1602,9 @@
<string name="no_collections_header1">Racuglite ciò chì conta per voi</string>
<!-- Deprecated: Label to describe what collections are to a new user without any collections -->
<string name="no_collections_description1">Gruppate inseme ricerche simile, i siti è lunghjette per un accessu future più prestu.</string>
<!-- Deprecated: text for the firefox account onboarding card header when we detect you're already signed in to -->
<string name="onboarding_firefox_account_auto_signin_header_2">Site cunnettu cumè %s nantà un altru navigatore Firefox cù stu telefonu. Vulete cunnettavvi cù stu contu ?</string>
<!-- Deprecated: Describes the add to homescreen functionality -->
<string name="add_to_homescreen_description">Hè faciule daghjunghje stu situ nantà u screnu daccolta di u vostru telefonu per accedeci direttamente è navigà più prestu cumè sella fussi unappiecazione.</string>
</resources>

@ -145,6 +145,8 @@
<string name="browser_menu_install_on_homescreen">Gosod</string>
<!-- Menu option on the toolbar that takes you to synced tabs page-->
<string name="synced_tabs">Tabiau wediu cydweddu</string>
<!-- Content description (not visible, for screen readers etc.) for the Resync tabs button -->
<string name="resync_button_content_description">Ailgydweddu</string>
<!-- Browser menu button that opens the find in page menu -->
<string name="browser_menu_find_in_page">Canfod yn y dudalen</string>
<!-- Browser menu button that creates a private tab -->

@ -148,6 +148,8 @@
<string name="browser_menu_install_on_homescreen">Installieren</string>
<!-- Menu option on the toolbar that takes you to synced tabs page-->
<string name="synced_tabs">Synchronisierte Tabs</string>
<!-- Content description (not visible, for screen readers etc.) for the Resync tabs button -->
<string name="resync_button_content_description">Neu synchronisieren</string>
<!-- Browser menu button that opens the find in page menu -->
<string name="browser_menu_find_in_page">In Seite suchen</string>
<!-- Browser menu button that creates a private tab -->

@ -146,6 +146,8 @@
<string name="browser_menu_install_on_homescreen">Instalěrowaś</string>
<!-- Menu option on the toolbar that takes you to synced tabs page-->
<string name="synced_tabs">Synchronizěrowane rejtariki</string>
<!-- Content description (not visible, for screen readers etc.) for the Resync tabs button -->
<string name="resync_button_content_description">Znowego synchronizěrowaś</string>
<!-- Browser menu button that opens the find in page menu -->
<string name="browser_menu_find_in_page">Na boku pytaś</string>
<!-- Browser menu button that creates a private tab -->

@ -139,6 +139,8 @@
<string name="browser_menu_install_on_homescreen">Εγκατάσταση</string>
<!-- Menu option on the toolbar that takes you to synced tabs page-->
<string name="synced_tabs">Συγχρονισμένες καρτέλες</string>
<!-- Content description (not visible, for screen readers etc.) for the Resync tabs button -->
<string name="resync_button_content_description">Επανασυγχρονισμός</string>
<!-- Browser menu button that opens the find in page menu -->
<string name="browser_menu_find_in_page">Εύρεση στη σελίδα</string>
<!-- Browser menu button that creates a private tab -->
@ -320,6 +322,8 @@
<string name="preferences_search_browsing_history">Αναζήτηση ιστορικού περιήγησης</string>
<!-- Preference title for switch preference to suggest bookmarks when searching -->
<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 -->
<string name="preferences_account_settings">Ρυθμίσεις λογαριασμού</string>
<!-- Preference for enabling url autocomplete-->

@ -145,6 +145,8 @@
<string name="browser_menu_install_on_homescreen">Install</string>
<!-- Menu option on the toolbar that takes you to synced tabs page-->
<string name="synced_tabs">Synced tabs</string>
<!-- Content description (not visible, for screen readers etc.) for the Resync tabs button -->
<string name="resync_button_content_description">Resync</string>
<!-- Browser menu button that opens the find in page menu -->
<string name="browser_menu_find_in_page">Find in page</string>
<!-- Browser menu button that creates a private tab -->

@ -146,6 +146,8 @@
<string name="browser_menu_install_on_homescreen">Instalar</string>
<!-- Menu option on the toolbar that takes you to synced tabs page-->
<string name="synced_tabs">Pestañas 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 -->
<string name="browser_menu_find_in_page">Buscar en la página</string>
<!-- Browser menu button that creates a private tab -->

@ -324,6 +324,8 @@
<string name="preferences_search_browsing_history">Buscar historial de navegación</string>
<!-- Preference title for switch preference to suggest bookmarks when searching -->
<string name="preferences_search_bookmarks">Buscar marcadores</string>
<!-- Preference title for switch preference to suggest synced tabs when searching -->
<string name="preferences_search_synced_tabs">Buscar pestañas sincronizadas</string>
<!-- Preference for account settings -->
<string name="preferences_account_settings">Ajustes de la cuenta</string>
<!-- Preference for enabling url autocomplete-->

@ -147,6 +147,8 @@
<string name="browser_menu_install_on_homescreen">Instalar</string>
<!-- Menu option on the toolbar that takes you to synced tabs page-->
<string name="synced_tabs">Pestañas 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 -->
<string name="browser_menu_find_in_page">Buscar en la página</string>
<!-- Browser menu button that creates a private tab -->
@ -331,6 +333,8 @@
<string name="preferences_search_browsing_history">Buscar historial de navegación</string>
<!-- Preference title for switch preference to suggest bookmarks when searching -->
<string name="preferences_search_bookmarks">Buscar marcadores</string>
<!-- Preference title for switch preference to suggest synced tabs when searching -->
<string name="preferences_search_synced_tabs">Buscar pestañas sincronizadas</string>
<!-- Preference for account settings -->
<string name="preferences_account_settings">Ajustes de la cuenta</string>

@ -72,12 +72,19 @@
<!-- Text for the negative action button -->
<string name="open_in_app_cfr_negative_button_text">Descartar</string>
<!-- 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>
<!-- Text for the negative action button to dismiss the dialog. -->
<string name="camera_permissions_needed_negative_button_text">Descartar</string>
<!-- Text for the banner message to tell users about our auto close feature. -->
<string name="tab_tray_close_tabs_banner_message">Configura que las pestañas abiertas se cierren automáticamente si no han sido vistas en el último día, semana o mes.</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">Ver opciones</string>
<!-- Text for the negative action button to dismiss the Close Tabs Banner. -->
<string name="tab_tray_close_tabs_banner_negative_button_text">Descartar</string>
<!-- Home screen icons - Long press shortcuts -->
<!-- Shortcut action to open new tab -->
<string name="home_screen_shortcut_open_new_tab_2">Nueva pestaña</string>
@ -122,6 +129,8 @@
<string name="browser_menu_install_on_homescreen">Instalar</string>
<!-- Menu option on the toolbar that takes you to synced tabs page-->
<string name="synced_tabs">Pestañas 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 -->
<string name="browser_menu_find_in_page">Buscar en la página</string>
<!-- Browser menu button that creates a private tab -->
@ -264,6 +273,8 @@
<string name="preferences_toolbar">Barra de herramientas</string>
<!-- Preference for changing default theme to dark or light mode -->
<string name="preferences_theme">Tema</string>
<!-- Preference for customizing the home screen -->
<string name="preferences_home">Inicio</string>
<!-- Preference for gestures based actions -->
<string name="preferences_gestures">Gestos</string>
<!-- Preference for settings related to visual options -->
@ -300,14 +311,23 @@
<string name="preferences_search_browsing_history">Buscar historial de navegación</string>
<!-- Preference title for switch preference to suggest bookmarks when searching -->
<string name="preferences_search_bookmarks">Buscar marcadores</string>
<!-- Preference title for switch preference to suggest synced tabs when searching -->
<string name="preferences_search_synced_tabs">Buscar pestañas sincronizadas</string>
<!-- Preference for account settings -->
<string name="preferences_account_settings">Configuración de la cuenta</string>
<!-- Preference for enabling url autocomplete-->
<string name="preferences_enable_autocomplete_urls">Autocompletar URLs</string>
<!-- Preference for open links in third party apps -->
<string name="preferences_open_links_in_apps">Abrir enlaces en aplicaciones</string>
<!-- Preference for open download with an external download manager app -->
<string name="preferences_external_download_manager">Administrador de descargas externo</string>
<!-- Preference for add_ons -->
<string name="preferences_addons">Complementos</string>
<!-- Preference for notifications -->
<string name="preferences_notifications">Notificaciones</string>
<!-- Account Preferences -->
<!-- Preference for triggering sync -->
<string name="preferences_sync_now">Sincronizar ahora</string>
@ -437,6 +457,9 @@
<!-- Preference for using following device theme -->
<string name="preference_follow_device_theme">Seguir el tema del dispositivo</string>
<!-- Gestures Preferences-->
<!-- Preferences for using pull to refresh in a webpage -->
<string name="preference_gestures_website_pull_to_refresh">Arrastrar para actualizar</string>
<!-- Preference for using the dynamic toolbar -->
<string name="preference_gestures_dynamic_toolbar">Desplazar para ocultar la barra</string>
<!-- Preference for switching tabs by swiping horizontally on the toolbar -->
@ -476,6 +499,31 @@
<!-- Content description (not visible, for screen readers etc.): "Close button for library settings" -->
<string name="content_description_close_button">Cerrar</string>
<!-- Option in library for Recently Closed Tabs -->
<string name="library_recently_closed_tabs">Pestañas cerradas recientemente</string>
<!-- Option in library to open Recently Closed Tabs page -->
<string name="recently_closed_show_full_history">Mostrar historial completo</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 pestañas</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 pestaña</string>
<!-- Recently closed tabs screen message when there are no recently closed tabs -->
<string name="recently_closed_empty_message">No hay pestañas recientemente cerradas</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">Cerrar pestañas</string>
<!-- Option for auto closing tabs that will never auto close tabs, always allows user to manually close tabs -->
<string name="close_tabs_manually">Manualmente</string>
<!-- Option for auto closing tabs that will auto close tabs after one day -->
<string name="close_tabs_after_one_day">Después de un día</string>
<!-- Option for auto closing tabs that will auto close tabs after one week -->
<string name="close_tabs_after_one_week">Después de una semana</string>
<!-- Option for auto closing tabs that will auto close tabs after one month -->
<string name="close_tabs_after_one_month">Después de un mes</string>
<!-- Sessions -->
<!-- Title for the list of tabs -->
<string name="tab_header_label">Pestañas abiertas</string>
@ -495,6 +543,8 @@
<string name="tab_tray_menu_item_save">Guardar en colección</string>
<!-- Text shown in the menu for sharing all tabs -->
<string name="tab_tray_menu_item_share">Compartir todas las pestañas</string>
<!-- Text shown in the menu to view recently closed tabs -->
<string name="tab_tray_menu_recently_closed">Pestañas cerradas recientemente</string>
<!-- Text shown in the menu for closing all tabs -->
<string name="tab_tray_menu_item_close">Cerrar todas las pestañas</string>
<!-- Shortcut action to open new tab -->
@ -542,6 +592,8 @@
<!-- Text for the menu button to remove a top site -->
<string name="remove_top_site">Eliminar</string>
<!-- Text for the menu button to delete a top site from history -->
<string name="delete_from_history">Eliminar del historial</string>
<!-- Postfix for private WebApp titles, placeholder is replaced with app name -->
<string name="pwa_site_controls_title_private">%1$s (modo privado)</string>
@ -587,6 +639,9 @@
<!-- Text shown when no history exists -->
<string name="history_empty_message">No hay ningún historial</string>
<!-- Downloads -->
<!-- Text shown when no download exists -->
<string name="download_empty_message">No hay descargas aquí</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 seleccionado</string>
@ -1326,8 +1381,12 @@
<string name="logins_site_copied">Sitio copiado al portapapeles</string>
<!-- Content Description (for screenreaders etc) read for the button to copy a password in logins-->
<string name="saved_logins_copy_password">Copiar contraseña</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 contraseña</string>
<!-- Content Description (for screenreaders etc) read for the button to copy a username in logins -->
<string name="saved_login_copy_username">Copiar nombre de usuario</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 nombre de usuario</string>
<!-- Content Description (for screenreaders etc) read for the button to copy a site in logins -->
<string name="saved_login_copy_site">Copiar sitio</string>
<!-- Content Description (for screenreaders etc) read for the button to reveal a password in logins -->
@ -1506,7 +1565,13 @@
<!-- Confirmation dialog button text when top sites limit is reached. -->
<string name="top_sites_max_limit_confirmation_button">Vale, entendido</string>
<!-- depcrecated: text for the firefox account onboarding card header
<!-- Label for the show most visited sites preference -->
<string name="top_sites_toggle_top_frecent_sites">Mostrar los sitios más visitados</string>
<!-- Content description for close button in collection placeholder. -->
<string name="remove_home_collection_placeholder_content_description">Eliminar</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ácale el máximo provecho a %s.</string>

@ -146,6 +146,8 @@
<string name="browser_menu_install_on_homescreen">Asenna</string>
<!-- Menu option on the toolbar that takes you to synced tabs page-->
<string name="synced_tabs">Synkronoidut välilehdet</string>
<!-- Content description (not visible, for screen readers etc.) for the Resync tabs button -->
<string name="resync_button_content_description">Synkronoi uudelleen</string>
<!-- Browser menu button that opens the find in page menu -->
<string name="browser_menu_find_in_page">Etsi sivulta</string>
<!-- Browser menu button that creates a private tab -->
@ -330,6 +332,8 @@
<string name="preferences_search_browsing_history">Etsi selaushistoriasta</string>
<!-- Preference title for switch preference to suggest bookmarks when searching -->
<string name="preferences_search_bookmarks">Etsi kirjanmerkeistä</string>
<!-- Preference title for switch preference to suggest synced tabs when searching -->
<string name="preferences_search_synced_tabs">Etsi synkronoiduista välilehdistä</string>
<!-- Preference for account settings -->
<string name="preferences_account_settings">Tilin asetukset</string>
@ -478,7 +482,7 @@
<!-- Preferences for using pull to refresh in a webpage -->
<string name="preference_gestures_website_pull_to_refresh">Vedä päivittääksesi</string>
<!-- Preference for using the dynamic toolbar -->
<string name="preference_gestures_dynamic_toolbar">Viertä piilottaaksesi työkalurivin</string>
<string name="preference_gestures_dynamic_toolbar">Vieritä piilottaaksesi työkalurivin</string>
<!-- Preference for switching tabs by swiping horizontally on the toolbar -->
<string name="preference_gestures_swipe_toolbar_switch_tabs">Pyyhkäise työkaluriviä sivuttain vaihtaaksesi välilehtiä</string>

@ -146,6 +146,8 @@
<string name="browser_menu_install_on_homescreen">Installer</string>
<!-- Menu option on the toolbar that takes you to synced tabs page-->
<string name="synced_tabs">Onglets synchronisés</string>
<!-- Content description (not visible, for screen readers etc.) for the Resync tabs button -->
<string name="resync_button_content_description">Resynchroniser</string>
<!-- Browser menu button that opens the find in page menu -->
<string name="browser_menu_find_in_page">Rechercher dans la page</string>
<!-- Browser menu button that creates a private tab -->
@ -478,9 +480,17 @@
<!-- Preference for using following device theme -->
<string name="preference_follow_device_theme">Suivre le thème de lappareil</string>
<!-- Gestures Preferences-->
<!-- Preferences for using pull to refresh in a webpage -->
<string name="preference_gestures_website_pull_to_refresh">Tirer pour actualiser</string>
<!-- Preference for using the dynamic toolbar -->
<string name="preference_gestures_dynamic_toolbar">Masquer la barre doutils au défilement</string>
<!-- Preference for switching tabs by swiping horizontally on the toolbar -->
<string name="preference_gestures_swipe_toolbar_switch_tabs">Changer donglet en glissant la barre doutils latéralement</string>
<!-- Preference for showing the opened tabs by swiping up on the toolbar-->
<string name="preference_gestures_swipe_toolbar_show_tabs">Ouvrir des onglets en glissant la barre doutils vers le haut</string>
<!-- Library -->
<!-- Option in Library to open Sessions page -->
<string name="library_sessions">Sessions</string>

@ -148,6 +148,8 @@
<string name="browser_menu_install_on_homescreen">Ynstallearje</string>
<!-- Menu option on the toolbar that takes you to synced tabs page-->
<string name="synced_tabs">Syngronisearre ljepblêden</string>
<!-- Content description (not visible, for screen readers etc.) for the Resync tabs button -->
<string name="resync_button_content_description">Opnij syngronisearje</string>
<!-- Browser menu button that opens the find in page menu -->
<string name="browser_menu_find_in_page">Sykje op side</string>
<!-- Browser menu button that creates a private tab -->

@ -149,6 +149,8 @@
<string name="browser_menu_install_on_homescreen">Mohenda</string>
<!-- Menu option on the toolbar that takes you to synced tabs page-->
<string name="synced_tabs">Tendayke mbojuehepyre</string>
<!-- Content description (not visible, for screen readers etc.) for the Resync tabs button -->
<string name="resync_button_content_description">Mbojuajujey</string>
<!-- Browser menu button that opens the find in page menu -->
<string name="browser_menu_find_in_page">Eheka kuatiaroguépe</string>
<!-- Browser menu button that creates a private tab -->
@ -330,6 +332,8 @@
<string name="preferences_search_browsing_history">Eheka kundahára rembiasakue</string>
<!-- Preference title for switch preference to suggest bookmarks when searching -->
<string name="preferences_search_bookmarks">Eheka techaukaha</string>
<!-- Preference title for switch preference to suggest synced tabs when searching -->
<string name="preferences_search_synced_tabs">Eheka tendayke mbojuehepyre</string>
<!-- Preference for account settings -->
<string name="preferences_account_settings">Mbaete ñemboheko</string>
<!-- Preference for enabling url autocomplete-->

@ -144,6 +144,8 @@
<string name="browser_menu_install_on_homescreen">Instaliraj</string>
<!-- Menu option on the toolbar that takes you to synced tabs page-->
<string name="synced_tabs">Sinkronizirane kartice</string>
<!-- Content description (not visible, for screen readers etc.) for the Resync tabs button -->
<string name="resync_button_content_description">Ponovna sinkronizacija</string>
<!-- Browser menu button that opens the find in page menu -->
<string name="browser_menu_find_in_page">Pronađi na stranici</string>
<!-- Browser menu button that creates a private tab -->
@ -325,6 +327,8 @@
<string name="preferences_search_browsing_history">Pretraži povijest pregledavanja</string>
<!-- Preference title for switch preference to suggest bookmarks when searching -->
<string name="preferences_search_bookmarks">Pretraži zabilješke</string>
<!-- Preference title for switch preference to suggest synced tabs when searching -->
<string name="preferences_search_synced_tabs">Pretraži sinkronizirane kartice</string>
<!-- Preference for account settings -->
<string name="preferences_account_settings">Postavke računa</string>
<!-- Preference for enabling url autocomplete-->
@ -1166,7 +1170,7 @@
<!-- Text shown for settings option for sign with pairing -->
<string name="sign_in_with_camera">Prijavi se pomoću kamere</string>
<!-- Text shown for settings option for sign with email -->
<string name="sign_in_with_email">Umjesto toga koristi e-mail</string>
<string name="sign_in_with_email">Umjesto toga koristi e-poštu</string>
<!-- Text shown in confirmation dialog to sign out of account -->
<string name="sign_out_confirmation_message">Firefox će prestati sinkronizirati s tvojim računom, ali neće izbrisati podatke o tvom pregledavanju na ovom uređaju.</string>
<!-- Text shown in confirmation dialog to sign out of account. The first parameter is the name of the app (e.g. Firefox Preview) -->

@ -146,6 +146,8 @@
<string name="browser_menu_install_on_homescreen">Instalować</string>
<!-- Menu option on the toolbar that takes you to synced tabs page-->
<string name="synced_tabs">Synchronizowane rajtarki</string>
<!-- Content description (not visible, for screen readers etc.) for the Resync tabs button -->
<string name="resync_button_content_description">Znowa synchronizować</string>
<!-- Browser menu button that opens the find in page menu -->
<string name="browser_menu_find_in_page">Na stronje pytać</string>
<!-- Browser menu button that creates a private tab -->

@ -145,6 +145,8 @@
<string name="browser_menu_install_on_homescreen">Telepítés</string>
<!-- Menu option on the toolbar that takes you to synced tabs page-->
<string name="synced_tabs">Szinkronizált lapok</string>
<!-- Content description (not visible, for screen readers etc.) for the Resync tabs button -->
<string name="resync_button_content_description">Újraszinkronizálás</string>
<!-- Browser menu button that opens the find in page menu -->
<string name="browser_menu_find_in_page">Keresés az oldalon</string>
<!-- Browser menu button that creates a private tab -->

@ -145,6 +145,8 @@
<string name="browser_menu_install_on_homescreen">Installa</string>
<!-- Menu option on the toolbar that takes you to synced tabs page-->
<string name="synced_tabs">Schede sincronizzate</string>
<!-- Content description (not visible, for screen readers etc.) for the Resync tabs button -->
<string name="resync_button_content_description">Risincronizza</string>
<!-- Browser menu button that opens the find in page menu -->
<string name="browser_menu_find_in_page">Trova nella pagina</string>
<!-- Browser menu button that creates a private tab -->
@ -331,6 +333,8 @@
<string name="preferences_search_browsing_history">Cerca nella cronologia</string>
<!-- Preference title for switch preference to suggest bookmarks when searching -->
<string name="preferences_search_bookmarks">Cerca nei segnalibri</string>
<!-- Preference title for switch preference to suggest synced tabs when searching -->
<string name="preferences_search_synced_tabs">Cerca nelle schede sincronizzate</string>
<!-- Preference for account settings -->
<string name="preferences_account_settings">Impostazioni account</string>

@ -144,6 +144,8 @@
<string name="browser_menu_install_on_homescreen">התקנה</string>
<!-- Menu option on the toolbar that takes you to synced tabs page-->
<string name="synced_tabs">לשוניות מסונכרנות</string>
<!-- Content description (not visible, for screen readers etc.) for the Resync tabs button -->
<string name="resync_button_content_description">סנכרון מחדש</string>
<!-- Browser menu button that opens the find in page menu -->
<string name="browser_menu_find_in_page">חיפוש בדף</string>
<!-- Browser menu button that creates a private tab -->

@ -84,7 +84,7 @@
<!-- 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>
<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 -->
@ -148,6 +148,8 @@
<string name="browser_menu_install_on_homescreen">インストール</string>
<!-- Menu option on the toolbar that takes you to synced tabs page-->
<string name="synced_tabs">同期したタブ</string>
<!-- Content description (not visible, for screen readers etc.) for the Resync tabs button -->
<string name="resync_button_content_description">再同期</string>
<!-- Browser menu button that opens the find in page menu -->
<string name="browser_menu_find_in_page">ページ内検索</string>
<!-- Browser menu button that creates a private tab -->
@ -340,7 +342,7 @@
<!-- Preference for enabling url autocomplete-->
<string name="preferences_enable_autocomplete_urls">自動補完 URL</string>
<!-- 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>

@ -142,6 +142,8 @@
<string name="browser_menu_install_on_homescreen">Орнату</string>
<!-- Menu option on the toolbar that takes you to synced tabs page-->
<string name="synced_tabs">Синхрондалған беттер</string>
<!-- Content description (not visible, for screen readers etc.) for the Resync tabs button -->
<string name="resync_button_content_description">Қайта синхрондау</string>
<!-- Browser menu button that opens the find in page menu -->
<string name="browser_menu_find_in_page">Беттен табу</string>
<!-- Browser menu button that creates a private tab -->
@ -285,6 +287,8 @@
<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 -->
<string name="preferences_customize">Баптау</string>
<!-- Preference description for banner about signing in -->
@ -319,8 +323,12 @@
<string name="preferences_search_browsing_history">Шолу тарихынан іздеу</string>
<!-- Preference title for switch preference to suggest bookmarks when searching -->
<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 -->
<string name="preferences_account_settings">Тіркелгі баптаулары</string>
<!-- Preference for enabling url autocomplete-->
<string name="preferences_enable_autocomplete_urls">URL адрестерін автотолықтыру</string>
<!-- Preference for open links in third party apps -->
<string name="preferences_open_links_in_apps">Сілтемелерді қолданбаларда ашу</string>
<!-- Preference for open download with an external download manager app -->
@ -456,6 +464,16 @@
<!-- Preference for using following device theme -->
<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>
<!-- Preference for using the dynamic toolbar -->
<string name="preference_gestures_dynamic_toolbar">Құралдар тақтасын жасыру үшін айналдырыңыз</string>
<!-- Preference for switching tabs by swiping horizontally on the toolbar -->
<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 -->
<!-- Option in Library to open Sessions page -->
<string name="library_sessions">Сессиялар</string>
@ -1044,6 +1062,10 @@
<string name="onboarding_account_sign_in_header">Firefox тіркелгісімен бетбелгілер, парольдер және т.б. синхрондауды бастаңыз.</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 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">Сіз осы құрылғыда басқа Firefox браузерінде %s ретінде кірдіңіз. Осы тіркелгімен кіргіңіз келе ме?</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 -->
@ -1288,6 +1310,9 @@
<!-- Placeholder text for the TextView in the Add to Homescreen dialog -->
<string name="add_to_homescreen_text_placeholder">Жарлық атауы</string>
<!-- Describes the add to homescreen functionality -->
<string name="add_to_homescreen_description_2">Бұл веб-сайтты жылдам қатынау және қолданба тектес режимде жылдам шолу мақсатымен құрылғыңыздың үй бетіңізге қосуға болады.</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 -->
@ -1357,8 +1382,12 @@
<string name="logins_site_copied">Сайт алмасу буферіне көшірілді</string>
<!-- Content Description (for screenreaders etc) read for the button to copy a password in logins-->
<string name="saved_logins_copy_password">Парольді көшіріп алу</string>
<!-- Content Description (for screenreaders etc) read for the button to clear a password while editing a login-->
<string name="saved_logins_clear_password">Парольді тазарту</string>
<!-- Content Description (for screenreaders etc) read for the button to copy a username in logins -->
<string name="saved_login_copy_username">Пайдаланушы атын көшіріп алу</string>
<!-- Content Description (for screenreaders etc) read for the button to clear a username while editing a login -->
<string name="saved_login_clear_username">Пайдаланушы атын тазарту</string>
<!-- Content Description (for screenreaders etc) read for the button to copy a site in logins -->
<string name="saved_login_copy_site">Сайтты көшіріп алу</string>
<!-- Content Description (for screenreaders etc) read for the button to open a site in logins -->
@ -1532,6 +1561,8 @@
<!-- Top Sites -->
<!-- Title text displayed in the dialog when top sites limit is reached. -->
<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">Жаңа үздік сайтын қосу үшін, біреуін өшіріңіз. Сайтқа басып, басулы ұстаңыз және өшіру таңдаңыз.</string>
<!-- Confirmation dialog button text when top sites limit is reached. -->
<string name="top_sites_max_limit_confirmation_button">Жақсы, түсіндім</string>

@ -152,6 +152,8 @@
<string name="browser_menu_install_on_homescreen">설치</string>
<!-- Menu option on the toolbar that takes you to synced tabs page-->
<string name="synced_tabs">동기화된 탭</string>
<!-- Content description (not visible, for screen readers etc.) for the Resync tabs button -->
<string name="resync_button_content_description">다시 동기화</string>
<!-- Browser menu button that opens the find in page menu -->
<string name="browser_menu_find_in_page">페이지에서 찾기</string>
<!-- Browser menu button that creates a private tab -->

@ -148,6 +148,8 @@
<string name="browser_menu_install_on_homescreen">Installer</string>
<!-- Menu option on the toolbar that takes you to synced tabs page-->
<string name="synced_tabs">Synkroniserte faner</string>
<!-- Content description (not visible, for screen readers etc.) for the Resync tabs button -->
<string name="resync_button_content_description">Synkroniser på nytt</string>
<!-- Browser menu button that opens the find in page menu -->
<string name="browser_menu_find_in_page">Finn på siden</string>
<!-- Browser menu button that creates a private tab -->
@ -253,7 +255,7 @@
<!-- Preference for settings related to saved passwords -->
<string name="preferences_passwords">Passord</string>
<!-- Preference for settings related to saved credit cards and addresses -->
<string name="preferences_credit_cards_addresses">Kredittkort og adresser</string>
<string name="preferences_credit_cards_addresses">Betalingskort og adresser</string>
<!-- Preference for settings related to changing the default browser -->
<string name="preferences_set_as_default_browser">Velg som standardnettleser</string>
<!-- Preference category for advanced settings -->

@ -150,6 +150,8 @@
<string name="browser_menu_install_on_homescreen">Installeren</string>
<!-- Menu option on the toolbar that takes you to synced tabs page-->
<string name="synced_tabs">Gesynchroniseerde tabbladen</string>
<!-- Content description (not visible, for screen readers etc.) for the Resync tabs button -->
<string name="resync_button_content_description">Opnieuw synchroniseren</string>
<!-- Browser menu button that opens the find in page menu -->
<string name="browser_menu_find_in_page">Zoeken op pagina</string>
<!-- Browser menu button that creates a private tab -->

@ -148,6 +148,8 @@
<string name="browser_menu_install_on_homescreen">Installer</string>
<!-- Menu option on the toolbar that takes you to synced tabs page-->
<string name="synced_tabs">Synkroniserte faner</string>
<!-- Content description (not visible, for screen readers etc.) for the Resync tabs button -->
<string name="resync_button_content_description">Synkroniser på nytt</string>
<!-- Browser menu button that opens the find in page menu -->
<string name="browser_menu_find_in_page">Finn på sida</string>
<!-- Browser menu button that creates a private tab -->

@ -186,7 +186,7 @@
<!-- Search Fragment -->
<!-- Button in the search view that lets a user search by scanning a QR code -->
<string name="search_scan_button">Escanerizar</string>
<string name="search_scan_button">Numerizar</string>
<!-- Button in the search view that lets a user change their search engine -->
<string name="search_engine_button">Motor de recèrca</string>
<!-- Button in the search view when shortcuts are displayed that takes a user to the search engine settings -->
@ -1110,7 +1110,7 @@
<!-- Text shown in snackbar for the "retry" action that the user has after sharing tabs failed -->
<string name="sync_sent_tab_error_snackbar_action">TORNAR ENSAJAR</string>
<!-- Title of QR Pairing Fragment -->
<string name="sync_scan_code">Escanerizatz lo còdi QR</string>
<string name="sync_scan_code">Numerizatz lo còdi QR</string>
<!-- Instructions on how to access pairing -->
<string name="sign_in_instructions"><![CDATA[Dorbissètz Firefox sus lordenador a la pagina <b>https://firefox.com/pair</b>]]></string>
<!-- Text shown for sign in pairing when ready -->

@ -141,6 +141,8 @@
<string name="browser_menu_install_on_homescreen">ਇੰਸਟਾਲ ਕਰੋ</string>
<!-- Menu option on the toolbar that takes you to synced tabs page-->
<string name="synced_tabs">ਸਿੰਕ ਕੀਤੀਆਂ ਟੈਬਾਂ</string>
<!-- Content description (not visible, for screen readers etc.) for the Resync tabs button -->
<string name="resync_button_content_description">ਮੁੜ-ਸਿੰਕ ਕਰੋ</string>
<!-- Browser menu button that opens the find in page menu -->
<string name="browser_menu_find_in_page">ਸਫ਼ੇ ‘ਚ ਲੱਭੋ</string>
<!-- Browser menu button that creates a private tab -->

@ -146,6 +146,8 @@
<string name="browser_menu_install_on_homescreen">Zainstaluj</string>
<!-- Menu option on the toolbar that takes you to synced tabs page-->
<string name="synced_tabs">Karty z innych urządzeń</string>
<!-- Content description (not visible, for screen readers etc.) for the Resync tabs button -->
<string name="resync_button_content_description">Synchronizuj ponownie</string>
<!-- Browser menu button that opens the find in page menu -->
<string name="browser_menu_find_in_page">Znajdź na stronie</string>
<!-- Browser menu button that creates a private tab -->
@ -328,6 +330,8 @@
<string name="preferences_search_browsing_history">Historia</string>
<!-- Preference title for switch preference to suggest bookmarks when searching -->
<string name="preferences_search_bookmarks">Zakładki</string>
<!-- Preference title for switch preference to suggest synced tabs when searching -->
<string name="preferences_search_synced_tabs">Karty z innych urządzeń</string>
<!-- Preference for account settings -->
<string name="preferences_account_settings">Ustawienia konta</string>

@ -145,6 +145,8 @@
<string name="browser_menu_install_on_homescreen">Instalar</string>
<!-- Menu option on the toolbar that takes you to synced tabs page-->
<string name="synced_tabs">Abas sincronizadas</string>
<!-- Content description (not visible, for screen readers etc.) for the Resync tabs button -->
<string name="resync_button_content_description">Ressincronizar</string>
<!-- Browser menu button that opens the find in page menu -->
<string name="browser_menu_find_in_page">Procurar na página</string>
<!-- Browser menu button that creates a private tab -->

@ -146,6 +146,8 @@
<string name="browser_menu_install_on_homescreen">Instalar</string>
<!-- Menu option on the toolbar that takes you to synced tabs page-->
<string name="synced_tabs">Separadores sincronizados</string>
<!-- Content description (not visible, for screen readers etc.) for the Resync tabs button -->
<string name="resync_button_content_description">Ressincronizar</string>
<!-- Browser menu button that opens the find in page menu -->
<string name="browser_menu_find_in_page">Encontrar na página</string>
<!-- Browser menu button that creates a private tab -->

@ -143,6 +143,8 @@
<string name="browser_menu_install_on_homescreen">Инсталирај</string>
<!-- Menu option on the toolbar that takes you to synced tabs page-->
<string name="synced_tabs">Синхронизовани језичци</string>
<!-- Content description (not visible, for screen readers etc.) for the Resync tabs button -->
<string name="resync_button_content_description">Поново синхронизујте</string>
<!-- Browser menu button that opens the find in page menu -->
<string name="browser_menu_find_in_page">Нађи на страници</string>
<!-- Browser menu button that creates a private tab -->
@ -267,6 +269,8 @@
<string name="preferences_open_links_in_a_private_tab">Отварај везе у приватном језичку</string>
<!-- Preference for allowing screenshots to be taken while in a private tab-->
<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 -->
<string name="preferences_add_private_browsing_shortcut">Додајте пречицу за приватно прегледање</string>
<!-- Preference for accessibility -->
@ -287,6 +291,8 @@
<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 -->
<string name="preferences_customize">Прилагоди</string>
<!-- Preference description for banner about signing in -->
@ -321,8 +327,12 @@
<string name="preferences_search_browsing_history">Претражи историјат прегледања</string>
<!-- Preference title for switch preference to suggest bookmarks when searching -->
<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 -->
<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 -->
<string name="preferences_open_links_in_apps">Отвори везе у апликацијама</string>
<!-- Preference for open download with an external download manager app -->
@ -460,6 +470,18 @@
<!-- Preference for using following device theme -->
<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>
<!-- Preference for using the dynamic toolbar -->
<string name="preference_gestures_dynamic_toolbar">Скролујте да сакријете траку с алаткама</string>
<!-- Preference for switching tabs by swiping horizontally on the toolbar -->
<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 -->
<!-- Option in Library to open Sessions page -->
<string name="library_sessions">Сесије</string>
@ -1051,7 +1073,7 @@
<!-- 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_2">Пријављени сте као %s у другом Firefox прегледачу, на овом телефону. Желите ли да се пријавите са тим налогом?</string>
<string name="onboarding_firefox_account_auto_signin_header_3">Пријављени сте као %s на другом Firefox прегледачу на овом уређају. Желите ли да се пријавите са овим налогом?</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 -->
@ -1300,7 +1322,7 @@
<string name="add_to_homescreen_text_placeholder">Назив пречице</string>
<!-- Describes the add to homescreen functionality -->
<string name="add_to_homescreen_description">Ову страницу можете лако додати на почетни екран вашег телефона за тренутни приступ и брже прегледање.</string>
<string name="add_to_homescreen_description_2">Овај сајт можете лако додати на почетни екран уређаја за директан приступ и брже прегледање, баш као што користите апликацију.</string>
<!-- Preference for managing the settings for logins and passwords in Fenix -->
<string name="preferences_passwords_logins_and_passwords">Пријаве и лозинке</string>
@ -1370,8 +1392,12 @@
<string name="logins_site_copied">Адреса странице копирана у оставу</string>
<!-- Content Description (for screenreaders etc) read for the button to copy a password in logins-->
<string name="saved_logins_copy_password">Копирај лозинку</string>
<!-- Content Description (for screenreaders etc) read for the button to clear a password while editing a login-->
<string name="saved_logins_clear_password">Обриши лозинку</string>
<!-- Content Description (for screenreaders etc) read for the button to copy a username in logins -->
<string name="saved_login_copy_username">Копирај корисничко</string>
<!-- Content Description (for screenreaders etc) read for the button to clear a username while editing a login -->
<string name="saved_login_clear_username">Обриши корисничко име</string>
<!-- Content Description (for screenreaders etc) read for the button to copy a site in logins -->
<string name="saved_login_copy_site">Копирај страницу</string>
<!-- Content Description (for screenreaders etc) read for the button to open a site in logins -->
@ -1528,7 +1554,7 @@
<string name="saved_login_duplicate">Пријава са овим корисничким именом већ постоји</string>
<!-- Synced Tabs -->
<!-- Text displayed to ask user to connect another device as no devices found with account -->
<!-- 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 asking user to re-authenticate -->
<string name="synced_tabs_reauth">Поново потврдите идентитет.</string>
@ -1549,7 +1575,7 @@
<!-- Title text displayed in the dialog when top sites limit is reached. -->
<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">Да бисте додали нову популарну страницу, избришите постојећу. Дуже притисните страницу и одаберите уклањање.</string>
<string name="top_sites_max_limit_content_2">За додавање новог омиљеног сајта, прво уклоните један. Дуго притисните и изаберите уклони.</string>
<!-- Confirmation dialog button text when top sites limit is reached. -->
<string name="top_sites_max_limit_confirmation_button">Важи, разумем</string>
@ -1559,7 +1585,7 @@
<!-- Content description for close button in collection placeholder. -->
<string name="remove_home_collection_placeholder_content_description">Уклони</string>
<!-- depcrecated: text for the firefox account onboarding card header
<!-- 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>
@ -1567,4 +1593,9 @@
<string name="no_collections_header1">Сакупљајте ствари које су вам важне</string>
<!-- Deprecated: Label to describe what collections are to a new user without any collections -->
<string name="no_collections_description1">Групишите сличне претраге, странице и језичке за брз приступ касније.</string>
</resources>
<!-- Deprecated: text for the firefox account onboarding card header when we detect you're already signed in to -->
<string name="onboarding_firefox_account_auto_signin_header_2">Пријављени сте као %s у другом Firefox прегледачу, на овом телефону. Желите ли да се пријавите са тим налогом?</string>
<!-- Deprecated: Describes the add to homescreen functionality -->
<string name="add_to_homescreen_description">Ову страницу можете лако додати на почетни екран вашег телефона за тренутни приступ и брже прегледање.</string>
</resources>

@ -147,6 +147,8 @@
<string name="browser_menu_install_on_homescreen">Installera</string>
<!-- Menu option on the toolbar that takes you to synced tabs page-->
<string name="synced_tabs">Synkade flikar</string>
<!-- Content description (not visible, for screen readers etc.) for the Resync tabs button -->
<string name="resync_button_content_description">Omsynkronisering</string>
<!-- Browser menu button that opens the find in page menu -->
<string name="browser_menu_find_in_page">Hitta på sidan</string>
<!-- Browser menu button that creates a private tab -->

@ -144,6 +144,8 @@
<string name="browser_menu_install_on_homescreen">ติดตั้ง</string>
<!-- Menu option on the toolbar that takes you to synced tabs page-->
<string name="synced_tabs">แท็บที่ซิงค์</string>
<!-- Content description (not visible, for screen readers etc.) for the Resync tabs button -->
<string name="resync_button_content_description">ซิงค์ใหม่</string>
<!-- Browser menu button that opens the find in page menu -->
<string name="browser_menu_find_in_page">ค้นหาในหน้า</string>
<!-- Browser menu button that creates a private tab -->
@ -325,6 +327,8 @@
<string name="preferences_search_browsing_history">ค้นหาประวัติการเรียกดู</string>
<!-- Preference title for switch preference to suggest bookmarks when searching -->
<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 -->
<string name="preferences_account_settings">การตั้งค่าบัญชี</string>
<!-- Preference for enabling url autocomplete-->

@ -145,6 +145,8 @@
<string name="browser_menu_install_on_homescreen">Yükle</string>
<!-- Menu option on the toolbar that takes you to synced tabs page-->
<string name="synced_tabs">Eşitlenmiş sekmeler</string>
<!-- Content description (not visible, for screen readers etc.) for the Resync tabs button -->
<string name="resync_button_content_description">Yeniden eşitle</string>
<!-- Browser menu button that opens the find in page menu -->
<string name="browser_menu_find_in_page">Sayfada bul</string>
<!-- Browser menu button that creates a private tab -->

@ -146,6 +146,8 @@
<string name="browser_menu_install_on_homescreen">Встановити</string>
<!-- Menu option on the toolbar that takes you to synced tabs page-->
<string name="synced_tabs">Синхронізовані вкладки</string>
<!-- Content description (not visible, for screen readers etc.) for the Resync tabs button -->
<string name="resync_button_content_description">Синхронізувати повторно</string>
<!-- Browser menu button that opens the find in page menu -->
<string name="browser_menu_find_in_page">Знайти на сторінці</string>
<!-- Browser menu button that creates a private tab -->

@ -146,6 +146,8 @@
<string name="browser_menu_install_on_homescreen">Cài đặt</string>
<!-- Menu option on the toolbar that takes you to synced tabs page-->
<string name="synced_tabs">Các thẻ đã đồng bộ</string>
<!-- Content description (not visible, for screen readers etc.) for the Resync tabs button -->
<string name="resync_button_content_description">Đồng bộ hóa lại</string>
<!-- Browser menu button that opens the find in page menu -->
<string name="browser_menu_find_in_page">Tìm trong trang</string>
<!-- Browser menu button that creates a private tab -->

@ -149,6 +149,8 @@
<string name="browser_menu_install_on_homescreen">安装</string>
<!-- Menu option on the toolbar that takes you to synced tabs page-->
<string name="synced_tabs">受同步的标签页</string>
<!-- Content description (not visible, for screen readers etc.) for the Resync tabs button -->
<string name="resync_button_content_description">重新同步</string>
<!-- Browser menu button that opens the find in page menu -->
<string name="browser_menu_find_in_page">在页面中查找</string>
<!-- Browser menu button that creates a private tab -->
@ -565,7 +567,7 @@
<!-- Content description (not visible, for screen readers etc.): Add tab button. Adds a news tab when pressed -->
<string name="add_private_tab">新建隐私标签页</string>
<!-- Text for the new tab button to indicate adding a new private tab in the tab -->
<string name="tab_drawer_fab_content">私密</string>
<string name="tab_drawer_fab_content">隐私标签页</string>
<!-- Text shown as the title of the open tab tray -->
<string name="tab_tray_title">打开的标签页</string>
<!-- Text shown in the menu for saving tabs to a collection -->

@ -146,6 +146,8 @@
<string name="browser_menu_install_on_homescreen">安裝</string>
<!-- Menu option on the toolbar that takes you to synced tabs page-->
<string name="synced_tabs">同步的分頁</string>
<!-- Content description (not visible, for screen readers etc.) for the Resync tabs button -->
<string name="resync_button_content_description">重新同步</string>
<!-- Browser menu button that opens the find in page menu -->
<string name="browser_menu_find_in_page">在頁面中搜尋</string>
<!-- Browser menu button that creates a private tab -->

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save