diff --git a/Clover/app/src/main/java/org/floens/chan/core/di/AppModule.java b/Clover/app/src/main/java/org/floens/chan/core/di/AppModule.java
index 5a63546a..4e253ae2 100644
--- a/Clover/app/src/main/java/org/floens/chan/core/di/AppModule.java
+++ b/Clover/app/src/main/java/org/floens/chan/core/di/AppModule.java
@@ -7,7 +7,6 @@ import com.android.volley.toolbox.ImageLoader;
import org.floens.chan.ChanApplication;
import org.floens.chan.chan.ChanLoader;
-import org.floens.chan.chan.ChanParser;
import org.floens.chan.core.cache.FileCache;
import org.floens.chan.core.database.DatabaseManager;
import org.floens.chan.core.manager.BoardManager;
@@ -57,7 +56,6 @@ import dagger.Provides;
injects = {
// Context.class, // ApplicationContext
- ChanParser.class,
BoardManager.class,
DatabaseManager.class,
ReplyManager.class,
diff --git a/Clover/app/src/main/java/org/floens/chan/core/presenter/SiteSetupPresenter.java b/Clover/app/src/main/java/org/floens/chan/core/presenter/SiteSetupPresenter.java
index 54f35194..5f46cdf7 100644
--- a/Clover/app/src/main/java/org/floens/chan/core/presenter/SiteSetupPresenter.java
+++ b/Clover/app/src/main/java/org/floens/chan/core/presenter/SiteSetupPresenter.java
@@ -21,6 +21,10 @@ public class SiteSetupPresenter {
}
public void show() {
+ setBoardCount(callback, site);
+ }
+
+ private void setBoardCount(Callback callback, Site site) {
callback.setBoardCount(
databaseManager.runTaskSync(
databaseManager.getDatabaseBoardManager().getSiteSavedBoards(site)
diff --git a/Clover/app/src/main/java/org/floens/chan/core/site/common/ChanParser.java b/Clover/app/src/main/java/org/floens/chan/core/site/common/ChanParser.java
new file mode 100644
index 00000000..8b4f8f3f
--- /dev/null
+++ b/Clover/app/src/main/java/org/floens/chan/core/site/common/ChanParser.java
@@ -0,0 +1,25 @@
+/*
+ * Clover - 4chan browser https://github.com/Floens/Clover/
+ * Copyright (C) 2014 Floens
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.floens.chan.core.site.common;
+
+import org.floens.chan.core.model.Post;
+import org.floens.chan.ui.theme.Theme;
+
+public interface ChanParser {
+ Post parse(Theme theme, Post.Builder builder);
+}
diff --git a/Clover/app/src/main/java/org/floens/chan/core/site/common/ChanReader.java b/Clover/app/src/main/java/org/floens/chan/core/site/common/ChanReader.java
index e0c98728..b80ce543 100644
--- a/Clover/app/src/main/java/org/floens/chan/core/site/common/ChanReader.java
+++ b/Clover/app/src/main/java/org/floens/chan/core/site/common/ChanReader.java
@@ -4,6 +4,8 @@ package org.floens.chan.core.site.common;
import android.util.JsonReader;
public interface ChanReader {
+ ChanParser getParser();
+
void loadThread(JsonReader reader, ChanReaderProcessingQueue queue) throws Exception;
void loadCatalog(JsonReader reader, ChanReaderProcessingQueue queue) throws Exception;
diff --git a/Clover/app/src/main/java/org/floens/chan/core/site/common/ChanReaderRequest.java b/Clover/app/src/main/java/org/floens/chan/core/site/common/ChanReaderRequest.java
index 5302ca54..1a22632a 100644
--- a/Clover/app/src/main/java/org/floens/chan/core/site/common/ChanReaderRequest.java
+++ b/Clover/app/src/main/java/org/floens/chan/core/site/common/ChanReaderRequest.java
@@ -21,7 +21,6 @@ import android.util.JsonReader;
import org.floens.chan.chan.ChanLoaderRequestParams;
import org.floens.chan.chan.ChanLoaderResponse;
-import org.floens.chan.chan.ChanParser;
import org.floens.chan.core.database.DatabaseManager;
import org.floens.chan.core.database.DatabaseSavedReplyManager;
import org.floens.chan.core.manager.FilterEngine;
@@ -70,9 +69,6 @@ public class ChanReaderRequest extends JsonReaderRequest {
@Inject
FilterEngine filterEngine;
- @Inject
- ChanParser chanParser;
-
private Loadable loadable;
private List cached;
private ChanReader reader;
@@ -181,7 +177,7 @@ public class ChanReaderRequest extends JsonReaderRequest {
List> tasks = new ArrayList<>(toParse.size());
for (int i = 0; i < toParse.size(); i++) {
Post.Builder post = toParse.get(i);
- tasks.add(new PostParseCallable(filterEngine, filters, databaseSavedReplyManager, post, chanParser));
+ tasks.add(new PostParseCallable(filterEngine, filters, databaseSavedReplyManager, post, reader));
}
if (!tasks.isEmpty()) {
diff --git a/Clover/app/src/main/java/org/floens/chan/core/site/common/DefaultFutabaChanParserHandler.java b/Clover/app/src/main/java/org/floens/chan/core/site/common/DefaultFutabaChanParserHandler.java
new file mode 100644
index 00000000..b64aa1f4
--- /dev/null
+++ b/Clover/app/src/main/java/org/floens/chan/core/site/common/DefaultFutabaChanParserHandler.java
@@ -0,0 +1,160 @@
+/*
+ * Clover - 4chan browser https://github.com/Floens/Clover/
+ * Copyright (C) 2014 Floens
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.floens.chan.core.site.common;
+
+import android.graphics.Typeface;
+import android.text.SpannableString;
+import android.text.TextUtils;
+import android.text.style.StrikethroughSpan;
+import android.text.style.StyleSpan;
+
+import org.floens.chan.core.model.Post;
+import org.floens.chan.core.model.PostLinkable;
+import org.floens.chan.ui.span.ForegroundColorSpanHashed;
+import org.floens.chan.ui.theme.Theme;
+import org.jsoup.nodes.Element;
+
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class DefaultFutabaChanParserHandler implements FutabaChanParserHandler {
+ private static final Pattern COLOR_PATTERN = Pattern.compile("color:#([0-9a-fA-F]*)");
+
+ @Override
+ public CharSequence handleParagraph(FutabaChanParser parser, Theme theme, Post.Builder post, CharSequence text, Element element) {
+ return text;
+ }
+
+ @Override
+ public CharSequence handleSpan(FutabaChanParser parser, Theme theme, Post.Builder post, Element span) {
+ SpannableString quote;
+
+ Set classes = span.classNames();
+ if (classes.contains("deadlink")) {
+ quote = new SpannableString(span.text());
+ quote.setSpan(new ForegroundColorSpanHashed(theme.quoteColor), 0, quote.length(), 0);
+ quote.setSpan(new StrikethroughSpan(), 0, quote.length(), 0);
+ } else if (classes.contains("fortune")) {
+ // html looks like
Your fortune:
+ // manually add these
+ quote = new SpannableString("\n\n" + span.text());
+
+ String style = span.attr("style");
+ if (!TextUtils.isEmpty(style)) {
+ style = style.replace(" ", "");
+
+ // private static final Pattern COLOR_PATTERN = Pattern.compile("color:#([0-9a-fA-F]*)");
+ Matcher matcher = COLOR_PATTERN.matcher(style);
+
+ int hexColor = 0xff0000;
+ if (matcher.find()) {
+ String group = matcher.group(1);
+ if (!TextUtils.isEmpty(group)) {
+ try {
+ hexColor = Integer.parseInt(group, 16);
+ } catch (NumberFormatException ignored) {
+ }
+ }
+ }
+
+ if (hexColor >= 0 && hexColor <= 0xffffff) {
+ quote.setSpan(new ForegroundColorSpanHashed(0xff000000 + hexColor), 0, quote.length(), 0);
+ quote.setSpan(new StyleSpan(Typeface.BOLD), 0, quote.length(), 0);
+ }
+ }
+ } else if (classes.contains("abbr")) {
+ return null;
+ } else {
+ quote = new SpannableString(span.text());
+ quote.setSpan(new ForegroundColorSpanHashed(theme.inlineQuoteColor), 0, quote.length(), 0);
+ parser.detectLinks(theme, post, span.text(), quote);
+ }
+
+ return quote;
+ }
+
+ @Override
+ public Link getLink(FutabaChanParser parser, Theme theme, Post.Builder post, Element anchor) {
+ String href = anchor.attr("href");
+ Set classes = anchor.classNames();
+
+ PostLinkable.Type t = null;
+ String key = null;
+ Object value = null;
+ if (classes.contains("quotelink")) {
+ if (href.contains("/thread/")) {
+ // link to another thread
+ PostLinkable.ThreadLink threadLink = null;
+
+ String[] slashSplit = href.split("/");
+ if (slashSplit.length == 4) {
+ String board = slashSplit[1];
+ String nums = slashSplit[3];
+ String[] numsSplitted = nums.split("#p");
+ if (numsSplitted.length == 2) {
+ try {
+ int tId = Integer.parseInt(numsSplitted[0]);
+ int pId = Integer.parseInt(numsSplitted[1]);
+ threadLink = new PostLinkable.ThreadLink(board, tId, pId);
+ } catch (NumberFormatException ignored) {
+ }
+ }
+ }
+
+ if (threadLink != null) {
+ t = PostLinkable.Type.THREAD;
+ key = anchor.text();
+ value = threadLink;
+ }
+ } else {
+ // normal quote
+ int id = -1;
+
+ String[] splitted = href.split("#p");
+ if (splitted.length == 2) {
+ try {
+ id = Integer.parseInt(splitted[1]);
+ } catch (NumberFormatException ignored) {
+ }
+ }
+
+ if (id >= 0) {
+ t = PostLinkable.Type.QUOTE;
+ key = anchor.text();
+ value = id;
+ }
+ }
+ } else {
+ // normal link
+ t = PostLinkable.Type.LINK;
+ key = anchor.text();
+ value = href;
+ }
+
+ if (t != null && key != null && value != null) {
+ Link link = new Link();
+ link.type = t;
+ link.key = key;
+ link.value = value;
+ return link;
+ } else {
+ return null;
+ }
+ }
+}
diff --git a/Clover/app/src/main/java/org/floens/chan/chan/ChanParser.java b/Clover/app/src/main/java/org/floens/chan/core/site/common/FutabaChanParser.java
similarity index 73%
rename from Clover/app/src/main/java/org/floens/chan/chan/ChanParser.java
rename to Clover/app/src/main/java/org/floens/chan/core/site/common/FutabaChanParser.java
index 943225e0..b9f71528 100644
--- a/Clover/app/src/main/java/org/floens/chan/chan/ChanParser.java
+++ b/Clover/app/src/main/java/org/floens/chan/core/site/common/FutabaChanParser.java
@@ -15,19 +15,17 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
-package org.floens.chan.chan;
+package org.floens.chan.core.site.common;
import android.graphics.Typeface;
import android.text.SpannableString;
import android.text.TextUtils;
import android.text.style.BackgroundColorSpan;
-import android.text.style.StrikethroughSpan;
import android.text.style.StyleSpan;
import android.text.style.TypefaceSpan;
import android.text.style.UnderlineSpan;
-import org.floens.chan.core.database.DatabaseManager;
import org.floens.chan.core.model.Post;
import org.floens.chan.core.model.PostLinkable;
import org.floens.chan.core.settings.ChanSettings;
@@ -54,34 +52,23 @@ import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import javax.inject.Inject;
-import javax.inject.Singleton;
import static org.floens.chan.utils.AndroidUtils.sp;
-@Singleton
-public class ChanParser {
- private static final String TAG = "ChanParser";
- private static final Pattern COLOR_PATTERN = Pattern.compile("color:#([0-9a-fA-F]*)");
+public class FutabaChanParser implements ChanParser {
+ private static final String TAG = "FutabaChanParser";
private static final String SAVED_REPLY_SUFFIX = " (You)";
private static final String OP_REPLY_SUFFIX = " (OP)";
- @Inject
- DatabaseManager databaseManager;
-
private final LinkExtractor linkExtractor = LinkExtractor.builder().linkTypes(EnumSet.of(LinkType.URL)).build();
- @Inject
- public ChanParser() {
- }
+ private FutabaChanParserHandler handler;
- public Post parse(Post.Builder post) {
- return parse(null, post);
+ public FutabaChanParser(FutabaChanParserHandler handler) {
+ this.handler = handler;
}
+ @Override
public Post parse(Theme theme, Post.Builder builder) {
if (theme == null) {
theme = ThemeHelper.getInstance().getTheme();
@@ -240,56 +227,30 @@ public class ChanParser {
return spannable;
} else {
switch (node.nodeName()) {
+ case "p": {
+ List innerNodes = node.childNodes();
+ List texts = new ArrayList<>(innerNodes.size() + 1);
+
+ for (Node innerNode : innerNodes) {
+ CharSequence nodeParsed = parseNode(theme, post, innerNode);
+ if (nodeParsed != null) {
+ texts.add(nodeParsed);
+ }
+ }
+
+ if (node.nextSibling() != null) {
+ texts.add("\n");
+ }
+
+ CharSequence res = TextUtils.concat(texts.toArray(new CharSequence[texts.size()]));
+
+ return handler.handleParagraph(this, theme, post, res, (Element) node);
+ }
case "br": {
return "\n";
}
case "span": {
- Element span = (Element) node;
-
- SpannableString quote;
-
- Set classes = span.classNames();
- if (classes.contains("deadlink")) {
- quote = new SpannableString(span.text());
- quote.setSpan(new ForegroundColorSpanHashed(theme.quoteColor), 0, quote.length(), 0);
- quote.setSpan(new StrikethroughSpan(), 0, quote.length(), 0);
- } else if (classes.contains("fortune")) {
- // html looks like
Your fortune:
- // manually add these
- quote = new SpannableString("\n\n" + span.text());
-
- String style = span.attr("style");
- if (!TextUtils.isEmpty(style)) {
- style = style.replace(" ", "");
-
- // private static final Pattern COLOR_PATTERN = Pattern.compile("color:#([0-9a-fA-F]*)");
- Matcher matcher = COLOR_PATTERN.matcher(style);
-
- int hexColor = 0xff0000;
- if (matcher.find()) {
- String group = matcher.group(1);
- if (!TextUtils.isEmpty(group)) {
- try {
- hexColor = Integer.parseInt(group, 16);
- } catch (NumberFormatException ignored) {
- }
- }
- }
-
- if (hexColor >= 0 && hexColor <= 0xffffff) {
- quote.setSpan(new ForegroundColorSpanHashed(0xff000000 + hexColor), 0, quote.length(), 0);
- quote.setSpan(new StyleSpan(Typeface.BOLD), 0, quote.length(), 0);
- }
- }
- } else if (classes.contains("abbr")) {
- return null;
- } else {
- quote = new SpannableString(span.text());
- quote.setSpan(new ForegroundColorSpanHashed(theme.inlineQuoteColor), 0, quote.length(), 0);
- detectLinks(theme, post, span.text(), quote);
- }
-
- return quote;
+ return handler.handleSpan(this, theme, post, (Element) node);
}
case "table": {
Element table = (Element) node;
@@ -383,78 +344,33 @@ public class ChanParser {
}
private CharSequence parseAnchor(Theme theme, Post.Builder post, Element anchor) {
- String href = anchor.attr("href");
- Set classes = anchor.classNames();
-
- PostLinkable.Type t = null;
- String key = null;
- Object value = null;
- if (classes.contains("quotelink")) {
- if (href.contains("/thread/")) {
- // link to another thread
- PostLinkable.ThreadLink threadLink = null;
-
- String[] slashSplit = href.split("/");
- if (slashSplit.length == 4) {
- String board = slashSplit[1];
- String nums = slashSplit[3];
- String[] numsSplitted = nums.split("#p");
- if (numsSplitted.length == 2) {
- try {
- int tId = Integer.parseInt(numsSplitted[0]);
- int pId = Integer.parseInt(numsSplitted[1]);
- threadLink = new PostLinkable.ThreadLink(board, tId, pId);
- } catch (NumberFormatException ignored) {
- }
- }
- }
+ FutabaChanParserHandler.Link handlerLink = handler.getLink(this, theme, post, anchor);
- if (threadLink != null) {
- t = PostLinkable.Type.THREAD;
- key = anchor.text() + " \u2192"; // arrow to the right
- value = threadLink;
- }
- } else {
- // normal quote
- int id = -1;
-
- String[] splitted = href.split("#p");
- if (splitted.length == 2) {
- try {
- id = Integer.parseInt(splitted[1]);
- } catch (NumberFormatException ignored) {
- }
- }
+ if (handlerLink != null) {
+ SpannableString link = new SpannableString(handlerLink.key);
+ PostLinkable pl = new PostLinkable(theme, handlerLink.key, handlerLink.value, handlerLink.type);
+ link.setSpan(pl, 0, link.length(), 0);
+ post.addLinkable(pl);
- if (id >= 0) {
- t = PostLinkable.Type.QUOTE;
- key = anchor.text();
- value = id;
- post.addReplyTo(id);
+ if (handlerLink.type == PostLinkable.Type.THREAD) {
+ handlerLink.key += " \u2192"; // arrow to the right
+ }
- // Append OP when its a reply to OP
- if (id == post.opId) {
- key += OP_REPLY_SUFFIX;
- }
+ if (handlerLink.type == PostLinkable.Type.QUOTE) {
+ int postNo = (int) handlerLink.value;
+ post.addReplyTo(postNo);
- // Append You when it's a reply to an saved reply
- if (databaseManager.getDatabaseSavedReplyManager().isSaved(post.board.code, id)) {
- key += SAVED_REPLY_SUFFIX;
- }
+ // Append OP when its a reply to OP
+ if (postNo == post.opId) {
+ handlerLink.key += OP_REPLY_SUFFIX;
}
- }
- } else {
- // normal link
- t = PostLinkable.Type.LINK;
- key = anchor.text();
- value = href;
- }
- if (t != null && key != null && value != null) {
- SpannableString link = new SpannableString(key);
- PostLinkable pl = new PostLinkable(theme, key, value, t);
- link.setSpan(pl, 0, link.length(), 0);
- post.addLinkable(pl);
+ // Append You when it's a reply to an saved reply
+ // TODO(multisite)
+ /*if (databaseManager.getDatabaseSavedReplyManager().isSaved(post.board.code, id)) {
+ key += SAVED_REPLY_SUFFIX;
+ }*/
+ }
return link;
} else {
@@ -462,10 +378,10 @@ public class ChanParser {
}
}
- private void detectLinks(Theme theme, Post.Builder post, String text, SpannableString spannable) {
+ public void detectLinks(Theme theme, Post.Builder post, String text, SpannableString spannable) {
// use autolink-java lib to detect links
final Iterable links = linkExtractor.extractLinks(text);
- for(final LinkSpan link : links) {
+ for (final LinkSpan link : links) {
final String linkText = text.substring(link.getBeginIndex(), link.getEndIndex());
final PostLinkable pl = new PostLinkable(theme, linkText, linkText, PostLinkable.Type.LINK);
spannable.setSpan(pl, link.getBeginIndex(), link.getEndIndex(), 0);
diff --git a/Clover/app/src/main/java/org/floens/chan/core/site/common/FutabaChanParserHandler.java b/Clover/app/src/main/java/org/floens/chan/core/site/common/FutabaChanParserHandler.java
new file mode 100644
index 00000000..8743dd17
--- /dev/null
+++ b/Clover/app/src/main/java/org/floens/chan/core/site/common/FutabaChanParserHandler.java
@@ -0,0 +1,36 @@
+/*
+ * Clover - 4chan browser https://github.com/Floens/Clover/
+ * Copyright (C) 2014 Floens
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */package org.floens.chan.core.site.common;
+
+import org.floens.chan.core.model.Post;
+import org.floens.chan.core.model.PostLinkable;
+import org.floens.chan.ui.theme.Theme;
+import org.jsoup.nodes.Element;
+
+public interface FutabaChanParserHandler {
+ CharSequence handleParagraph(FutabaChanParser parser, Theme theme, Post.Builder post, CharSequence text, Element element);
+
+ CharSequence handleSpan(FutabaChanParser parser, Theme theme, Post.Builder post, Element span);
+
+ Link getLink(FutabaChanParser parser, Theme theme, Post.Builder post, Element anchor);
+
+ class Link {
+ public PostLinkable.Type type;
+ public String key;
+ public Object value;
+ }
+}
diff --git a/Clover/app/src/main/java/org/floens/chan/core/site/common/FutabaChanReader.java b/Clover/app/src/main/java/org/floens/chan/core/site/common/FutabaChanReader.java
index 0814fa12..0120179c 100644
--- a/Clover/app/src/main/java/org/floens/chan/core/site/common/FutabaChanReader.java
+++ b/Clover/app/src/main/java/org/floens/chan/core/site/common/FutabaChanReader.java
@@ -15,6 +15,21 @@ import java.util.Map;
import okhttp3.HttpUrl;
public class FutabaChanReader implements ChanReader {
+ private final ChanParser chanParser;
+
+ public FutabaChanReader() {
+ this.chanParser = new FutabaChanParser(new DefaultFutabaChanParserHandler());
+ }
+
+ public FutabaChanReader(ChanParser chanParser) {
+ this.chanParser = chanParser;
+ }
+
+ @Override
+ public ChanParser getParser() {
+ return chanParser;
+ }
+
@Override
public void loadThread(JsonReader reader, ChanReaderProcessingQueue queue) throws Exception {
reader.beginObject();
diff --git a/Clover/app/src/main/java/org/floens/chan/core/site/common/PostParseCallable.java b/Clover/app/src/main/java/org/floens/chan/core/site/common/PostParseCallable.java
index ebc851c8..22e07769 100644
--- a/Clover/app/src/main/java/org/floens/chan/core/site/common/PostParseCallable.java
+++ b/Clover/app/src/main/java/org/floens/chan/core/site/common/PostParseCallable.java
@@ -17,7 +17,6 @@
*/
package org.floens.chan.core.site.common;
-import org.floens.chan.chan.ChanParser;
import org.floens.chan.core.database.DatabaseSavedReplyManager;
import org.floens.chan.core.manager.FilterEngine;
import org.floens.chan.core.model.orm.Filter;
@@ -27,7 +26,7 @@ import java.util.List;
import java.util.concurrent.Callable;
// Called concurrently to parse the post html and the filters on it
-// Belongs to ChanReaderRequest
+// belong to ChanReaderRequest
class PostParseCallable implements Callable {
private static final String TAG = "PostParseCallable";
@@ -35,18 +34,18 @@ class PostParseCallable implements Callable {
private List filters;
private DatabaseSavedReplyManager savedReplyManager;
private Post.Builder post;
- private ChanParser parser;
+ private ChanReader reader;
public PostParseCallable(FilterEngine filterEngine,
List filters,
DatabaseSavedReplyManager savedReplyManager,
Post.Builder post,
- ChanParser parser) {
+ ChanReader reader) {
this.filterEngine = filterEngine;
this.filters = filters;
this.savedReplyManager = savedReplyManager;
this.post = post;
- this.parser = parser;
+ this.reader = reader;
}
@Override
@@ -60,7 +59,7 @@ class PostParseCallable implements Callable {
// Logger.e(TAG, "Incorrect data about post received for post " + post.no);
// return null;
// }
- return parser.parse(post);
+ return reader.getParser().parse(null, post);
}
private void processPostFilter(Post.Builder post) {
diff --git a/Clover/app/src/main/java/org/floens/chan/core/site/sites/chan8/Chan8.java b/Clover/app/src/main/java/org/floens/chan/core/site/sites/chan8/Chan8.java
index 56a94e85..72b2f102 100644
--- a/Clover/app/src/main/java/org/floens/chan/core/site/sites/chan8/Chan8.java
+++ b/Clover/app/src/main/java/org/floens/chan/core/site/sites/chan8/Chan8.java
@@ -33,6 +33,7 @@ import org.floens.chan.core.site.SiteEndpoints;
import org.floens.chan.core.site.SiteIcon;
import org.floens.chan.core.site.SiteRequestModifier;
import org.floens.chan.core.site.common.ChanReader;
+import org.floens.chan.core.site.common.FutabaChanParser;
import org.floens.chan.core.site.common.FutabaChanReader;
import org.floens.chan.core.site.http.DeleteRequest;
import org.floens.chan.core.site.http.HttpCall;
@@ -225,7 +226,8 @@ public class Chan8 extends SiteBase {
@Override
public ChanReader chanReader() {
- return new FutabaChanReader();
+ FutabaChanParser parser = new FutabaChanParser(new Chan8ParserHandler());
+ return new FutabaChanReader(parser);
}
@Override
diff --git a/Clover/app/src/main/java/org/floens/chan/core/site/sites/chan8/Chan8ParserHandler.java b/Clover/app/src/main/java/org/floens/chan/core/site/sites/chan8/Chan8ParserHandler.java
new file mode 100644
index 00000000..1cd47709
--- /dev/null
+++ b/Clover/app/src/main/java/org/floens/chan/core/site/sites/chan8/Chan8ParserHandler.java
@@ -0,0 +1,133 @@
+/*
+ * Clover - 4chan browser https://github.com/Floens/Clover/
+ * Copyright (C) 2014 Floens
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+package org.floens.chan.core.site.sites.chan8;
+
+import android.text.SpannableString;
+
+import org.floens.chan.core.model.Post;
+import org.floens.chan.core.model.PostLinkable;
+import org.floens.chan.core.site.common.DefaultFutabaChanParserHandler;
+import org.floens.chan.core.site.common.FutabaChanParser;
+import org.floens.chan.ui.span.ForegroundColorSpanHashed;
+import org.floens.chan.ui.theme.Theme;
+import org.jsoup.nodes.Element;
+
+import java.util.Set;
+
+public class Chan8ParserHandler extends DefaultFutabaChanParserHandler {
+ @Override
+ public CharSequence handleParagraph(FutabaChanParser parser, Theme theme, Post.Builder post, CharSequence text, Element element) {
+ if (element.hasClass("quote")) {
+ SpannableString quote = new SpannableString(text);
+ quote.setSpan(new ForegroundColorSpanHashed(theme.inlineQuoteColor), 0, quote.length(), 0);
+ parser.detectLinks(theme, post, quote.toString(), quote);
+ return quote;
+ } else {
+ return text;
+ }
+ }
+
+ @Override
+ public CharSequence handleSpan(FutabaChanParser parser, Theme theme, Post.Builder post, Element span) {
+ SpannableString quote;
+
+ Set classes = span.classNames();
+ if (classes.contains("abbr")) {
+ return null;
+ } else if (classes.contains("spoiler")) {
+ quote = new SpannableString(span.text());
+ PostLinkable pl = new PostLinkable(theme, span.text(), span.text(), PostLinkable.Type.SPOILER);
+ quote.setSpan(pl, 0, quote.length(), 0);
+ post.addLinkable(pl);
+ } else {
+ quote = new SpannableString(span.text());
+ quote.setSpan(new ForegroundColorSpanHashed(theme.inlineQuoteColor), 0, quote.length(), 0);
+ parser.detectLinks(theme, post, span.text(), quote);
+ }
+
+ return quote;
+ }
+
+ @Override
+ public Link getLink(FutabaChanParser parser, Theme theme, Post.Builder post, Element anchor) {
+ String href = anchor.attr("href");
+
+ PostLinkable.Type t = null;
+ String key = null;
+ Object value = null;
+ if (href.startsWith("/")) {
+ if (href.contains("/thread/")) {
+ // link to another thread
+ PostLinkable.ThreadLink threadLink = null;
+
+ String[] slashSplit = href.split("/");
+ if (slashSplit.length == 4) {
+ String board = slashSplit[1];
+ String nums = slashSplit[3];
+ String[] numsSplitted = nums.split("#p");
+ if (numsSplitted.length == 2) {
+ try {
+ int tId = Integer.parseInt(numsSplitted[0]);
+ int pId = Integer.parseInt(numsSplitted[1]);
+ threadLink = new PostLinkable.ThreadLink(board, tId, pId);
+ } catch (NumberFormatException ignored) {
+ }
+ }
+ }
+
+ if (threadLink != null) {
+ t = PostLinkable.Type.THREAD;
+ key = anchor.text();
+ value = threadLink;
+ }
+ } else {
+ // normal quote
+ int id = -1;
+
+ String[] splitted = href.split("#");
+ if (splitted.length == 2) {
+ try {
+ id = Integer.parseInt(splitted[1]);
+ } catch (NumberFormatException ignored) {
+ }
+ }
+
+ if (id >= 0) {
+ t = PostLinkable.Type.QUOTE;
+ key = anchor.text();
+ value = id;
+ }
+ }
+ } else {
+ // normal link
+ t = PostLinkable.Type.LINK;
+ key = anchor.text();
+ value = href;
+ }
+
+ if (t != null && key != null && value != null) {
+ Link link = new Link();
+ link.type = t;
+ link.key = key;
+ link.value = value;
+ return link;
+ } else {
+ return null;
+ }
+ }
+}
diff --git a/Clover/app/src/main/java/org/floens/chan/ui/activity/StartActivity.java b/Clover/app/src/main/java/org/floens/chan/ui/activity/StartActivity.java
index 830aaacf..fc4bf8b5 100644
--- a/Clover/app/src/main/java/org/floens/chan/ui/activity/StartActivity.java
+++ b/Clover/app/src/main/java/org/floens/chan/ui/activity/StartActivity.java
@@ -20,7 +20,6 @@ package org.floens.chan.ui.activity;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Configuration;
-import android.net.Uri;
import android.nfc.NdefMessage;
import android.nfc.NfcAdapter;
import android.nfc.NfcEvent;
@@ -35,7 +34,6 @@ import android.view.ViewGroup;
import org.floens.chan.Chan;
import org.floens.chan.R;
-import org.floens.chan.chan.ChanHelper;
import org.floens.chan.controller.Controller;
import org.floens.chan.controller.NavigationController;
import org.floens.chan.core.database.DatabaseLoadableManager;
@@ -135,7 +133,7 @@ public class StartActivity extends AppCompatActivity implements NfcAdapter.Creat
private void setupFromStateOrFreshLaunch(Bundle savedInstanceState) {
boolean loadDefault = true;
- if (savedInstanceState != null) {
+ /*if (savedInstanceState != null) {
// Restore the activity state from the previously saved state.
ChanState chanState = savedInstanceState.getParcelable(STATE_KEY);
if (chanState == null) {
@@ -177,7 +175,7 @@ public class StartActivity extends AppCompatActivity implements NfcAdapter.Creat
.show();
}
}
- }
+ }*/
// Not from a state or from an url, launch the setup controller if no boards are setup up yet,
// otherwise load the default saved board.
diff --git a/Clover/app/src/main/java/org/floens/chan/ui/controller/SiteSetupController.java b/Clover/app/src/main/java/org/floens/chan/ui/controller/SiteSetupController.java
index 0309d8ad..598e7c12 100644
--- a/Clover/app/src/main/java/org/floens/chan/ui/controller/SiteSetupController.java
+++ b/Clover/app/src/main/java/org/floens/chan/ui/controller/SiteSetupController.java
@@ -58,10 +58,11 @@ public class SiteSetupController extends SettingsController implements SiteSetup
// Preferences
populatePreferences();
- buildPreferences();
// Presenter
presenter.create(this, site);
+
+ buildPreferences();
}
public void setSite(Site site) {
diff --git a/Clover/app/src/main/java/org/floens/chan/ui/controller/ThemeSettingsController.java b/Clover/app/src/main/java/org/floens/chan/ui/controller/ThemeSettingsController.java
index 848c53aa..18385105 100644
--- a/Clover/app/src/main/java/org/floens/chan/ui/controller/ThemeSettingsController.java
+++ b/Clover/app/src/main/java/org/floens/chan/ui/controller/ThemeSettingsController.java
@@ -37,7 +37,8 @@ import android.widget.LinearLayout;
import android.widget.TextView;
import org.floens.chan.R;
-import org.floens.chan.chan.ChanParser;
+import org.floens.chan.core.site.common.DefaultFutabaChanParserHandler;
+import org.floens.chan.core.site.common.FutabaChanParser;
import org.floens.chan.controller.Controller;
import org.floens.chan.core.model.orm.Board;
import org.floens.chan.core.model.orm.Loadable;
@@ -250,7 +251,7 @@ public class ThemeSettingsController extends Controller implements View.OnClickL
"http://example.com/" +
"
" +
"Phasellus consequat semper sodales. Donec dolor lectus, aliquet nec mollis vel, rutrum vel enim.");
- Post post = getGraph().get(ChanParser.class).parse(theme, builder);
+ Post post = new FutabaChanParser(new DefaultFutabaChanParserHandler()).parse(theme, builder);
LinearLayout linearLayout = new LinearLayout(themeContext);
linearLayout.setOrientation(LinearLayout.VERTICAL);
diff --git a/Clover/app/src/main/java/org/floens/chan/ui/settings/SettingsController.java b/Clover/app/src/main/java/org/floens/chan/ui/settings/SettingsController.java
index 51104bf7..c2aa91b6 100644
--- a/Clover/app/src/main/java/org/floens/chan/ui/settings/SettingsController.java
+++ b/Clover/app/src/main/java/org/floens/chan/ui/settings/SettingsController.java
@@ -168,7 +168,10 @@ public class SettingsController extends Controller implements AndroidUtils.OnMea
bottom.setText(bottomText);
}
- AnimationUtils.animateHeight(bottom, bottomText != null, ((View) view.getParent()).getWidth());
+ // This way of animating never works on textviews if they're just added.
+ if (bottom.getHeight() != 0) {
+ AnimationUtils.animateHeight(bottom, bottomText != null, ((View) view.getParent()).getWidth());
+ }
} else {
bottom.setText(bottomText);
bottom.setVisibility(bottomText == null ? View.GONE : View.VISIBLE);
diff --git a/Clover/app/src/main/java/org/floens/chan/ui/theme/Theme.java b/Clover/app/src/main/java/org/floens/chan/ui/theme/Theme.java
index b7223539..b3343e5a 100644
--- a/Clover/app/src/main/java/org/floens/chan/ui/theme/Theme.java
+++ b/Clover/app/src/main/java/org/floens/chan/ui/theme/Theme.java
@@ -30,7 +30,7 @@ import org.floens.chan.utils.AndroidUtils;
/**
* A Theme
- * Used for setting the toolbar color, and passed around {@link org.floens.chan.chan.ChanParser} to give the spans the correct color.
+ * Used for setting the toolbar color, and passed around {@link org.floens.chan.core.site.common.ChanParser} to give the spans the correct color.
* Technically should the parser not do UI, but it is important that the spans do not get created on an UI thread for performance.
*/
public class Theme {