1
0
mirror of https://github.com/moparisthebest/k-9 synced 2024-08-13 17:03:48 -04:00

Merge branch 'Issue_4019_pinch_zoom'

Conflicts:
	src/com/fsck/k9/view/MessageWebView.java
This commit is contained in:
cketti 2013-03-19 21:09:23 +01:00
commit 9ea46cf03b
8 changed files with 95 additions and 100 deletions

View File

@ -1126,7 +1126,7 @@ public class MessageCompose extends K9Activity implements OnClickListener {
mQuotedHtmlContent =
(InsertableHtmlContent) savedInstanceState.getSerializable(STATE_KEY_HTML_QUOTE);
if (mQuotedHtmlContent != null && mQuotedHtmlContent.getQuotedContent() != null) {
mQuotedHTML.setText(mQuotedHtmlContent.getQuotedContent(), "text/html");
mQuotedHTML.setText(mQuotedHtmlContent.getQuotedContent());
}
mDraftId = savedInstanceState.getLong(STATE_KEY_DRAFT_ID);
@ -2815,7 +2815,7 @@ public class MessageCompose extends K9Activity implements OnClickListener {
} else {
mQuotedHtmlContent.setFooterInsertionPoint(bodyOffset);
}
mQuotedHTML.setText(mQuotedHtmlContent.getQuotedContent(), "text/html");
mQuotedHTML.setText(mQuotedHtmlContent.getQuotedContent());
}
}
if (bodyPlainOffset != null && bodyPlainLength != null) {
@ -2999,7 +2999,7 @@ public class MessageCompose extends K9Activity implements OnClickListener {
mQuotedHtmlContent = quoteOriginalHtmlMessage(mSourceMessage, content, mQuoteStyle);
// Load the message with the reply header.
mQuotedHTML.setText(mQuotedHtmlContent.getQuotedContent(), "text/html");
mQuotedHTML.setText(mQuotedHtmlContent.getQuotedContent());
// TODO: Also strip the signature from the text/plain part
mQuotedText.setText(quoteOriginalTextMessage(mSourceMessage,
@ -3047,7 +3047,7 @@ public class MessageCompose extends K9Activity implements OnClickListener {
if (part != null) {
if (K9.DEBUG)
Log.d(K9.LOG_TAG, "getBodyTextFromMessage: HTML requested, text found.");
return HtmlConverter.textToHtml(MimeUtility.getTextFromPart(part), true);
return HtmlConverter.textToHtml(MimeUtility.getTextFromPart(part));
}
} else if (format == SimpleMessageFormat.TEXT) {
// Text takes precedence, then html.

View File

@ -126,40 +126,29 @@ public class HtmlConverter {
private static final int MAX_SMART_HTMLIFY_MESSAGE_LENGTH = 1024 * 256 ;
public static final String getHtmlHeader() {
return "<html><head/><body>";
}
public static final String getHtmlFooter() {
return "</body></html>";
}
/**
* Naively convert a text string into an HTML document.
*
* <p>
* This method avoids using regular expressions on the entire message body to save memory.
* </p>
* <p>
* No HTML headers or footers are added to the result. Headers and footers
* are added at display time in
* {@link com.fsck.k9.view#MessageWebView.setText(String) MessageWebView.setText()}
* </p>
*
* @param text
* Plain text string.
* @param useHtmlTag
* If {@code true} this method adds headers and footers to create a proper HTML
* document.
*
* @return HTML string.
*/
private static String simpleTextToHtml(String text, boolean useHtmlTag) {
private static String simpleTextToHtml(String text) {
// Encode HTML entities to make sure we don't display something evil.
text = TextUtils.htmlEncode(text);
StringReader reader = new StringReader(text);
StringBuilder buff = new StringBuilder(text.length() + TEXT_TO_HTML_EXTRA_BUFFER_LENGTH);
if (useHtmlTag) {
buff.append(getHtmlHeader());
}
buff.append(htmlifyMessageHeader());
int c;
@ -184,10 +173,6 @@ public class HtmlConverter {
buff.append(htmlifyMessageFooter());
if (useHtmlTag) {
buff.append(getHtmlFooter());
}
return buff.toString();
}
@ -201,26 +186,28 @@ public class HtmlConverter {
* Convert a text string into an HTML document.
*
* <p>
* Attempts to do smart replacement for large documents to prevent OOM errors. This method
* optionally adds headers and footers to create a proper HTML document. To convert to a
* fragment, use {@link #textToHtmlFragment(String)}.
* Attempts to do smart replacement for large documents to prevent OOM
* errors.
* <p>
* No HTML headers or footers are added to the result. Headers and footers
* are added at display time in
* {@link com.fsck.k9.view#MessageWebView.setText(String) MessageWebView.setText()}
* </p>
* <p>
* To convert to a fragment, use {@link #textToHtmlFragment(String)} .
* </p>
*
* @param text
* Plain text string.
* @param useHtmlTag
* If {@code true} this method adds headers and footers to create a proper HTML
* document.
*
* @return HTML string.
*/
public static String textToHtml(String text, boolean useHtmlTag) {
public static String textToHtml(String text) {
// Our HTMLification code is somewhat memory intensive
// and was causing lots of OOM errors on the market
// if the message is big and plain text, just do
// a trivial htmlification
if (text.length() > MAX_SMART_HTMLIFY_MESSAGE_LENGTH) {
return simpleTextToHtml(text, useHtmlTag);
return simpleTextToHtml(text);
}
StringReader reader = new StringReader(text);
StringBuilder buff = new StringBuilder(text.length() + TEXT_TO_HTML_EXTRA_BUFFER_LENGTH);
@ -312,18 +299,10 @@ public class HtmlConverter {
StringBuffer sb = new StringBuffer(text.length() + TEXT_TO_HTML_EXTRA_BUFFER_LENGTH);
if (useHtmlTag) {
sb.append(getHtmlHeader());
}
sb.append(htmlifyMessageHeader());
linkifyText(text, sb);
sb.append(htmlifyMessageFooter());
if (useHtmlTag) {
sb.append(getHtmlFooter());
}
text = sb.toString();
// Above we replaced > with <gt>, now make it &gt;
@ -338,6 +317,7 @@ public class HtmlConverter {
protected static final String QUOTE_COLOR_LEVEL_3 = "#8ae234";
protected static final String QUOTE_COLOR_LEVEL_4 = "#fcaf3e";
protected static final String QUOTE_COLOR_LEVEL_5 = "#e9b96e";
private static final String K9MAIL_CSS_CLASS = "k9mail";
/**
* Return an HTML hex color string for a given quote level.
@ -1251,16 +1231,34 @@ public class HtmlConverter {
}
private static String htmlifyMessageHeader() {
final String font = K9.messageViewFixedWidthFont()
? "monospace"
: "sans-serif";
return "<pre style=\"white-space: pre-wrap; word-wrap:break-word; font-family: " + font + "; margin-top: 0px\">";
return "<pre class=\"" + K9MAIL_CSS_CLASS + "\">";
}
private static String htmlifyMessageFooter() {
return "</pre>";
}
/**
* Dynamically generate a CSS style for {@code <pre>} elements.
*
* <p>
* The style incorporates the user's current preference
* setting for the font family used for plain text messages.
* </p>
*
* @return
* A {@code <style>} element that can be dynamically included in the HTML
* {@code <head>} element when messages are displayed.
*/
public static String cssStylePre() {
final String font = K9.messageViewFixedWidthFont()
? "monospace"
: "sans-serif";
return "<style type=\"text/css\"> pre." + K9MAIL_CSS_CLASS +
" {white-space: pre-wrap; word-wrap:break-word; " +
"font-family: " + font + "; margin-top: 0px}</style>";
}
/**
* Convert a plain text string into an HTML fragment.
* @param text Plain text.

View File

@ -1389,7 +1389,6 @@ public class MimeUtility {
StringBuilder text = new StringBuilder();
StringBuilder html = new StringBuilder();
html.append(HtmlConverter.getHtmlHeader());
for (Viewable viewable : viewables) {
if (viewable instanceof Textual) {
@ -1441,8 +1440,6 @@ public class MimeUtility {
}
}
html.append(HtmlConverter.getHtmlFooter());
return new ViewableContainer(text.toString(), html.toString(), attachments);
} catch (Exception e) {
throw new MessagingException("Couldn't extract viewable parts", e);
@ -1936,7 +1933,7 @@ public class MimeUtility {
* Use the contents of a {@link Viewable} to create the HTML to be displayed.
*
* <p>
* This will use {@link HtmlConverter#textToHtml(String, boolean)} to convert plain text parts
* This will use {@link HtmlConverter#textToHtml(String)} to convert plain text parts
* to HTML if necessary.
* </p>
*
@ -1959,7 +1956,7 @@ public class MimeUtility {
if (t == null) {
t = "";
} else if (viewable instanceof Text) {
t = HtmlConverter.textToHtml(t, false);
t = HtmlConverter.textToHtml(t);
}
html.append(t);
} else if (viewable instanceof Alternative) {
@ -3379,7 +3376,7 @@ public class MimeUtility {
String bodyText = getTextFromPart(part);
if (bodyText != null) {
text = fixDraftTextBody(bodyText);
html = HtmlConverter.textToHtml(text, false);
html = HtmlConverter.textToHtml(text);
}
} else if (part.isMimeType("multipart/alternative") &&
firstBody instanceof MimeMultipart) {

View File

@ -68,10 +68,8 @@ public class AccessibleWebView extends TextView {
return mDummyWebView.getSettings();
}
public void loadDataWithBaseURL(String baseUrl, String data, String mimeType, String encoding,
String historyUrl) {
mHtmlSource = data;
this.setText(Html.fromHtml(mHtmlSource, null, null));
public void setText(String text) {
this.setText(Html.fromHtml(text, null, null));
// Let everyone know that loading has finished.
if (mListeners != null) {

View File

@ -11,6 +11,8 @@ import android.webkit.WebSettings;
import android.widget.Toast;
import com.fsck.k9.K9;
import com.fsck.k9.R;
import com.fsck.k9.helper.HtmlConverter;
import java.lang.reflect.Method;
import com.nobu_games.android.view.web.TitleBarWebView;
@ -109,6 +111,7 @@ public class MessageWebView extends TitleBarWebView {
webSettings.setSupportZoom(true);
webSettings.setBuiltInZoomControls(true);
webSettings.setUseWideViewPort(true);
disableDisplayZoomControls();
@ -153,17 +156,29 @@ public class MessageWebView extends TitleBarWebView {
}
}
public void setText(String text, String contentType) {
String content = text;
/**
* Load a message body into a {@code MessageWebView}
*
* <p>
* Before loading, the text is wrapped in an HTML header and footer
* so that it displays properly.
* </p>
*
* @param text
* The message body to display. Assumed to be MIME type text/html.
*/
public void setText(String text) {
// Include a meta tag so the WebView will not use a fixed viewport width of 980 px
String content = "<html><head><meta name=\"viewport\" content=\"width=device-width\"/>";
if (K9.getK9MessageViewTheme() == K9.Theme.DARK) {
// It's a little wrong to just throw in the <style> before the opening <html>
// but it's less wrong than trying to edit the html stream
content = "<style>* { background: black ! important; color: white !important }" +
content += "<style type=\"text/css\">" +
"* { background: black ! important; color: white !important }" +
":link, :link * { color: #CCFF33 !important }" +
":visited, :visited * { color: #551A8B !important }</style> "
+ content;
":visited, :visited * { color: #551A8B !important }</style> ";
}
loadDataWithBaseURL("http://", content, contentType, "utf-8", null);
content += HtmlConverter.cssStylePre();
content += "</head><body>" + text + "</body></html>";
loadDataWithBaseURL("http://", content, "text/html", "utf-8", null);
mOverrideScrollCounter = 0;
}

View File

@ -405,7 +405,7 @@ public class SingleMessageView extends LinearLayout implements OnClickListener,
// Allow network access first...
setLoadPictures(true);
// ...then re-populate the WebView with the message text
loadBodyFromText(mText, "text/html");
loadBodyFromText(mText);
break;
}
}
@ -556,7 +556,7 @@ public class SingleMessageView extends LinearLayout implements OnClickListener,
if (pgpData != null) {
text = pgpData.getDecryptedData();
if (text != null) {
text = HtmlConverter.textToHtml(text, true);
text = HtmlConverter.textToHtml(text);
}
}
@ -616,7 +616,7 @@ public class SingleMessageView extends LinearLayout implements OnClickListener,
}
if (text != null) {
loadBodyFromText(text, "text/html");
loadBodyFromText(text);
updateCryptoLayout(account.getCryptoProvider(), pgpData, message);
} else {
showStatusMessage(getContext().getString(R.string.webview_empty_message));
@ -627,15 +627,15 @@ public class SingleMessageView extends LinearLayout implements OnClickListener,
String text = "<html><body><div style=\"text-align:center; color: grey;\">" +
status +
"</div></body></html>";
loadBodyFromText(text, "text/html");
loadBodyFromText(text);
mCryptoView.hide();
}
private void loadBodyFromText(String emailText, String contentType) {
private void loadBodyFromText(String emailText) {
if (mScreenReaderEnabled) {
mAccessibleMessageContentView.loadDataWithBaseURL("http://", emailText, contentType, "utf-8", null);
mAccessibleMessageContentView.setText(emailText);
} else {
mMessageContentView.setText(emailText, contentType);
mMessageContentView.setText(emailText);
}
}
@ -739,7 +739,7 @@ public class SingleMessageView extends LinearLayout implements OnClickListener,
* its size because the button to download the complete message was previously shown and
* is now hidden.
*/
loadBodyFromText("", "text/plain");
loadBodyFromText("");
}
public void resetHeaderView() {

View File

@ -23,9 +23,9 @@ public class HtmlConverterTest extends TestCase {
"\n" +
"Nice job :)\n" +
">> Guess!";
String result = HtmlConverter.textToHtml(message, false);
String result = HtmlConverter.textToHtml(message);
writeToFile(result);
assertEquals("<pre style=\"white-space: pre-wrap; word-wrap:break-word; font-family: sans-serif; margin-top: 0px\">Panama!<br /><br />Bob Barker &lt;bob@aol.com&gt; wrote:<br /><blockquote class=\"gmail_quote\" style=\"margin: 0pt 0pt 1ex 0.8ex; border-left: 1px solid #729fcf; padding-left: 1ex;\">a canal<br /><br />Dorothy Jo Gideon &lt;dorothy@aol.com&gt; espoused:<br /><blockquote class=\"gmail_quote\" style=\"margin: 0pt 0pt 1ex 0.8ex; border-left: 1px solid #ad7fa8; padding-left: 1ex;\">A man, a plan...<br /></blockquote>Too easy!</blockquote><br />Nice job :)<br /><blockquote class=\"gmail_quote\" style=\"margin: 0pt 0pt 1ex 0.8ex; border-left: 1px solid #729fcf; padding-left: 1ex;\"><blockquote class=\"gmail_quote\" style=\"margin: 0pt 0pt 1ex 0.8ex; border-left: 1px solid #ad7fa8; padding-left: 1ex;\">Guess!</blockquote></blockquote></pre>", result);
assertEquals("<pre class=\"k9mail\">Panama!<br /><br />Bob Barker &lt;bob@aol.com&gt; wrote:<br /><blockquote class=\"gmail_quote\" style=\"margin: 0pt 0pt 1ex 0.8ex; border-left: 1px solid #729fcf; padding-left: 1ex;\">a canal<br /><br />Dorothy Jo Gideon &lt;dorothy@aol.com&gt; espoused:<br /><blockquote class=\"gmail_quote\" style=\"margin: 0pt 0pt 1ex 0.8ex; border-left: 1px solid #ad7fa8; padding-left: 1ex;\">A man, a plan...<br /></blockquote>Too easy!</blockquote><br />Nice job :)<br /><blockquote class=\"gmail_quote\" style=\"margin: 0pt 0pt 1ex 0.8ex; border-left: 1px solid #729fcf; padding-left: 1ex;\"><blockquote class=\"gmail_quote\" style=\"margin: 0pt 0pt 1ex 0.8ex; border-left: 1px solid #ad7fa8; padding-left: 1ex;\">Guess!</blockquote></blockquote></pre>", result);
}
public void testTextQuoteToHtmlBlockquoteIndented() {
@ -37,9 +37,9 @@ public class HtmlConverterTest extends TestCase {
"> LOL F1RST!!!!!\n" +
">\n" +
"> :)";
String result = HtmlConverter.textToHtml(message, false);
String result = HtmlConverter.textToHtml(message);
writeToFile(result);
assertEquals("<pre style=\"white-space: pre-wrap; word-wrap:break-word; font-family: sans-serif; margin-top: 0px\">*facepalm*<br /><br />Bob Barker &lt;bob@aol.com&gt; wrote:<br /><blockquote class=\"gmail_quote\" style=\"margin: 0pt 0pt 1ex 0.8ex; border-left: 1px solid #729fcf; padding-left: 1ex;\">A wise man once said...<br /><br />LOL F1RST!!!!!<br /><br />:)</blockquote></pre>", result);
assertEquals("<pre class=\"k9mail\">*facepalm*<br /><br />Bob Barker &lt;bob@aol.com&gt; wrote:<br /><blockquote class=\"gmail_quote\" style=\"margin: 0pt 0pt 1ex 0.8ex; border-left: 1px solid #729fcf; padding-left: 1ex;\">A wise man once said...<br /><br />LOL F1RST!!!!!<br /><br />:)</blockquote></pre>", result);
}
public void testQuoteDepthColor() {
@ -60,9 +60,9 @@ public class HtmlConverterTest extends TestCase {
">>>> four\n" +
">>>>> five\n" +
">>>>>> six";
String result = HtmlConverter.textToHtml(message, false);
String result = HtmlConverter.textToHtml(message);
writeToFile(result);
assertEquals("<pre style=\"white-space: pre-wrap; word-wrap:break-word; font-family: sans-serif; margin-top: 0px\">zero<br /><blockquote class=\"gmail_quote\" style=\"margin: 0pt 0pt 1ex 0.8ex; border-left: 1px solid #729fcf; padding-left: 1ex;\">one<br /><blockquote class=\"gmail_quote\" style=\"margin: 0pt 0pt 1ex 0.8ex; border-left: 1px solid #ad7fa8; padding-left: 1ex;\">two<br /><blockquote class=\"gmail_quote\" style=\"margin: 0pt 0pt 1ex 0.8ex; border-left: 1px solid #8ae234; padding-left: 1ex;\">three<br /><blockquote class=\"gmail_quote\" style=\"margin: 0pt 0pt 1ex 0.8ex; border-left: 1px solid #fcaf3e; padding-left: 1ex;\">four<br /><blockquote class=\"gmail_quote\" style=\"margin: 0pt 0pt 1ex 0.8ex; border-left: 1px solid #e9b96e; padding-left: 1ex;\">five<br /><blockquote class=\"gmail_quote\" style=\"margin: 0pt 0pt 1ex 0.8ex; border-left: 1px solid #ccc; padding-left: 1ex;\">six</blockquote></blockquote></blockquote></blockquote></blockquote></blockquote></pre>", result);
assertEquals("<pre class=\"k9mail\">zero<br /><blockquote class=\"gmail_quote\" style=\"margin: 0pt 0pt 1ex 0.8ex; border-left: 1px solid #729fcf; padding-left: 1ex;\">one<br /><blockquote class=\"gmail_quote\" style=\"margin: 0pt 0pt 1ex 0.8ex; border-left: 1px solid #ad7fa8; padding-left: 1ex;\">two<br /><blockquote class=\"gmail_quote\" style=\"margin: 0pt 0pt 1ex 0.8ex; border-left: 1px solid #8ae234; padding-left: 1ex;\">three<br /><blockquote class=\"gmail_quote\" style=\"margin: 0pt 0pt 1ex 0.8ex; border-left: 1px solid #fcaf3e; padding-left: 1ex;\">four<br /><blockquote class=\"gmail_quote\" style=\"margin: 0pt 0pt 1ex 0.8ex; border-left: 1px solid #e9b96e; padding-left: 1ex;\">five<br /><blockquote class=\"gmail_quote\" style=\"margin: 0pt 0pt 1ex 0.8ex; border-left: 1px solid #ccc; padding-left: 1ex;\">six</blockquote></blockquote></blockquote></blockquote></blockquote></blockquote></pre>", result);
}
private void writeToFile(final String content) {

View File

@ -29,12 +29,9 @@ public class ViewablesTest extends AndroidTestCase {
String expectedText = bodyText;
String expectedHtml =
"<html><head/><body>" +
"<pre style=\"white-space: pre-wrap; word-wrap:break-word; " +
"font-family: sans-serif; margin-top: 0px\">" +
"<pre class=\"k9mail\">" +
"K-9 Mail rocks :&gt;" +
"</pre>" +
"</body></html>";
"</pre>";
assertEquals(expectedText, container.text);
assertEquals(expectedHtml, container.html);
@ -56,9 +53,7 @@ public class ViewablesTest extends AndroidTestCase {
String expectedText = "K-9 Mail rocks :>";
String expectedHtml =
"<html><head/><body>" +
bodyText +
"</body></html>";
bodyText;
assertEquals(expectedText, container.text);
assertEquals(expectedHtml, container.html);
@ -91,18 +86,14 @@ public class ViewablesTest extends AndroidTestCase {
"------------------------------------------------------------------------\n\n" +
bodyText2;
String expectedHtml =
"<html><head/><body>" +
"<pre style=\"white-space: pre-wrap; word-wrap:break-word; " +
"font-family: sans-serif; margin-top: 0px\">" +
"<pre class=\"k9mail\">" +
bodyText1 +
"</pre>" +
"<p style=\"margin-top: 2.5em; margin-bottom: 1em; " +
"border-bottom: 1px solid #000\"></p>" +
"<pre style=\"white-space: pre-wrap; word-wrap:break-word; " +
"font-family: sans-serif; margin-top: 0px\">" +
"<pre class=\"k9mail\">" +
bodyText2 +
"</pre>" +
"</body></html>";
"</pre>";
assertEquals(expectedText, container.text);
@ -158,9 +149,7 @@ public class ViewablesTest extends AndroidTestCase {
"\n" +
innerBodyText;
String expectedHtml =
"<html><head/><body>" +
"<pre style=\"white-space: pre-wrap; word-wrap:break-word; " +
"font-family: sans-serif; margin-top: 0px\">" +
"<pre class=\"k9mail\">" +
bodyText +
"</pre>" +
"<p style=\"margin-top: 2.5em; margin-bottom: 1em; border-bottom: " +
@ -180,11 +169,9 @@ public class ViewablesTest extends AndroidTestCase {
"<td>Subject</td>" +
"</tr>" +
"</table>" +
"<pre style=\"white-space: pre-wrap; word-wrap:break-word; " +
"font-family: sans-serif; margin-top: 0px\">" +
"<pre class=\"k9mail\">" +
innerBodyText +
"</pre>" +
"</body></html>";
"</pre>";
assertEquals(expectedText, container.text);
assertEquals(expectedHtml, container.html);