Commit 74844ea6 authored by mimi89999's avatar mimi89999 Committed by clairehurst
Browse files

Bug 1812898 - Part 1: Add domain alignment in Android toolbar component....

Bug 1812898 - Part 1: Add domain alignment in Android toolbar component. r=tthibaud,android-reviewers

Differential Revision: https://phabricator.services.mozilla.com/D244508
parent 57410173
Loading
Loading
Loading
Loading
+44 −1
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@ package mozilla.components.browser.toolbar.display
import android.animation.LayoutTransition
import android.content.Context
import android.graphics.Typeface
import android.text.Spanned
import android.util.AttributeSet
import android.util.TypedValue
import android.view.Gravity
@@ -17,6 +18,7 @@ import androidx.annotation.VisibleForTesting
import androidx.core.view.isVisible
import mozilla.components.browser.toolbar.BrowserToolbar
import mozilla.components.browser.toolbar.R
import mozilla.components.concept.toolbar.Toolbar

/**
 * View displaying the URL and optionally the title of a website.
@@ -137,9 +139,50 @@ internal class OriginView @JvmOverloads constructor(
        titleView.setOnLongClickListener(handler)
    }

    /**
     * Scrolls the URL view to ensure the registrable domain is visible.
     */
    @VisibleForTesting
    internal fun scrollToShowRegistrableDomain() {
        val text = urlView.text

        val spans = (text as? Spanned)?.getSpans(
            0,
            text.length,
            Toolbar.RegistrableDomainColorSpan::class.java,
        )

        if (spans?.size == 1) {
            val registrableDomainSpan = (urlView.text as? Spanned)?.getSpans(
                0,
                text.length,
                Toolbar.RegistrableDomainColorSpan::class.java,
            )?.getOrNull(0)

            val valueUntilRegistrableDomainEnd = text.subSequence(0, text.getSpanEnd(registrableDomainSpan))

            val urlViewWidth = urlView.width
            val valueWidth = measureUrlTextWidh(valueUntilRegistrableDomainEnd.toString())

            if (valueWidth > urlViewWidth) {
                urlView.scrollTo((valueWidth - urlViewWidth).toInt(), 0)
                return
            }
        }

        urlView.scrollTo(0, 0)
    }

    @VisibleForTesting
    internal fun measureUrlTextWidh(text: String) = urlView.paint.measureText(text)

    internal var url: CharSequence
        get() = urlView.text
        set(value) { urlView.text = value }
        set(value) {
            urlView.text = value

            scrollToShowRegistrableDomain()
        }

    /**
     * Sets the colour of the text to be displayed when the URL of the toolbar is empty.
+86 −0
Original line number Diff line number Diff line
@@ -4,15 +4,101 @@

package mozilla.components.browser.toolbar.display

import android.graphics.Color
import android.text.SpannableStringBuilder
import android.text.SpannableStringBuilder.SPAN_INCLUSIVE_INCLUSIVE
import android.text.style.ForegroundColorSpan
import android.view.View
import androidx.annotation.ColorInt
import androidx.test.ext.junit.runners.AndroidJUnit4
import mozilla.components.concept.toolbar.Toolbar
import mozilla.components.support.test.any
import mozilla.components.support.test.robolectric.testContext
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mockito.doReturn
import org.mockito.Mockito.spy

@RunWith(AndroidJUnit4::class)
class OriginViewTest {

    private fun SpannableStringBuilder.applyUrlColors(
        @ColorInt urlColor: Int,
        @ColorInt registrableDomainColor: Int,
        registrableDomainOrHostSpan: Pair<Int, Int>,
    ): SpannableStringBuilder = apply {
        setSpan(
            ForegroundColorSpan(urlColor),
            0,
            length,
            SPAN_INCLUSIVE_INCLUSIVE,
        )

        val (start, end) = registrableDomainOrHostSpan
        setSpan(
            Toolbar.RegistrableDomainColorSpan(registrableDomainColor),
            start,
            end,
            SPAN_INCLUSIVE_INCLUSIVE,
        )
    }

    @Test
    fun `scrollToShowRegistrableDomain scrolls when domain exceeds width`() {
        val view = spy(OriginView(testContext))
        val url = "https://www.really-long-example-domain.com/"
        val spannedUrl = SpannableStringBuilder(url).apply {
            applyUrlColors(
                urlColor = Color.GREEN,
                registrableDomainColor = Color.RED,
                registrableDomainOrHostSpan = 8 to 42,
            )
        }

        // Long domain wouldn't fit in the view
        doReturn(500f).`when`(view).measureUrlTextWidh(any())
        view.urlView.layout(0, 0, 200, 100)

        view.url = spannedUrl

        assertEquals(300, view.urlView.scrollX)
    }

    @Test
    fun `scrollToShowRegistrableDomain does not scroll when domain fits in view`() {
        val view = spy(OriginView(testContext))
        val url = "https://mozilla.org/"
        val spannedUrl = SpannableStringBuilder(url).apply {
            applyUrlColors(
                urlColor = Color.GREEN,
                registrableDomainColor = Color.RED,
                registrableDomainOrHostSpan = 8 to 19,
            )
        }

        doReturn(50f).`when`(view).measureUrlTextWidh(any())
        view.urlView.layout(0, 0, 200, 100)

        view.url = spannedUrl

        assertEquals(0, view.urlView.scrollX)
    }

    @Test
    fun `scrollToShowRegistrableDomain does not scroll when no span exists`() {
        val view = OriginView(testContext)

        val spanned = SpannableStringBuilder("nospan.com") // no span set

        view.measure(0, 0)
        view.layout(0, 0, 500, 100)

        view.url = spanned

        assertEquals(0, view.urlView.scrollX)
    }

    @Test
    fun `URL text direction is always LTR`() {
        val originView = OriginView(testContext)
+9 −0
Original line number Diff line number Diff line
@@ -5,11 +5,13 @@
package mozilla.components.concept.toolbar

import android.graphics.drawable.Drawable
import android.text.style.ForegroundColorSpan
import android.view.View
import android.view.View.NO_ID
import android.view.ViewGroup
import android.widget.ImageButton
import android.widget.ImageView
import androidx.annotation.ColorInt
import androidx.annotation.ColorRes
import androidx.annotation.Dimension
import androidx.annotation.Dimension.Companion.DP
@@ -548,6 +550,13 @@ interface Toolbar : ScrollableToolbar {
         */
        END,
    }

    /**
     * Registrable domain foreground color span.
     *
     * This simple class extension is used so that we can filter for it elsewhere.
     */
    class RegistrableDomainColorSpan(@ColorInt color: Int) : ForegroundColorSpan(color)
}

private fun AppCompatImageButton.setTintResource(@ColorRes tintColorResource: Int) {
+1 −1
Original line number Diff line number Diff line
@@ -174,7 +174,7 @@ private fun SpannableStringBuilder.applyUrlColors(

    val (start, end) = registrableDomainOrHostSpan
    setSpan(
        ForegroundColorSpan(registrableDomainColor),
        Toolbar.RegistrableDomainColorSpan(registrableDomainColor),
        start,
        end,
        SPAN_INCLUSIVE_INCLUSIVE,