package org.wikipedia.page;
import android.content.Context;
import android.net.Uri;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.Log;
import org.json.JSONException;
import org.json.JSONObject;
import org.wikipedia.bridge.CommunicationBridge;
import org.wikipedia.dataclient.WikiSite;
import org.wikipedia.util.UriUtil;
import static org.wikipedia.util.UriUtil.decodeURL;
import static org.wikipedia.util.UriUtil.handleExternalLink;
/**
* Handles any html links coming from a {@link org.wikipedia.page.PageFragment}
*/
public abstract class LinkHandler implements CommunicationBridge.JSEventListener, LinkMovementMethodExt.UrlHandler {
private final Context context;
public LinkHandler(Context context) {
this.context = context;
}
public abstract void onPageLinkClicked(String anchor);
public abstract void onInternalLinkClicked(PageTitle title);
// message from JS bridge:
@Override
public void onMessage(String messageType, JSONObject messagePayload) {
try {
String href = decodeURL(messagePayload.getString("href"));
onUrlClick(href, messagePayload.getString("title"));
} catch (IllegalArgumentException e) {
// The URL is malformed and URL decoder can't understand it. Just do nothing.
Log.d("Wikipedia", "A malformed URL was tapped.");
} catch (JSONException e) {
throw new RuntimeException(e);
}
}
@Override
public void onUrlClick(@NonNull String href, @Nullable String titleString) {
if (href.startsWith("//")) {
// That's a protocol specific link! Make it https!
href = "https:" + href;
}
Log.d("Wikipedia", "Link clicked was " + href);
if (href.startsWith("/wiki/")) {
PageTitle title = TextUtils.isEmpty(titleString)
? getWikiSite().titleForInternalLink(href)
: PageTitle.withSeparateFragment(titleString, UriUtil.getFragment(href), getWikiSite());
onInternalLinkClicked(title);
} else if (href.startsWith("#")) {
onPageLinkClicked(href.substring(1));
} else {
Uri uri = Uri.parse(href);
String authority = uri.getAuthority();
// FIXME: Make this more complete, only to not handle URIs that contain unsupported actions
if (authority != null && WikiSite.supportedAuthority(authority) && uri.getPath().startsWith("/wiki/")) {
WikiSite wiki = new WikiSite(authority, getWikiSite().languageCode());
PageTitle title = wiki.titleForUri(uri);
onInternalLinkClicked(title);
} else {
// if it's a /w/ URI, turn it into a full URI and go external
if (href.startsWith("/w/")) {
href = String.format("%1$s://%2$s", getWikiSite().scheme(), getWikiSite().authority()) + href;
}
handleExternalLink(context, Uri.parse(href));
}
}
}
public abstract WikiSite getWikiSite();
}