/** * Copyright (C) 2012 Google Inc. * Licensed to The Android Open Source Project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.mail.ui; import android.content.Context; import android.support.v4.text.TextUtilsCompat; import android.support.v4.view.ViewCompat; import com.android.mail.R; import com.android.mail.utils.LogTag; import com.android.mail.utils.LogUtils; import com.android.mail.utils.Utils; import com.google.common.annotations.VisibleForTesting; import java.util.Locale; import java.util.regex.Pattern; /** * Renders data into very simple string-substitution HTML templates for conversation view. */ public class HtmlConversationTemplates extends AbstractHtmlTemplates { /** * Prefix applied to a message id for use as a div id */ public static final String MESSAGE_PREFIX = "m"; public static final int MESSAGE_PREFIX_LENGTH = MESSAGE_PREFIX.length(); private static final String TAG = LogTag.getLogTag(); /** * Pattern for HTML img tags with a "src" attribute where the value is an absolutely-specified * HTTP or HTTPS URL. In other words, these are images with valid URLs that we should munge to * prevent WebView from firing bad onload handlers for them. Part of the workaround for * b/5522414. * * Pattern documentation: * There are 3 top-level parts of the pattern: * 1. required preceding string * 2. the literal string "src" * 3. required trailing string * * The preceding string must be an img tag "]*\\s+)?)src(\\s*=[\\s'\"]*http)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE); /** * The text replacement for {@link #sAbsoluteImgUrlPattern}. The "src" attribute is set to * something inert and not left unset to minimize interactions with existing JS. */ private static final String IMG_URL_REPLACEMENT = "$1src='data:' blocked-src$2"; private static final String LEFT_TO_RIGHT_TRIANGLE = "\u25B6 "; private static final String RIGHT_TO_LEFT_TRIANGLE = "\u25C0 "; private static boolean sLoadedTemplates; private static String sSuperCollapsed; private static String sMessage; private static String sConversationUpper; private static String sConversationLower; public HtmlConversationTemplates(Context context) { super(context); // The templates are small (~2KB total in ICS MR2), so it's okay to load them once and keep // them in memory. if (!sLoadedTemplates) { sLoadedTemplates = true; sSuperCollapsed = readTemplate(R.raw.template_super_collapsed); sMessage = readTemplate(R.raw.template_message); sConversationUpper = readTemplate(R.raw.template_conversation_upper); sConversationLower = readTemplate(R.raw.template_conversation_lower); } } public void appendSuperCollapsedHtml(int firstCollapsed, int blockHeight) { if (!mInProgress) { throw new IllegalStateException("must call startConversation first"); } append(sSuperCollapsed, firstCollapsed, blockHeight); } @VisibleForTesting static String replaceAbsoluteImgUrls(final String html) { return sAbsoluteImgUrlPattern.matcher(html).replaceAll(IMG_URL_REPLACEMENT); } /** * Wrap a given message body string to prevent its contents from flowing out of the current DOM * block context. * */ public static String wrapMessageBody(String msgBody) { // FIXME: this breaks RTL for an as-yet undetermined reason. b/13678928 // no-op for now. return msgBody; // final StringBuilder sb = new StringBuilder("