Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3b1424a4 authored by Dmitri Plotnikov's avatar Dmitri Plotnikov Committed by Android (Google) Code Review
Browse files

Merge "Posprocessing HTML for stream items."

parents e050438f 1b4572ba
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -71,4 +71,7 @@
    <!--  Color of the semi-transparent shadow box on contact tiles -->
    <color name="contact_tile_shadow_box_color">#7F000000</color>

    <!--  Color of the vertical stripe that goes on the left of a block quote inside a stream item -->
    <color name="stream_item_stripe_color">#CCCCCC</color>

</resources>
+3 −0
Original line number Diff line number Diff line
@@ -191,4 +191,7 @@
    <!--  Vertical and horizontal padding in between contact tiles -->
    <dimen name="contact_tile_divider_padding">1dip</dimen>

    <!--  Width of the lead margin on the left of a block quote inside a stream item -->
    <dimen name="stream_item_stripe_width">8dip</dimen>

</resources>
+5 −3
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import com.android.contacts.ContactPhotoManager;
import com.android.contacts.R;
import com.android.contacts.preference.ContactsPreferences;
import com.android.contacts.util.ContactBadgeUtil;
import com.android.contacts.util.HtmlUtils;
import com.android.contacts.util.StreamItemEntry;
import com.android.contacts.util.StreamItemPhotoEntry;
import com.google.common.annotations.VisibleForTesting;
@@ -236,7 +237,7 @@ public class ContactDetailDisplayUtils {
        String photoUri = null;
        if (!contactData.getStreamItems().isEmpty()) {
            StreamItemEntry firstEntry = contactData.getStreamItems().get(0);
            snippet = Html.fromHtml(firstEntry.getText());
            snippet = HtmlUtils.fromHtml(context, firstEntry.getText());
            if (!firstEntry.getPhotos().isEmpty()) {
                StreamItemPhotoEntry firstPhoto = firstEntry.getPhotos().get(0);
                photoUri = firstPhoto.getPhotoUri();
@@ -338,10 +339,11 @@ public class ContactDetailDisplayUtils {
                R.id.stream_item_attribution);
        TextView commentsView = (TextView) rootView.findViewById(R.id.stream_item_comments);
        ImageGetter imageGetter = new DefaultImageGetter(context.getPackageManager());
        htmlView.setText(Html.fromHtml(streamItem.getText(), imageGetter, null));
        htmlView.setText(HtmlUtils.fromHtml(context, streamItem.getText(), imageGetter, null));
        attributionView.setText(ContactBadgeUtil.getSocialDate(streamItem, context));
        if (streamItem.getComments() != null) {
            commentsView.setText(Html.fromHtml(streamItem.getComments(), imageGetter, null));
            commentsView.setText(HtmlUtils.fromHtml(context, streamItem.getComments(), imageGetter,
                    null));
            commentsView.setVisibility(View.VISIBLE);
        } else {
            commentsView.setVisibility(View.GONE);
+2 −2
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import com.android.contacts.R;
import com.android.contacts.model.AccountType;
import com.android.contacts.model.AccountTypeManager;
import com.android.contacts.util.ContactBadgeUtil;
import com.android.contacts.util.HtmlUtils;
import com.android.contacts.util.StreamItemEntry;

import android.app.PendingIntent;
@@ -36,7 +37,6 @@ import android.graphics.Typeface;
import android.net.Uri;
import android.provider.ContactsContract.QuickContact;
import android.provider.ContactsContract.StreamItems;
import android.text.Html;
import android.text.SpannableStringBuilder;
import android.text.TextUtils;
import android.text.style.AbsoluteSizeSpan;
@@ -208,7 +208,7 @@ public class SocialWidgetProvider extends AppWidgetProvider {
        } else {
            // TODO: Rotate between all the stream items?
            StreamItemEntry streamItem = streamItems.get(0);
            CharSequence status = Html.fromHtml(streamItem.getText());
            CharSequence status = HtmlUtils.fromHtml(context, streamItem.getText());
            if (status.length() <= SHORT_SNIPPET_LENGTH) {
                sb.append("\n");
            } else {
+101 −0
Original line number Diff line number Diff line
package com.android.contacts.util;

import android.content.Context;
import android.content.res.Resources;
import android.text.Html;
import android.text.Html.ImageGetter;
import android.text.Html.TagHandler;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.style.ImageSpan;
import android.text.style.QuoteSpan;

import com.android.contacts.R;

/**
 * Provides static functions to perform custom HTML to text conversions.
 * Specifically, it adjusts the color and padding of the vertical
 * stripe on block quotes and alignment of inlined images.
 */
public class HtmlUtils {

    /**
     * Converts HTML string to a {@link Spanned} text, adjusting formatting.
     */
    public static Spanned fromHtml(Context context, String text) {
        Spanned spanned = Html.fromHtml(text);
        postprocess(context, spanned);
        return spanned;
    }

    /**
     * Converts HTML string to a {@link Spanned} text, adjusting formatting and using a custom
     * image getter.
     */
    public static CharSequence fromHtml(Context context, String text, ImageGetter imageGetter,
            TagHandler tagHandler) {
        Spanned spanned = Html.fromHtml(text, imageGetter, tagHandler);
        postprocess(context, spanned);
        return spanned;
    }

    /**
     * Replaces some spans with custom versions of those.
     */
    private static void postprocess(Context context, Spanned spanned) {
        if (!(spanned instanceof SpannableStringBuilder)) {
            return;
        }

        int length = spanned.length();

        SpannableStringBuilder builder = (SpannableStringBuilder)spanned;
        QuoteSpan[] quoteSpans = spanned.getSpans(0, length, QuoteSpan.class);
        if (quoteSpans != null && quoteSpans.length != 0) {
            Resources resources = context.getResources();
            int color = resources.getColor(R.color.stream_item_stripe_color);
            int width = resources.getDimensionPixelSize(R.dimen.stream_item_stripe_width);
            for (int i = 0; i < quoteSpans.length; i++) {
                replaceSpan(builder, quoteSpans[i], new StreamItemQuoteSpan(color, width));
            }
        }

        ImageSpan[] imageSpans = spanned.getSpans(0, length, ImageSpan.class);
        if (imageSpans != null) {
            for (int i = 0; i < imageSpans.length; i++) {
                ImageSpan span = imageSpans[i];
                replaceSpan(builder, span, new ImageSpan(span.getDrawable(),
                        ImageSpan.ALIGN_BASELINE));
            }
        }
    }

    /**
     * Replaces one span with the other.
     */
    private static void replaceSpan(SpannableStringBuilder builder, Object originalSpan,
            Object newSpan) {
        builder.setSpan(newSpan,
                builder.getSpanStart(originalSpan),
                builder.getSpanEnd(originalSpan),
                builder.getSpanFlags(originalSpan));
        builder.removeSpan(originalSpan);
    }

    public static class StreamItemQuoteSpan extends QuoteSpan {
        private final int mWidth;

        public StreamItemQuoteSpan(int color, int width) {
            super(color);
            this.mWidth = width;
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public int getLeadingMargin(boolean first) {
            return mWidth;
        }
    }
}