Browse Source

Removed webview / html advanced options

main
M66B 6 years ago
parent
commit
5ac769af01
6 changed files with 26 additions and 183 deletions
  1. +2
    -2
      app/src/main/java/eu/faircode/email/FragmentCompose.java
  2. +1
    -11
      app/src/main/java/eu/faircode/email/FragmentMessage.java
  3. +0
    -26
      app/src/main/java/eu/faircode/email/FragmentOptions.java
  4. +22
    -110
      app/src/main/java/eu/faircode/email/HtmlHelper.java
  5. +1
    -31
      app/src/main/res/layout/fragment_options.xml
  6. +0
    -3
      app/src/main/res/values/strings.xml

+ 2
- 2
app/src/main/java/eu/faircode/email/FragmentCompose.java View File

@ -825,13 +825,13 @@ public class FragmentCompose extends FragmentEx {
text.replaceAll("\\r?\\n", "<br />"),
Html.escapeHtml(new Date().toString()),
Html.escapeHtml(MessageHelper.getFormattedAddresses(draft.to, true)),
HtmlHelper.sanitize(context, ref.read(context), true));
HtmlHelper.sanitize(ref.read(context)));
} else if ("forward".equals(action)) {
draft.subject = context.getString(R.string.title_subject_forward, ref.subject);
body = String.format("<br><br>%s %s:<br><br>%s",
Html.escapeHtml(new Date().toString()),
Html.escapeHtml(MessageHelper.getFormattedAddresses(ref.from, true)),
HtmlHelper.sanitize(context, ref.read(context), true));
HtmlHelper.sanitize(ref.read(context)));
}
if (pro && !TextUtils.isEmpty(account.signature))


+ 1
- 11
app/src/main/java/eu/faircode/email/FragmentMessage.java View File

@ -246,16 +246,6 @@ public class FragmentMessage extends FragmentEx {
new Intent(ActivityView.ACTION_ACTIVATE_PRO)
.putExtra("uri", uri));
} else if (prefs.getBoolean("webview", false)) {
Bundle args = new Bundle();
args.putString("url", url);
FragmentWebView fragment = new FragmentWebView();
fragment.setArguments(args);
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.content_frame, fragment).addToBackStack("webview");
fragmentTransaction.commit();
} else {
// https://developer.chrome.com/multidevice/android/customtabs
CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder();
@ -1071,7 +1061,7 @@ public class FragmentMessage extends FragmentEx {
};
private static Spanned decodeHtml(final Context context, final long id, String body, final boolean show_images) {
return Html.fromHtml(HtmlHelper.sanitize(context, body, false), new Html.ImageGetter() {
return Html.fromHtml(HtmlHelper.sanitize(body), new Html.ImageGetter() {
@Override
public Drawable getDrawable(String source) {
float scale = context.getResources().getDisplayMetrics().density;


+ 0
- 26
app/src/main/java/eu/faircode/email/FragmentOptions.java View File

@ -22,22 +22,17 @@ package eu.faircode.email;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.text.method.LinkMovementMethod;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
public class FragmentOptions extends FragmentEx {
private CheckBox cbWebView;
private TextView tvCustomTabs;
private CheckBox cbSanitize;
private CheckBox cbCompressImap;
private CheckBox cbAvatars;
private CheckBox cbDebug;
@ -50,9 +45,6 @@ public class FragmentOptions extends FragmentEx {
View view = inflater.inflate(R.layout.fragment_options, container, false);
// Get controls
cbWebView = view.findViewById(R.id.cbWebView);
tvCustomTabs = view.findViewById(R.id.tvCustomTabs);
cbSanitize = view.findViewById(R.id.cbSanitize);
cbCompressImap = view.findViewById(R.id.cbCompressImap);
cbAvatars = view.findViewById(R.id.cbAvatars);
cbDebug = view.findViewById(R.id.cbDebug);
@ -61,22 +53,6 @@ public class FragmentOptions extends FragmentEx {
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext());
cbWebView.setChecked(prefs.getBoolean("webview", false));
cbWebView.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
prefs.edit().putBoolean("webview", checked).apply();
}
});
cbSanitize.setChecked(prefs.getBoolean("sanitize", false));
cbSanitize.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
prefs.edit().putBoolean("sanitize", checked).apply();
}
});
cbCompressImap.setChecked(prefs.getBoolean("compress", true));
cbCompressImap.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
@ -109,8 +85,6 @@ public class FragmentOptions extends FragmentEx {
}
});
tvCustomTabs.setMovementMethod(LinkMovementMethod.getInstance());
return view;
}
}

+ 22
- 110
app/src/main/java/eu/faircode/email/HtmlHelper.java View File

@ -19,14 +19,7 @@ package eu.faircode.email;
Copyright 2018 by Marcel Bokhorst (M66B)
*/
import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.text.Html;
import android.text.TextUtils;
import org.jsoup.Jsoup;
import org.jsoup.helper.StringUtil;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.nodes.Node;
@ -35,116 +28,35 @@ import org.jsoup.safety.Whitelist;
import org.jsoup.select.NodeTraversor;
import org.jsoup.select.NodeVisitor;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class HtmlHelper implements NodeVisitor {
private Context context;
private String newline;
private List<String> refs = new ArrayList<>();
private StringBuilder sb = new StringBuilder();
public class HtmlHelper {
private static Pattern pattern = Pattern.compile("([http|https]+://[\\w\\S(\\.|:|/)]+)");
private HtmlHelper(Context context, boolean reply) {
this.context = context;
this.newline = (reply ? "<br>> " : "<br>");
}
public void head(Node node, int depth) {
String name = node.nodeName();
if (node instanceof TextNode) {
String text = ((TextNode) node).text();
Matcher matcher = pattern.matcher(text);
while (matcher.find()) {
String ref = matcher.group();
if (!refs.contains(ref))
refs.add(ref);
String alt = context.getString(R.string.title_link);
text = text.replace(ref, String.format("<a href=\"%s\">%s [%d]</a>", ref, alt, refs.size()));
}
sb.append(text);
} else if (name.equals("li"))
sb.append(newline).append(" * ");
else if (name.equals("dt"))
sb.append(" ");
else if (StringUtil.in(name, "p", "h1", "h2", "h3", "h4", "h5", "tr", "div"))
sb.append(newline);
}
public void tail(Node node, int depth) {
String name = node.nodeName();
if (StringUtil.in(name, "br", "dd", "dt", "p", "h1", "h2", "h3", "h4", "h5", "div"))
sb.append(newline);
else if (name.equals("a")) {
String ref = node.absUrl("href");
if (!TextUtils.isEmpty(ref)) {
if (!refs.contains(ref))
refs.add(ref);
String alt = node.attr("alt");
if (TextUtils.isEmpty(alt))
alt = context.getString(R.string.title_link);
alt = Html.escapeHtml(alt);
sb.append(" ").append(String.format("<a href=\"%s\">%s [%d]</a>", ref, alt, refs.size()));
}
} else if (name.equals("img")) {
String ref = node.absUrl("src");
if (!TextUtils.isEmpty(ref)) {
if (!refs.contains(ref))
refs.add(ref);
String alt = node.attr("alt");
if (TextUtils.isEmpty(alt))
alt = context.getString(R.string.title_image);
alt = Html.escapeHtml(alt);
sb.append(" ").append(String.format("<a href=\"%s\">%s [%d]</a>", ref, alt, refs.size()));
sb.append("<img src=\"" + ref + "\" alt=\"" + alt + "\">");
}
}
}
@Override
public String toString() {
if (refs.size() > 0)
sb.append(newline).append(newline);
for (int i = 0; i < refs.size(); i++)
sb.append(String.format("[%d] %s ", i + 1, refs.get(i))).append(newline);
return sb.toString();
}
public static String sanitize(Context context, String html, boolean reply) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
if (prefs.getBoolean("sanitize", false)) {
Document document = Jsoup.parse(html);
HtmlHelper visitor = new HtmlHelper(context, reply);
NodeTraversor.traverse(visitor, document.body());
return visitor.toString();
} else {
Document document = Jsoup.parse(Jsoup.clean(html, Whitelist.relaxed()));
for (Element tr : document.select("tr"))
tr.after("<br>");
NodeTraversor.traverse(new NodeVisitor() {
@Override
public void head(Node node, int depth) {
if (node instanceof TextNode) {
String text = ((TextNode) node).text();
Matcher matcher = pattern.matcher(text);
while (matcher.find()) {
String ref = matcher.group();
text = text.replace(ref, String.format("<a href=\"%s\">%s</a>", ref, ref));
}
node.before(text);
((TextNode) node).text("");
public static String sanitize(String html) {
Document document = Jsoup.parse(Jsoup.clean(html, Whitelist.relaxed()));
for (Element tr : document.select("tr"))
tr.after("<br>");
NodeTraversor.traverse(new NodeVisitor() {
@Override
public void head(Node node, int depth) {
if (node instanceof TextNode) {
String text = ((TextNode) node).text();
Matcher matcher = pattern.matcher(text);
while (matcher.find()) {
String ref = matcher.group();
text = text.replace(ref, String.format("<a href=\"%s\">%s</a>", ref, ref));
}
node.before(text);
((TextNode) node).text("");
}
}
@Override
public void tail(Node node, int depth) {
}
}, document.body());
return document.body().html();
}
@Override
public void tail(Node node, int depth) {
}
}, document.body());
return document.body().html();
}
}

+ 1
- 31
app/src/main/res/layout/fragment_options.xml View File

@ -11,36 +11,6 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
<CheckBox
android:id="@+id/cbWebView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="12dp"
android:text="@string/title_advanced_webview"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tvCustomTabs"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="45dp"
android:text="@string/title_advanced_customtabs"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/cbWebView" />
<CheckBox
android:id="@+id/cbSanitize"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginTop="12dp"
android:text="@string/title_advanced_sanitize"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvCustomTabs" />
<CheckBox
android:id="@+id/cbCompressImap"
android:layout_width="wrap_content"
@ -49,7 +19,7 @@
android:layout_marginTop="12dp"
android:text="@string/title_advanced_compress_imap"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/cbSanitize" />
app:layout_constraintTop_toTopOf="parent" />
<CheckBox
android:id="@+id/cbAvatars"


+ 0
- 3
app/src/main/res/values/strings.xml View File

@ -72,9 +72,6 @@
<string name="title_setup_dark_theme">Dark theme</string>
<string name="title_advanced">Advanced options</string>
<string name="title_advanced_webview">Use WebView to show external links</string>
<string name="title_advanced_customtabs">Instead of <a href="https://developer.chrome.com/multidevice/android/customtabs">Chrome Custom Tabs</a></string>
<string name="title_advanced_sanitize">Remove HTML formatting from messages</string>
<string name="title_advanced_compress_imap">Compress IMAP data</string>
<string name="title_advanced_avatars">Show contact photos</string>
<string name="title_advanced_debug">Debug</string>


Loading…
Cancel
Save