Convert 'HtmlConverter' to Kotlin

This commit is contained in:
cketti 2019-05-22 03:06:48 +02:00
parent e7b6d6b5d3
commit eddd6827a4

View file

@ -1,152 +1,147 @@
package com.fsck.k9.message.html; package com.fsck.k9.message.html
import android.text.Editable; import android.text.Editable
import android.text.Html; import android.text.Html
import android.text.Html.TagHandler; import android.text.Html.TagHandler
import android.text.Spanned; import android.text.Spanned
import com.fsck.k9.K9; import com.fsck.k9.K9
import org.jsoup.Jsoup; import org.jsoup.Jsoup
import org.jsoup.nodes.Document; import org.xml.sax.XMLReader
import org.xml.sax.XMLReader;
/** /**
* Contains common routines to convert html to text and vice versa. * Contains common routines to convert html to text and vice versa.
*/ */
public class HtmlConverter { object HtmlConverter {
/** /**
* When generating previews, Spannable objects that can't be converted into a String are * When generating previews, Spannable objects that can't be converted into a String are
* represented as 0xfffc. When displayed, these show up as undisplayed squares. These constants * represented as 0xfffc. When displayed, these show up as undisplayed squares. These constants
* define the object character and the replacement character. * define the object character and the replacement character.
*/ */
private static final char PREVIEW_OBJECT_CHARACTER = (char)0xfffc; private const val PREVIEW_OBJECT_CHARACTER = 0xfffc.toChar()
private static final char PREVIEW_OBJECT_REPLACEMENT = (char)0x20; // space private const val PREVIEW_OBJECT_REPLACEMENT = 0x20.toChar() // space
/** /**
* toHtml() converts non-breaking spaces into the UTF-8 non-breaking space, which doesn't get * toHtml() converts non-breaking spaces into the UTF-8 non-breaking space, which doesn't get
* rendered properly in some clients. Replace it with a simple space. * rendered properly in some clients. Replace it with a simple space.
*/ */
private static final char NBSP_CHARACTER = (char)0x00a0; // utf-8 non-breaking space private const val NBSP_CHARACTER = 0x00a0.toChar() // utf-8 non-breaking space
private static final char NBSP_REPLACEMENT = (char)0x20; // space private const val NBSP_REPLACEMENT = 0x20.toChar() // space
/** /**
* Convert an HTML string to a plain text string. * Convert an HTML string to a plain text string.
* @param html HTML string to convert.
* @return Plain text result.
*/ */
public static String htmlToText(final String html) { @JvmStatic
Document document = Jsoup.parse(html); fun htmlToText(html: String): String {
val document = Jsoup.parse(html)
return HtmlToPlainText.toPlainText(document.body()) return HtmlToPlainText.toPlainText(document.body())
.replace(PREVIEW_OBJECT_CHARACTER, PREVIEW_OBJECT_REPLACEMENT) .replace(PREVIEW_OBJECT_CHARACTER, PREVIEW_OBJECT_REPLACEMENT)
.replace(NBSP_CHARACTER, NBSP_REPLACEMENT); .replace(NBSP_CHARACTER, NBSP_REPLACEMENT)
} }
/** /**
* Convert a text string into an HTML document. * Convert a text string into an HTML document.
* *
* <p> * No HTML headers or footers are added to the result. Headers and footers are added at display time.
* No HTML headers or footers are added to the result. Headers and footers
* are added at display time.
* </p>
*/ */
public static String textToHtml(String text) { @JvmStatic
return EmailTextToHtml.convert(text); fun textToHtml(text: String): String {
return EmailTextToHtml.convert(text)
} }
public static String wrapStatusMessage(CharSequence status) { @JvmStatic
return wrapMessageContent("<div style=\"text-align:center; color: grey;\">" + status + "</div>"); fun wrapStatusMessage(status: CharSequence): String {
return wrapMessageContent("<div style=\"text-align:center; color: grey;\">$status</div>")
} }
public static String wrapMessageContent(CharSequence messageContent) { @JvmStatic
fun wrapMessageContent(messageContent: CharSequence): String {
// Include a meta tag so the WebView will not use a fixed viewport width of 980 px // Include a meta tag so the WebView will not use a fixed viewport width of 980 px
return "<html dir=\"auto\"><head><meta name=\"viewport\" content=\"width=device-width\"/>" + return "<html dir=\"auto\"><head><meta name=\"viewport\" content=\"width=device-width\"/>" +
HtmlConverter.cssStyleTheme() + cssStyleTheme() +
HtmlConverter.cssStylePre() + cssStylePre() +
"</head><body>" + "</head><body>" +
messageContent + messageContent +
"</body></html>"; "</body></html>"
} }
static String cssStyleTheme() { @JvmStatic
if (K9.getK9MessageViewTheme() == K9.Theme.DARK) { fun cssStyleTheme(): String {
return "<style type=\"text/css\">" + return if (K9.k9MessageViewTheme === K9.Theme.DARK) {
"<style type=\"text/css\">" +
"* { background: black ! important; color: #F3F3F3 !important }" + "* { background: black ! important; color: #F3F3F3 !important }" +
":link, :link * { color: #CCFF33 !important }" + ":link, :link * { color: #CCFF33 !important }" +
":visited, :visited * { color: #551A8B !important }</style> "; ":visited, :visited * { color: #551A8B !important }</style> "
} else { } else {
return ""; ""
} }
} }
/** /**
* Dynamically generate a CSS style for {@code <pre>} elements. * Dynamically generate a CSS style for `<pre>` elements.
* *
* <p> * The style incorporates the user's current preference setting for the font family used for plain text messages.
* The style incorporates the user's current preference
* setting for the font family used for plain text messages.
* </p>
* *
* @return * @return A `<style>` element that can be dynamically included in the HTML `<head>` element when messages are
* A {@code <style>} element that can be dynamically included in the HTML * displayed.
* {@code <head>} element when messages are displayed.
*/ */
static String cssStylePre() { @JvmStatic
final String font = K9.isUseMessageViewFixedWidthFont() fun cssStylePre(): String {
? "monospace" val font = if (K9.isUseMessageViewFixedWidthFont) "monospace" else "sans-serif"
: "sans-serif";
return "<style type=\"text/css\"> pre." + EmailTextToHtml.K9MAIL_CSS_CLASS + return "<style type=\"text/css\"> pre." + EmailTextToHtml.K9MAIL_CSS_CLASS +
" {white-space: pre-wrap; word-wrap:break-word; " + " {white-space: pre-wrap; word-wrap:break-word; " +
"font-family: " + font + "; margin-top: 0px}</style>"; "font-family: " + font + "; margin-top: 0px}</style>"
} }
/** /**
* Convert a plain text string into an HTML fragment. * Convert a plain text string into an HTML fragment.
*/ */
public static String textToHtmlFragment(String text) { @JvmStatic
return TextToHtml.toHtmlFragment(text); fun textToHtmlFragment(text: String): String {
return TextToHtml.toHtmlFragment(text)
} }
/** /**
* Convert HTML to a {@link Spanned} that can be used in a {@link android.widget.TextView}. * Convert HTML to a [Spanned] that can be used in a [android.widget.TextView].
* *
* @param html * @param html The HTML fragment to be converted.
* The HTML fragment to be converted.
* *
* @return A {@link Spanned} containing the text in {@code html} formatted using spans. * @return A [Spanned] containing the text in `html` formatted using spans.
*/ */
public static Spanned htmlToSpanned(String html) { @JvmStatic
return Html.fromHtml(html, null, new ListTagHandler()); fun htmlToSpanned(html: String): Spanned {
return Html.fromHtml(html, null, ListTagHandler())
} }
/** /**
* {@link TagHandler} that supports unordered lists. * [TagHandler] that supports unordered lists.
* *
* @see HtmlConverter#htmlToSpanned(String) * @see HtmlConverter.htmlToSpanned
*/ */
public static class ListTagHandler implements TagHandler { private class ListTagHandler : TagHandler {
@Override override fun handleTag(opening: Boolean, tag: String, output: Editable, xmlReader: XMLReader) {
public void handleTag(boolean opening, String tag, Editable output, XMLReader xmlReader) { if (tag == "ul") {
if (tag.equals("ul")) {
if (opening) { if (opening) {
char lastChar = 0; var lastChar: Char = 0.toChar()
if (output.length() > 0) { if (output.length > 0) {
lastChar = output.charAt(output.length() - 1); lastChar = output[output.length - 1]
} }
if (lastChar != '\n') { if (lastChar != '\n') {
output.append("\r\n"); output.append("\r\n")
} }
} else { } else {
output.append("\r\n"); output.append("\r\n")
} }
} }
if (tag.equals("li")) { if (tag == "li") {
if (opening) { if (opening) {
output.append("\t"); output.append("\t")
} else { } else {
output.append("\r\n"); output.append("\r\n")
} }
} }
} }