1
0
Fork 0

Copione merged onto master
continuous-integration/drone/push Build is passing Details

master
blallo 2020-07-07 00:00:44 +02:00
commit dd65dc2995
65 changed files with 2086 additions and 248 deletions

View File

@ -22,10 +22,11 @@ class AppRequestInterceptor(private val context: Context) : RequestInterceptor {
uri: String, uri: String,
hasUserGesture: Boolean, hasUserGesture: Boolean,
isSameDomain: Boolean, isSameDomain: Boolean,
isRedirect: Boolean isRedirect: Boolean,
isDirectNavigation: Boolean
): RequestInterceptor.InterceptionResponse? { ): RequestInterceptor.InterceptionResponse? {
return appContext.components.services.accountsAuthFeature.interceptor.onLoadRequest( return appContext.components.services.accountsAuthFeature.interceptor.onLoadRequest(
engineSession, uri, hasUserGesture, isSameDomain, isRedirect engineSession, uri, hasUserGesture, isSameDomain, isRedirect, isDirectNavigation
) )
} }
} }

View File

@ -173,6 +173,7 @@ class ContextMenusTest {
} }
@Test @Test
@Ignore("Intermittent: https://github.com/mozilla-mobile/fenix/issues/12309")
fun verifyContextSaveImage() { fun verifyContextSaveImage() {
val pageLinks = val pageLinks =
TestAssetHelper.getGenericAsset(mockWebServer, 4) TestAssetHelper.getGenericAsset(mockWebServer, 4)
@ -197,6 +198,7 @@ class ContextMenusTest {
} }
@Test @Test
@Ignore("Intermittent: https://github.com/mozilla-mobile/fenix/issues/12309")
fun verifyContextMixedVariations() { fun verifyContextMixedVariations() {
val pageLinks = val pageLinks =
TestAssetHelper.getGenericAsset(mockWebServer, 4) TestAssetHelper.getGenericAsset(mockWebServer, 4)

View File

@ -43,7 +43,7 @@ class ThreeDotMenuMainTest {
@JvmStatic @JvmStatic
fun setDevicePreference() { fun setDevicePreference() {
val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) val mDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
mDevice.executeShellCommand("settings put secure long_press_timeout 1500") mDevice.executeShellCommand("settings put secure long_press_timeout 3000")
} }
} }

View File

@ -21,10 +21,11 @@ class AppRequestInterceptor(private val context: Context) : RequestInterceptor {
uri: String, uri: String,
hasUserGesture: Boolean, hasUserGesture: Boolean,
isSameDomain: Boolean, isSameDomain: Boolean,
isRedirect: Boolean isRedirect: Boolean,
isDirectNavigation: Boolean
): RequestInterceptor.InterceptionResponse? { ): RequestInterceptor.InterceptionResponse? {
return context.components.services.appLinksInterceptor return context.components.services.appLinksInterceptor
.onLoadRequest(engineSession, uri, hasUserGesture, isSameDomain, isRedirect) .onLoadRequest(engineSession, uri, hasUserGesture, isSameDomain, isRedirect, isDirectNavigation)
} }
override fun onErrorRequest( override fun onErrorRequest(

View File

@ -63,8 +63,8 @@ import org.mozilla.fenix.exceptions.ExceptionsFragmentDirections
import org.mozilla.fenix.ext.alreadyOnDestination import org.mozilla.fenix.ext.alreadyOnDestination
import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.nav import org.mozilla.fenix.ext.nav
import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.ext.resetPoliciesAfter import org.mozilla.fenix.ext.resetPoliciesAfter
import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.home.HomeFragmentDirections import org.mozilla.fenix.home.HomeFragmentDirections
import org.mozilla.fenix.home.intent.CrashReporterIntentProcessor import org.mozilla.fenix.home.intent.CrashReporterIntentProcessor
import org.mozilla.fenix.home.intent.DeepLinkIntentProcessor import org.mozilla.fenix.home.intent.DeepLinkIntentProcessor
@ -100,7 +100,7 @@ import org.mozilla.fenix.utils.RunWhenReadyQueue
* - browser screen * - browser screen
*/ */
@SuppressWarnings("TooManyFunctions", "LargeClass") @SuppressWarnings("TooManyFunctions", "LargeClass")
open class HomeActivity : LocaleAwareAppCompatActivity() { open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
private var webExtScope: CoroutineScope? = null private var webExtScope: CoroutineScope? = null
lateinit var themeManager: ThemeManager lateinit var themeManager: ThemeManager
@ -392,7 +392,7 @@ open class HomeActivity : LocaleAwareAppCompatActivity() {
* Returns the [supportActionBar], inflating it if necessary. * Returns the [supportActionBar], inflating it if necessary.
* Everyone should call this instead of supportActionBar. * Everyone should call this instead of supportActionBar.
*/ */
fun getSupportActionBarAndInflateIfNecessary(): ActionBar { override fun getSupportActionBarAndInflateIfNecessary(): ActionBar {
if (!isToolbarInflated) { if (!isToolbarInflated) {
navigationToolbar = navigationToolbarStub.inflate() as Toolbar navigationToolbar = navigationToolbarStub.inflate() as Toolbar

View File

@ -0,0 +1,20 @@
/* 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
import androidx.appcompat.app.ActionBar
/**
* Interface for the main activity in a single-activity architecture.
* All fragments will be displayed inside this activity.
*/
interface NavHostActivity {
/**
* Returns the support action bar, inflating it if necessary.
* Everyone should call this instead of supportActionBar.
*/
fun getSupportActionBarAndInflateIfNecessary(): ActionBar
}

View File

@ -5,10 +5,11 @@
package org.mozilla.fenix.addons package org.mozilla.fenix.addons
import android.content.Intent import android.content.Intent
import android.net.Uri import android.content.Intent.ACTION_VIEW
import android.os.Bundle import android.os.Bundle
import android.view.View import android.view.View
import androidx.annotation.StringRes import androidx.annotation.StringRes
import androidx.core.net.toUri
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.navigation.fragment.navArgs import androidx.navigation.fragment.navArgs
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
@ -26,7 +27,7 @@ private const val LEARN_MORE_URL =
/** /**
* A fragment to show the permissions of an add-on. * A fragment to show the permissions of an add-on.
*/ */
class AddonPermissionsDetailsFragment : Fragment(R.layout.fragment_add_on_permissions), View.OnClickListener { class AddonPermissionsDetailsFragment : Fragment(R.layout.fragment_add_on_permissions) {
private val args by navArgs<AddonPermissionsDetailsFragmentArgs>() private val args by navArgs<AddonPermissionsDetailsFragmentArgs>()
@ -55,12 +56,9 @@ class AddonPermissionsDetailsFragment : Fragment(R.layout.fragment_add_on_permis
} }
private fun bindLearnMore(view: View) { private fun bindLearnMore(view: View) {
view.learn_more_label.setOnClickListener(this) view.learn_more_label.setOnClickListener {
} val intent = Intent(ACTION_VIEW, LEARN_MORE_URL.toUri())
startActivity(intent)
override fun onClick(v: View?) { }
val intent =
Intent(Intent.ACTION_VIEW).setData(Uri.parse(LEARN_MORE_URL))
startActivity(intent)
} }
} }

View File

@ -24,7 +24,6 @@ import mozilla.components.feature.app.links.AppLinksUseCases
import mozilla.components.feature.contextmenu.ContextMenuCandidate import mozilla.components.feature.contextmenu.ContextMenuCandidate
import mozilla.components.feature.readerview.ReaderViewFeature import mozilla.components.feature.readerview.ReaderViewFeature
import mozilla.components.feature.search.SearchFeature import mozilla.components.feature.search.SearchFeature
import mozilla.components.feature.session.TrackingProtectionUseCases
import mozilla.components.feature.sitepermissions.SitePermissions import mozilla.components.feature.sitepermissions.SitePermissions
import mozilla.components.feature.tab.collections.TabCollection import mozilla.components.feature.tab.collections.TabCollection
import mozilla.components.feature.tabs.WindowFeature import mozilla.components.feature.tabs.WindowFeature
@ -207,11 +206,7 @@ class BrowserFragment : BaseBrowserFragment(), UserInteractionHandler {
override fun navToTrackingProtectionPanel(session: Session) { override fun navToTrackingProtectionPanel(session: Session) {
val navController = findNavController() val navController = findNavController()
val useCase = TrackingProtectionUseCases( requireComponents.useCases.trackingProtectionUseCases.containsException(session.id) { contains ->
sessionManager = requireComponents.core.sessionManager,
engine = requireComponents.core.engine
)
useCase.containsException(session) { contains ->
val isEnabled = session.trackerBlockingEnabled && !contains val isEnabled = session.trackerBlockingEnabled && !contains
val directions = val directions =
BrowserFragmentDirections.actionBrowserFragmentToTrackingProtectionPanelDialogFragment( BrowserFragmentDirections.actionBrowserFragmentToTrackingProtectionPanelDialogFragment(

View File

@ -84,11 +84,7 @@ class TabCollectionStorage(
} }
fun removeTabFromCollection(tabCollection: TabCollection, tab: Tab) { fun removeTabFromCollection(tabCollection: TabCollection, tab: Tab) {
if (tabCollection.tabs.size == 1) { collectionStorage.removeTabFromCollection(tabCollection, tab)
removeCollection(tabCollection)
} else {
collectionStorage.removeTabFromCollection(tabCollection, tab)
}
} }
fun renameCollection(tabCollection: TabCollection, title: String) { fun renameCollection(tabCollection: TabCollection, title: String) {

View File

@ -18,6 +18,7 @@ import mozilla.components.feature.pwa.WebAppUseCases
import mozilla.components.feature.search.SearchUseCases import mozilla.components.feature.search.SearchUseCases
import mozilla.components.feature.session.SessionUseCases import mozilla.components.feature.session.SessionUseCases
import mozilla.components.feature.session.SettingsUseCases import mozilla.components.feature.session.SettingsUseCases
import mozilla.components.feature.session.TrackingProtectionUseCases
import mozilla.components.feature.tabs.TabsUseCases import mozilla.components.feature.tabs.TabsUseCases
import org.mozilla.fenix.utils.Mockable import org.mozilla.fenix.utils.Mockable
@ -42,7 +43,7 @@ class UseCases(
/** /**
* Use cases that provide tab management. * Use cases that provide tab management.
*/ */
val tabsUseCases: TabsUseCases by lazy { TabsUseCases(sessionManager) } val tabsUseCases: TabsUseCases by lazy { TabsUseCases(store, sessionManager) }
/** /**
* Use cases that provide search engine integration. * Use cases that provide search engine integration.
@ -65,4 +66,6 @@ class UseCases(
val contextMenuUseCases by lazy { ContextMenuUseCases(sessionManager, store) } val contextMenuUseCases by lazy { ContextMenuUseCases(sessionManager, store) }
val engineSessionUseCases by lazy { EngineSessionUseCases(sessionManager) } val engineSessionUseCases by lazy { EngineSessionUseCases(sessionManager) }
val trackingProtectionUseCases by lazy { TrackingProtectionUseCases(store, engine) }
} }

View File

@ -11,7 +11,6 @@ import androidx.core.view.isVisible
import androidx.navigation.fragment.navArgs import androidx.navigation.fragment.navArgs
import kotlinx.android.synthetic.main.component_browser_top_toolbar.* import kotlinx.android.synthetic.main.component_browser_top_toolbar.*
import kotlinx.android.synthetic.main.fragment_browser.* import kotlinx.android.synthetic.main.fragment_browser.*
import kotlinx.android.synthetic.main.fragment_browser.view.*
import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.ExperimentalCoroutinesApi
import mozilla.components.browser.session.Session import mozilla.components.browser.session.Session
import mozilla.components.concept.engine.manifest.WebAppManifestParser import mozilla.components.concept.engine.manifest.WebAppManifestParser
@ -22,7 +21,6 @@ import mozilla.components.feature.pwa.feature.ManifestUpdateFeature
import mozilla.components.feature.pwa.feature.WebAppActivityFeature import mozilla.components.feature.pwa.feature.WebAppActivityFeature
import mozilla.components.feature.pwa.feature.WebAppHideToolbarFeature import mozilla.components.feature.pwa.feature.WebAppHideToolbarFeature
import mozilla.components.feature.pwa.feature.WebAppSiteControlsFeature import mozilla.components.feature.pwa.feature.WebAppSiteControlsFeature
import mozilla.components.feature.session.TrackingProtectionUseCases
import mozilla.components.feature.sitepermissions.SitePermissions import mozilla.components.feature.sitepermissions.SitePermissions
import mozilla.components.support.base.feature.UserInteractionHandler import mozilla.components.support.base.feature.UserInteractionHandler
import mozilla.components.support.base.feature.ViewBoundFeatureWrapper import mozilla.components.support.base.feature.ViewBoundFeatureWrapper
@ -171,11 +169,7 @@ class ExternalAppBrowserFragment : BaseBrowserFragment(), UserInteractionHandler
} }
override fun navToTrackingProtectionPanel(session: Session) { override fun navToTrackingProtectionPanel(session: Session) {
val useCase = TrackingProtectionUseCases( requireComponents.useCases.trackingProtectionUseCases.containsException(session.id) { contains ->
sessionManager = requireComponents.core.sessionManager,
engine = requireComponents.core.engine
)
useCase.containsException(session) { contains ->
val isEnabled = session.trackerBlockingEnabled && !contains val isEnabled = session.trackerBlockingEnabled && !contains
val directions = val directions =
ExternalAppBrowserFragmentDirections ExternalAppBrowserFragmentDirections

View File

@ -44,10 +44,7 @@ class ExceptionsFragment : Fragment() {
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View? { ): View? {
val view = inflater.inflate(R.layout.fragment_exceptions, container, false) val view = inflater.inflate(R.layout.fragment_exceptions, container, false)
trackingProtectionUseCases = TrackingProtectionUseCases( trackingProtectionUseCases = view.context.components.useCases.trackingProtectionUseCases
sessionManager = view.context.components.core.sessionManager,
engine = view.context.components.core.engine
)
exceptionsStore = StoreProvider.get(this) { exceptionsStore = StoreProvider.get(this) {
ExceptionsFragmentStore( ExceptionsFragmentStore(
ExceptionsFragmentState( ExceptionsFragmentState(

View File

@ -1,29 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.fenix.ext
import org.mozilla.fenix.search.telemetry.SearchProviderModel
fun SearchProviderModel.containsAds(urlList: List<String>): Boolean {
return urlList.containsAds(this.extraAdServersRegexps)
}
private fun String.isAd(adRegexps: List<String>): Boolean {
for (adsRegex in adRegexps) {
if (Regex(adsRegex).containsMatchIn(this)) {
return true
}
}
return false
}
private fun List<String>.containsAds(adRegexps: List<String>): Boolean {
for (url in this) {
if (url.isAd(adRegexps)) {
return true
}
}
return false
}

View File

@ -13,7 +13,7 @@ import androidx.navigation.NavOptions
import androidx.navigation.Navigator import androidx.navigation.Navigator
import androidx.navigation.fragment.NavHostFragment.findNavController import androidx.navigation.fragment.NavHostFragment.findNavController
import androidx.navigation.fragment.findNavController import androidx.navigation.fragment.findNavController
import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.NavHostActivity
import org.mozilla.fenix.R import org.mozilla.fenix.R
import org.mozilla.fenix.components.Components import org.mozilla.fenix.components.Components
@ -43,7 +43,7 @@ fun Fragment.getPreferenceKey(@StringRes resourceId: Int): String = getString(re
*/ */
fun Fragment.showToolbar(title: String) { fun Fragment.showToolbar(title: String) {
(requireActivity() as AppCompatActivity).title = title (requireActivity() as AppCompatActivity).title = title
(activity as HomeActivity).getSupportActionBarAndInflateIfNecessary().show() (activity as NavHostActivity).getSupportActionBarAndInflateIfNecessary().show()
} }
/** /**

View File

@ -20,7 +20,6 @@ import android.view.accessibility.AccessibilityEvent
import android.widget.Button import android.widget.Button
import android.widget.LinearLayout import android.widget.LinearLayout
import android.widget.PopupWindow import android.widget.PopupWindow
import androidx.annotation.StringRes
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.constraintlayout.widget.ConstraintLayout import androidx.constraintlayout.widget.ConstraintLayout
import androidx.constraintlayout.widget.ConstraintSet import androidx.constraintlayout.widget.ConstraintSet
@ -133,11 +132,11 @@ class HomeFragment : Fragment() {
private val collectionStorageObserver = object : TabCollectionStorage.Observer { private val collectionStorageObserver = object : TabCollectionStorage.Observer {
override fun onCollectionCreated(title: String, sessions: List<Session>) { override fun onCollectionCreated(title: String, sessions: List<Session>) {
scrollAndAnimateCollection(sessions.size) scrollAndAnimateCollection()
} }
override fun onTabsAdded(tabCollection: TabCollection, sessions: List<Session>) { override fun onTabsAdded(tabCollection: TabCollection, sessions: List<Session>) {
scrollAndAnimateCollection(sessions.size, tabCollection) scrollAndAnimateCollection(tabCollection)
} }
override fun onCollectionRenamed(tabCollection: TabCollection, title: String) { override fun onCollectionRenamed(tabCollection: TabCollection, title: String) {
@ -218,7 +217,8 @@ class HomeFragment : Fragment() {
sessionControlView = SessionControlView( sessionControlView = SessionControlView(
view.sessionControlRecyclerView, view.sessionControlRecyclerView,
sessionControlInteractor, sessionControlInteractor,
homeViewModel homeViewModel,
requireComponents.core.store.state.normalTabs.isNotEmpty()
) )
updateSessionControlView(view) updateSessionControlView(view)
@ -470,11 +470,10 @@ class HomeFragment : Fragment() {
} }
} }
private fun showDeleteCollectionPrompt(tabCollection: TabCollection) { private fun showDeleteCollectionPrompt(tabCollection: TabCollection, title: String?, message: String) {
val context = context ?: return val context = context ?: return
AlertDialog.Builder(context).apply { AlertDialog.Builder(context).apply {
val message = setTitle(title)
context.getString(R.string.tab_collection_dialog_message, tabCollection.title)
setMessage(message) setMessage(message)
setNegativeButton(R.string.tab_collection_dialog_negative) { dialog: DialogInterface, _ -> setNegativeButton(R.string.tab_collection_dialog_negative) { dialog: DialogInterface, _ ->
dialog.cancel() dialog.cancel()
@ -787,7 +786,6 @@ class HomeFragment : Fragment() {
} }
private fun scrollAndAnimateCollection( private fun scrollAndAnimateCollection(
tabsAddedToCollectionSize: Int,
changedCollection: TabCollection? = null changedCollection: TabCollection? = null
) { ) {
if (view != null) { if (view != null) {
@ -818,7 +816,7 @@ class HomeFragment : Fragment() {
) { ) {
super.onScrollStateChanged(recyclerView, newState) super.onScrollStateChanged(recyclerView, newState)
if (newState == SCROLL_STATE_IDLE) { if (newState == SCROLL_STATE_IDLE) {
animateCollection(tabsAddedToCollectionSize, indexOfCollection) animateCollection(indexOfCollection)
recyclerView.removeOnScrollListener(this) recyclerView.removeOnScrollListener(this)
} }
} }
@ -826,13 +824,13 @@ class HomeFragment : Fragment() {
recyclerView.addOnScrollListener(onScrollListener) recyclerView.addOnScrollListener(onScrollListener)
recyclerView.smoothScrollToPosition(indexOfCollection) recyclerView.smoothScrollToPosition(indexOfCollection)
} else { } else {
animateCollection(tabsAddedToCollectionSize, indexOfCollection) animateCollection(indexOfCollection)
} }
} }
} }
} }
private fun animateCollection(addedTabsSize: Int, indexOfCollection: Int) { private fun animateCollection(indexOfCollection: Int) {
viewLifecycleOwner.lifecycleScope.launch { viewLifecycleOwner.lifecycleScope.launch {
val viewHolder = val viewHolder =
sessionControlView!!.view.findViewHolderForAdapterPosition(indexOfCollection) sessionControlView!!.view.findViewHolderForAdapterPosition(indexOfCollection)
@ -859,26 +857,20 @@ class HomeFragment : Fragment() {
?.setDuration(FADE_ANIM_DURATION) ?.setDuration(FADE_ANIM_DURATION)
?.setListener(listener)?.start() ?.setListener(listener)?.start()
}.invokeOnCompletion { }.invokeOnCompletion {
showSavedSnackbar(addedTabsSize) showSavedSnackbar()
} }
} }
private fun showSavedSnackbar(tabSize: Int) { private fun showSavedSnackbar() {
viewLifecycleOwner.lifecycleScope.launch { viewLifecycleOwner.lifecycleScope.launch {
delay(ANIM_SNACKBAR_DELAY) delay(ANIM_SNACKBAR_DELAY)
view?.let { view -> view?.let { view ->
@StringRes
val stringRes = if (tabSize > 1) {
R.string.create_collection_tabs_saved
} else {
R.string.create_collection_tab_saved
}
FenixSnackbar.make( FenixSnackbar.make(
view = view, view = view,
duration = Snackbar.LENGTH_LONG, duration = Snackbar.LENGTH_LONG,
isDisplayedWithBrowserToolbar = false isDisplayedWithBrowserToolbar = false
) )
.setText(view.context.getString(stringRes)) .setText(view.context.getString(R.string.create_collection_tabs_saved_new_collection))
.setAnchorView(snackbarAnchorView) .setAnchorView(snackbarAnchorView)
.show() .show()
} }

View File

@ -108,7 +108,8 @@ class AdapterItemDiffCallback : DiffUtil.ItemCallback<AdapterItem>() {
} }
class SessionControlAdapter( class SessionControlAdapter(
private val interactor: SessionControlInteractor private val interactor: SessionControlInteractor,
private val hasNormalTabsOpened: Boolean
) : ListAdapter<AdapterItem, RecyclerView.ViewHolder>(AdapterItemDiffCallback()) { ) : ListAdapter<AdapterItem, RecyclerView.ViewHolder>(AdapterItemDiffCallback()) {
// This method triggers the ComplexMethod lint error when in fact it's quite simple. // This method triggers the ComplexMethod lint error when in fact it's quite simple.
@ -119,7 +120,8 @@ class SessionControlAdapter(
ButtonTipViewHolder.LAYOUT_ID -> ButtonTipViewHolder(view, interactor) ButtonTipViewHolder.LAYOUT_ID -> ButtonTipViewHolder(view, interactor)
TopSiteViewHolder.LAYOUT_ID -> TopSiteViewHolder(view, interactor) TopSiteViewHolder.LAYOUT_ID -> TopSiteViewHolder(view, interactor)
PrivateBrowsingDescriptionViewHolder.LAYOUT_ID -> PrivateBrowsingDescriptionViewHolder(view, interactor) PrivateBrowsingDescriptionViewHolder.LAYOUT_ID -> PrivateBrowsingDescriptionViewHolder(view, interactor)
NoCollectionsMessageViewHolder.LAYOUT_ID -> NoCollectionsMessageViewHolder(view, interactor) NoCollectionsMessageViewHolder.LAYOUT_ID ->
NoCollectionsMessageViewHolder(view, interactor, hasNormalTabsOpened)
CollectionHeaderViewHolder.LAYOUT_ID -> CollectionHeaderViewHolder(view) CollectionHeaderViewHolder.LAYOUT_ID -> CollectionHeaderViewHolder(view)
CollectionViewHolder.LAYOUT_ID -> CollectionViewHolder(view, interactor) CollectionViewHolder.LAYOUT_ID -> CollectionViewHolder(view, interactor)
TabInCollectionViewHolder.LAYOUT_ID -> TabInCollectionViewHolder(view, interactor, differentLastItem = true) TabInCollectionViewHolder.LAYOUT_ID -> TabInCollectionViewHolder(view, interactor, differentLastItem = true)

View File

@ -136,7 +136,7 @@ class DefaultSessionControlController(
private val getListOfTabs: () -> List<Tab>, private val getListOfTabs: () -> List<Tab>,
private val hideOnboarding: () -> Unit, private val hideOnboarding: () -> Unit,
private val registerCollectionStorageObserver: () -> Unit, private val registerCollectionStorageObserver: () -> Unit,
private val showDeleteCollectionPrompt: (tabCollection: TabCollection) -> Unit, private val showDeleteCollectionPrompt: (tabCollection: TabCollection, title: String?, message: String) -> Unit,
private val openSettingsScreen: () -> Unit, private val openSettingsScreen: () -> Unit,
private val openWhatsNewLink: () -> Unit, private val openWhatsNewLink: () -> Unit,
private val openPrivacyNotice: () -> Unit, private val openPrivacyNotice: () -> Unit,
@ -196,8 +196,14 @@ class DefaultSessionControlController(
override fun handleCollectionRemoveTab(collection: TabCollection, tab: ComponentTab) { override fun handleCollectionRemoveTab(collection: TabCollection, tab: ComponentTab) {
metrics.track(Event.CollectionTabRemoved) metrics.track(Event.CollectionTabRemoved)
viewLifecycleScope.launch(Dispatchers.IO) { if (collection.tabs.size == 1) {
tabCollectionStorage.removeTabFromCollection(collection, tab) val title = activity.resources.getString(R.string.delete_tab_and_collection_dialog_title, collection.title)
val message = activity.resources.getString(R.string.delete_tab_and_collection_dialog_message)
showDeleteCollectionPrompt(collection, title, message)
} else {
viewLifecycleScope.launch(Dispatchers.IO) {
tabCollectionStorage.removeTabFromCollection(collection, tab)
}
} }
} }
@ -207,7 +213,8 @@ class DefaultSessionControlController(
} }
override fun handleDeleteCollectionTapped(collection: TabCollection) { override fun handleDeleteCollectionTapped(collection: TabCollection) {
showDeleteCollectionPrompt(collection) val message = activity.resources.getString(R.string.tab_collection_dialog_message, collection.title)
showDeleteCollectionPrompt(collection, null, message)
} }
override fun handleOpenInPrivateTabClicked(topSite: TopSite) { override fun handleOpenInPrivateTabClicked(topSite: TopSite) {

View File

@ -114,12 +114,13 @@ private fun collectionTabItems(collection: TabCollection) = collection.tabs.mapI
class SessionControlView( class SessionControlView(
override val containerView: View?, override val containerView: View?,
interactor: SessionControlInteractor, interactor: SessionControlInteractor,
private var homeScreenViewModel: HomeScreenViewModel private var homeScreenViewModel: HomeScreenViewModel,
private val hasNormalTabsOpened: Boolean
) : LayoutContainer { ) : LayoutContainer {
val view: RecyclerView = containerView as RecyclerView val view: RecyclerView = containerView as RecyclerView
private val sessionControlAdapter = SessionControlAdapter(interactor) private val sessionControlAdapter = SessionControlAdapter(interactor, hasNormalTabsOpened)
init { init {
view.apply { view.apply {

View File

@ -5,6 +5,7 @@
package org.mozilla.fenix.home.sessioncontrol.viewholders package org.mozilla.fenix.home.sessioncontrol.viewholders
import android.view.View import android.view.View
import androidx.core.view.isVisible
import kotlinx.android.synthetic.main.no_collections_message.view.* import kotlinx.android.synthetic.main.no_collections_message.view.*
import org.mozilla.fenix.R import org.mozilla.fenix.R
import org.mozilla.fenix.ext.ViewHolder import org.mozilla.fenix.ext.ViewHolder
@ -12,13 +13,15 @@ import org.mozilla.fenix.home.sessioncontrol.CollectionInteractor
open class NoCollectionsMessageViewHolder( open class NoCollectionsMessageViewHolder(
view: View, view: View,
interactor: CollectionInteractor interactor: CollectionInteractor,
hasNormalTabsOpened: Boolean
) : ViewHolder(view) { ) : ViewHolder(view) {
init { init {
view.add_tabs_to_collections_button.setOnClickListener { view.add_tabs_to_collections_button.setOnClickListener {
interactor.onAddTabsToCollectionTapped() interactor.onAddTabsToCollectionTapped()
} }
view.add_tabs_to_collections_button.isVisible = hasNormalTabsOpened
} }
companion object { companion object {
const val LAYOUT_ID = R.layout.no_collections_message const val LAYOUT_ID = R.layout.no_collections_message

View File

@ -37,7 +37,7 @@ import mozilla.components.concept.storage.BookmarkNode
import mozilla.components.concept.storage.BookmarkNodeType import mozilla.components.concept.storage.BookmarkNodeType
import mozilla.components.lib.state.ext.consumeFrom import mozilla.components.lib.state.ext.consumeFrom
import mozilla.components.support.base.feature.UserInteractionHandler import mozilla.components.support.base.feature.UserInteractionHandler
import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.NavHostActivity
import org.mozilla.fenix.R import org.mozilla.fenix.R
import org.mozilla.fenix.components.FenixSnackbar import org.mozilla.fenix.components.FenixSnackbar
import org.mozilla.fenix.components.StoreProvider import org.mozilla.fenix.components.StoreProvider
@ -147,7 +147,7 @@ class BookmarkFragment : LibraryPageFragment<BookmarkNode>(), UserInteractionHan
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
(activity as HomeActivity).getSupportActionBarAndInflateIfNecessary().show() (activity as NavHostActivity).getSupportActionBarAndInflateIfNecessary().show()
// Reload bookmarks when returning to this fragment in case they have been edited // Reload bookmarks when returning to this fragment in case they have been edited
val args by navArgs<BookmarkFragmentArgs>() val args by navArgs<BookmarkFragmentArgs>()

View File

@ -31,7 +31,7 @@ import mozilla.components.concept.storage.BookmarkNode
import mozilla.components.concept.storage.BookmarkNodeType import mozilla.components.concept.storage.BookmarkNodeType
import mozilla.components.support.ktx.android.content.getColorFromAttr import mozilla.components.support.ktx.android.content.getColorFromAttr
import mozilla.components.support.ktx.android.view.hideKeyboard import mozilla.components.support.ktx.android.view.hideKeyboard
import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.NavHostActivity
import org.mozilla.fenix.R import org.mozilla.fenix.R
import org.mozilla.fenix.components.FenixSnackbar import org.mozilla.fenix.components.FenixSnackbar
import org.mozilla.fenix.components.metrics.Event import org.mozilla.fenix.components.metrics.Event
@ -111,15 +111,13 @@ class EditBookmarkFragment : Fragment(R.layout.fragment_edit_bookmark) {
} }
private fun initToolbar() { private fun initToolbar() {
val activity = activity as? AppCompatActivity val activity = activity as AppCompatActivity
val actionBar = (activity as HomeActivity).getSupportActionBarAndInflateIfNecessary() val actionBar = (activity as NavHostActivity).getSupportActionBarAndInflateIfNecessary()
val toolbar = activity.findViewById<Toolbar>(R.id.navigationToolbar) val toolbar = activity.findViewById<Toolbar>(R.id.navigationToolbar)
context?.let { toolbar?.setToolbarColors(
toolbar?.setToolbarColors( foreground = activity.getColorFromAttr(R.attr.primaryText),
foreground = it.getColorFromAttr(R.attr.primaryText), background = activity.getColorFromAttr(R.attr.foundation)
background = it.getColorFromAttr(R.attr.foundation) )
)
}
actionBar.show() actionBar.show()
} }

View File

@ -101,6 +101,7 @@ class SearchFragment : Fragment(), UserInteractionHandler {
requireComponents.analytics.metrics.track(Event.InteractWithSearchURLArea) requireComponents.analytics.metrics.track(Event.InteractWithSearchURLArea)
val areShortcutsAvailable = areShortcutsAvailable()
searchStore = StoreProvider.get(this) { searchStore = StoreProvider.get(this) {
SearchFragmentStore( SearchFragmentStore(
SearchFragmentState( SearchFragmentState(
@ -111,7 +112,10 @@ class SearchFragment : Fragment(), UserInteractionHandler {
defaultEngineSource = currentSearchEngine, defaultEngineSource = currentSearchEngine,
showSearchSuggestions = shouldShowSearchSuggestions(isPrivate), showSearchSuggestions = shouldShowSearchSuggestions(isPrivate),
showSearchSuggestionsHint = false, showSearchSuggestionsHint = false,
showSearchShortcuts = requireContext().settings().shouldShowSearchShortcuts && url.isEmpty(), showSearchShortcuts = requireContext().settings().shouldShowSearchShortcuts &&
url.isEmpty() &&
areShortcutsAvailable,
areShortcutsAvailable = areShortcutsAvailable,
showClipboardSuggestions = requireContext().settings().shouldShowClipboardSuggestions, showClipboardSuggestions = requireContext().settings().shouldShowClipboardSuggestions,
showHistorySuggestions = requireContext().settings().shouldShowHistorySuggestions, showHistorySuggestions = requireContext().settings().shouldShowHistorySuggestions,
showBookmarkSuggestions = requireContext().settings().shouldShowBookmarkSuggestions, showBookmarkSuggestions = requireContext().settings().shouldShowBookmarkSuggestions,
@ -334,6 +338,12 @@ class SearchFragment : Fragment(), UserInteractionHandler {
) )
} }
// Users can from this fragment go to install/uninstall search engines and then return.
val areShortcutsAvailable = areShortcutsAvailable()
if (searchStore.state.areShortcutsAvailable != areShortcutsAvailable) {
searchStore.dispatch(SearchFragmentAction.UpdateShortcutsAvailability(areShortcutsAvailable))
}
if (!permissionDidUpdate) { if (!permissionDidUpdate) {
toolbarView.view.edit.focus() toolbarView.view.edit.focus()
} }
@ -431,6 +441,8 @@ class SearchFragment : Fragment(), UserInteractionHandler {
private fun updateSearchShortcutsIcon(searchState: SearchFragmentState) { private fun updateSearchShortcutsIcon(searchState: SearchFragmentState) {
view?.apply { view?.apply {
search_shortcuts_button.isVisible = searchState.areShortcutsAvailable
val showShortcuts = searchState.showSearchShortcuts val showShortcuts = searchState.showSearchShortcuts
search_shortcuts_button.isChecked = showShortcuts search_shortcuts_button.isChecked = showShortcuts
@ -441,7 +453,16 @@ class SearchFragment : Fragment(), UserInteractionHandler {
} }
} }
/**
* Return if the user has *at least 2* installed search engines.
* Useful to decide whether to show / enable certain functionalities.
*/
private fun areShortcutsAvailable() =
requireContext().components.search.provider.installedSearchEngines(requireContext())
.list.size >= MINIMUM_SEARCH_ENGINES_NUMBER_TO_SHOW_SHORTCUTS
companion object { companion object {
private const val REQUEST_CODE_CAMERA_PERMISSIONS = 1 private const val REQUEST_CODE_CAMERA_PERMISSIONS = 1
private const val MINIMUM_SEARCH_ENGINES_NUMBER_TO_SHOW_SHORTCUTS = 2
} }
} }

View File

@ -41,6 +41,8 @@ sealed class SearchEngineSource {
* @property showSearchSuggestions Whether or not to show search suggestions from the search engine in the AwesomeBar * @property showSearchSuggestions Whether or not to show search suggestions from the search engine in the AwesomeBar
* @property showSearchSuggestionsHint Whether or not to show search suggestions in private hint panel * @property showSearchSuggestionsHint Whether or not to show search suggestions in private hint panel
* @property showSearchShortcuts Whether or not to show search shortcuts in the AwesomeBar * @property showSearchShortcuts Whether or not to show search shortcuts in the AwesomeBar
* @property areShortcutsAvailable Whether or not there are >=2 search engines installed
* so to know to present users with certain options or not.
* @property showClipboardSuggestions Whether or not to show clipboard suggestion in the AwesomeBar * @property showClipboardSuggestions Whether or not to show clipboard suggestion in the AwesomeBar
* @property showHistorySuggestions Whether or not to show history suggestions in the AwesomeBar * @property showHistorySuggestions Whether or not to show history suggestions in the AwesomeBar
* @property showBookmarkSuggestions Whether or not to show the bookmark suggestion in the AwesomeBar * @property showBookmarkSuggestions Whether or not to show the bookmark suggestion in the AwesomeBar
@ -55,6 +57,7 @@ data class SearchFragmentState(
val showSearchSuggestions: Boolean, val showSearchSuggestions: Boolean,
val showSearchSuggestionsHint: Boolean, val showSearchSuggestionsHint: Boolean,
val showSearchShortcuts: Boolean, val showSearchShortcuts: Boolean,
val areShortcutsAvailable: Boolean,
val showClipboardSuggestions: Boolean, val showClipboardSuggestions: Boolean,
val showHistorySuggestions: Boolean, val showHistorySuggestions: Boolean,
val showBookmarkSuggestions: Boolean, val showBookmarkSuggestions: Boolean,
@ -71,6 +74,7 @@ sealed class SearchFragmentAction : Action {
data class SearchShortcutEngineSelected(val engine: SearchEngine) : SearchFragmentAction() data class SearchShortcutEngineSelected(val engine: SearchEngine) : SearchFragmentAction()
data class SelectNewDefaultSearchEngine(val engine: SearchEngine) : SearchFragmentAction() data class SelectNewDefaultSearchEngine(val engine: SearchEngine) : SearchFragmentAction()
data class ShowSearchShortcutEnginePicker(val show: Boolean) : SearchFragmentAction() data class ShowSearchShortcutEnginePicker(val show: Boolean) : SearchFragmentAction()
data class UpdateShortcutsAvailability(val areShortcutsAvailable: Boolean) : SearchFragmentAction()
data class AllowSearchSuggestionsInPrivateModePrompt(val show: Boolean) : SearchFragmentAction() data class AllowSearchSuggestionsInPrivateModePrompt(val show: Boolean) : SearchFragmentAction()
data class UpdateQuery(val query: String) : SearchFragmentAction() data class UpdateQuery(val query: String) : SearchFragmentAction()
} }
@ -86,7 +90,9 @@ private fun searchStateReducer(state: SearchFragmentState, action: SearchFragmen
showSearchShortcuts = false showSearchShortcuts = false
) )
is SearchFragmentAction.ShowSearchShortcutEnginePicker -> is SearchFragmentAction.ShowSearchShortcutEnginePicker ->
state.copy(showSearchShortcuts = action.show) state.copy(showSearchShortcuts = action.show && state.areShortcutsAvailable)
is SearchFragmentAction.UpdateShortcutsAvailability ->
state.copy(areShortcutsAvailable = action.areShortcutsAvailable)
is SearchFragmentAction.UpdateQuery -> is SearchFragmentAction.UpdateQuery ->
state.copy(query = action.query) state.copy(query = action.query)
is SearchFragmentAction.SelectNewDefaultSearchEngine -> is SearchFragmentAction.SelectNewDefaultSearchEngine ->

View File

@ -82,14 +82,8 @@ abstract class BaseSearchTelemetry {
abstract fun install(engine: Engine, store: BrowserStore) abstract fun install(engine: Engine, store: BrowserStore)
internal fun getProviderForUrl(url: String): SearchProviderModel? { internal fun getProviderForUrl(url: String): SearchProviderModel? =
for (provider in providerList) { providerList.find { provider -> provider.regexp.containsMatchIn(url) }
if (Regex(provider.regexp).containsMatchIn(url)) {
return provider
}
}
return null
}
internal fun installWebExtension( internal fun installWebExtension(
engine: Engine, engine: Engine,

View File

@ -6,11 +6,41 @@ package org.mozilla.fenix.search.telemetry
data class SearchProviderModel( data class SearchProviderModel(
val name: String, val name: String,
val regexp: String, val regexp: Regex,
val queryParam: String, val queryParam: String,
val codeParam: String = "", val codeParam: String,
val codePrefixes: List<String> = ArrayList(), val codePrefixes: List<String>,
val followOnParams: List<String> = ArrayList(), val followOnParams: List<String>,
val extraAdServersRegexps: List<String> = ArrayList(), val extraAdServersRegexps: List<Regex>,
val followOnCookies: List<SearchProviderCookie> = ArrayList() val followOnCookies: List<SearchProviderCookie>
) ) {
constructor(
name: String,
regexp: String,
queryParam: String,
codeParam: String = "",
codePrefixes: List<String> = emptyList(),
followOnParams: List<String> = emptyList(),
extraAdServersRegexps: List<String> = emptyList(),
followOnCookies: List<SearchProviderCookie> = emptyList()
) : this(
name = name,
regexp = regexp.toRegex(),
queryParam = queryParam,
codeParam = codeParam,
codePrefixes = codePrefixes,
followOnParams = followOnParams,
extraAdServersRegexps = extraAdServersRegexps.map { it.toRegex() },
followOnCookies = followOnCookies
)
/**
* Checks if any of the given URLs represent an ad from the search engine.
* Used to check if a clicked link was for an ad.
*/
fun containsAds(urlList: List<String>) = urlList.any { url -> isAd(url) }
private fun isAd(url: String) =
extraAdServersRegexps.any { adsRegex -> adsRegex.containsMatchIn(url) }
}

View File

@ -10,7 +10,6 @@ import mozilla.components.concept.engine.Engine
import org.json.JSONObject import org.json.JSONObject
import org.mozilla.fenix.components.metrics.Event import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.components.metrics.MetricController import org.mozilla.fenix.components.metrics.MetricController
import org.mozilla.fenix.ext.containsAds
import org.mozilla.fenix.search.telemetry.BaseSearchTelemetry import org.mozilla.fenix.search.telemetry.BaseSearchTelemetry
import org.mozilla.fenix.search.telemetry.ExtensionInfo import org.mozilla.fenix.search.telemetry.ExtensionInfo

View File

@ -14,7 +14,6 @@ import android.view.MenuItem
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.CompoundButton import android.widget.CompoundButton
import androidx.appcompat.app.AppCompatActivity
import androidx.constraintlayout.widget.ConstraintLayout import androidx.constraintlayout.widget.ConstraintLayout
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
@ -36,6 +35,7 @@ import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.components.searchengine.CustomSearchEngineStore import org.mozilla.fenix.components.searchengine.CustomSearchEngineStore
import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.requireComponents import org.mozilla.fenix.ext.requireComponents
import org.mozilla.fenix.ext.showToolbar
import org.mozilla.fenix.settings.SupportUtils import org.mozilla.fenix.settings.SupportUtils
import java.util.Locale import java.util.Locale
@ -93,7 +93,7 @@ class AddSearchEngineFragment : Fragment(), CompoundButton.OnCheckedChangeListen
availableEngines.forEachIndexed(setupSearchEngineItem) availableEngines.forEachIndexed(setupSearchEngineItem)
val engineItem = makeCustomButton(layoutInflater) val engineItem = makeCustomButton(layoutInflater, res = resources)
engineItem.id = CUSTOM_INDEX engineItem.id = CUSTOM_INDEX
engineItem.radio_button.isChecked = selectedIndex == CUSTOM_INDEX engineItem.radio_button.isChecked = selectedIndex == CUSTOM_INDEX
engineViews.add(engineItem) engineViews.add(engineItem)
@ -115,8 +115,7 @@ class AddSearchEngineFragment : Fragment(), CompoundButton.OnCheckedChangeListen
override fun onResume() { override fun onResume() {
super.onResume() super.onResume()
(activity as AppCompatActivity).title = getString(R.string.search_engine_add_custom_search_engine_title) showToolbar(getString(R.string.search_engine_add_custom_search_engine_title))
(activity as HomeActivity).getSupportActionBarAndInflateIfNecessary().show()
} }
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
@ -250,11 +249,12 @@ class AddSearchEngineFragment : Fragment(), CompoundButton.OnCheckedChangeListen
toggleCustomForm(selectedIndex == -1) toggleCustomForm(selectedIndex == -1)
} }
private fun makeCustomButton(layoutInflater: LayoutInflater): View { private fun makeCustomButton(layoutInflater: LayoutInflater, res: Resources): View {
val wrapper = layoutInflater val wrapper = layoutInflater
.inflate(R.layout.custom_search_engine_radio_button, null) as ConstraintLayout .inflate(R.layout.custom_search_engine_radio_button, null) as ConstraintLayout
wrapper.setOnClickListener { wrapper.radio_button.isChecked = true } wrapper.setOnClickListener { wrapper.radio_button.isChecked = true }
wrapper.radio_button.setOnCheckedChangeListener(this) wrapper.radio_button.setOnCheckedChangeListener(this)
wrapper.minHeight = res.getDimensionPixelSize(R.dimen.radio_button_preference_height)
return wrapper return wrapper
} }
@ -280,6 +280,7 @@ class AddSearchEngineFragment : Fragment(), CompoundButton.OnCheckedChangeListen
engineIcon.setBounds(0, 0, iconSize, iconSize) engineIcon.setBounds(0, 0, iconSize, iconSize)
wrapper.engine_icon.setImageDrawable(engineIcon) wrapper.engine_icon.setImageDrawable(engineIcon)
wrapper.overflow_menu.visibility = View.GONE wrapper.overflow_menu.visibility = View.GONE
wrapper.minHeight = res.getDimensionPixelSize(R.dimen.radio_button_preference_height)
return wrapper return wrapper
} }

View File

@ -28,7 +28,7 @@ import kotlinx.coroutines.Dispatchers.IO
import kotlinx.coroutines.Dispatchers.Main import kotlinx.coroutines.Dispatchers.Main
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import mozilla.components.feature.sitepermissions.SitePermissions import mozilla.components.feature.sitepermissions.SitePermissions
import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.NavHostActivity
import org.mozilla.fenix.R import org.mozilla.fenix.R
import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.loadIntoView import org.mozilla.fenix.ext.loadIntoView
@ -44,7 +44,7 @@ class SitePermissionsExceptionsFragment :
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
(activity as HomeActivity).getSupportActionBarAndInflateIfNecessary().show() (activity as NavHostActivity).getSupportActionBarAndInflateIfNecessary().show()
} }
override fun onViewCreated(rootView: View, savedInstanceState: Bundle?) { override fun onViewCreated(rootView: View, savedInstanceState: Bundle?) {

View File

@ -51,11 +51,11 @@ class TabTrayDialogFragment : AppCompatDialogFragment() {
private val collectionStorageObserver = object : TabCollectionStorage.Observer { private val collectionStorageObserver = object : TabCollectionStorage.Observer {
override fun onCollectionCreated(title: String, sessions: List<Session>) { override fun onCollectionCreated(title: String, sessions: List<Session>) {
showCollectionSnackbar() showCollectionSnackbar(sessions.size, true)
} }
override fun onTabsAdded(tabCollection: TabCollection, sessions: List<Session>) { override fun onTabsAdded(tabCollection: TabCollection, sessions: List<Session>) {
showCollectionSnackbar() showCollectionSnackbar(sessions.size)
} }
} }
@ -245,8 +245,19 @@ class TabTrayDialogFragment : AppCompatDialogFragment() {
} }
} }
private fun showCollectionSnackbar() { private fun showCollectionSnackbar(tabSize: Int, isNewCollection: Boolean = false) {
view.let { view.let {
val messageStringRes = when {
isNewCollection -> {
R.string.create_collection_tabs_saved_new_collection
}
tabSize > 1 -> {
R.string.create_collection_tabs_saved
}
else -> {
R.string.create_collection_tab_saved
}
}
val snackbar = FenixSnackbar val snackbar = FenixSnackbar
.make( .make(
duration = FenixSnackbar.LENGTH_LONG, duration = FenixSnackbar.LENGTH_LONG,
@ -254,7 +265,7 @@ class TabTrayDialogFragment : AppCompatDialogFragment() {
view = (view as View) view = (view as View)
) )
.setAnchorView(snackbarAnchor) .setAnchorView(snackbarAnchor)
.setText(requireContext().getString(R.string.create_collection_tabs_saved)) .setText(requireContext().getString(messageStringRes))
.setAction(requireContext().getString(R.string.create_collection_view)) { .setAction(requireContext().getString(R.string.create_collection_view)) {
dismissAllowingStateLoss() dismissAllowingStateLoss()
findNavController().navigate( findNavController().navigate(

View File

@ -61,11 +61,7 @@ class TrackingProtectionPanelDialogFragment : AppCompatDialogFragment(), UserInt
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
val components = requireComponents trackingProtectionUseCases = requireComponents.useCases.trackingProtectionUseCases
trackingProtectionUseCases = TrackingProtectionUseCases(
sessionManager = components.core.sessionManager,
engine = components.core.engine
)
} }
override fun onCreateView( override fun onCreateView(
@ -115,7 +111,7 @@ class TrackingProtectionPanelDialogFragment : AppCompatDialogFragment(), UserInt
private fun updateTrackers(session: Session) { private fun updateTrackers(session: Session) {
trackingProtectionUseCases.fetchTrackingLogs( trackingProtectionUseCases.fetchTrackingLogs(
session, session.id,
onSuccess = { onSuccess = {
trackingProtectionStore.dispatch(TrackingProtectionAction.TrackerLogChange(it)) trackingProtectionStore.dispatch(TrackingProtectionAction.TrackerLogChange(it))
}, },
@ -150,10 +146,10 @@ class TrackingProtectionPanelDialogFragment : AppCompatDialogFragment(), UserInt
val session = context.components.core.sessionManager.findSessionById(args.sessionId) val session = context.components.core.sessionManager.findSessionById(args.sessionId)
session?.let { session?.let {
if (isEnabled) { if (isEnabled) {
trackingProtectionUseCases.removeException(it) trackingProtectionUseCases.removeException(it.id)
} else { } else {
context.metrics.track(Event.TrackingProtectionException) context.metrics.track(Event.TrackingProtectionException)
trackingProtectionUseCases.addException(it) trackingProtectionUseCases.addException(it.id)
} }
with(context.components) { with(context.components) {

View File

@ -1,4 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?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" <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -10,7 +13,6 @@
android:id="@+id/locale_list" android:id="@+id/locale_list"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="0dp" android:layout_height="0dp"
android:layout_margin="@dimen/locale_list_margin"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"

View File

@ -29,6 +29,7 @@
android:id="@+id/edit_engine_name" android:id="@+id/edit_engine_name"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:minHeight="@dimen/accessibility_min_height"
android:hint="@string/search_add_custom_engine_name_hint" android:hint="@string/search_add_custom_engine_name_hint"
android:inputType="text" /> android:inputType="text" />
</com.google.android.material.textfield.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>
@ -46,6 +47,7 @@
android:id="@+id/edit_search_string" android:id="@+id/edit_search_string"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:minHeight="@dimen/accessibility_min_height"
android:hint="@string/search_add_custom_engine_search_string_hint" android:hint="@string/search_add_custom_engine_search_string_hint"
android:inputType="text" /> android:inputType="text" />
</com.google.android.material.textfield.TextInputLayout> </com.google.android.material.textfield.TextInputLayout>

View File

@ -20,7 +20,8 @@
android:textAppearance="?android:attr/textAppearanceListItem" android:textAppearance="?android:attr/textAppearanceListItem"
android:layout_marginStart="@dimen/search_bar_search_engine_icon_padding" android:layout_marginStart="@dimen/search_bar_search_engine_icon_padding"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
<TextView <TextView
android:id="@+id/engine_text" android:id="@+id/engine_text"
android:textColor="?primaryText" android:textColor="?primaryText"
@ -29,8 +30,9 @@
android:layout_marginStart="@dimen/search_bar_search_icon_margin" android:layout_marginStart="@dimen/search_bar_search_icon_margin"
android:layout_marginEnd="@dimen/radio_button_padding_horizontal" android:layout_marginEnd="@dimen/radio_button_padding_horizontal"
android:text="@string/search_add_custom_engine_label_other" android:text="@string/search_add_custom_engine_label_other"
android:textSize="16sp"
app:layout_constraintStart_toEndOf="@id/radio_button" app:layout_constraintStart_toEndOf="@id/radio_button"
app:layout_constraintTop_toTopOf="@id/radio_button" app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="@id/radio_button" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" /> app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -1,4 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?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" <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"

View File

@ -1,19 +1,22 @@
<?xml version="1.0" encoding="utf-8"?> <?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" <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="48dp">
<ImageView <ImageView
android:id="@+id/locale_selected_icon" android:id="@+id/locale_selected_icon"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="@dimen/locale_item_vertical_margin" android:layout_marginStart="@dimen/locale_list_margin"
android:layout_marginBottom="@dimen/locale_item_vertical_margin"
android:contentDescription="@string/a11y_selected_locale_content_description" android:contentDescription="@string/a11y_selected_locale_content_description"
app:srcCompat="@drawable/mozac_ic_check" app:srcCompat="@drawable/mozac_ic_check"
android:tint="?primaryText" app:tint="?primaryText"
android:visibility="gone" android:visibility="visible"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
@ -23,7 +26,7 @@
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="@dimen/locale_item_text_margin_start" android:layout_marginStart="@dimen/locale_item_text_margin_start"
android:layout_marginTop="@dimen/locale_item_vertical_margin" android:layout_marginEnd="@dimen/locale_item_text_margin_end"
android:textColor="?primaryText" android:textColor="?primaryText"
android:textAlignment="viewStart" android:textAlignment="viewStart"
app:layout_goneMarginStart="@dimen/locale_item_text_margin_gone_start" app:layout_goneMarginStart="@dimen/locale_item_text_margin_gone_start"
@ -33,22 +36,24 @@
app:layout_constraintStart_toEndOf="@+id/locale_selected_icon" app:layout_constraintStart_toEndOf="@+id/locale_selected_icon"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed" app:layout_constraintVertical_chainStyle="packed"
app:layout_goneMarginBottom="@dimen/locale_item_vertical_margin" /> tools:text="English (United States)" />
<TextView <TextView
android:id="@+id/locale_subtitle_text" android:id="@+id/locale_subtitle_text"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="@dimen/locale_item_text_margin_start" android:layout_marginStart="@dimen/locale_item_text_margin_start"
android:layout_marginBottom="@dimen/locale_item_vertical_margin" android:layout_marginEnd="@dimen/locale_item_text_margin_end"
android:textColor="?secondaryText" android:textColor="?secondaryText"
android:textAlignment="viewStart" android:textAlignment="viewStart"
android:textSize="@dimen/locale_item_subtitle_size" android:textSize="@dimen/locale_item_subtitle_size"
android:visibility="visible"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_goneMarginStart="@dimen/locale_item_text_margin_gone_start" app:layout_goneMarginStart="@dimen/locale_item_text_margin_gone_start"
app:layout_constraintStart_toEndOf="@+id/locale_selected_icon" app:layout_constraintStart_toEndOf="@+id/locale_selected_icon"
app:layout_constraintTop_toBottomOf="@+id/locale_title_text" app:layout_constraintTop_toBottomOf="@+id/locale_title_text"
app:layout_constraintVertical_chainStyle="packed" /> app:layout_constraintVertical_chainStyle="packed"
tools:text="English (United States)" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -1,13 +1,15 @@
<?xml version="1.0" encoding="utf-8"?> <?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/. -->
<TextView xmlns:android="http://schemas.android.com/apk/res/android" <TextView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" android:id="@android:id/title"
style="?android:attr/listViewStyle"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
style="?android:attr/listViewStyle"
android:layout_marginTop="16dp"
android:textAlignment="viewStart"
android:layout_marginStart="72dp" android:layout_marginStart="72dp"
android:layout_marginTop="16dp"
android:gravity="start|center_vertical" android:gravity="start|center_vertical"
app:fontFamily="@font/metropolis_semibold" android:textAlignment="viewStart"
android:id="@android:id/title" /> app:fontFamily="@font/metropolis_semibold" />

View File

@ -29,6 +29,7 @@
<TextView <TextView
android:id="@+id/title" android:id="@+id/title"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_marginStart="8dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="center|start" android:gravity="center|start"
android:layout_marginEnd="@dimen/radio_button_preference_horizontal" android:layout_marginEnd="@dimen/radio_button_preference_horizontal"

View File

@ -3,8 +3,8 @@
- License, v. 2.0. If a copy of the MPL was not distributed with this - License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. --> - 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" <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/synced_tabs_group" android:id="@+id/synced_tabs_group"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -12,17 +12,19 @@
<TextView <TextView
android:id="@+id/synced_tabs_group_name" android:id="@+id/synced_tabs_group_name"
android:layout_width="wrap_content" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="16dp" android:layout_marginStart="16dp"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:drawablePadding="32dp" android:drawablePadding="32dp"
android:gravity="center_vertical|start"
android:textAppearance="@style/Header14TextStyle" android:textAppearance="@style/Header14TextStyle"
android:textColor="?primaryText" android:textColor="?primaryText"
android:textSize="12sp" android:textSize="12sp"
android:gravity="center"
app:drawableStartCompat="@drawable/mozac_ic_device_desktop" app:drawableStartCompat="@drawable/mozac_ic_device_desktop"
app:drawableTint="?primaryText" app:drawableTint="?primaryText"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
tools:text="Header" /> tools:text="Header" />

View File

@ -807,6 +807,9 @@
<string name="tip_firefox_preview_moved_description">Firefox Nightly anuévase cada nueche y tien carauterístiques esperimentales. <string name="tip_firefox_preview_moved_description">Firefox Nightly anuévase cada nueche y tien carauterístiques esperimentales.
Por embargu, ye menos estable. Baxa la versión beta del restolador pa una esperiencia más estable.</string> Por embargu, ye menos estable. Baxa la versión beta del restolador pa una esperiencia más estable.</string>
<!-- text for firefox preview moving tip button. "Firefox for Android Beta" is intentionally hardcoded -->
<string name="tip_firefox_preview_moved_button_2">Consiguir Firefox Beta p\'Android</string>
<!-- text for firefox preview moving tip header. "Firefox Nightly" is intentionally hardcoded --> <!-- text for firefox preview moving tip header. "Firefox Nightly" is intentionally hardcoded -->
<string name="tip_firefox_preview_moved_header_preview_installed">Firefox Nightly mudó</string> <string name="tip_firefox_preview_moved_header_preview_installed">Firefox Nightly mudó</string>
<!-- text for firefox preview moving tip description --> <!-- text for firefox preview moving tip description -->
@ -819,6 +822,9 @@
<string name="tip_firefox_preview_moved_description_preview_not_installed">Dexa d\'usar esta aplicación darréu que nun va recibir más anovamientos de seguranza. Consigui la versión nueva de Nightly. <string name="tip_firefox_preview_moved_description_preview_not_installed">Dexa d\'usar esta aplicación darréu que nun va recibir más anovamientos de seguranza. Consigui la versión nueva de Nightly.
\n\nPa tresferir los marcadores, anicios de sesión y l\'historial a otra aplicación, crea una cuenta de Firefox.</string> \n\nPa tresferir los marcadores, anicios de sesión y l\'historial a otra aplicación, crea una cuenta de Firefox.</string>
<!-- text for firefox preview moving tip button -->
<string name="tip_firefox_preview_moved_button_preview_not_installed">Consiguir el Nightly nuevu</string>
<!-- Onboarding --> <!-- Onboarding -->
<!-- Text for onboarding welcome message <!-- Text for onboarding welcome message
The first parameter is the name of the app (e.g. Firefox Preview) --> The first parameter is the name of the app (e.g. Firefox Preview) -->

View File

@ -698,6 +698,8 @@
<!-- Confirmation dialog button --> <!-- Confirmation dialog button -->
<string name="sync_confirmation_button">Зразумела</string> <string name="sync_confirmation_button">Зразумела</string>
<!-- Share error message -->
<string name="share_error_snackbar">Немагчыма падзяліцца гэтай праграмай</string>
<!-- Add new device screen title --> <!-- Add new device screen title -->
<string name="sync_add_new_device_title">Даслаць на прыладу</string> <string name="sync_add_new_device_title">Даслаць на прыладу</string>
<!-- Text for the warning message on the Add new device screen --> <!-- Text for the warning message on the Add new device screen -->
@ -751,6 +753,9 @@
<string name="a11y_dialog_deleted_undo">Адмяніць</string> <string name="a11y_dialog_deleted_undo">Адмяніць</string>
<!-- Text for action to confirm deleting a tab or collection shown in a11y dialog --> <!-- Text for action to confirm deleting a tab or collection shown in a11y dialog -->
<string name="a11y_dialog_deleted_confirm">Пацвердзіць</string> <string name="a11y_dialog_deleted_confirm">Пацвердзіць</string>
<!-- QR code scanner prompt which appears after scanning a code, but before navigating to it
First parameter is the name of the app, second parameter is the URL or text scanned-->
<string name="qr_scanner_confirmation_dialog_message">Дазволіць %1$s адкрыць %2$s</string>
<!-- QR code scanner prompt dialog positive option to allow navigation to scanned link --> <!-- QR code scanner prompt dialog positive option to allow navigation to scanned link -->
<string name="qr_scanner_dialog_positive">ДАЗВОЛІЦЬ</string> <string name="qr_scanner_dialog_positive">ДАЗВОЛІЦЬ</string>
<!-- QR code scanner prompt dialog positive option to deny navigation to scanned link --> <!-- QR code scanner prompt dialog positive option to deny navigation to scanned link -->
@ -766,12 +771,18 @@
<!-- Message for copying the URL via long press on the toolbar --> <!-- Message for copying the URL via long press on the toolbar -->
<string name="url_copied">URL скапіраваны</string> <string name="url_copied">URL скапіраваны</string>
<!-- Sample text for accessibility font size -->
<string name="accessibility_text_size_sample_text_1">Гэта ўзор тэксту. Ён тут, каб паказаць, як тэкст будзе выглядаць пры павелічэнні або памяншэнні памеру з дапамогай гэтай налады.</string>
<!-- Summary for Accessibility Text Size Scaling Preference -->
<string name="preference_accessibility_text_size_summary">Зрабіць тэкст на сайтах большым ці меншым</string>
<!-- Title for Accessibility Text Size Scaling Preference --> <!-- Title for Accessibility Text Size Scaling Preference -->
<string name="preference_accessibility_font_size_title">Памер шрыфту</string> <string name="preference_accessibility_font_size_title">Памер шрыфту</string>
<!-- Title for Accessibility Text Automatic Size Scaling Preference --> <!-- Title for Accessibility Text Automatic Size Scaling Preference -->
<string name="preference_accessibility_auto_size_2">Аўтаматычны памер шрыфту</string> <string name="preference_accessibility_auto_size_2">Аўтаматычны памер шрыфту</string>
<!-- Title for the Delete browsing data preference -->
<string name="preferences_delete_browsing_data">Выдаліць дадзеныя аглядання</string>
<!-- Title for the tabs item in Delete browsing data --> <!-- Title for the tabs item in Delete browsing data -->
<string name="preferences_delete_browsing_data_tabs_title_2">Адкрытыя карткі</string> <string name="preferences_delete_browsing_data_tabs_title_2">Адкрытыя карткі</string>
<!-- Subtitle for the tabs item in Delete browsing data, parameter will be replaced with the number of open tabs --> <!-- Subtitle for the tabs item in Delete browsing data, parameter will be replaced with the number of open tabs -->
@ -788,12 +799,18 @@
<string name="preferences_delete_browsing_data_browsing_history_subtitle">Старонак: %d</string> <string name="preferences_delete_browsing_data_browsing_history_subtitle">Старонак: %d</string>
<!-- Title for the cookies item in Delete browsing data --> <!-- Title for the cookies item in Delete browsing data -->
<string name="preferences_delete_browsing_data_cookies">Кукі</string> <string name="preferences_delete_browsing_data_cookies">Кукі</string>
<!-- Subtitle for the cookies item in Delete browsing data -->
<string name="preferences_delete_browsing_data_cookies_subtitle">Вы выйдзеце з большасці сайтаў</string>
<!-- Title for the cached images and files item in Delete browsing data -->
<string name="preferences_delete_browsing_data_cached_files">Кэшаваныя відарысы і файлы</string>
<!-- Title for the site permissions item in Delete browsing data --> <!-- Title for the site permissions item in Delete browsing data -->
<string name="preferences_delete_browsing_data_site_permissions">Дазволы для сайтаў</string> <string name="preferences_delete_browsing_data_site_permissions">Дазволы для сайтаў</string>
<!-- Text for the button to delete browsing data --> <!-- Text for the button to delete browsing data -->
<string name="preferences_delete_browsing_data_button">Выдаліць звесткі аглядання</string> <string name="preferences_delete_browsing_data_button">Выдаліць звесткі аглядання</string>
<!-- Title for the Delete browsing data on quit preference --> <!-- Title for the Delete browsing data on quit preference -->
<string name="preferences_delete_browsing_data_on_quit">Выдаляць звесткі аглядання пры выхадзе</string> <string name="preferences_delete_browsing_data_on_quit">Выдаляць звесткі аглядання пры выхадзе</string>
<!-- Summary for the Delete browsing data on quit preference. "Quit" translation should match delete_browsing_data_on_quit_action translation. -->
<string name="preference_summary_delete_browsing_data_on_quit">Аўтаматычна выдаляе дадзеныя аглядання, калі вы выбіраеце &quot;Выйсці&quot; ў галоўным меню</string>
<!-- Action item in menu for the Delete browsing data on quit feature --> <!-- Action item in menu for the Delete browsing data on quit feature -->
<string name="delete_browsing_data_on_quit_action">Выйсці</string> <string name="delete_browsing_data_on_quit_action">Выйсці</string>
@ -802,6 +819,15 @@
<!-- Text for the allow button for the data deletion dialog --> <!-- Text for the allow button for the data deletion dialog -->
<string name="delete_browsing_data_prompt_allow">Выдаліць</string> <string name="delete_browsing_data_prompt_allow">Выдаліць</string>
<!-- Text for the snackbar confirmation that the data was deleted -->
<string name="preferences_delete_browsing_data_snackbar">Дадзеныя аглядання выдалены</string>
<!-- Tips -->
<!-- text for firefox preview moving tip header "Firefox Preview" and "Firefox Nightly" are intentionally hardcoded -->
<string name="tip_firefox_preview_moved_header">Firefox Preview цяпер Firefox Nightly</string>
<!-- text for firefox preview moving tip description -->
<string name="tip_firefox_preview_moved_description">Firefox Nightly абнаўляецца кожную ноч і мае новыя эксперыментальныя магчымасці.
Аднак ён можа быць менш стабільным. Сцягніце нашу бэта-версію для больш стабільнай працы.</string>
<!-- text for firefox preview moving tip button. "Firefox for Android Beta" is intentionally hardcoded --> <!-- text for firefox preview moving tip button. "Firefox for Android Beta" is intentionally hardcoded -->
<string name="tip_firefox_preview_moved_button_2">Атрымаць Firefox для Android Beta</string> <string name="tip_firefox_preview_moved_button_2">Атрымаць Firefox для Android Beta</string>
@ -835,8 +861,14 @@
<!-- text for the firefox account onboarding card header <!-- text for the firefox account onboarding card header
The first parameter is the name of the app (e.g. Firefox Preview) --> The first parameter is the name of the app (e.g. Firefox Preview) -->
<string name="onboarding_firefox_account_header">Атрымайце максімум ад %s.</string> <string name="onboarding_firefox_account_header">Атрымайце максімум ад %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 -->
<string name="onboarding_firefox_account_signing_in">Уваход…</string>
<!-- text for the button to manually sign into Firefox account. The word "Firefox" should not be translated --> <!-- text for the button to manually sign into Firefox account. The word "Firefox" should not be translated -->
<string name="onboarding_firefox_account_sign_in">Увайсці ў Firefox</string> <string name="onboarding_firefox_account_sign_in">Увайсці ў Firefox</string>
<!-- text for the button to stay signed out when presented with an option to automatically sign-in. -->
<string name="onboarding_firefox_account_stay_signed_out">Не ўваходзіць</string>
<!-- text to display in the snackbar once account is signed-in --> <!-- text to display in the snackbar once account is signed-in -->
<string name="onboarding_firefox_account_sync_is_on">Сінхранізацыя ўключана</string> <string name="onboarding_firefox_account_sync_is_on">Сінхранізацыя ўключана</string>
<!-- text to display in the snackbar if automatic sign-in fails. user may try again --> <!-- text to display in the snackbar if automatic sign-in fails. user may try again -->
@ -940,6 +972,8 @@
<string name="preference_enhanced_tracking_protection_explanation_learn_more">Даведацца больш</string> <string name="preference_enhanced_tracking_protection_explanation_learn_more">Даведацца больш</string>
<!-- Preference for enhanced tracking protection for the standard protection settings --> <!-- Preference for enhanced tracking protection for the standard protection settings -->
<string name="preference_enhanced_tracking_protection_standard_default_1">Стандартная (прадвызначана)</string> <string name="preference_enhanced_tracking_protection_standard_default_1">Стандартная (прадвызначана)</string>
<!-- Preference description for enhanced tracking protection for the standard protection settings -->
<string name="preference_enhanced_tracking_protection_standard_description_3">Блакуе менш трэкераў. Старонкі загружаюцца нармальна.</string>
<!-- Accessibility text for the Standard protection information icon --> <!-- Accessibility text for the Standard protection information icon -->
<string name="preference_enhanced_tracking_protection_standard_info_button">Што блакуецца стандартнай аховай ад сачэння</string> <string name="preference_enhanced_tracking_protection_standard_info_button">Што блакуецца стандартнай аховай ад сачэння</string>
<!-- Preference for enhanced tracking protection for the strict protection settings --> <!-- Preference for enhanced tracking protection for the strict protection settings -->
@ -1149,6 +1183,13 @@
<!-- Text shown when a user leaves the name field empty --> <!-- Text shown when a user leaves the name field empty -->
<string name="search_add_custom_engine_error_empty_name">Увядзіце назву пошукавай сістэмы</string> <string name="search_add_custom_engine_error_empty_name">Увядзіце назву пошукавай сістэмы</string>
<!-- Text shown when a user leaves the search string field empty -->
<string name="search_add_custom_engine_error_empty_search_string">Увядзіце радок пошуку</string>
<!-- Text on the disabled button while in progress. Placeholder replaced with app name -->
<string name="migration_updating_app_button_text">Абнаўленне %s…</string>
<!-- Text on the enabled button. Placeholder replaced with app name-->
<string name="migration_update_app_button">Запусціць %s</string>
<!-- Accessibility description text for a completed migration item --> <!-- Accessibility description text for a completed migration item -->
<string name="migration_icon_description">Міграцыя завершана</string> <string name="migration_icon_description">Міграцыя завершана</string>
<!--Text on list of migrated items (e.g. Settings, History, etc.)--> <!--Text on list of migrated items (e.g. Settings, History, etc.)-->
@ -1184,6 +1225,10 @@
<string name="login_deletion_confirmation">Вы сапраўды хочаце выдаліць гэтае лагін?</string> <string name="login_deletion_confirmation">Вы сапраўды хочаце выдаліць гэтае лагін?</string>
<!-- Positive action of a dialog asking to delete --> <!-- Positive action of a dialog asking to delete -->
<string name="dialog_delete_positive">Выдаліць</string> <string name="dialog_delete_positive">Выдаліць</string>
<!-- The editable text field for a login's web address. -->
<string name="saved_login_hostname_description">Тэкставае поле для рэдагавання вэб-адраса для ўваходу ў сістэму.</string>
<!-- The editable text field for a login's username. -->
<string name="saved_login_username_description">Тэкставае поле для рэдагавання імені карыстальніка для ўваходу ў сістэму.</string>
<!-- The error message in edit login view when password field is blank. --> <!-- The error message in edit login view when password field is blank. -->
<string name="saved_login_password_required">Патрабуецца пароль</string> <string name="saved_login_password_required">Патрабуецца пароль</string>
<!-- Voice search button content description --> <!-- Voice search button content description -->

View File

@ -914,7 +914,7 @@
<!-- text for firefox preview moving tip header. "Firefox Nightly" is intentionally hardcoded --> <!-- text for firefox preview moving tip header. "Firefox Nightly" is intentionally hardcoded -->
<string name="tip_firefox_preview_moved_header_preview_installed">Mae Firefox Nightly wedi symud</string> <string name="tip_firefox_preview_moved_header_preview_installed">Mae Firefox Nightly wedi symud</string>
<!-- text for firefox preview moving tip description --> <!-- text for firefox preview moving tip description -->
<string name="tip_firefox_preview_moved_description_preview_installed">Ni fydd yr ap hon yn derbyn diweddariadau diogelwch mwyach. Peidiwch a defnyddior ap hon a symud ir Nightly newydd. <string name="tip_firefox_preview_moved_description_preview_installed">Ni fydd yr ap hwn yn derbyn diweddariadau diogelwch mwyach. Peidiwch â defnyddior ap hwn a newidiwch ir Nightly newydd.
\n\nEr mwyn trosglwyddoch nodau tudalen, eich mewngofnodion ach hanes i ap arall, crëwch gyfrif Firefox.</string> \n\nEr mwyn trosglwyddoch nodau tudalen, eich mewngofnodion ach hanes i ap arall, crëwch gyfrif Firefox.</string>
<!-- text for firefox preview moving tip button --> <!-- text for firefox preview moving tip button -->
<string name="tip_firefox_preview_moved_button_preview_installed">Newid ir Nightly newydd</string> <string name="tip_firefox_preview_moved_button_preview_installed">Newid ir Nightly newydd</string>
@ -922,7 +922,7 @@
<!-- text for firefox preview moving tip header. "Firefox Nightly" is intentionally hardcoded --> <!-- text for firefox preview moving tip header. "Firefox Nightly" is intentionally hardcoded -->
<string name="tip_firefox_preview_moved_header_preview_not_installed">Mae Firefox Nightly wedi symud</string> <string name="tip_firefox_preview_moved_header_preview_not_installed">Mae Firefox Nightly wedi symud</string>
<!-- text for firefox preview moving tip description --> <!-- text for firefox preview moving tip description -->
<string name="tip_firefox_preview_moved_description_preview_not_installed">Ni fydd yr ap hon yn derbyn diweddariadau diogelwch bellach. Estynnwch y Nightly newydd a pheidio a defnyddior ap hon. <string name="tip_firefox_preview_moved_description_preview_not_installed">Ni fydd yr ap hwn yn derbyn diweddariadau diogelwch bellach. Estynnwch y Nightly newydd a pheidio â defnyddior ap hwn bellach.
\n\nEr mwyn trosglwyddoch nodau tudalen, eich mewngofnodion ach hanes i ap arall, crëwch gyfrif Firefox.</string> \n\nEr mwyn trosglwyddoch nodau tudalen, eich mewngofnodion ach hanes i ap arall, crëwch gyfrif Firefox.</string>
<!-- text for firefox preview moving tip button --> <!-- text for firefox preview moving tip button -->
<string name="tip_firefox_preview_moved_button_preview_not_installed">Estyn y Nightly newydd</string> <string name="tip_firefox_preview_moved_button_preview_not_installed">Estyn y Nightly newydd</string>

View File

@ -908,8 +908,6 @@
<string name="preference_summary_delete_browsing_data_on_quit">Elimina automáticamente los datos de navegación cuando seleccionás &quot;Salir&quot; en el menú principal</string> <string name="preference_summary_delete_browsing_data_on_quit">Elimina automáticamente los datos de navegación cuando seleccionás &quot;Salir&quot; en el menú principal</string>
<!-- Summary for the Delete browsing data on quit preference. "Quit" translation should match delete_browsing_data_on_quit_action translation. --> <!-- Summary for the Delete browsing data on quit preference. "Quit" translation should match delete_browsing_data_on_quit_action translation. -->
<string name="preference_summary_delete_browsing_data_on_quit_2">Elimina automáticamente los datos de navegación cuando seleccionás &quot;Salir&quot; en el menú principal</string> <string name="preference_summary_delete_browsing_data_on_quit_2">Elimina automáticamente los datos de navegación cuando seleccionás &quot;Salir&quot; en el menú principal</string>
<!-- Category for history items to delete on quit in delete browsing data on quit -->
<string name="preferences_delete_browsing_data_on_quit_browsing_history">Historial de navegación</string>
<!-- Action item in menu for the Delete browsing data on quit feature --> <!-- Action item in menu for the Delete browsing data on quit feature -->
<string name="delete_browsing_data_on_quit_action">Salir</string> <string name="delete_browsing_data_on_quit_action">Salir</string>
@ -931,25 +929,22 @@
<!-- text for firefox preview moving tip header "Firefox Preview" and "Firefox Nightly" are intentionally hardcoded --> <!-- text for firefox preview moving tip header "Firefox Preview" and "Firefox Nightly" are intentionally hardcoded -->
<string name="tip_firefox_preview_moved_header">Firefox Nightly ahora es Firefox Preview</string> <string name="tip_firefox_preview_moved_header">Firefox Nightly ahora es Firefox Preview</string>
<!-- text for firefox preview moving tip description --> <!-- text for firefox preview moving tip description -->
<string name="tip_firefox_preview_moved_description">Firefox Nightly se actualiza todas las noches y tiene nuevas funciones experimentales. <string name="tip_firefox_preview_moved_description">Firefox Nightly se actualiza todas las noches y tiene nuevas funciones experimentales.  Sin embargo, puede ser menos estable. Para una experiencia más estable descargá nuestro navegador beta.</string>
        Sin embargo, puede ser menos estable. Descargá nuestro navegador beta para una experiencia más estable.</string>
<!-- text for firefox preview moving tip button. "Firefox for Android Beta" is intentionally hardcoded --> <!-- text for firefox preview moving tip button. "Firefox for Android Beta" is intentionally hardcoded -->
<string name="tip_firefox_preview_moved_button_2">Obtené Firefox para Android Beta</string> <string name="tip_firefox_preview_moved_button_2">Obtené Firefox para Android Beta</string>
<!-- text for firefox preview moving tip header. "Firefox Nightly" is intentionally hardcoded --> <!-- text for firefox preview moving tip header. "Firefox Nightly" is intentionally hardcoded -->
<string name="tip_firefox_preview_moved_header_preview_installed">Firefox Nightly se mov</string> <string name="tip_firefox_preview_moved_header_preview_installed">Firefox Nightly camb</string>
<!-- text for firefox preview moving tip description --> <!-- text for firefox preview moving tip description -->
<string name="tip_firefox_preview_moved_description_preview_installed">Esta aplicación ya no va arecibir actualizaciones de seguridad. Deja de usar la y cambiá al nuevo Nightly. <string name="tip_firefox_preview_moved_description_preview_installed">Esta aplicación ya no va a recibir actualizaciones de seguridad. Dejá de usarla y cambiá al nuevo Nightly. Para transferir tus marcadores, inicios de sesión e historial a otra aplicación, creá una cuenta de Firefox.</string>
        \ n \ nPara transferir tus marcadores, inicios de sesión e historial a otra aplicación, creá una cuenta de Firefox.</string>
<!-- text for firefox preview moving tip button --> <!-- text for firefox preview moving tip button -->
<string name="tip_firefox_preview_moved_button_preview_installed">Cambiá al nuevo Nightly</string> <string name="tip_firefox_preview_moved_button_preview_installed">Cambiá al nuevo Nightly</string>
<!-- text for firefox preview moving tip header. "Firefox Nightly" is intentionally hardcoded --> <!-- text for firefox preview moving tip header. "Firefox Nightly" is intentionally hardcoded -->
<string name="tip_firefox_preview_moved_header_preview_not_installed">Firefox Nightly se mov</string> <string name="tip_firefox_preview_moved_header_preview_not_installed">Firefox Nightly camb</string>
<!-- text for firefox preview moving tip description --> <!-- text for firefox preview moving tip description -->
<string name="tip_firefox_preview_moved_description_preview_not_installed">Esta aplicación ya no va a recibir actualizaciones de seguridad. Deja de usarla y cambiá al nuevo Nightly. <string name="tip_firefox_preview_moved_description_preview_not_installed">Esta aplicación ya no va a recibir actualizaciones de seguridad. Deja de usarla y cambiá al nuevo Nightly. Para transferir tus marcadores, inicios de sesión e historial a otra aplicación, creá una cuenta de Firefox.</string>
        \ n \ nPara transferir tus marcadores, inicios de sesión e historial a otra aplicación, creá una cuenta de Firefox.</string>
<!-- text for firefox preview moving tip button --> <!-- text for firefox preview moving tip button -->
<string name="tip_firefox_preview_moved_button_preview_not_installed">Obtené el nuevo Nightly</string> <string name="tip_firefox_preview_moved_button_preview_not_installed">Obtené el nuevo Nightly</string>

View File

@ -892,8 +892,6 @@
<string name="preference_summary_delete_browsing_data_on_quit">Automatski briše podatke pregledavanja kad u glavnom izborniku odabereš „Zatvori”</string> <string name="preference_summary_delete_browsing_data_on_quit">Automatski briše podatke pregledavanja kad u glavnom izborniku odabereš „Zatvori”</string>
<!-- Summary for the Delete browsing data on quit preference. "Quit" translation should match delete_browsing_data_on_quit_action translation. --> <!-- Summary for the Delete browsing data on quit preference. "Quit" translation should match delete_browsing_data_on_quit_action translation. -->
<string name="preference_summary_delete_browsing_data_on_quit_2">Automatski briše podatke pregledavanja kad u glavnom izborniku odabereš „Zatvori”</string> <string name="preference_summary_delete_browsing_data_on_quit_2">Automatski briše podatke pregledavanja kad u glavnom izborniku odabereš „Zatvori”</string>
<!-- Category for history items to delete on quit in delete browsing data on quit -->
<string name="preferences_delete_browsing_data_on_quit_browsing_history">Povijest pregledavanja</string>
<!-- Action item in menu for the Delete browsing data on quit feature --> <!-- Action item in menu for the Delete browsing data on quit feature -->
<string name="delete_browsing_data_on_quit_action">Zatvori</string> <string name="delete_browsing_data_on_quit_action">Zatvori</string>
@ -915,8 +913,8 @@
<!-- text for firefox preview moving tip header "Firefox Preview" and "Firefox Nightly" are intentionally hardcoded --> <!-- text for firefox preview moving tip header "Firefox Preview" and "Firefox Nightly" are intentionally hardcoded -->
<string name="tip_firefox_preview_moved_header">Firefox pregled je sada Firefox Nightly</string> <string name="tip_firefox_preview_moved_header">Firefox pregled je sada Firefox Nightly</string>
<!-- text for firefox preview moving tip description --> <!-- text for firefox preview moving tip description -->
<string name="tip_firefox_preview_moved_description">Firefox Nightly se aktualizira svake večeri i sadrži nove eksperimentalne funkcije. <string name="tip_firefox_preview_moved_description">Firefox Nightly je aktualiziran svake noći i sadrži nove eksperimentalne značajke.
        Međutim, vjerojatno je manje stabilna verzija. Preuzmi naš beta preglednik za stabilnije iskustvo.</string> Međutim, Nightly može biti manje stabilan. Preuzmi beta verziju našeg preglednika za stabilnije iskustvo.</string>
<!-- text for firefox preview moving tip button. "Firefox for Android Beta" is intentionally hardcoded --> <!-- text for firefox preview moving tip button. "Firefox for Android Beta" is intentionally hardcoded -->
<string name="tip_firefox_preview_moved_button_2">Preuzmite Firefox za Android Beta</string> <string name="tip_firefox_preview_moved_button_2">Preuzmite Firefox za Android Beta</string>

View File

@ -1107,7 +1107,7 @@
<!-- Accessibility text for the Standard protection information icon --> <!-- Accessibility text for the Standard protection information icon -->
<string name="preference_enhanced_tracking_protection_standard_info_button">Elementi bloccati nella protezione antitracciamento normale</string> <string name="preference_enhanced_tracking_protection_standard_info_button">Elementi bloccati nella protezione antitracciamento normale</string>
<!-- Preference for enhanced tracking protection for the strict protection settings --> <!-- Preference for enhanced tracking protection for the strict protection settings -->
<string name="preference_enhanced_tracking_protection_strict">Restrittivo</string> <string name="preference_enhanced_tracking_protection_strict">Restrittiva</string>
<!-- Preference description for enhanced tracking protection for the strict protection settings --> <!-- Preference description for enhanced tracking protection for the strict protection settings -->
<string name="preference_enhanced_tracking_protection_strict_description_2">Blocca più elementi traccianti, annunci pubblicitari e pop-up. Le pagine verranno caricate più velocemente, ma alcuni elementi potrebbero non funzionare correttamente.</string> <string name="preference_enhanced_tracking_protection_strict_description_2">Blocca più elementi traccianti, annunci pubblicitari e pop-up. Le pagine verranno caricate più velocemente, ma alcuni elementi potrebbero non funzionare correttamente.</string>
<!-- Accessibility text for the Strict protection information icon --> <!-- Accessibility text for the Strict protection information icon -->

View File

@ -0,0 +1,132 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- App name for private browsing mode. The first parameter is the name of the app defined in app_name (for example: Fenix)-->
<string name="app_name_private_5">Privou %s</string>
<!-- App name for private browsing mode. The first parameter is the name of the app defined in app_name (for example: Fenix)-->
<string name="app_name_private_4">%s (Privou)</string>
<!-- Home Fragment -->
<!-- Content description (not visible, for screen readers etc.): "Three dot" menu button. -->
<string name="content_description_menu">Ciù inpostaçioin</string>
<!-- Content description (not visible, for screen readers etc.): "Private Browsing" menu button. -->
<string name="content_description_private_browsing_button">Abilita Navegaçion privâ</string>
<!-- Content description (not visible, for screen readers etc.): "Private Browsing" menu button. -->
<string name="content_description_disable_private_browsing_button">Dizabilita Navegaçion privâ</string>
<!-- Placeholder text shown in the search bar before a user enters text -->
<string name="search_hint">Scrivi ò çerca indirisso</string>
<!-- Text for the negative button -->
<string name="cfr_neg_button_text">No graçie</string>
<!-- Text for the positive button -->
<string name="search_widget_cfr_pos_button_text">Azonzi widget</string>
<!-- Text for the negative button -->
<string name="search_widget_cfr_neg_button_text">Oua no</string>
<!-- Home screen icons - Long press shortcuts -->
<!-- Shortcut action to open new tab -->
<string name="home_screen_shortcut_open_new_tab_2">Neuvo feuggio</string>
<!-- Shortcut action to open new private tab -->
<string name="home_screen_shortcut_open_new_private_tab_2">Neuvo feuggio privou</string>
<!-- Heading for the Top Sites block -->
<string name="home_screen_top_sites_heading">I megio sciti</string>
<!-- Browser Fragment -->
<!-- Content description (not visible, for screen readers etc.): Navigate to open tabs -->
<string name="browser_tabs_button">Arvi Feuggi</string>
<!-- Content description (not visible, for screen readers etc.): Navigate backward (browsing history) -->
<string name="browser_menu_back">Inderê</string>
<!-- Content description (not visible, for screen readers etc.): Navigate forward (browsing history) -->
<string name="browser_menu_forward"></string>
<!-- Content description (not visible, for screen readers etc.): Refresh current website -->
<string name="browser_menu_refresh">Agiorna</string>
<!-- Content description (not visible, for screen readers etc.): Stop loading current website -->
<string name="browser_menu_stop">Ferma</string>
<!-- Content description (not visible, for screen readers etc.): Bookmark the current page -->
<string name="browser_menu_bookmark">Segnalibbro</string>
<!-- Content description (not visible, for screen readers etc.): Un-bookmark the current page -->
<string name="browser_menu_edit_bookmark">Cangia segnalibbro</string>
<!-- Browser menu button that opens the addon manager -->
<string name="browser_menu_add_ons">Conponenti azonti</string>
<!-- Browser menu button that sends a user to help articles -->
<string name="browser_menu_help">Agiutto</string>
<!-- Browser menu button that sends a to a the what's new article -->
<string name="browser_menu_whats_new">Cöse gh\'é de neuvo</string>
<!-- Browser menu button that opens the settings menu -->
<string name="browser_menu_settings">Inpostaçioin</string>
<!-- Browser menu button that opens a user's library -->
<string name="browser_menu_library">Libraia</string>
<!-- Browser menu toggle that requests a desktop site -->
<string name="browser_menu_desktop_site">Scito desktop</string>
<!-- Browser menu toggle that adds a shortcut to the site on the device home screen. -->
<string name="browser_menu_add_to_homescreen">Azonzi a-a Pagina Prinçipâ</string>
<!-- Browser menu toggle that installs a Progressive Web App shortcut to the site on the device home screen. -->
<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"></string>
<!-- Browser menu button that opens the find in page menu -->
<string name="browser_menu_find_in_page">Treuva in pagina</string>
<!-- Browser menu button that creates a private tab -->
<string name="browser_menu_private_tab">Feuggio privou</string>
<!-- Browser menu button that creates a new tab -->
<string name="browser_menu_new_tab">Neuvo feuggio</string>
<!-- Browser menu button that open a share menu to share the current site -->
<string name="browser_menu_share">Condividdi</string>
<!-- Share menu title, displayed when a user is sharing their current site -->
<string name="menu_share_with">Condividdi con…</string>
<!-- Browser menu button shown in custom tabs that opens the current tab in Fenix
The first parameter is the name of the app defined in app_name (for example: Fenix) -->
<string name="browser_menu_open_in_fenix">Arvi in %1$s</string>
<!-- Browser menu text shown in custom tabs to indicate this is a Fenix tab
The first parameter is the name of the app defined in app_name (for example: Fenix) -->
<string name="browser_menu_powered_by">FÆTO CON %1$s</string>
<!-- Browser menu text shown in custom tabs to indicate this is a Fenix tab
The first parameter is the name of the app defined in app_name (for example: Fenix) -->
<string name="browser_menu_powered_by2">Tecnologia de %s</string>
<!-- Browser menu button to put the current page in reader mode -->
<string name="browser_menu_read">Mòddo letua</string>
<!-- Browser menu button content description to close reader mode and return the user to the regular browser -->
<string name="browser_menu_read_close">Særa modalitæ letua</string>
<!-- Browser menu button to open the current page in an external app -->
<string name="browser_menu_open_app_link">Arvi in app</string>
<!-- Browser menu button to configure reader mode appearance e.g. the used font type and size -->
<string name="browser_menu_read_appearance">Aparensa</string>
<!-- Locale Settings Fragment -->
<!-- Content description for tick mark on selected language -->
<string name="a11y_selected_locale_content_description">Seleçionn-a lengoa</string>
<!-- Content description for search icon -->
<string name="a11y_search_icon_content_description">Çerca</string>
<!-- Text for default locale item -->
<string name="default_locale_text">Deuvia lengoa do dispoxitivo</string>
<!-- Placeholder text shown in the search bar before a user enters text -->
<string name="locale_search_hint">Çerca lengoa</string>
<!-- Search Fragment -->
<!-- Button in the search view that lets a user search by scanning a QR code -->
<string name="search_scan_button">Scanscionn-a</string>
<!-- Button in the search view that lets a user search by using a shortcut -->
<string name="search_shortcuts_button">Scorsaiéu</string>
<!-- DEPRECATED: Header displayed when selecting a shortcut search engine -->
<string name="search_shortcuts_search_with">Çerca con</string>
<!-- Button in the search suggestions onboarding that allows search suggestions in private sessions -->
<string name="search_suggestions_onboarding_allow_button">Permetti</string>
<!-- Button in the search suggestions onboarding that does not allow search suggestions in private sessions -->
<string name="search_suggestions_onboarding_do_not_allow_button">No permette</string>
<!-- Search suggestion onboarding hint Learn more link text -->
<string name="search_suggestions_onboarding_learn_more_link">Atre informaçioin</string>
<!-- Search Widget -->
<!-- Text preview for smaller sized widgets -->
<string name="search_widget_text_short">Çerca</string>
<!-- Text preview for larger sized widgets -->
<string name="search_widget_text_long">Çerca inta ræ</string>
<!-- Content description (not visible, for screen readers etc.): Voice search -->
<string name="search_widget_voice">Çerca co-a voxe</string>
<!-- Preferences -->
<!-- Title for the settings page-->
<string name="settings">Inpostaçioin</string>
<!-- Preference category for basic settings -->
<string name="preferences_category_basics">Generale</string>
</resources>

File diff suppressed because one or more lines are too long

View File

@ -894,8 +894,6 @@
<string name="preference_summary_delete_browsing_data_on_quit">Sletter nettlesardata automatisk når du vel «Avslutt» frå hovudmenyen</string> <string name="preference_summary_delete_browsing_data_on_quit">Sletter nettlesardata automatisk når du vel «Avslutt» frå hovudmenyen</string>
<!-- Summary for the Delete browsing data on quit preference. "Quit" translation should match delete_browsing_data_on_quit_action translation. --> <!-- Summary for the Delete browsing data on quit preference. "Quit" translation should match delete_browsing_data_on_quit_action translation. -->
<string name="preference_summary_delete_browsing_data_on_quit_2">Slettar nettlesardata automatisk når du vel «Avslutt» frå hovudmenyen</string> <string name="preference_summary_delete_browsing_data_on_quit_2">Slettar nettlesardata automatisk når du vel «Avslutt» frå hovudmenyen</string>
<!-- Category for history items to delete on quit in delete browsing data on quit -->
<string name="preferences_delete_browsing_data_on_quit_browsing_history">Nettlesarhistorikk</string>
<!-- Action item in menu for the Delete browsing data on quit feature --> <!-- Action item in menu for the Delete browsing data on quit feature -->
<string name="delete_browsing_data_on_quit_action">Avslutt</string> <string name="delete_browsing_data_on_quit_action">Avslutt</string>
@ -980,17 +978,17 @@
<string name="onboarding_tracking_protection_header_2">Automatisk personvern</string> <string name="onboarding_tracking_protection_header_2">Automatisk personvern</string>
<!-- text for the tracking protection card description <!-- text for the tracking protection card description
The first parameter is the name of the app (e.g. Firefox Preview) --> The first parameter is the name of the app (e.g. Firefox Preview) -->
<string name="onboarding_tracking_protection_description_2">Innstillingar for personvern og sikkerheit blokkerer sporfølgjarar, skadeleg kode og selskap som følgjer deg.</string> <string name="onboarding_tracking_protection_description_2">Innstillingar for personvern og sikkerheit blokkerer sporarar, skadeleg kode og selskap som følgjer deg.</string>
<!-- text for tracking protection radio button option for standard level of blocking --> <!-- text for tracking protection radio button option for standard level of blocking -->
<string name="onboarding_tracking_protection_standard_button_2">Standard (standard)</string> <string name="onboarding_tracking_protection_standard_button_2">Standard (standard)</string>
<!-- text for standard blocking option button description --> <!-- text for standard blocking option button description -->
<string name="onboarding_tracking_protection_standard_button_description_2">Blokkerer færre sporfølgjarar. Sider vert lasta normalt.</string> <string name="onboarding_tracking_protection_standard_button_description_2">Blokkerer færre sporarar. Sider vert lasta normalt.</string>
<!-- text for tracking protection radio button option for strict level of blocking --> <!-- text for tracking protection radio button option for strict level of blocking -->
<string name="onboarding_tracking_protection_strict_button">Streng (tilrådd)</string> <string name="onboarding_tracking_protection_strict_button">Streng (tilrådd)</string>
<!-- text for tracking protection radio button option for strict level of blocking --> <!-- text for tracking protection radio button option for strict level of blocking -->
<string name="onboarding_tracking_protection_strict_option">Streng</string> <string name="onboarding_tracking_protection_strict_option">Streng</string>
<!-- text for strict blocking option button description --> <!-- text for strict blocking option button description -->
<string name="onboarding_tracking_protection_strict_button_description_2">Blokkerer fleire sporfølgjarar, reklamer og sprettoppvindauge. Sider vert lasta raskere, men nokre funksjonar fungerer kanskje ikkje.</string> <string name="onboarding_tracking_protection_strict_button_description_2">Blokkerer fleire sporarar, reklamer og sprettoppvindauge. Sider vert lasta raskere, men nokre funksjonar fungerer kanskje ikkje.</string>
<!-- text for the toolbar position card header <!-- text for the toolbar position card header
In English this is an idiom for "choose a side as in an argument or fight" 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 --> but it is ok to make this more literally about "choosing a position in a physical space -->
@ -1079,19 +1077,19 @@
<!-- Preference for enhanced tracking protection for the standard protection settings --> <!-- Preference for enhanced tracking protection for the standard protection settings -->
<string name="preference_enhanced_tracking_protection_standard_default_1">Standard (standard)</string> <string name="preference_enhanced_tracking_protection_standard_default_1">Standard (standard)</string>
<!-- Preference description for enhanced tracking protection for the standard protection settings --> <!-- Preference description for enhanced tracking protection for the standard protection settings -->
<string name="preference_enhanced_tracking_protection_standard_description_3">Blokkerer færre sporfølgjarar. Sider vert lasta normalt.</string> <string name="preference_enhanced_tracking_protection_standard_description_3">Blokkerer færre sporarar. Sider vert lasta normalt.</string>
<!-- Accessibility text for the Standard protection information icon --> <!-- Accessibility text for the Standard protection information icon -->
<string name="preference_enhanced_tracking_protection_standard_info_button">Kva er blokkert av standard sporingsvern</string> <string name="preference_enhanced_tracking_protection_standard_info_button">Kva er blokkert av standard sporingsvern</string>
<!-- Preference for enhanced tracking protection for the strict protection settings --> <!-- Preference for enhanced tracking protection for the strict protection settings -->
<string name="preference_enhanced_tracking_protection_strict">Streng</string> <string name="preference_enhanced_tracking_protection_strict">Streng</string>
<!-- Preference description for enhanced tracking protection for the strict protection settings --> <!-- Preference description for enhanced tracking protection for the strict protection settings -->
<string name="preference_enhanced_tracking_protection_strict_description_2">Blokkerer fleire sporfølgjarar, reklamer og sprettoppvindauge. Sider vert lasta raskere, men nokre funksjonar fungerer kanskje ikkje.</string> <string name="preference_enhanced_tracking_protection_strict_description_2">Blokkerer fleire sporarar, reklamer og sprettoppvindauge. Sider vert lasta raskere, men nokre funksjonar fungerer kanskje ikkje.</string>
<!-- Accessibility text for the Strict protection information icon --> <!-- Accessibility text for the Strict protection information icon -->
<string name="preference_enhanced_tracking_protection_strict_info_button">Kva er blokkert av strengt sporingsvern?</string> <string name="preference_enhanced_tracking_protection_strict_info_button">Kva er blokkert av strengt sporingsvern?</string>
<!-- Preference for enhanced tracking protection for the custom protection settings --> <!-- Preference for enhanced tracking protection for the custom protection settings -->
<string name="preference_enhanced_tracking_protection_custom">Tilpassa</string> <string name="preference_enhanced_tracking_protection_custom">Tilpassa</string>
<!-- Preference description for enhanced tracking protection for the strict protection settings --> <!-- Preference description for enhanced tracking protection for the strict protection settings -->
<string name="preference_enhanced_tracking_protection_custom_description_2">Vel kva for sporfølgjarar og skript som skal blokkerast.</string> <string name="preference_enhanced_tracking_protection_custom_description_2">Vel kva for sporarar og skript som skal blokkerast.</string>
<!-- Accessibility text for the Strict protection information icon --> <!-- Accessibility text for the Strict protection information icon -->
<string name="preference_enhanced_tracking_protection_custom_info_button">Kva er blokkert av tilpassa sporingsvern</string> <string name="preference_enhanced_tracking_protection_custom_info_button">Kva er blokkert av tilpassa sporingsvern</string>
<!-- Header for categories that are being blocked by current Enhanced Tracking Protection settings --> <!-- Header for categories that are being blocked by current Enhanced Tracking Protection settings -->
@ -1141,7 +1139,7 @@
<!-- Description of tracking content that can be blocked by Enhanced Tracking Protection --> <!-- Description of tracking content that can be blocked by Enhanced Tracking Protection -->
<string name="etp_tracking_content_description">Stoppar innlasting av eksterne annonsar, videoar og anna innhald, då dei kan innehalde sporingskode. Kan påverke visse nettstadfunksjonar.</string> <string name="etp_tracking_content_description">Stoppar innlasting av eksterne annonsar, videoar og anna innhald, då dei kan innehalde sporingskode. Kan påverke visse nettstadfunksjonar.</string>
<!-- Enhanced Tracking Protection Onboarding Message shown in a dialog above the toolbar. The first parameter is the name of the application (For example: Fenix) --> <!-- Enhanced Tracking Protection Onboarding Message shown in a dialog above the toolbar. The first parameter is the name of the application (For example: Fenix) -->
<string name="etp_onboarding_cfr_message">Kvar gong skjoldet er lilla, har %s blokkert sporfølgjarar på ein nettstad. Trykk for meir info.</string> <string name="etp_onboarding_cfr_message">Kvar gong skjoldet er lilla, har %s blokkert sporarar på ein nettstad. Trykk for meir info.</string>
<!-- Enhanced Tracking Protection message that protection is currently on for this site --> <!-- Enhanced Tracking Protection message that protection is currently on for this site -->
<string name="etp_panel_on">Vern er slått PÅ for denne nettstaden</string> <string name="etp_panel_on">Vern er slått PÅ for denne nettstaden</string>
<!-- Enhanced Tracking Protection message that protection is currently off for this site --> <!-- Enhanced Tracking Protection message that protection is currently off for this site -->

View File

@ -886,8 +886,6 @@
<string name="preference_summary_delete_browsing_data_on_quit">ਜਦੋਂ ਤੁਸੀਂ ਮੁੱਖ ਮੇਨੂ ਤੋਂ &quot;ਬਾਹਰ&quot; ਨੂੰ ਚੁਣਦੇ ਹੋ ਤਾਂ ਬਰਾਊਜ਼ ਕਰਨ ਵਾਲਾ ਡਾਟਾ ਆਪਣੇ-ਆਪ ਹਟਾਇਆ ਜਾਂਦਾ ਹੈ</string> <string name="preference_summary_delete_browsing_data_on_quit">ਜਦੋਂ ਤੁਸੀਂ ਮੁੱਖ ਮੇਨੂ ਤੋਂ &quot;ਬਾਹਰ&quot; ਨੂੰ ਚੁਣਦੇ ਹੋ ਤਾਂ ਬਰਾਊਜ਼ ਕਰਨ ਵਾਲਾ ਡਾਟਾ ਆਪਣੇ-ਆਪ ਹਟਾਇਆ ਜਾਂਦਾ ਹੈ</string>
<!-- Summary for the Delete browsing data on quit preference. "Quit" translation should match delete_browsing_data_on_quit_action translation. --> <!-- Summary for the Delete browsing data on quit preference. "Quit" translation should match delete_browsing_data_on_quit_action translation. -->
<string name="preference_summary_delete_browsing_data_on_quit_2">ਜਦੋਂ ਤੁਸੀਂ ਮੁੱਖ ਮੇਨੂ ਰਾਹੀਂ \&quot;ਬਾਹਰ\&quot; ਨੂੰ ਚੁਣਦੇ ਹੋ ਤਾਂ ਬਰਾਊਜ਼ ਕੀਤੇ ਡਾਟੇ ਨੂੰ ਆਪਣੇ-ਆਪ ਹਟਾਇਆ ਜਾਂਦਾ ਹੈ</string> <string name="preference_summary_delete_browsing_data_on_quit_2">ਜਦੋਂ ਤੁਸੀਂ ਮੁੱਖ ਮੇਨੂ ਰਾਹੀਂ \&quot;ਬਾਹਰ\&quot; ਨੂੰ ਚੁਣਦੇ ਹੋ ਤਾਂ ਬਰਾਊਜ਼ ਕੀਤੇ ਡਾਟੇ ਨੂੰ ਆਪਣੇ-ਆਪ ਹਟਾਇਆ ਜਾਂਦਾ ਹੈ</string>
<!-- Category for history items to delete on quit in delete browsing data on quit -->
<string name="preferences_delete_browsing_data_on_quit_browsing_history">ਬਰਾਊਜ਼ਿੰਗ ਅਤੀਤ</string>
<!-- Action item in menu for the Delete browsing data on quit feature --> <!-- Action item in menu for the Delete browsing data on quit feature -->
<string name="delete_browsing_data_on_quit_action">ਬਾਹਰ</string> <string name="delete_browsing_data_on_quit_action">ਬਾਹਰ</string>
@ -1396,6 +1394,8 @@
<string name="synced_tabs_connect_another_device">ਹੋਰ ਡਿਵਾਈਸ ਨਾਲ ਕਨੈਕਟ ਕਰੋ।</string> <string name="synced_tabs_connect_another_device">ਹੋਰ ਡਿਵਾਈਸ ਨਾਲ ਕਨੈਕਟ ਕਰੋ।</string>
<!-- Text displayed asking user to re-authenticate --> <!-- Text displayed asking user to re-authenticate -->
<string name="synced_tabs_reauth">ਮੁੜ-ਪ੍ਰਮਾਣਿਤ ਕਰੋ।</string> <string name="synced_tabs_reauth">ਮੁੜ-ਪ੍ਰਮਾਣਿਤ ਕਰੋ।</string>
<!-- Text displayed when user has disabled tab syncing in Firefox Sync Account -->
<string name="synced_tabs_enable_tab_syncing">ਟੈਬ ਨੂੰ ਸਿੰਕ ਕਰਨਾ ਸਮਰੱਥ ਕਰੋ।</string>
<!-- Text displayed on a button in the synced tabs screen to link users to sign in when a user is not signed in to Firefox Sync --> <!-- Text displayed on a button in the synced tabs screen to link users to sign in when a user is not signed in to Firefox Sync -->
<string name="synced_tabs_sign_in_button">ਸਿੰਕ ਕਰਨ ਲਈ ਸਾਈਨ ਇਨ ਕਰੋ</string> <string name="synced_tabs_sign_in_button">ਸਿੰਕ ਕਰਨ ਲਈ ਸਾਈਨ ਇਨ ਕਰੋ</string>

View File

@ -911,7 +911,7 @@
No entanto, pode ser menos estável. Instale nosso navegador beta se quiser uma experiência de uso mais estável.</string> No entanto, pode ser menos estável. Instale nosso navegador beta se quiser uma experiência de uso mais estável.</string>
<!-- text for firefox preview moving tip button. "Firefox for Android Beta" is intentionally hardcoded --> <!-- text for firefox preview moving tip button. "Firefox for Android Beta" is intentionally hardcoded -->
<string name="tip_firefox_preview_moved_button_2">Instale o Firefox para Android Beta</string> <string name="tip_firefox_preview_moved_button_2">Instale o Firefox Beta para Android</string>
<!-- text for firefox preview moving tip header. "Firefox Nightly" is intentionally hardcoded --> <!-- text for firefox preview moving tip header. "Firefox Nightly" is intentionally hardcoded -->
<string name="tip_firefox_preview_moved_header_preview_installed">O Firefox Nightly mudou</string> <string name="tip_firefox_preview_moved_header_preview_installed">O Firefox Nightly mudou</string>

View File

@ -917,8 +917,6 @@
<string name="preference_summary_delete_browsing_data_on_quit">Автоматически удаляет данные веб-сёрфинга, когда вы выбираете «Выйти» в главном меню</string> <string name="preference_summary_delete_browsing_data_on_quit">Автоматически удаляет данные веб-сёрфинга, когда вы выбираете «Выйти» в главном меню</string>
<!-- Summary for the Delete browsing data on quit preference. "Quit" translation should match delete_browsing_data_on_quit_action translation. --> <!-- Summary for the Delete browsing data on quit preference. "Quit" translation should match delete_browsing_data_on_quit_action translation. -->
<string name="preference_summary_delete_browsing_data_on_quit_2">Автоматически удаляет данные веб-сёрфинга, когда вы выбираете \&quot;Выйти\&quot; в главном меню</string> <string name="preference_summary_delete_browsing_data_on_quit_2">Автоматически удаляет данные веб-сёрфинга, когда вы выбираете \&quot;Выйти\&quot; в главном меню</string>
<!-- Category for history items to delete on quit in delete browsing data on quit -->
<string name="preferences_delete_browsing_data_on_quit_browsing_history">История веб-сёрфинга</string>
<!-- Action item in menu for the Delete browsing data on quit feature --> <!-- Action item in menu for the Delete browsing data on quit feature -->
<string name="delete_browsing_data_on_quit_action">Выйти</string> <string name="delete_browsing_data_on_quit_action">Выйти</string>
@ -940,9 +938,8 @@
<!-- text for firefox preview moving tip header "Firefox Preview" and "Firefox Nightly" are intentionally hardcoded --> <!-- text for firefox preview moving tip header "Firefox Preview" and "Firefox Nightly" are intentionally hardcoded -->
<string name="tip_firefox_preview_moved_header">Firefox Preview теперь стал Firefox Nightly</string> <string name="tip_firefox_preview_moved_header">Firefox Preview теперь стал Firefox Nightly</string>
<!-- text for firefox preview moving tip description --> <!-- text for firefox preview moving tip description -->
<string name="tip_firefox_preview_moved_description"> <string name="tip_firefox_preview_moved_description">Firefox Nightly обновляется каждую ночь и включает в себя новые, экспериментальные возможности.
· Firefox Nightly обновляется каждую ночь и включает в себя новые, экспериментальные возможности.¶ Однако, он может быть менее стабилен. Если вы хотите более стабильной работы, загрузите нашу бета-версию браузера.</string>
· Однако, он может быть менее стабилен. Если вы хотите более стабильной работы, загрузите нашу бета-версию браузера.</string>
<!-- text for firefox preview moving tip button. "Firefox for Android Beta" is intentionally hardcoded --> <!-- text for firefox preview moving tip button. "Firefox for Android Beta" is intentionally hardcoded -->
<string name="tip_firefox_preview_moved_button_2">Загрузить Firefox для Android Бета</string> <string name="tip_firefox_preview_moved_button_2">Загрузить Firefox для Android Бета</string>
@ -950,18 +947,16 @@
<!-- text for firefox preview moving tip header. "Firefox Nightly" is intentionally hardcoded --> <!-- text for firefox preview moving tip header. "Firefox Nightly" is intentionally hardcoded -->
<string name="tip_firefox_preview_moved_header_preview_installed">Firefox Nightly переехал</string> <string name="tip_firefox_preview_moved_header_preview_installed">Firefox Nightly переехал</string>
<!-- text for firefox preview moving tip description --> <!-- text for firefox preview moving tip description -->
<string name="tip_firefox_preview_moved_description_preview_installed"> <string name="tip_firefox_preview_moved_description_preview_installed">Это приложение больше не будет получать обновлений безопасности. Прекратите использование этого приложения и переключитесь на новый Nightly.
· Это приложение больше не будет получать обновлений безопасности. Прекратите использование этого приложения и переключитесь на новый Nightly.¶ \n\nЧтобы переместить ваши закладки, логины и историю в другое приложение, создайте аккаунт Firefox.</string>
· \n\nЧтобы переместить ваши закладки, логины и историю в другое приложение, создайте аккаунт Firefox.</string>
<!-- text for firefox preview moving tip button --> <!-- text for firefox preview moving tip button -->
<string name="tip_firefox_preview_moved_button_preview_installed">Переключиться на новый Nightly</string> <string name="tip_firefox_preview_moved_button_preview_installed">Переключиться на новый Nightly</string>
<!-- text for firefox preview moving tip header. "Firefox Nightly" is intentionally hardcoded --> <!-- text for firefox preview moving tip header. "Firefox Nightly" is intentionally hardcoded -->
<string name="tip_firefox_preview_moved_header_preview_not_installed">Firefox Nightly переехал</string> <string name="tip_firefox_preview_moved_header_preview_not_installed">Firefox Nightly переехал</string>
<!-- text for firefox preview moving tip description --> <!-- text for firefox preview moving tip description -->
<string name="tip_firefox_preview_moved_description_preview_not_installed"> <string name="tip_firefox_preview_moved_description_preview_not_installed">Это приложение больше не будет получать обновлений безопасности. Получите новый Nightly и прекратите использование этого приложения.
· Это приложение больше не будет получать обновлений безопасности. Получите новый Nightly и прекратите использование этого приложения.¶ \n\nЧтобы переместить ваши закладки, логины и историю в другое приложение, создайте аккаунт Firefox.</string>
· \n\nЧтобы переместить ваши закладки, логины и историю в другое приложение, создайте аккаунт Firefox.</string>
<!-- text for firefox preview moving tip button --> <!-- text for firefox preview moving tip button -->
<string name="tip_firefox_preview_moved_button_preview_not_installed">Получить новый Nightly</string> <string name="tip_firefox_preview_moved_button_preview_not_installed">Получить новый Nightly</string>

View File

@ -150,6 +150,8 @@
<string name="preferences_theme">கருப்பொருள்</string> <string name="preferences_theme">கருப்பொருள்</string>
<!-- Preference shown instead of account display name while account profile information isn't available yet. --> <!-- Preference shown instead of account display name while account profile information isn't available yet. -->
<string name="preferences_account_default_name">பயர்பாக்சு கணக்கு</string> <string name="preferences_account_default_name">பயர்பாக்சு கணக்கு</string>
<!-- Preference text for account title when there was an error syncing FxA -->
<string name="preferences_account_sync_error">ஒத்திசைவை மீள்தொடங்க மீண்டும் இணைக்கவும்</string>
<!-- Preference for language --> <!-- Preference for language -->
<string name="preferences_language">மொழி</string> <string name="preferences_language">மொழி</string>
<!-- Preference for data choices --> <!-- Preference for data choices -->
@ -210,4 +212,129 @@
<!-- Name of the "receive tabs" notification channel. Displayed in the "App notifications" system settings for the app --> <!-- Name of the "receive tabs" notification channel. Displayed in the "App notifications" system settings for the app -->
<string name="fxa_received_tab_channel_name">பெறப்பட்ட கீற்றுகள்</string> <string name="fxa_received_tab_channel_name">பெறப்பட்ட கீற்றுகள்</string>
<!-- Description of the "receive tabs" notification channel. Displayed in the "App notifications" system settings for the app -->
<string name="fxa_received_tab_channel_description">பிற பயர்பாக்சு சாதனங்களிலிருந்து பெறப்பட்ட கீற்றுகளுக்கான அறிவிப்புகள்.</string>
<!-- The body for these is the URL of the tab received -->
<string name="fxa_tab_received_notification_name">கீற்று பெறப்பட்டது</string>
<!-- When multiple tabs have been received -->
<string name="fxa_tabs_received_notification_name">கீற்றுகள் பெறப்பட்டன</string>
<!-- Advanced Preferences -->
<!-- Preference for tracking protection settings -->
<string name="preferences_tracking_protection_settings">தடமறியல் பாதுகாப்பு</string>
<!-- Preference switch for tracking protection -->
<string name="preferences_tracking_protection">தடமறியல் பாதுகாப்பு</string>
<!-- Preference for tracking protection exceptions -->
<string name="preferences_tracking_protection_exceptions">விதிவிலக்குகள்</string>
<!-- Button in Exceptions Preference to turn on tracking protection for all sites (remove all exceptions) -->
<string name="preferences_tracking_protection_exceptions_turn_on_for_all">எல்லா தளங்களுக்கும் இயக்கு</string>
<!-- Text displayed when there are no exceptions, with learn more link that brings users to a tracking protection SUMO page -->
<string name="exceptions_empty_message_learn_more_link">மேலும் அறிய</string>
<!-- Title for experiments preferences -->
<string name="preference_experiments">சோதனைகள்</string>
<!-- Preference switch for crash reporter -->
<string name="preferences_crash_reporter">செயலிழப்பு அறிக்கையாளர்</string>
<!-- Preference switch for Mozilla location service -->
<string name="preferences_mozilla_location_service">மொசில்லா புவியிடச்சேவை</string>
<!-- Turn On Sync Preferences -->
<!-- Header of the Turn on Sync preference view -->
<string name="preferences_sync">ஒத்திசைவை இயக்கு</string>
<!-- Preference for account login -->
<string name="preferences_sync_sign_in">புகுபதிகை</string>
<!-- Preference for reconnecting to FxA sync -->
<string name="preferences_sync_sign_in_to_reconnect">மறுஇணைக்க புகுபதியுங்கள்</string>
<!-- Preference for removing FxA account -->
<string name="preferences_sync_remove_account">கணக்கை அகற்று</string>
<!-- Button to open camera for pairing -->
<string name="pair_open_camera">படக்கருவியைத் திற</string>
<!-- Button to cancel pairing -->
<string name="pair_cancel">இரத்து</string>
<!-- Toolbar Preferences -->
<!-- Preference for using top toolbar -->
<string name="preference_top_toolbar">மேல்</string>
<!-- Preference for using bottom toolbar -->
<string name="preference_bottom_toolbar">கீழ்</string>
<!-- Theme Preferences -->
<!-- Preference for using light theme -->
<string name="preference_light_theme">வெளிர்</string>
<!-- Preference for using dark theme -->
<string name="preference_dark_theme">கருமை</string>
<!-- Preference for using using dark or light theme automatically set by battery -->
<string name="preference_auto_battery_theme">மின்கலச்சேமிப்பான் அமைத்தது</string>
<!-- Preference for using following device theme -->
<string name="preference_follow_device_theme">சாதனக் கருப்பொருளைப் பின்பற்று</string>
<!-- Library -->
<!-- Option in Library to open Sessions page -->
<string name="library_sessions">அமர்வுகள்</string>
<!-- Option in Library to open Screenshots page -->
<string name="library_screenshots">திரைப்பிடிப்புகள்</string>
<!-- Option in Library to open Downloads page -->
<string name="library_downloads">பதிவிறக்கங்கள்</string>
<!-- Option in library to open Bookmarks page -->
<string name="library_bookmarks">புத்தகக்குறிகள்</string>
<!-- Option in library to open Desktop Bookmarks root page -->
<string name="library_desktop_bookmarks_root">மேசைக்கணினி புத்தகக்குறிகள்</string>
<!-- Option in library to open Desktop Bookmarks "menu" page -->
<string name="library_desktop_bookmarks_menu">புத்தகக்குறிகள் பட்டி</string>
<!-- Option in library to open Desktop Bookmarks "toolbar" page -->
<string name="library_desktop_bookmarks_toolbar">புத்தகக்குறிகள் கருவிப்பட்டை</string>
<!-- Option in library to open Desktop Bookmarks "unfiled" page -->
<string name="library_desktop_bookmarks_unfiled">பிற புத்தகக்குறிகள்</string>
<!-- Option in Library to open History page -->
<string name="library_history">வரலாறு</string>
<!-- Option in Library to open Reading List -->
<string name="library_reading_list">வாசிப்புப் பட்டியல்</string>
<!-- Menu Item Label for Search in Library -->
<string name="library_search">தேடல்</string>
<!-- Settings Page Title -->
<string name="settings_title">அமைவுகள்</string>
<!-- Content description (not visible, for screen readers etc.): "Menu icon for items on a history item" -->
<string name="content_description_history_menu">வரலாறு உருப்படி பட்டி</string>
<!-- Content description (not visible, for screen readers etc.): "Close button for library settings" -->
<string name="content_description_close_button">மூடு</string>
<!-- Sessions -->
<!-- Title for the list of tabs -->
<string name="tab_header_label">திறந்த கீற்றுகள்</string>
<!-- Title for the list of tabs in the current private session -->
<string name="tabs_header_private_title">கமுக்க அமர்வு</string>
<!-- Title for the list of tabs in the current private session -->
<string name="tabs_header_private_tabs_title">கமுக்கக் கீற்றுகள்</string>
<!-- Content description (not visible, for screen readers etc.): Add tab button. Adds a news tab when pressed -->
<string name="add_tab">கீற்றைச் சேர்</string>
<!-- Content description (not visible, for screen readers etc.): Close tab button. Closes the current session when pressed -->
<string name="close_tab">கீற்றை மூடு</string>
<!-- Content description (not visible, for screen readers etc.): Close tab <title> button. First parameter is tab title -->
<string name="close_tab_title">%s கீற்றை மூடு</string>
<!-- Content description (not visible, for screen readers etc.): Opens the open tabs menu when pressed -->
<string name="open_tabs_menu">கீற்றுப் பட்டியைத் திற</string>
<!-- Open tabs menu item to close all tabs -->
<string name="tabs_menu_close_all_tabs">எல்லாக் கீற்றுகளையும் மூடு</string>
<!-- Open tabs menu item to share all tabs -->
<string name="tabs_menu_share_tabs">கீற்றுகளைப் பகிர்</string>
<!-- Content description (not visible, for screen readers etc.): Opens the tab menu when pressed -->
<string name="tab_menu">கீற்றுப் பட்டி</string>
<!-- Tab menu item to share the tab -->
<string name="tab_share">தரவைப் பகிர்</string>
<!-- Button in the current session menu. Deletes the session when pressed -->
<string name="current_session_delete">நீக்கு</string>
<!-- Button in the current session menu. Saves the session when pressed -->
<string name="current_session_save">சேமி</string>
<!-- Button in the current session menu. Opens the share menu when pressed -->
<string name="current_session_share">பகிர்</string>
<!-- Button to save the current set of tabs into a collection -->
<string name="save_to_collection">திரட்டில் சேமி</string>
<!-- Text for the menu button to delete a collection -->
<string name="collection_delete">திரட்டை நீக்கு</string>
<!-- Text for the menu button to rename a collection -->
<string name="collection_rename">திரட்டை மறுபெயரிடு</string>
<!-- Text for the button to open tabs of the selected collection -->
<string name="collection_open_tabs">கீற்றுகளைத் திற</string>
</resources> </resources>

View File

@ -897,8 +897,6 @@
<string name="preference_summary_delete_browsing_data_on_quit">Автоматично видаляє дані перегляду при виборі &quot;Вихід&quot; в головному меню</string> <string name="preference_summary_delete_browsing_data_on_quit">Автоматично видаляє дані перегляду при виборі &quot;Вихід&quot; в головному меню</string>
<!-- Summary for the Delete browsing data on quit preference. "Quit" translation should match delete_browsing_data_on_quit_action translation. --> <!-- Summary for the Delete browsing data on quit preference. "Quit" translation should match delete_browsing_data_on_quit_action translation. -->
<string name="preference_summary_delete_browsing_data_on_quit_2">Автоматично видаляє дані перегляду при виборі \&quot;Вихід\&quot; в головному меню</string> <string name="preference_summary_delete_browsing_data_on_quit_2">Автоматично видаляє дані перегляду при виборі \&quot;Вихід\&quot; в головному меню</string>
<!-- Category for history items to delete on quit in delete browsing data on quit -->
<string name="preferences_delete_browsing_data_on_quit_browsing_history">Історія перегляду</string>
<!-- Action item in menu for the Delete browsing data on quit feature --> <!-- Action item in menu for the Delete browsing data on quit feature -->
<string name="delete_browsing_data_on_quit_action">Вихід</string> <string name="delete_browsing_data_on_quit_action">Вихід</string>
@ -1444,7 +1442,7 @@
<!-- 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> <string name="synced_tabs_connect_another_device">Під’єднати інший пристрій.</string>
<!-- Text displayed asking user to re-authenticate --> <!-- Text displayed asking user to re-authenticate -->
<string name="synced_tabs_reauth">Необхідно повторно авторизуватись.</string> <string name="synced_tabs_reauth">Повторіть автентифікацію.</string>
<!-- Text displayed when user has disabled tab syncing in Firefox Sync Account --> <!-- Text displayed when user has disabled tab syncing in Firefox Sync Account -->
<string name="synced_tabs_enable_tab_syncing">Увімкніть синхронізацію вкладок.</string> <string name="synced_tabs_enable_tab_syncing">Увімкніть синхронізацію вкладок.</string>
<!-- Text displayed when user has no tabs that have been synced --> <!-- Text displayed when user has no tabs that have been synced -->

View File

@ -926,8 +926,6 @@
<string name="preference_summary_delete_browsing_data_on_quit">从主菜单中选择“退出”时,自动删除浏览数据</string> <string name="preference_summary_delete_browsing_data_on_quit">从主菜单中选择“退出”时,自动删除浏览数据</string>
<!-- Summary for the Delete browsing data on quit preference. "Quit" translation should match delete_browsing_data_on_quit_action translation. --> <!-- Summary for the Delete browsing data on quit preference. "Quit" translation should match delete_browsing_data_on_quit_action translation. -->
<string name="preference_summary_delete_browsing_data_on_quit_2">从主菜单中选择“退出”时,自动删除浏览数据</string> <string name="preference_summary_delete_browsing_data_on_quit_2">从主菜单中选择“退出”时,自动删除浏览数据</string>
<!-- Category for history items to delete on quit in delete browsing data on quit -->
<string name="preferences_delete_browsing_data_on_quit_browsing_history">浏览历史</string>
<!-- Action item in menu for the Delete browsing data on quit feature --> <!-- Action item in menu for the Delete browsing data on quit feature -->
<string name="delete_browsing_data_on_quit_action">退出</string> <string name="delete_browsing_data_on_quit_action">退出</string>
@ -947,7 +945,7 @@
<!-- Tips --> <!-- Tips -->
<!-- text for firefox preview moving tip header "Firefox Preview" and "Firefox Nightly" are intentionally hardcoded --> <!-- text for firefox preview moving tip header "Firefox Preview" and "Firefox Nightly" are intentionally hardcoded -->
<string name="tip_firefox_preview_moved_header">Firefox Preview 即为现在的 Firefox Nightly</string> <string name="tip_firefox_preview_moved_header">Firefox Preview 已迁移至 Firefox Nightly</string>
<!-- text for firefox preview moving tip description --> <!-- text for firefox preview moving tip description -->
<string name="tip_firefox_preview_moved_description">Firefox Nightly 每日获得更新,包含实验性的新功能。 <string name="tip_firefox_preview_moved_description">Firefox Nightly 每日获得更新,包含实验性的新功能。
但可能不够稳定,您可以下载我们的 Beta 版浏览器以获得更稳定的体验。</string> 但可能不够稳定,您可以下载我们的 Beta 版浏览器以获得更稳定的体验。</string>

View File

@ -919,8 +919,6 @@
<string name="preference_summary_delete_browsing_data_on_quit">當您點擊主選單當中的「離開」時,自動刪除瀏覽資料</string> <string name="preference_summary_delete_browsing_data_on_quit">當您點擊主選單當中的「離開」時,自動刪除瀏覽資料</string>
<!-- Summary for the Delete browsing data on quit preference. "Quit" translation should match delete_browsing_data_on_quit_action translation. --> <!-- Summary for the Delete browsing data on quit preference. "Quit" translation should match delete_browsing_data_on_quit_action translation. -->
<string name="preference_summary_delete_browsing_data_on_quit_2">點擊主選單中的「離開」時,自動清除上網資料</string> <string name="preference_summary_delete_browsing_data_on_quit_2">點擊主選單中的「離開」時,自動清除上網資料</string>
<!-- Category for history items to delete on quit in delete browsing data on quit -->
<string name="preferences_delete_browsing_data_on_quit_browsing_history">瀏覽紀錄</string>
<!-- Action item in menu for the Delete browsing data on quit feature --> <!-- Action item in menu for the Delete browsing data on quit feature -->
<string name="delete_browsing_data_on_quit_action">離開</string> <string name="delete_browsing_data_on_quit_action">離開</string>
@ -940,9 +938,9 @@
<!-- Tips --> <!-- Tips -->
<!-- text for firefox preview moving tip header "Firefox Preview" and "Firefox Nightly" are intentionally hardcoded --> <!-- text for firefox preview moving tip header "Firefox Preview" and "Firefox Nightly" are intentionally hardcoded -->
<string name="tip_firefox_preview_moved_header">Firefox Nightly 已被 Firefox Preview 取代</string> <string name="tip_firefox_preview_moved_header">Firefox Nightly 已接手原 Firefox Preview 功能</string>
<!-- text for firefox preview moving tip description --> <!-- text for firefox preview moving tip description -->
<string name="tip_firefox_preview_moved_description">Firefox Nightly 每天都會更新一次,當中包含實驗中的新功能,然而這些新功能可能會較不穩定。若須有較穩定的使用體驗,請下載我們的 Beta 測試版。</string> <string name="tip_firefox_preview_moved_description">Firefox Nightly 每天都會更新,當中包含實驗中的新功能,然而這些新功能可能會較不穩定。\n\n若想要有較穩定的使用體驗,請下載我們的 Beta 測試版。</string>
<!-- text for firefox preview moving tip button. "Firefox for Android Beta" is intentionally hardcoded --> <!-- text for firefox preview moving tip button. "Firefox for Android Beta" is intentionally hardcoded -->
<string name="tip_firefox_preview_moved_button_2">下載 Firefox for Android Beta 測試版</string> <string name="tip_firefox_preview_moved_button_2">下載 Firefox for Android Beta 測試版</string>
@ -950,14 +948,14 @@
<!-- text for firefox preview moving tip header. "Firefox Nightly" is intentionally hardcoded --> <!-- text for firefox preview moving tip header. "Firefox Nightly" is intentionally hardcoded -->
<string name="tip_firefox_preview_moved_header_preview_installed">Firefox Nightly 版本更新</string> <string name="tip_firefox_preview_moved_header_preview_installed">Firefox Nightly 版本更新</string>
<!-- text for firefox preview moving tip description --> <!-- text for firefox preview moving tip description -->
<string name="tip_firefox_preview_moved_description_preview_installed">此應用程式不會再收到安全性更新。請改用新版的 Nightly 並停用此應用程式。\n\n註冊 Firefox 帳號,即可快速移轉書籤、登入資訊、瀏覽紀錄到新版本當中</string> <string name="tip_firefox_preview_moved_description_preview_installed">此應用程式不會再收到安全性更新。請改用新版的 Nightly 並停止使用此應用程式。\n\n註冊 Firefox 帳號,即可快速移轉書籤、登入資訊、瀏覽紀錄到新版本。</string>
<!-- text for firefox preview moving tip button --> <!-- text for firefox preview moving tip button -->
<string name="tip_firefox_preview_moved_button_preview_installed">改用新版 Nightly</string> <string name="tip_firefox_preview_moved_button_preview_installed">改用新版 Nightly</string>
<!-- text for firefox preview moving tip header. "Firefox Nightly" is intentionally hardcoded --> <!-- text for firefox preview moving tip header. "Firefox Nightly" is intentionally hardcoded -->
<string name="tip_firefox_preview_moved_header_preview_not_installed">Firefox Nightly 版本更新</string> <string name="tip_firefox_preview_moved_header_preview_not_installed">Firefox Nightly 版本更新</string>
<!-- text for firefox preview moving tip description --> <!-- text for firefox preview moving tip description -->
<string name="tip_firefox_preview_moved_description_preview_not_installed">此應用程式不會再收到安全性更新。請下載新版的 Nightly 並停用此應用程式。\n\n請註冊 Firefox 帳號,即可快速移轉書籤、登入資訊、瀏覽紀錄到新版本當中</string> <string name="tip_firefox_preview_moved_description_preview_not_installed">此應用程式不會再收到安全性更新。請改用新版的 Nightly 並停止使用此版應用程式。\n\n註冊 Firefox 帳號,即可快速移轉書籤、登入資訊、瀏覽紀錄到新版本。</string>
<!-- text for firefox preview moving tip button --> <!-- text for firefox preview moving tip button -->
<string name="tip_firefox_preview_moved_button_preview_not_installed">下載新版 Nightly</string> <string name="tip_firefox_preview_moved_button_preview_not_installed">下載新版 Nightly</string>

View File

@ -109,12 +109,10 @@
<dimen name="about_header_text_line_spacing_extra">4dp</dimen> <dimen name="about_header_text_line_spacing_extra">4dp</dimen>
<!-- Locale Settings Fragment --> <!-- Locale Settings Fragment -->
<dimen name="locale_search_bar_margin">8dp</dimen>
<dimen name="locale_search_bar_padding_start">-12dp</dimen>
<dimen name="locale_list_margin">16dp</dimen> <dimen name="locale_list_margin">16dp</dimen>
<dimen name="locale_item_vertical_margin">8dp</dimen> <dimen name="locale_item_text_margin_start">32dp</dimen>
<dimen name="locale_item_text_margin_start">16dp</dimen> <dimen name="locale_item_text_margin_end">16dp</dimen>
<dimen name="locale_item_text_margin_gone_start">40dp</dimen> <dimen name="locale_item_text_margin_gone_start">72dp</dimen>
<dimen name="locale_item_title_size">16sp</dimen> <dimen name="locale_item_title_size">16sp</dimen>
<dimen name="locale_item_subtitle_size">12sp</dimen> <dimen name="locale_item_subtitle_size">12sp</dimen>

View File

@ -714,6 +714,8 @@
<string name="create_collection_save_to_collection_tab_selected">%d tab selected</string> <string name="create_collection_save_to_collection_tab_selected">%d tab selected</string>
<!-- Text shown in snackbar when multiple tabs have been saved in a collection --> <!-- Text shown in snackbar when multiple tabs have been saved in a collection -->
<string name="create_collection_tabs_saved">Tabs saved!</string> <string name="create_collection_tabs_saved">Tabs saved!</string>
<!-- Text shown in snackbar when one or multiple tabs have been saved in a new collection -->
<string name="create_collection_tabs_saved_new_collection">Collection saved!</string>
<!-- Text shown in snackbar when one tab has been saved in a collection --> <!-- Text shown in snackbar when one tab has been saved in a collection -->
<string name="create_collection_tab_saved">Tab saved!</string> <string name="create_collection_tab_saved">Tab saved!</string>
<!-- Content description (not visible, for screen readers etc.): button to close the collection creator --> <!-- Content description (not visible, for screen readers etc.): button to close the collection creator -->
@ -817,6 +819,10 @@
<string name="qr_scanner_dialog_negative">DENY</string> <string name="qr_scanner_dialog_negative">DENY</string>
<!-- Tab collection deletion prompt dialog message. Placeholder will be replaced with the collection name --> <!-- Tab collection deletion prompt dialog message. Placeholder will be replaced with the collection name -->
<string name="tab_collection_dialog_message">Are you sure you want to delete %1$s?</string> <string name="tab_collection_dialog_message">Are you sure you want to delete %1$s?</string>
<!-- Collection and tab deletion prompt dialog message. This will show when the last tab from a collection is deleted -->
<string name="delete_tab_and_collection_dialog_message">Deleting this tab will delete the entire collection. You can create new collections at any time.</string>
<!-- Collection and tab deletion prompt dialog title. Placeholder will be replaced with the collection name. This will show when the last tab from a collection is deleted -->
<string name="delete_tab_and_collection_dialog_title">Delete collection %1$s?</string>
<!-- Tab collection deletion prompt dialog option to delete the collection --> <!-- Tab collection deletion prompt dialog option to delete the collection -->
<string name="tab_collection_dialog_positive">Delete</string> <string name="tab_collection_dialog_positive">Delete</string>
<!-- Tab collection deletion prompt dialog option to cancel deleting the collection --> <!-- Tab collection deletion prompt dialog option to cancel deleting the collection -->

View File

@ -244,7 +244,8 @@
<item name="android:textAlignment">center</item> <item name="android:textAlignment">center</item>
<item name="android:background">@drawable/rounded_button_background</item> <item name="android:background">@drawable/rounded_button_background</item>
<item name="android:layout_width">match_parent</item> <item name="android:layout_width">match_parent</item>
<item name="android:layout_height">48dp</item> <item name="android:minHeight">48dp</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:textStyle">bold</item> <item name="android:textStyle">bold</item>
<item name="android:textAllCaps">false</item> <item name="android:textAllCaps">false</item>
<item name="backgroundTint">@color/grey_button_color</item> <item name="backgroundTint">@color/grey_button_color</item>

View File

@ -2,21 +2,17 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public <!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this - License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. --> - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
xmlns:app="http://schemas.android.com/apk/res-auto"> <SwitchPreference
<androidx.preference.SwitchPreference
android:key="@string/pref_key_telemetry" android:key="@string/pref_key_telemetry"
android:summary="@string/preferences_usage_data_description" android:summary="@string/preferences_usage_data_description"
android:title="@string/preference_usage_data" android:title="@string/preference_usage_data" />
app:iconSpaceReserved="false" /> <SwitchPreference
<androidx.preference.SwitchPreference
android:key="@string/pref_key_marketing_telemetry" android:key="@string/pref_key_marketing_telemetry"
android:summary="@string/preferences_marketing_data_description" android:summary="@string/preferences_marketing_data_description"
android:title="@string/preferences_marketing_data" android:title="@string/preferences_marketing_data" />
app:iconSpaceReserved="false" /> <SwitchPreference
<androidx.preference.SwitchPreference
android:key="@string/pref_key_experimentation" android:key="@string/pref_key_experimentation"
android:summary="@string/preference_experiments_summary" android:summary="@string/preference_experiments_summary"
android:title="@string/preference_experiments" android:title="@string/preference_experiments" />
app:iconSpaceReserved="false" />
</PreferenceScreen> </PreferenceScreen>

View File

@ -0,0 +1,48 @@
/* 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
import androidx.appcompat.app.ActionBar
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import io.mockk.mockk
import org.robolectric.Robolectric
class MockNavHostActivity : AppCompatActivity(), NavHostActivity {
private val mockActionBar = mockk<ActionBar>(relaxed = true)
override fun getSupportActionBarAndInflateIfNecessary() = mockActionBar
}
/**
* Set up an added [Fragment] to a [FragmentActivity] that has been initialized to a resumed state.
*
* Variant of [mozilla.components.support.test.robolectric.createAddedTestFragment] that uses
* a custom Fenix activity to hold the fragment.
*
* @param fragmentTag the name that will be used to tag the fragment inside the [FragmentManager].
* @param fragmentFactory a lambda function that returns a Fragment that will be added to the Activity.
*
* @return The same [Fragment] that was returned from [fragmentFactory] after it got added to the
* Activity.
*/
inline fun <T : Fragment> createAddedTestFragmentInNavHostActivity(
fragmentTag: String = "test",
fragmentFactory: () -> T
): T {
val activity = Robolectric.buildActivity(MockNavHostActivity::class.java)
.create()
.start()
.resume()
.get()
return fragmentFactory().also {
activity.supportFragmentManager.beginTransaction()
.add(it, fragmentTag)
.commitNow()
}
}

View File

@ -0,0 +1,47 @@
/* 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.addons
import android.content.Intent.ACTION_VIEW
import androidx.core.net.toUri
import kotlinx.android.synthetic.main.fragment_add_on_permissions.*
import mozilla.components.feature.addons.Addon
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
import org.mozilla.fenix.createAddedTestFragmentInNavHostActivity
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
import org.robolectric.Shadows.shadowOf
@RunWith(FenixRobolectricTestRunner::class)
class AddonPermissionsDetailsFragmentTest {
private val addon = Addon(
id = "",
translatableName = mapOf(
Addon.DEFAULT_LOCALE to "Some blank addon"
)
)
@Test
fun `trigger view intent when learn more is clicked`() {
val fragment = createAddedTestFragmentInNavHostActivity {
AddonPermissionsDetailsFragment().apply {
arguments = AddonPermissionsDetailsFragmentArgs(addon).toBundle()
}
}
assertEquals("Some blank addon", fragment.activity?.title)
fragment.learn_more_label.performClick()
val intent = shadowOf(fragment.activity).peekNextStartedActivity()
assertEquals(ACTION_VIEW, intent.action)
assertEquals(
"https://support.mozilla.org/kb/permission-request-messages-firefox-extensions".toUri(),
intent.data
)
}
}

View File

@ -49,7 +49,7 @@ class DefaultSessionControlControllerTest {
private val openPrivacyNotice: () -> Unit = mockk(relaxed = true) private val openPrivacyNotice: () -> Unit = mockk(relaxed = true)
private val registerCollectionStorageObserver: () -> Unit = mockk(relaxed = true) private val registerCollectionStorageObserver: () -> Unit = mockk(relaxed = true)
private val showTabTray: () -> Unit = mockk(relaxed = true) private val showTabTray: () -> Unit = mockk(relaxed = true)
private val showDeleteCollectionPrompt: (tabCollection: TabCollection) -> Unit = private val showDeleteCollectionPrompt: (tabCollection: TabCollection, title: String?, message: String) -> Unit =
mockk(relaxed = true) mockk(relaxed = true)
private val metrics: MetricController = mockk(relaxed = true) private val metrics: MetricController = mockk(relaxed = true)
private val state: HomeFragmentState = mockk(relaxed = true) private val state: HomeFragmentState = mockk(relaxed = true)
@ -137,7 +137,7 @@ class DefaultSessionControlControllerTest {
fun handleDeleteCollectionTapped() { fun handleDeleteCollectionTapped() {
val collection: TabCollection = mockk(relaxed = true) val collection: TabCollection = mockk(relaxed = true)
controller.handleDeleteCollectionTapped(collection) controller.handleDeleteCollectionTapped(collection)
verify { showDeleteCollectionPrompt(collection) } verify { showDeleteCollectionPrompt(collection, null, any()) }
} }
@Test @Test

View File

@ -47,6 +47,16 @@ class SearchFragmentStoreTest {
assertEquals(true, store.state.showSearchShortcuts) assertEquals(true, store.state.showSearchShortcuts)
} }
@Test
fun hideSearchShortcutEnginePicker() = runBlocking {
val initialState = emptyDefaultState()
val store = SearchFragmentStore(initialState)
store.dispatch(SearchFragmentAction.UpdateShortcutsAvailability(false)).join()
assertNotSame(initialState, store.state)
assertEquals(false, store.state.showSearchShortcuts)
}
private fun emptyDefaultState(): SearchFragmentState = SearchFragmentState( private fun emptyDefaultState(): SearchFragmentState = SearchFragmentState(
tabId = null, tabId = null,
url = "", url = "",
@ -57,6 +67,7 @@ class SearchFragmentStoreTest {
showSearchSuggestionsHint = false, showSearchSuggestionsHint = false,
showSearchSuggestions = false, showSearchSuggestions = false,
showSearchShortcuts = false, showSearchShortcuts = false,
areShortcutsAvailable = true,
showClipboardSuggestions = false, showClipboardSuggestions = false,
showHistorySuggestions = false, showHistorySuggestions = false,
showBookmarkSuggestions = false, showBookmarkSuggestions = false,

View File

@ -2,14 +2,14 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.fenix.ext package org.mozilla.fenix.search
import org.junit.Assert.assertFalse import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue import org.junit.Assert.assertTrue
import org.junit.Test import org.junit.Test
import org.mozilla.fenix.search.telemetry.SearchProviderModel import org.mozilla.fenix.search.telemetry.SearchProviderModel
class AdsTest { class SearchProviderModelTest {
private val testSearchProvider = private val testSearchProvider =
SearchProviderModel( SearchProviderModel(

View File

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

View File

@ -7,14 +7,14 @@ object Versions {
const val coroutines = "1.3.3" const val coroutines = "1.3.3"
const val android_gradle_plugin = "3.5.0" const val android_gradle_plugin = "3.5.0"
const val sentry = "1.7.10" const val sentry = "1.7.10"
const val leakcanary = "2.3" const val leakcanary = "2.4"
const val leanplum = "5.4.0" const val leanplum = "5.4.0"
const val osslicenses_plugin = "0.9.5" const val osslicenses_plugin = "0.9.5"
const val osslicenses_library = "17.0.0" const val osslicenses_library = "17.0.0"
const val detekt = "1.6.0" const val detekt = "1.6.0"
const val androidx_appcompat = "1.2.0-rc01" const val androidx_appcompat = "1.2.0-rc01"
const val androidx_biometric = "1.0.1" const val androidx_biometric = "1.1.0-alpha01"
const val androidx_coordinator_layout = "1.1.0-rc01" const val androidx_coordinator_layout = "1.1.0-rc01"
const val androidx_constraint_layout = "2.0.0-beta6" const val androidx_constraint_layout = "2.0.0-beta6"
const val androidx_preference = "1.1.0" const val androidx_preference = "1.1.0"
@ -22,7 +22,7 @@ object Versions {
const val androidx_annotation = "1.1.0" const val androidx_annotation = "1.1.0"
const val androidx_lifecycle = "2.2.0" const val androidx_lifecycle = "2.2.0"
const val androidx_fragment = "1.2.5" const val androidx_fragment = "1.2.5"
const val androidx_navigation = "2.2.1" const val androidx_navigation = "2.3.0"
const val androidx_recyclerview = "1.1.0" const val androidx_recyclerview = "1.1.0"
const val androidx_core = "1.2.0" const val androidx_core = "1.2.0"
const val androidx_paging = "2.1.0" const val androidx_paging = "2.1.0"
@ -44,7 +44,7 @@ object Versions {
const val google_ads_id_version = "16.0.0" const val google_ads_id_version = "16.0.0"
const val airbnb_lottie = "3.3.0" const val airbnb_lottie = "3.4.0"
} }
@Suppress("unused") @Suppress("unused")