summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorByteHamster <info@bytehamster.com>2022-10-14 22:25:10 +0200
committerByteHamster <info@bytehamster.com>2022-10-14 22:39:05 +0200
commit7d0b0e57eeee5d7d958ab6f85cd37fa7f85f66ec (patch)
tree9f44f763e9a155a7723c60dab4f8228ccaee19f6
parent504002c48f2760d4b62ef75b4806579358225e57 (diff)
downloadAntennaPod-7d0b0e57eeee5d7d958ab6f85cd37fa7f85f66ec.zip
Remove text colors from shownotes
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java7
-rw-r--r--app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java4
-rw-r--r--app/src/main/java/de/danoeh/antennapod/view/ShownotesWebView.java14
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/util/gui/ShownotesCleaner.java (renamed from core/src/main/java/de/danoeh/antennapod/core/util/playback/Timeline.java)34
-rw-r--r--core/src/test/java/de/danoeh/antennapod/core/util/gui/ShownotesCleanerTest.java (renamed from core/src/test/java/de/danoeh/antennapod/core/util/playback/TimelineTest.java)79
5 files changed, 76 insertions, 62 deletions
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java
index 518450f92..8a7d2432a 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/ItemDescriptionFragment.java
@@ -14,7 +14,7 @@ import androidx.fragment.app.Fragment;
import de.danoeh.antennapod.R;
import de.danoeh.antennapod.core.storage.DBReader;
import de.danoeh.antennapod.core.util.playback.PlaybackController;
-import de.danoeh.antennapod.core.util.playback.Timeline;
+import de.danoeh.antennapod.core.util.gui.ShownotesCleaner;
import de.danoeh.antennapod.model.feed.FeedMedia;
import de.danoeh.antennapod.model.playback.Playable;
import de.danoeh.antennapod.view.ShownotesWebView;
@@ -99,8 +99,9 @@ public class ItemDescriptionFragment extends Fragment {
}
DBReader.loadDescriptionOfFeedItem(feedMedia.getItem());
}
- Timeline timeline = new Timeline(getActivity(), media.getDescription(), media.getDuration());
- emitter.onSuccess(timeline.processShownotes());
+ ShownotesCleaner shownotesCleaner = new ShownotesCleaner(
+ getActivity(), media.getDescription(), media.getDuration());
+ emitter.onSuccess(shownotesCleaner.processShownotes());
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
diff --git a/app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java b/app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java
index 04aeef1c5..c80545bb2 100644
--- a/app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java
+++ b/app/src/main/java/de/danoeh/antennapod/fragment/ItemFragment.java
@@ -58,7 +58,7 @@ import de.danoeh.antennapod.core.util.FeedItemUtil;
import de.danoeh.antennapod.ui.common.CircularProgressBar;
import de.danoeh.antennapod.ui.common.ThemeUtils;
import de.danoeh.antennapod.core.util.playback.PlaybackController;
-import de.danoeh.antennapod.core.util.playback.Timeline;
+import de.danoeh.antennapod.core.util.gui.ShownotesCleaner;
import de.danoeh.antennapod.view.ShownotesWebView;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
@@ -438,7 +438,7 @@ public class ItemFragment extends Fragment {
if (feedItem != null && context != null) {
int duration = feedItem.getMedia() != null ? feedItem.getMedia().getDuration() : Integer.MAX_VALUE;
DBReader.loadDescriptionOfFeedItem(feedItem);
- Timeline t = new Timeline(context, feedItem.getDescription(), duration);
+ ShownotesCleaner t = new ShownotesCleaner(context, feedItem.getDescription(), duration);
webviewData = t.processShownotes();
}
return feedItem;
diff --git a/app/src/main/java/de/danoeh/antennapod/view/ShownotesWebView.java b/app/src/main/java/de/danoeh/antennapod/view/ShownotesWebView.java
index 3f4cc17ae..9dc4a76c6 100644
--- a/app/src/main/java/de/danoeh/antennapod/view/ShownotesWebView.java
+++ b/app/src/main/java/de/danoeh/antennapod/view/ShownotesWebView.java
@@ -30,7 +30,7 @@ import de.danoeh.antennapod.core.util.Converter;
import de.danoeh.antennapod.core.util.IntentUtils;
import de.danoeh.antennapod.core.util.NetworkUtils;
import de.danoeh.antennapod.core.util.ShareUtils;
-import de.danoeh.antennapod.core.util.playback.Timeline;
+import de.danoeh.antennapod.core.util.gui.ShownotesCleaner;
public class ShownotesWebView extends WebView implements View.OnLongClickListener {
private static final String TAG = "ShownotesWebView";
@@ -73,8 +73,8 @@ public class ShownotesWebView extends WebView implements View.OnLongClickListene
setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
- if (Timeline.isTimecodeLink(url) && timecodeSelectedListener != null) {
- timecodeSelectedListener.accept(Timeline.getTimecodeLinkTime(url));
+ if (ShownotesCleaner.isTimecodeLink(url) && timecodeSelectedListener != null) {
+ timecodeSelectedListener.accept(ShownotesCleaner.getTimecodeLinkTime(url));
} else {
IntentUtils.openInBrowser(getContext(), url);
}
@@ -137,8 +137,8 @@ public class ShownotesWebView extends WebView implements View.OnLongClickListene
ViewCompat.setElevation(s.getView(), 100);
s.show();
} else if (itemId == R.id.go_to_position_item) {
- if (Timeline.isTimecodeLink(selectedUrl) && timecodeSelectedListener != null) {
- timecodeSelectedListener.accept(Timeline.getTimecodeLinkTime(selectedUrl));
+ if (ShownotesCleaner.isTimecodeLink(selectedUrl) && timecodeSelectedListener != null) {
+ timecodeSelectedListener.accept(ShownotesCleaner.getTimecodeLinkTime(selectedUrl));
} else {
Log.e(TAG, "Selected go_to_position_item, but URL was no timecode link: " + selectedUrl);
}
@@ -157,9 +157,9 @@ public class ShownotesWebView extends WebView implements View.OnLongClickListene
return;
}
- if (Timeline.isTimecodeLink(selectedUrl)) {
+ if (ShownotesCleaner.isTimecodeLink(selectedUrl)) {
menu.add(Menu.NONE, R.id.go_to_position_item, Menu.NONE, R.string.go_to_position_label);
- menu.setHeaderTitle(Converter.getDurationStringLong(Timeline.getTimecodeLinkTime(selectedUrl)));
+ menu.setHeaderTitle(Converter.getDurationStringLong(ShownotesCleaner.getTimecodeLinkTime(selectedUrl)));
} else {
Uri uri = Uri.parse(selectedUrl);
final Intent intent = new Intent(Intent.ACTION_VIEW, uri);
diff --git a/core/src/main/java/de/danoeh/antennapod/core/util/playback/Timeline.java b/core/src/main/java/de/danoeh/antennapod/core/util/gui/ShownotesCleaner.java
index e125c7e66..dbb2815e2 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/util/playback/Timeline.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/util/gui/ShownotesCleaner.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.core.util.playback;
+package de.danoeh.antennapod.core.util.gui;
import android.content.Context;
import android.content.res.TypedArray;
@@ -26,27 +26,26 @@ import de.danoeh.antennapod.core.R;
import de.danoeh.antennapod.core.util.Converter;
/**
- * Connects chapter information and shownotes of a shownotesProvider, for example by making it possible to use the
- * shownotes to navigate to another position in the podcast or by highlighting certain parts of the shownotesProvider's
- * shownotes.
- * <p/>
- * A timeline object needs a shownotesProvider from which the chapter information
- * is retrieved and shownotes are generated.
+ * Cleans up and prepares shownotes:
+ * - Guesses time stamps to make them clickable
+ * - Removes some formatting
*/
-public class Timeline {
+public class ShownotesCleaner {
private static final String TAG = "Timeline";
private static final Pattern TIMECODE_LINK_REGEX = Pattern.compile("antennapod://timecode/(\\d+)");
private static final String TIMECODE_LINK = "<a class=\"timecode\" href=\"antennapod://timecode/%d\">%s</a>";
private static final Pattern TIMECODE_REGEX = Pattern.compile("\\b((\\d+):)?(\\d+):(\\d{2})\\b");
private static final Pattern LINE_BREAK_REGEX = Pattern.compile("<br */?>");
+ private static final String CSS_COLOR = "(?<=(\\s|;|^))color\\s*:([^;])*;";
+ private static final String CSS_COMMENT = "/\\*.*?\\*/";
private final String rawShownotes;
private final String noShownotesLabel;
private final int playableDuration;
private final String webviewStyle;
- public Timeline(Context context, @Nullable String rawShownotes, int playableDuration) {
+ public ShownotesCleaner(Context context, @Nullable String rawShownotes, int playableDuration) {
this.rawShownotes = rawShownotes;
noShownotesLabel = context.getString(R.string.no_shownotes_label);
@@ -98,9 +97,8 @@ public class Timeline {
}
Document document = Jsoup.parse(shownotes);
+ cleanCss(document);
document.head().appendElement("style").attr("type", "text/css").text(webviewStyle);
-
- // apply timecode links
addTimecodes(document);
return document.toString();
}
@@ -193,4 +191,18 @@ public class Timeline {
element.html(buffer.toString());
}
}
+
+ private void cleanCss(Document document) {
+ for (Element element : document.getAllElements()) {
+ if (element.hasAttr("style")) {
+ element.attr("style", element.attr("style").replaceAll(CSS_COLOR, ""));
+ } else if (element.tagName().equals("style")) {
+ element.html(cleanStyleTag(element.html()));
+ }
+ }
+ }
+
+ public static String cleanStyleTag(String oldCss) {
+ return oldCss.replaceAll(CSS_COMMENT, "").replaceAll(CSS_COLOR, "");
+ }
}
diff --git a/core/src/test/java/de/danoeh/antennapod/core/util/playback/TimelineTest.java b/core/src/test/java/de/danoeh/antennapod/core/util/gui/ShownotesCleanerTest.java
index 987a75981..527d0e0a3 100644
--- a/core/src/test/java/de/danoeh/antennapod/core/util/playback/TimelineTest.java
+++ b/core/src/test/java/de/danoeh/antennapod/core/util/gui/ShownotesCleanerTest.java
@@ -1,4 +1,4 @@
-package de.danoeh.antennapod.core.util.playback;
+package de.danoeh.antennapod.core.util.gui;
import android.content.Context;
@@ -7,14 +7,10 @@ import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
-import de.danoeh.antennapod.core.storage.DBReader;
-import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.mockito.MockedStatic;
-import org.mockito.Mockito;
import org.robolectric.RobolectricTestRunner;
import static org.junit.Assert.assertEquals;
@@ -23,25 +19,16 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
/**
- * Test class for {@link Timeline}.
+ * Test class for {@link ShownotesCleaner}.
*/
@RunWith(RobolectricTestRunner.class)
-public class TimelineTest {
+public class ShownotesCleanerTest {
private Context context;
- MockedStatic<DBReader> dbReaderMock;
@Before
public void setUp() {
context = InstrumentationRegistry.getInstrumentation().getTargetContext();
- // mock DBReader, because Timeline.processShownotes() calls FeedItem.loadShownotes()
- // which calls DBReader.loadDescriptionOfFeedItem(), but we don't need the database here
- dbReaderMock = Mockito.mockStatic(DBReader.class);
- }
-
- @After
- public void tearDown() {
- dbReaderMock.close();
}
@Test
@@ -50,7 +37,7 @@ public class TimelineTest {
final long time = 3600 * 1000 * 10 + 60 * 1000 * 11 + 12 * 1000;
String shownotes = "<p> Some test text with a timecode " + timeStr + " here.</p>";
- Timeline t = new Timeline(context, shownotes, Integer.MAX_VALUE);
+ ShownotesCleaner t = new ShownotesCleaner(context, shownotes, Integer.MAX_VALUE);
String res = t.processShownotes();
checkLinkCorrect(res, new long[]{time}, new String[]{timeStr});
}
@@ -61,7 +48,7 @@ public class TimelineTest {
final long time = 25 * 60 * 60 * 1000;
String shownotes = "<p> Some test text with a timecode " + timeStr + " here.</p>";
- Timeline t = new Timeline(context, shownotes, Integer.MAX_VALUE);
+ ShownotesCleaner t = new ShownotesCleaner(context, shownotes, Integer.MAX_VALUE);
String res = t.processShownotes();
checkLinkCorrect(res, new long[]{time}, new String[]{timeStr});
}
@@ -72,7 +59,7 @@ public class TimelineTest {
final long time = 3600 * 1000 * 10 + 60 * 1000 * 11;
String shownotes = "<p> Some test text with a timecode " + timeStr + " here.</p>";
- Timeline t = new Timeline(context, shownotes, Integer.MAX_VALUE);
+ ShownotesCleaner t = new ShownotesCleaner(context, shownotes, Integer.MAX_VALUE);
String res = t.processShownotes();
checkLinkCorrect(res, new long[]{time}, new String[]{timeStr});
}
@@ -83,7 +70,7 @@ public class TimelineTest {
final long time = 10 * 60 * 1000 + 11 * 1000;
String shownotes = "<p> Some test text with a timecode " + timeStr + " here.</p>";
- Timeline t = new Timeline(context, shownotes, 11 * 60 * 1000);
+ ShownotesCleaner t = new ShownotesCleaner(context, shownotes, 11 * 60 * 1000);
String res = t.processShownotes();
checkLinkCorrect(res, new long[]{time}, new String[]{timeStr});
}
@@ -94,7 +81,7 @@ public class TimelineTest {
final long time = 2 * 60 * 60 * 1000 + 11 * 60 * 1000 + 12 * 1000;
String shownotes = "<p> Some test text with a timecode " + timeStr + " here.</p>";
- Timeline t = new Timeline(context, shownotes, Integer.MAX_VALUE);
+ ShownotesCleaner t = new ShownotesCleaner(context, shownotes, Integer.MAX_VALUE);
String res = t.processShownotes();
checkLinkCorrect(res, new long[]{time}, new String[]{timeStr});
}
@@ -105,7 +92,7 @@ public class TimelineTest {
final long time = 60 * 1000 + 12 * 1000;
String shownotes = "<p> Some test text with a timecode " + timeStr + " here.</p>";
- Timeline t = new Timeline(context, shownotes, 2 * 60 * 1000);
+ ShownotesCleaner t = new ShownotesCleaner(context, shownotes, 2 * 60 * 1000);
String res = t.processShownotes();
checkLinkCorrect(res, new long[]{time}, new String[]{timeStr});
}
@@ -116,7 +103,7 @@ public class TimelineTest {
final int time = 2 * 60 * 60 * 1000 + 11 * 60 * 1000 + 12 * 1000;
String shownotes = "<p> Some test text with a timecode " + timeStr + " here.</p>";
- Timeline t = new Timeline(context, shownotes, time);
+ ShownotesCleaner t = new ShownotesCleaner(context, shownotes, time);
String res = t.processShownotes();
Document d = Jsoup.parse(res);
assertEquals("Should not parse time codes that equal duration", 0, d.body().getElementsByTag("a").size());
@@ -128,7 +115,7 @@ public class TimelineTest {
String shownotes = "<p> Some test text with a timecode " + timeStrings[0]
+ " here. Hey look another one " + timeStrings[1] + " here!</p>";
- Timeline t = new Timeline(context, shownotes, 2 * 60 * 60 * 1000);
+ ShownotesCleaner t = new ShownotesCleaner(context, shownotes, 2 * 60 * 60 * 1000);
String res = t.processShownotes();
checkLinkCorrect(res, new long[]{10 * 60 * 1000 + 12 * 1000,
60 * 60 * 1000 + 10 * 60 * 1000 + 12 * 1000}, timeStrings);
@@ -142,7 +129,7 @@ public class TimelineTest {
String shownotes = "<p> Some test text with a timecode " + timeStrings[0]
+ " here. Hey look another one " + timeStrings[1] + " here!</p>";
- Timeline t = new Timeline(context, shownotes, 3 * 60 * 60 * 1000);
+ ShownotesCleaner t = new ShownotesCleaner(context, shownotes, 3 * 60 * 60 * 1000);
String res = t.processShownotes();
checkLinkCorrect(res, new long[]{10 * 60 * 1000 + 12 * 1000, 2 * 60 * 1000 + 12 * 1000}, timeStrings);
}
@@ -153,7 +140,7 @@ public class TimelineTest {
final long time = 3600 * 1000 * 10 + 60 * 1000 * 11;
String shownotes = "<p> Some test text with a timecode (" + timeStr + ") here.</p>";
- Timeline t = new Timeline(context, shownotes, Integer.MAX_VALUE);
+ ShownotesCleaner t = new ShownotesCleaner(context, shownotes, Integer.MAX_VALUE);
String res = t.processShownotes();
checkLinkCorrect(res, new long[]{time}, new String[]{timeStr});
}
@@ -164,7 +151,7 @@ public class TimelineTest {
final long time = 3600 * 1000 * 10 + 60 * 1000 * 11;
String shownotes = "<p> Some test text with a timecode [" + timeStr + "] here.</p>";
- Timeline t = new Timeline(context, shownotes, Integer.MAX_VALUE);
+ ShownotesCleaner t = new ShownotesCleaner(context, shownotes, Integer.MAX_VALUE);
String res = t.processShownotes();
checkLinkCorrect(res, new long[]{time}, new String[]{timeStr});
}
@@ -175,7 +162,7 @@ public class TimelineTest {
final long time = 3600 * 1000 * 10 + 60 * 1000 * 11;
String shownotes = "<p> Some test text with a timecode <" + timeStr + "> here.</p>";
- Timeline t = new Timeline(context, shownotes, Integer.MAX_VALUE);
+ ShownotesCleaner t = new ShownotesCleaner(context, shownotes, Integer.MAX_VALUE);
String res = t.processShownotes();
checkLinkCorrect(res, new long[]{time}, new String[]{timeStr});
}
@@ -190,7 +177,7 @@ public class TimelineTest {
}
shownotes.append("here.</p>");
- Timeline t = new Timeline(context, shownotes.toString(), Integer.MAX_VALUE);
+ ShownotesCleaner t = new ShownotesCleaner(context, shownotes.toString(), Integer.MAX_VALUE);
String res = t.processShownotes();
checkLinkCorrect(res, new long[0], new String[0]);
}
@@ -216,20 +203,34 @@ public class TimelineTest {
@Test
public void testIsTimecodeLink() {
- assertFalse(Timeline.isTimecodeLink(null));
- assertFalse(Timeline.isTimecodeLink("http://antennapod/timecode/123123"));
- assertFalse(Timeline.isTimecodeLink("antennapod://timecode/"));
- assertFalse(Timeline.isTimecodeLink("antennapod://123123"));
- assertFalse(Timeline.isTimecodeLink("antennapod://timecode/123123a"));
- assertTrue(Timeline.isTimecodeLink("antennapod://timecode/123"));
- assertTrue(Timeline.isTimecodeLink("antennapod://timecode/1"));
+ assertFalse(ShownotesCleaner.isTimecodeLink(null));
+ assertFalse(ShownotesCleaner.isTimecodeLink("http://antennapod/timecode/123123"));
+ assertFalse(ShownotesCleaner.isTimecodeLink("antennapod://timecode/"));
+ assertFalse(ShownotesCleaner.isTimecodeLink("antennapod://123123"));
+ assertFalse(ShownotesCleaner.isTimecodeLink("antennapod://timecode/123123a"));
+ assertTrue(ShownotesCleaner.isTimecodeLink("antennapod://timecode/123"));
+ assertTrue(ShownotesCleaner.isTimecodeLink("antennapod://timecode/1"));
}
@Test
public void testGetTimecodeLinkTime() {
- assertEquals(-1, Timeline.getTimecodeLinkTime(null));
- assertEquals(-1, Timeline.getTimecodeLinkTime("http://timecode/123"));
- assertEquals(123, Timeline.getTimecodeLinkTime("antennapod://timecode/123"));
+ assertEquals(-1, ShownotesCleaner.getTimecodeLinkTime(null));
+ assertEquals(-1, ShownotesCleaner.getTimecodeLinkTime("http://timecode/123"));
+ assertEquals(123, ShownotesCleaner.getTimecodeLinkTime("antennapod://timecode/123"));
+ }
+ @Test
+ public void testCleanupColors() {
+ final String input = "/* /* */ .foo { text-decoration: underline;color:#f00;font-weight:bold;}"
+ + "#bar { text-decoration: underline;color:#f00;font-weight:bold; }"
+ + "div {text-decoration: underline; color /* */ : /* */ #f00 /* */; font-weight:bold; }"
+ + "#foobar { /* color: */ text-decoration: underline; /* color: */font-weight:bold /* ; */; }"
+ + "baz { background-color:#f00;border: solid 2px;border-color:#0f0;text-decoration: underline; }";
+ final String expected = " .foo { text-decoration: underline;font-weight:bold;}"
+ + "#bar { text-decoration: underline;font-weight:bold; }"
+ + "div {text-decoration: underline; font-weight:bold; }"
+ + "#foobar { text-decoration: underline; font-weight:bold ; }"
+ + "baz { background-color:#f00;border: solid 2px;border-color:#0f0;text-decoration: underline; }";
+ assertEquals(expected, ShownotesCleaner.cleanStyleTag(input));
}
}