move more handling to the parserhandler, fix 8ch quotes outside thread.

multisite
Floens 8 years ago
parent 5fc8c7b0d7
commit 10ed72775e
  1. 128
      Clover/app/src/main/java/org/floens/chan/core/site/common/ChanParserHelper.java
  2. 9
      Clover/app/src/main/java/org/floens/chan/core/site/common/ChanReaderRequest.java
  3. 82
      Clover/app/src/main/java/org/floens/chan/core/site/common/DefaultFutabaChanParserHandler.java
  4. 160
      Clover/app/src/main/java/org/floens/chan/core/site/common/FutabaChanParser.java
  5. 10
      Clover/app/src/main/java/org/floens/chan/core/site/common/FutabaChanParserHandler.java
  6. 13
      Clover/app/src/main/java/org/floens/chan/core/site/sites/chan8/Chan8ParserHandler.java

@ -0,0 +1,128 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/
package org.floens.chan.core.site.common;
import android.text.SpannableString;
import org.floens.chan.core.model.Post;
import org.floens.chan.core.model.PostLinkable;
import org.floens.chan.ui.theme.Theme;
import org.jsoup.helper.StringUtil;
import org.jsoup.nodes.Element;
import org.jsoup.nodes.Node;
import org.jsoup.nodes.TextNode;
import org.jsoup.select.NodeTraversor;
import org.jsoup.select.NodeVisitor;
import org.nibor.autolink.LinkExtractor;
import org.nibor.autolink.LinkSpan;
import org.nibor.autolink.LinkType;
import java.util.EnumSet;
public class ChanParserHelper {
private static final LinkExtractor LINK_EXTRACTOR = LinkExtractor.builder()
.linkTypes(EnumSet.of(LinkType.URL))
.build();
/**
* Detect links in the given spannable, and create PostLinkables with Type.LINK for the
* links found onto the spannable.
* <p>
* The links are detected with the autolink-java library.
*
* @param theme The theme to style the links with
* @param post The post where the linkables get added to.
* @param text Text to find links in
* @param spannable Spannable to set the spans on.
*/
public static void detectLinks(Theme theme, Post.Builder post, String text, SpannableString spannable) {
final Iterable<LinkSpan> links = LINK_EXTRACTOR.extractLinks(text);
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);
post.addLinkable(pl);
}
}
// Below code taken from org.jsoup.nodes.Element.text(), but it preserves <br>
public static String getNodeTextPreservingLineBreaks(Element node) {
final StringBuilder accum = new StringBuilder();
new NodeTraversor(new NodeVisitor() {
public void head(Node node, int depth) {
if (node instanceof TextNode) {
TextNode textNode = (TextNode) node;
appendNormalisedText(accum, textNode);
} else if (node instanceof Element) {
Element element = (Element) node;
if (accum.length() > 0 &&
element.isBlock() &&
!lastCharIsWhitespace(accum))
accum.append(" ");
if (element.tag().getName().equals("br")) {
accum.append("\n");
}
}
}
public void tail(Node node, int depth) {
}
}).traverse(node);
return accum.toString().trim();
}
// Copied from org.jsoup.nodes.Element.text()
private static boolean lastCharIsWhitespace(StringBuilder sb) {
return sb.length() != 0 && sb.charAt(sb.length() - 1) == ' ';
}
// Copied from org.jsoup.nodes.Element.text()
private static void appendNormalisedText(StringBuilder accum, TextNode textNode) {
String text = textNode.getWholeText();
if (!preserveWhitespace(textNode.parent())) {
text = normaliseWhitespace(text);
if (lastCharIsWhitespace(accum))
text = stripLeadingWhitespace(text);
}
accum.append(text);
}
// Copied from org.jsoup.nodes.Element.text()
private static String normaliseWhitespace(String text) {
text = StringUtil.normaliseWhitespace(text);
return text;
}
// Copied from org.jsoup.nodes.Element.text()
private static String stripLeadingWhitespace(String text) {
return text.replaceFirst("^\\s+", "");
}
// Copied from org.jsoup.nodes.Element.text()
private static boolean preserveWhitespace(Node node) {
// looks only at this element and one level up, to prevent recursion & needless stack searches
if (node != null && node instanceof Element) {
Element element = (Element) node;
return element.tag().preserveWhitespace() ||
element.parent() != null && element.parent().tag().preserveWhitespace();
}
return false;
}
}

@ -283,9 +283,12 @@ public class ChanReaderRequest extends JsonReaderRequest<ChanLoaderResponse> {
List<Integer> value = entry.getValue(); List<Integer> value = entry.getValue();
Post subject = postsByNo.get(key); Post subject = postsByNo.get(key);
synchronized (subject.repliesFrom) { // Sometimes a post replies to a ghost, a post that doesn't exist.
subject.repliesFrom.clear(); if (subject != null) {
subject.repliesFrom.addAll(value); synchronized (subject.repliesFrom) {
subject.repliesFrom.clear();
subject.repliesFrom.addAll(value);
}
} }
} }

@ -22,17 +22,25 @@ import android.text.SpannableString;
import android.text.TextUtils; import android.text.TextUtils;
import android.text.style.StrikethroughSpan; import android.text.style.StrikethroughSpan;
import android.text.style.StyleSpan; import android.text.style.StyleSpan;
import android.text.style.TypefaceSpan;
import android.text.style.UnderlineSpan;
import org.floens.chan.core.model.Post; import org.floens.chan.core.model.Post;
import org.floens.chan.core.model.PostLinkable; import org.floens.chan.core.model.PostLinkable;
import org.floens.chan.ui.span.AbsoluteSizeSpanHashed;
import org.floens.chan.ui.span.ForegroundColorSpanHashed; import org.floens.chan.ui.span.ForegroundColorSpanHashed;
import org.floens.chan.ui.theme.Theme; import org.floens.chan.ui.theme.Theme;
import org.jsoup.nodes.Element; import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.util.ArrayList;
import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import static org.floens.chan.utils.AndroidUtils.sp;
public class DefaultFutabaChanParserHandler implements FutabaChanParserHandler { public class DefaultFutabaChanParserHandler implements FutabaChanParserHandler {
private static final Pattern COLOR_PATTERN = Pattern.compile("color:#([0-9a-fA-F]*)"); private static final Pattern COLOR_PATTERN = Pattern.compile("color:#([0-9a-fA-F]*)");
@ -83,14 +91,84 @@ public class DefaultFutabaChanParserHandler implements FutabaChanParserHandler {
} else { } else {
quote = new SpannableString(span.text()); quote = new SpannableString(span.text());
quote.setSpan(new ForegroundColorSpanHashed(theme.inlineQuoteColor), 0, quote.length(), 0); quote.setSpan(new ForegroundColorSpanHashed(theme.inlineQuoteColor), 0, quote.length(), 0);
parser.detectLinks(theme, post, span.text(), quote); ChanParserHelper.detectLinks(theme, post, span.text(), quote);
} }
return quote; return quote;
} }
@Override @Override
public Link getLink(FutabaChanParser parser, Theme theme, Post.Builder post, Element anchor) { public CharSequence handleTable(FutabaChanParser parser, Theme theme, Post.Builder post, Element table) {
List<CharSequence> parts = new ArrayList<>();
Elements tableRows = table.getElementsByTag("tr");
for (int i = 0; i < tableRows.size(); i++) {
Element tableRow = tableRows.get(i);
if (tableRow.text().length() > 0) {
Elements tableDatas = tableRow.getElementsByTag("td");
for (int j = 0; j < tableDatas.size(); j++) {
Element tableData = tableDatas.get(j);
SpannableString tableDataPart = new SpannableString(tableData.text());
if (tableData.getElementsByTag("b").size() > 0) {
tableDataPart.setSpan(new StyleSpan(Typeface.BOLD), 0, tableDataPart.length(), 0);
tableDataPart.setSpan(new UnderlineSpan(), 0, tableDataPart.length(), 0);
}
parts.add(tableDataPart);
if (j < tableDatas.size() - 1) {
parts.add(": ");
}
}
if (i < tableRows.size() - 1) {
parts.add("\n");
}
}
}
SpannableString tableTotal = new SpannableString(TextUtils.concat(parts.toArray(new CharSequence[parts.size()])));
tableTotal.setSpan(new ForegroundColorSpanHashed(theme.inlineQuoteColor), 0, tableTotal.length(), 0);
tableTotal.setSpan(new AbsoluteSizeSpanHashed(sp(12f)), 0, tableTotal.length(), 0);
return tableTotal;
}
@Override
public CharSequence handleStrong(FutabaChanParser parser, Theme theme, Post.Builder post, Element strong) {
SpannableString red = new SpannableString(strong.text());
red.setSpan(new ForegroundColorSpanHashed(theme.quoteColor), 0, red.length(), 0);
red.setSpan(new StyleSpan(Typeface.BOLD), 0, red.length(), 0);
return red;
}
@Override
public CharSequence handlePre(FutabaChanParser parser, Theme theme, Post.Builder post, Element pre) {
Set<String> classes = pre.classNames();
if (classes.contains("prettyprint")) {
String text = ChanParserHelper.getNodeTextPreservingLineBreaks(pre);
SpannableString monospace = new SpannableString(text);
monospace.setSpan(new TypefaceSpan("monospace"), 0, monospace.length(), 0);
monospace.setSpan(new AbsoluteSizeSpanHashed(sp(12f)), 0, monospace.length(), 0);
return monospace;
} else {
return pre.text();
}
}
@Override
public CharSequence handleStrike(FutabaChanParser parser, Theme theme, Post.Builder post, Element strike) {
SpannableString link = new SpannableString(strike.text());
PostLinkable pl = new PostLinkable(theme, strike.text(), strike.text(), PostLinkable.Type.SPOILER);
link.setSpan(pl, 0, link.length(), 0);
post.addLinkable(pl);
return link;
}
@Override
public Link handleAnchor(FutabaChanParser parser, Theme theme, Post.Builder post, Element anchor) {
String href = anchor.attr("href"); String href = anchor.attr("href");
Set<String> classes = anchor.classNames(); Set<String> classes = anchor.classNames();

@ -18,13 +18,9 @@
package org.floens.chan.core.site.common; package org.floens.chan.core.site.common;
import android.graphics.Typeface;
import android.text.SpannableString; import android.text.SpannableString;
import android.text.TextUtils; import android.text.TextUtils;
import android.text.style.BackgroundColorSpan; import android.text.style.BackgroundColorSpan;
import android.text.style.StyleSpan;
import android.text.style.TypefaceSpan;
import android.text.style.UnderlineSpan;
import org.floens.chan.core.model.Post; import org.floens.chan.core.model.Post;
import org.floens.chan.core.model.PostLinkable; import org.floens.chan.core.model.PostLinkable;
@ -35,23 +31,14 @@ import org.floens.chan.ui.theme.Theme;
import org.floens.chan.ui.theme.ThemeHelper; import org.floens.chan.ui.theme.ThemeHelper;
import org.floens.chan.utils.Logger; import org.floens.chan.utils.Logger;
import org.jsoup.Jsoup; import org.jsoup.Jsoup;
import org.jsoup.helper.StringUtil;
import org.jsoup.nodes.Document; import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element; import org.jsoup.nodes.Element;
import org.jsoup.nodes.Node; import org.jsoup.nodes.Node;
import org.jsoup.nodes.TextNode; import org.jsoup.nodes.TextNode;
import org.jsoup.parser.Parser; import org.jsoup.parser.Parser;
import org.jsoup.select.Elements;
import org.jsoup.select.NodeTraversor;
import org.jsoup.select.NodeVisitor;
import org.nibor.autolink.LinkExtractor;
import org.nibor.autolink.LinkSpan;
import org.nibor.autolink.LinkType;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List; import java.util.List;
import java.util.Set;
import static org.floens.chan.utils.AndroidUtils.sp; import static org.floens.chan.utils.AndroidUtils.sp;
@ -60,8 +47,6 @@ public class FutabaChanParser implements ChanParser {
private static final String SAVED_REPLY_SUFFIX = " (You)"; private static final String SAVED_REPLY_SUFFIX = " (You)";
private static final String OP_REPLY_SUFFIX = " (OP)"; private static final String OP_REPLY_SUFFIX = " (OP)";
private final LinkExtractor linkExtractor = LinkExtractor.builder().linkTypes(EnumSet.of(LinkType.URL)).build();
private FutabaChanParserHandler handler; private FutabaChanParserHandler handler;
public FutabaChanParser(FutabaChanParserHandler handler) { public FutabaChanParser(FutabaChanParserHandler handler) {
@ -156,6 +141,7 @@ public class FutabaChanParser implements ChanParser {
int g = (hash >> 16) & 0xff; int g = (hash >> 16) & 0xff;
int b = (hash >> 8) & 0xff; int b = (hash >> 8) & 0xff;
//noinspection NumericOverflow
int idColor = (0xff << 24) + (r << 16) + (g << 8) + b; int idColor = (0xff << 24) + (r << 16) + (g << 8) + b;
boolean lightColor = (r * 0.299f) + (g * 0.587f) + (b * 0.114f) > 125f; boolean lightColor = (r * 0.299f) + (g * 0.587f) + (b * 0.114f) > 125f;
int idBgColor = lightColor ? theme.idBackgroundLight : theme.idBackgroundDark; int idBgColor = lightColor ? theme.idBackgroundLight : theme.idBackgroundDark;
@ -222,12 +208,13 @@ public class FutabaChanParser implements ChanParser {
String text = ((TextNode) node).text(); String text = ((TextNode) node).text();
SpannableString spannable = new SpannableString(text); SpannableString spannable = new SpannableString(text);
detectLinks(theme, post, text, spannable); ChanParserHelper.detectLinks(theme, post, text, spannable);
return spannable; return spannable;
} else { } else {
switch (node.nodeName()) { switch (node.nodeName()) {
case "p": { case "p": {
// Recursively call parseNode with the nodes of the paragraph.
List<Node> innerNodes = node.childNodes(); List<Node> innerNodes = node.childNodes();
List<CharSequence> texts = new ArrayList<>(innerNodes.size() + 1); List<CharSequence> texts = new ArrayList<>(innerNodes.size() + 1);
@ -253,50 +240,10 @@ public class FutabaChanParser implements ChanParser {
return handler.handleSpan(this, theme, post, (Element) node); return handler.handleSpan(this, theme, post, (Element) node);
} }
case "table": { case "table": {
Element table = (Element) node; return handler.handleTable(this, theme, post, (Element) node);
List<CharSequence> parts = new ArrayList<>();
Elements tableRows = table.getElementsByTag("tr");
for (int i = 0; i < tableRows.size(); i++) {
Element tableRow = tableRows.get(i);
if (tableRow.text().length() > 0) {
Elements tableDatas = tableRow.getElementsByTag("td");
for (int j = 0; j < tableDatas.size(); j++) {
Element tableData = tableDatas.get(j);
SpannableString tableDataPart = new SpannableString(tableData.text());
if (tableData.getElementsByTag("b").size() > 0) {
tableDataPart.setSpan(new StyleSpan(Typeface.BOLD), 0, tableDataPart.length(), 0);
tableDataPart.setSpan(new UnderlineSpan(), 0, tableDataPart.length(), 0);
}
parts.add(tableDataPart);
if (j < tableDatas.size() - 1) {
parts.add(": ");
}
}
if (i < tableRows.size() - 1) {
parts.add("\n");
}
}
}
SpannableString tableTotal = new SpannableString(TextUtils.concat(parts.toArray(new CharSequence[parts.size()])));
tableTotal.setSpan(new ForegroundColorSpanHashed(theme.inlineQuoteColor), 0, tableTotal.length(), 0);
tableTotal.setSpan(new AbsoluteSizeSpanHashed(sp(12f)), 0, tableTotal.length(), 0);
return tableTotal;
} }
case "strong": { case "strong": {
Element strong = (Element) node; return handler.handleStrong(this, theme, post, (Element) node);
SpannableString red = new SpannableString(strong.text());
red.setSpan(new ForegroundColorSpanHashed(theme.quoteColor), 0, red.length(), 0);
red.setSpan(new StyleSpan(Typeface.BOLD), 0, red.length(), 0);
return red;
} }
case "a": { case "a": {
CharSequence anchor = parseAnchor(theme, post, (Element) node); CharSequence anchor = parseAnchor(theme, post, (Element) node);
@ -307,29 +254,10 @@ public class FutabaChanParser implements ChanParser {
} }
} }
case "s": { case "s": {
Element spoiler = (Element) node; return handler.handleStrike(this, theme, post, (Element) node);
SpannableString link = new SpannableString(spoiler.text());
PostLinkable pl = new PostLinkable(theme, spoiler.text(), spoiler.text(), PostLinkable.Type.SPOILER);
link.setSpan(pl, 0, link.length(), 0);
post.addLinkable(pl);
return link;
} }
case "pre": { case "pre": {
Element pre = (Element) node; return handler.handlePre(this, theme, post, (Element) node);
Set<String> classes = pre.classNames();
if (classes.contains("prettyprint")) {
String text = getNodeText(pre);
SpannableString monospace = new SpannableString(text);
monospace.setSpan(new TypefaceSpan("monospace"), 0, monospace.length(), 0);
monospace.setSpan(new AbsoluteSizeSpanHashed(sp(12f)), 0, monospace.length(), 0);
return monospace;
} else {
return pre.text();
}
} }
default: { default: {
// Unknown tag, add the inner part // Unknown tag, add the inner part
@ -344,7 +272,7 @@ public class FutabaChanParser implements ChanParser {
} }
private CharSequence parseAnchor(Theme theme, Post.Builder post, Element anchor) { private CharSequence parseAnchor(Theme theme, Post.Builder post, Element anchor) {
FutabaChanParserHandler.Link handlerLink = handler.getLink(this, theme, post, anchor); FutabaChanParserHandler.Link handlerLink = handler.handleAnchor(this, theme, post, anchor);
if (handlerLink != null) { if (handlerLink != null) {
SpannableString link = new SpannableString(handlerLink.key); SpannableString link = new SpannableString(handlerLink.key);
@ -377,76 +305,4 @@ public class FutabaChanParser implements ChanParser {
return null; return null;
} }
} }
public void detectLinks(Theme theme, Post.Builder post, String text, SpannableString spannable) {
// use autolink-java lib to detect links
final Iterable<LinkSpan> links = linkExtractor.extractLinks(text);
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);
post.addLinkable(pl);
}
}
// Below code taken from org.jsoup.nodes.Element.text(), but it preserves <br>
private String getNodeText(Element node) {
final StringBuilder accum = new StringBuilder();
new NodeTraversor(new NodeVisitor() {
public void head(Node node, int depth) {
if (node instanceof TextNode) {
TextNode textNode = (TextNode) node;
appendNormalisedText(accum, textNode);
} else if (node instanceof Element) {
Element element = (Element) node;
if (accum.length() > 0 &&
element.isBlock() &&
!lastCharIsWhitespace(accum))
accum.append(" ");
if (element.tag().getName().equals("br")) {
accum.append("\n");
}
}
}
public void tail(Node node, int depth) {
}
}).traverse(node);
return accum.toString().trim();
}
private static boolean lastCharIsWhitespace(StringBuilder sb) {
return sb.length() != 0 && sb.charAt(sb.length() - 1) == ' ';
}
private static void appendNormalisedText(StringBuilder accum, TextNode textNode) {
String text = textNode.getWholeText();
if (!preserveWhitespace(textNode.parent())) {
text = normaliseWhitespace(text);
if (lastCharIsWhitespace(accum))
text = stripLeadingWhitespace(text);
}
accum.append(text);
}
private static String normaliseWhitespace(String text) {
text = StringUtil.normaliseWhitespace(text);
return text;
}
private static String stripLeadingWhitespace(String text) {
return text.replaceFirst("^\\s+", "");
}
private static boolean preserveWhitespace(Node node) {
// looks only at this element and one level up, to prevent recursion & needless stack searches
if (node != null && node instanceof Element) {
Element element = (Element) node;
return element.tag().preserveWhitespace() ||
element.parent() != null && element.parent().tag().preserveWhitespace();
}
return false;
}
} }

@ -26,7 +26,15 @@ public interface FutabaChanParserHandler {
CharSequence handleSpan(FutabaChanParser parser, Theme theme, Post.Builder post, Element span); CharSequence handleSpan(FutabaChanParser parser, Theme theme, Post.Builder post, Element span);
Link getLink(FutabaChanParser parser, Theme theme, Post.Builder post, Element anchor); CharSequence handleTable(FutabaChanParser parser, Theme theme, Post.Builder post, Element table);
CharSequence handleStrong(FutabaChanParser parser, Theme theme, Post.Builder post, Element strong);
CharSequence handlePre(FutabaChanParser parser, Theme theme, Post.Builder post, Element pre);
CharSequence handleStrike(FutabaChanParser parser, Theme theme, Post.Builder post, Element strike);
Link handleAnchor(FutabaChanParser parser, Theme theme, Post.Builder post, Element anchor);
class Link { class Link {
public PostLinkable.Type type; public PostLinkable.Type type;

@ -21,6 +21,7 @@ import android.text.SpannableString;
import org.floens.chan.core.model.Post; import org.floens.chan.core.model.Post;
import org.floens.chan.core.model.PostLinkable; import org.floens.chan.core.model.PostLinkable;
import org.floens.chan.core.site.common.ChanParserHelper;
import org.floens.chan.core.site.common.DefaultFutabaChanParserHandler; import org.floens.chan.core.site.common.DefaultFutabaChanParserHandler;
import org.floens.chan.core.site.common.FutabaChanParser; import org.floens.chan.core.site.common.FutabaChanParser;
import org.floens.chan.ui.span.ForegroundColorSpanHashed; import org.floens.chan.ui.span.ForegroundColorSpanHashed;
@ -35,7 +36,7 @@ public class Chan8ParserHandler extends DefaultFutabaChanParserHandler {
if (element.hasClass("quote")) { if (element.hasClass("quote")) {
SpannableString quote = new SpannableString(text); SpannableString quote = new SpannableString(text);
quote.setSpan(new ForegroundColorSpanHashed(theme.inlineQuoteColor), 0, quote.length(), 0); quote.setSpan(new ForegroundColorSpanHashed(theme.inlineQuoteColor), 0, quote.length(), 0);
parser.detectLinks(theme, post, quote.toString(), quote); ChanParserHelper.detectLinks(theme, post, quote.toString(), quote);
return quote; return quote;
} else { } else {
return text; return text;
@ -57,21 +58,21 @@ public class Chan8ParserHandler extends DefaultFutabaChanParserHandler {
} else { } else {
quote = new SpannableString(span.text()); quote = new SpannableString(span.text());
quote.setSpan(new ForegroundColorSpanHashed(theme.inlineQuoteColor), 0, quote.length(), 0); quote.setSpan(new ForegroundColorSpanHashed(theme.inlineQuoteColor), 0, quote.length(), 0);
parser.detectLinks(theme, post, span.text(), quote); ChanParserHelper.detectLinks(theme, post, span.text(), quote);
} }
return quote; return quote;
} }
@Override @Override
public Link getLink(FutabaChanParser parser, Theme theme, Post.Builder post, Element anchor) { public Link handleAnchor(FutabaChanParser parser, Theme theme, Post.Builder post, Element anchor) {
String href = anchor.attr("href"); String href = anchor.attr("href");
PostLinkable.Type t = null; PostLinkable.Type t = null;
String key = null; String key = null;
Object value = null; Object value = null;
if (href.startsWith("/")) { if (href.startsWith("/")) {
if (href.contains("/thread/")) { if (!href.startsWith("/" + post.board.code + "/res/")) {
// link to another thread // link to another thread
PostLinkable.ThreadLink threadLink = null; PostLinkable.ThreadLink threadLink = null;
@ -79,10 +80,10 @@ public class Chan8ParserHandler extends DefaultFutabaChanParserHandler {
if (slashSplit.length == 4) { if (slashSplit.length == 4) {
String board = slashSplit[1]; String board = slashSplit[1];
String nums = slashSplit[3]; String nums = slashSplit[3];
String[] numsSplitted = nums.split("#p"); String[] numsSplitted = nums.split("#");
if (numsSplitted.length == 2) { if (numsSplitted.length == 2) {
try { try {
int tId = Integer.parseInt(numsSplitted[0]); int tId = Integer.parseInt(numsSplitted[0].replace(".html", ""));
int pId = Integer.parseInt(numsSplitted[1]); int pId = Integer.parseInt(numsSplitted[1]);
threadLink = new PostLinkable.ThreadLink(board, tId, pId); threadLink = new PostLinkable.ThreadLink(board, tId, pId);
} catch (NumberFormatException ignored) { } catch (NumberFormatException ignored) {

Loading…
Cancel
Save