Untitled
unknown
plain_text
5 years ago
44 kB
10
Indexable
package com.folioreader.fragments;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.Observer;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.core.content.ContextCompat;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.webkit.JavascriptInterface;
import android.webkit.JsResult;
import android.webkit.WebChromeClient;
import android.webkit.WebResourceRequest;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.TextView;
import android.widget.Toast;
import com.folioreader.AnnotationEpubSourceType;
import com.folioreader.Config;
import com.folioreader.R;
import com.folioreader.activity.FolioActivity;
import com.folioreader.model.Highlight;
import com.folioreader.model.ReloadData;
import com.folioreader.model.RewindIndex;
import com.folioreader.model.Sentence;
import com.folioreader.model.WebViewPosition;
import com.folioreader.quickaction.ActionItem;
import com.folioreader.quickaction.QuickAction;
import com.folioreader.smil.TextElement;
import com.folioreader.sqlite.HighLightTable;
import com.folioreader.util.AppUtil;
import com.folioreader.util.HighlightUtil;
import com.folioreader.util.UiUtil;
import com.folioreader.view.ObservableWebView;
import com.folioreader.view.VerticalSeekbar;
import com.squareup.otto.Subscribe;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Locale;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@SuppressLint("SetJavaScriptEnabled")
public class FolioPageFragment extends Fragment {
public static final String KEY_FRAGMENT_FOLIO_POSITION = "com.folioreader.fragments.FolioPageFragment.POSITION";
public static final String KEY_FRAGMENT_FOLIO_BOOK_TITLE = "com.folioreader.fragments.FolioPageFragment.BOOK_TITLE";
public static final String KEY_FRAGMENT_EPUB_FILE_NAME = "com.folioreader.fragments.FolioPageFragment.EPUB_FILE_NAME";
public static final String KEY_FRAGMENT_EPUB_DESTINATION_PATH = "com.folioreader.fragments.FolioPageFragment.EPUB_DESTINATION_PATH";
public static final String KEY_FRAGMENT_EPUB_SOURCE_TYPE = "com.folioreader.fragments.FolioPageFragment.EPUB_SOURCE_TYPE";
public static final String SP_FOLIO_PAGE_FRAGMENT = "com.folioreader.fragments.FolioPageFragment.SP_FOLIO_PAGE_FRAGMENT";
public static final String TAG = FolioPageFragment.class.getSimpleName();
private static final String KEY_IS_SMIL_AVAILABLE = "com.folioreader.fragments.FolioPageFragment.IS_SMIL_AVAILABLE";
private static final int ACTION_ID_COPY = 1001;
private static final int ACTION_ID_SHARE = 1002;
private static final int ACTION_ID_HIGHLIGHT = 1003;
private static final int ACTION_ID_DEFINE = 1004;
private static final int ACTION_ID_HIGHLIGHT_COLOR = 1005;
private static final int ACTION_ID_DELETE = 1006;
private static final int ACTION_ID_HIGHLIGHT_YELLOW = 1007;
private static final int ACTION_ID_HIGHLIGHT_GREEN = 1008;
private static final int ACTION_ID_HIGHLIGHT_BLUE = 1009;
private static final int ACTION_ID_HIGHLIGHT_PINK = 1010;
private static final int ACTION_ID_HIGHLIGHT_UNDERLINE = 1011;
private static final String KEY_TEXT_ELEMENTS = "text_elements";
private WebViewPosition mWebviewposition;
private String mBookTitle;
private String mHtmlContent;
private String mPageHref;
private View mRootView;
private Context mContext;
private VerticalSeekbar mScrollSeekbar;
private ObservableWebView mWebview;
private TextView mPagesLeftTextView, mMinutesLeftTextView;
private FolioPageFragmentCallback mActivityCallback;
private int mScrollY;
private int mTotalMinutes;
private String mSelectedText;
private boolean mIsSpeaking = true;
private Map<String, String> mHighlightMap;
private Handler mHandler = new Handler();
private Animation mFadeInAnimation, mFadeOutAnimation;
private ArrayList<TextElement> mTextElementList;
private int mPosition = -1;
private boolean mIsSmilAvailable;
private int mPos;
private boolean mIsPageReloaded;
private int mLastWebviewScrollpos;
private Runnable mHideSeekbarRunnable = new Runnable() {
@Override
public void run() {
fadeoutSeekbarIfVisible();
}
};
private MutableLiveData<Boolean> isFragmentVisible = new MutableLiveData<>();
public static FolioPageFragment newInstance(int position, String bookTitle, String epubFileName, ArrayList<TextElement> textElementArrayList, boolean isSmileAvailable) {
FolioPageFragment fragment = new FolioPageFragment();
Bundle args = new Bundle();
args.putInt(KEY_FRAGMENT_FOLIO_POSITION, position);
args.putString(KEY_FRAGMENT_FOLIO_BOOK_TITLE, bookTitle);
args.putString(KEY_FRAGMENT_EPUB_FILE_NAME, epubFileName);
args.putParcelableArrayList(KEY_TEXT_ELEMENTS, textElementArrayList);
args.putBoolean(KEY_IS_SMIL_AVAILABLE, isSmileAvailable);
fragment.setArguments(args);
return fragment;
}
public static FolioPageFragment newInstance(int position,
String bookTitle,
String epubFileName,
String destinationPath,
@AnnotationEpubSourceType.EpubSourceType int sourceType,
ArrayList<TextElement> textElementArrayList,
boolean isSmileAvailable) {
FolioPageFragment fragment = new FolioPageFragment();
Bundle args = new Bundle();
args.putInt(KEY_FRAGMENT_FOLIO_POSITION, position);
args.putString(KEY_FRAGMENT_FOLIO_BOOK_TITLE, bookTitle);
args.putString(KEY_FRAGMENT_EPUB_FILE_NAME, epubFileName);
args.putString(KEY_FRAGMENT_EPUB_DESTINATION_PATH, destinationPath);
args.putInt(KEY_FRAGMENT_EPUB_SOURCE_TYPE, sourceType);
args.putParcelableArrayList(KEY_TEXT_ELEMENTS, textElementArrayList);
args.putBoolean(KEY_IS_SMIL_AVAILABLE, isSmileAvailable);
fragment.setArguments(args);
return fragment;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mContext = getActivity();
if (getActivity() instanceof FolioPageFragmentCallback) {
mActivityCallback = (FolioPageFragmentCallback) getActivity();
}
mPosition = getArguments().getInt(KEY_FRAGMENT_FOLIO_POSITION);
mBookTitle = getArguments().getString(KEY_FRAGMENT_FOLIO_BOOK_TITLE);
mIsSmilAvailable = getArguments().getBoolean(KEY_IS_SMIL_AVAILABLE);
mTextElementList = getArguments().getParcelableArrayList(KEY_TEXT_ELEMENTS);
mHtmlContent = getHtmlContent(mActivityCallback.getChapterHtmlContent(mPosition));
mPageHref = mActivityCallback.getPageHref(mPosition);
mRootView = View.inflate(getActivity(), R.layout.folio_page_fragment, null);
mWebview = mRootView.findViewById(R.id.contentWebView);
mPagesLeftTextView = mRootView.findViewById(R.id.pagesLeft);
mMinutesLeftTextView = mRootView.findViewById(R.id.minutesLeft);
FolioActivity.BUS.register(this);
initSeekbar();
initAnimations();
observeFragmentVisibility();
return mRootView;
}
private void observeFragmentVisibility() {
isFragmentVisible.observe(this, new Observer<Boolean>() {
@Override
public void onChanged(@Nullable Boolean isVisible) {
if (isVisible) initWebView(mHtmlContent);
}
});
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
float positionTopView = mWebview.getTop();
float contentHeight = mWebview.getContentHeight();
float currentScrollPosition = mScrollY;
float percentWebview = (currentScrollPosition - positionTopView) / contentHeight;
float webviewsize = mWebview.getContentHeight() - mWebview.getTop();
float positionInWV = webviewsize * percentWebview;
mScrollY = Math.round(mWebview.getTop() + positionInWV);
}
private void initWebView(String htmlContent) {
mWebview.setFragment(FolioPageFragment.this);
mWebview.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
int height = (int) Math.floor(mWebview.getContentHeight() * mWebview.getCurrentScale());
int webViewHeight = mWebview.getMeasuredHeight();
mScrollSeekbar.setMaximum(height - webViewHeight);
}
});
mWebview.getSettings().setJavaScriptEnabled(true);
mWebview.getSettings().setAllowFileAccess(true);
mWebview.getSettings().setDefaultTextEncodingName("utf-8");
mWebview.getSettings().setUseWideViewPort(true);
mWebview.getSettings().setLoadWithOverviewMode(true);
mWebview.getSettings().setBuiltInZoomControls(true);
mWebview.getSettings().setDisplayZoomControls(false);
//<editor-fold desc="Improve webView performance">
mWebview.setLayerType(View.LAYER_TYPE_HARDWARE, null);
mWebview.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ONLY);
mWebview.getSettings().setAppCacheEnabled(true);
mWebview.getSettings().setDomStorageEnabled(true);
//</editor-fold>
mWebview.setVerticalScrollBarEnabled(false);
mWebview.setHorizontalScrollBarEnabled(false);
//<editor-fold desc="Disable webView selection text">
mWebview.setLongClickable(false);
mWebview.setHapticFeedbackEnabled(false);
mWebview.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
return true;
}
});
//</editor-fold>
mWebview.setScrollListener(new ObservableWebView.ScrollListener() {
@Override
public void onScrollChange(int percent) {
if (mWebview.getScrollY() != 0) {
mScrollY = mWebview.getScrollY();
((FolioActivity) getActivity()).setLastWebViewPosition(mScrollY);
}
mScrollSeekbar.setProgressAndThumb(percent);
updatePagesLeftText(percent);
}
});
mWebview.setWebViewClient(new WebViewClient() {
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
updateTextSize();
updateIndicatorView();
}
@Override
public void onPageFinished(WebView view, String url) {
if (isAdded()) {
updateIndicatorView();
if (mWebviewposition != null) {
setWebViewPosition(mWebviewposition.getWebviewPos());
} else if (!((FolioActivity) getActivity()).isbookOpened() && isCurrentFragment()) {
setWebViewPosition(AppUtil.getPreviousBookStateWebViewPosition(mContext, mBookTitle));
((FolioActivity) getActivity()).setIsbookOpened(true);
} else if (mIsPageReloaded) {
mIsPageReloaded = false;
}
mWebview.loadUrl("javascript:alert(getReadingTime())");
if (!mIsSmilAvailable) {
mWebview.loadUrl("javascript:alert(wrappingSentencesWithinPTags())");
mWebview.loadUrl(String.format(getString(R.string.setmediaoverlaystyle),
Highlight.HighlightStyle.classForStyle(Highlight.HighlightStyle.Normal)));
}
}
}
@Override
public void onScaleChanged(WebView view, float oldScale, float newScale) {
super.onScaleChanged(view, oldScale, newScale);
mWebview.setScale(newScale);
}
@SuppressWarnings("deprecation")
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (!url.isEmpty() && url.length() > 0) {
if (Uri.parse(url).getScheme().startsWith("highlight")) {
final Pattern pattern = Pattern.compile(getString(R.string.pattern));
try {
String htmlDecode = URLDecoder.decode(url, "UTF-8");
Matcher matcher = pattern.matcher(htmlDecode.substring(12));
if (matcher.matches()) {
double left = Double.parseDouble(matcher.group(1));
double top = Double.parseDouble(matcher.group(2));
double width = Double.parseDouble(matcher.group(3));
double height = Double.parseDouble(matcher.group(4));
onHighlight((int) (UiUtil.convertDpToPixel((float) left,
getActivity())),
(int) (UiUtil.convertDpToPixel((float) top,
getActivity())),
(int) (UiUtil.convertDpToPixel((float) width,
getActivity())),
(int) (UiUtil.convertDpToPixel((float) height,
getActivity())));
}
} catch (UnsupportedEncodingException e) {
Log.d(TAG, e.getMessage());
}
} else {
if (url.contains("storage")) {
mActivityCallback.setPagerToPosition(url);
} else {
// Otherwise, give the default behavior (open in browser)
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(intent);
}
}
}
return true;
}
@TargetApi(Build.VERSION_CODES.N)
@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
if (request != null && request.getUrl() != null) {
String url = request.getUrl().toString();
if (request.getUrl().getScheme().startsWith("highlight")) {
final Pattern pattern = Pattern.compile(getString(R.string.pattern));
try {
String htmlDecode = URLDecoder.decode(url, "UTF-8");
Matcher matcher = pattern.matcher(htmlDecode.substring(12));
if (matcher.matches()) {
double left = Double.parseDouble(matcher.group(1));
double top = Double.parseDouble(matcher.group(2));
double width = Double.parseDouble(matcher.group(3));
double height = Double.parseDouble(matcher.group(4));
onHighlight((int) (UiUtil.convertDpToPixel((float) left,
getActivity())),
(int) (UiUtil.convertDpToPixel((float) top,
getActivity())),
(int) (UiUtil.convertDpToPixel((float) width,
getActivity())),
(int) (UiUtil.convertDpToPixel((float) height,
getActivity())));
}
} catch (UnsupportedEncodingException e) {
Log.d(TAG, e.getMessage());
}
} else {
if (url.contains("storage")) {
mActivityCallback.setPagerToPosition(url);
} else {
// Otherwise, give the default behavior (open in browser)
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(intent);
}
}
}
return true;
}
});
mWebview.setWebChromeClient(new WebChromeClient() {
@Override
public void onProgressChanged(WebView view, int progress) {
if (view.getProgress() == 100) {
mWebview.postDelayed(new Runnable() {
@Override
public void run() {
mWebview.scrollTo(0, mScrollY);
}
}, 100);
}
}
@Override
public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
Log.d("FolioPageFragment", "Message from js: " + message);
if (FolioPageFragment.this.isVisible()) {
if (TextUtils.isDigitsOnly(message)) {
mTotalMinutes = Math.round(Integer.parseInt(message) / 60);
((FolioActivity) getActivity()).setMaxDuration(Double.parseDouble(message));
} else {
final Pattern pattern = Pattern.compile(getString(R.string.pattern));
Matcher matcher = pattern.matcher(message);
if (matcher.matches()) {
double left = Double.parseDouble(matcher.group(1));
double top = Double.parseDouble(matcher.group(2));
double width = Double.parseDouble(matcher.group(3));
double height = Double.parseDouble(matcher.group(4));
showTextSelectionMenu((int) (UiUtil.convertDpToPixel((float) left,
getActivity())),
(int) (UiUtil.convertDpToPixel((float) top,
getActivity())),
(int) (UiUtil.convertDpToPixel((float) width,
getActivity())),
(int) (UiUtil.convertDpToPixel((float) height,
getActivity())));
} else {
if (mIsSpeaking && (!message.equals("undefined"))) {
if (isCurrentFragment()) {
Sentence sentence = new Sentence(message);
FolioActivity.BUS.post(sentence);
}
}
}
}
result.confirm();
}
return true;
}
});
//TODO : disable text selection
// TextSelectionSupport mTextSelectionSupport = TextSelectionSupport.support(getActivity(), mWebview);
// mTextSelectionSupport.setSelectionListener(new TextSelectionSupport.SelectionListener() {
// @Override
// public void startSelection() {
// }
//
// @Override
// public void selectionChanged(String text) {
// mSelectedText = text;
// getActivity().runOnUiThread(new Runnable() {
// @Override
// public void run() {
// mWebview.loadUrl("javascript:alert(getRectForSelectedText())");
// }
// });
// }
//
// @Override
// public void endSelection() {
//
// }
// });
// mWebview.addJavascriptInterface(this, "Highlight");
mWebview.loadDataWithBaseURL(
baseUrl(), mHtmlContent, "text/html", "UTF-8", null);
((FolioActivity) getActivity()).setLastWebViewPosition(mScrollY);
}
private void initSeekbar() {
mScrollSeekbar = mRootView.findViewById(R.id.scrollSeekbar);
mScrollSeekbar.getProgressDrawable()
.setColorFilter(ContextCompat.getColor(getActivity(), R.color.app_blue),
PorterDuff.Mode.SRC_IN);
}
private String baseUrl() {
return String.format("file://%s", mPageHref);
}
private void evaluateJavaScript(String javaScript) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
mWebview.evaluateJavascript("javascript:" + javaScript, null);
} else {
mWebview.loadUrl("javascript:" + javaScript);
}
}
private String javaScriptCSS() {
StringBuilder builder = new StringBuilder();
builder.append("function addCSSRule(selector, newRule) {" +
"if (document.styleSheets[0].addRule) {" +
"document.styleSheets[0].addRule(selector, newRule);" +
"} else {" +
"ruleIndex = document.styleSheets[0].cssRules.length;" +
"document.styleSheets[0].insertRule(selector + '{' + newRule + ';}', ruleIndex);" +
"}" +
"}");
builder.append("addCSSRule('html', 'padding: 0px !important; word-wrap:break-word;');");
builder.append("addCSSRule('img', 'display: block; margin: auto; horizontal-align: middle; height: auto !important; max-width: 100% !important;');");
builder.append("addCSSRule('svg', 'horizontal-align: middle; max-width: 100% !important; height:auto; max-height: 100% !important;');");
if (Config.getConfig(mContext).isNightMode()) {
builder.append("addCSSRule('body', 'background-color: #131313 !important; -webkit-text-fill-color: #bcbeb0;');");
// } else {
// builder.append("document.styleSheets[0].cssRules[0].style.removeProperty('-webkit-text-fill-color');");
// builder.append("addCSSRule('body', 'background-color: transparent !important');");
}
String fontFamily = "";
switch (Config.getConfig(mContext).getFont()) {
case 0:
fontFamily = "andada, sans-serif";
break;
case 1:
fontFamily = "lato, serif";
break;
case 2:
fontFamily = "lora, serif";
break;
case 3:
fontFamily = "raleway, sans-serif";
break;
default:
break;
}
builder.append(String.format(Locale.US, "addCSSRule('body', 'font-family: %s !important;');", fontFamily));
builder.append(String.format(Locale.US, "addCSSRule('p', 'text-align: left !important; line-height: 150%% !important; margin-bottom: 1em !important; font-family: %s !important;');", fontFamily));
builder.append(String.format(Locale.US, "addCSSRule('span', 'font-family: %s !important;');", fontFamily));
builder.append(String.format(Locale.US, "addCSSRule('div', 'font-family: %s !important;');", fontFamily));
return builder.toString();
}
private void updateIndicatorView() {
if (Config.getConfig(mContext).isNightMode()) {
mRootView.findViewById(R.id.indicatorLayout)
.setBackgroundColor(Color.parseColor("#131313"));
} else {
mRootView.findViewById(R.id.indicatorLayout)
.setBackgroundColor(Color.WHITE);
}
}
private void updateTextSize() {
int fontSizePercentage;
switch (Config.getConfig(mContext).getFontSize()) {
case 0:
fontSizePercentage = 80;
break;
case 2:
fontSizePercentage = 120;
break;
case 3:
fontSizePercentage = 140;
break;
case 4:
fontSizePercentage = 160;
break;
default:
fontSizePercentage = 100;
break;
}
if (mActivityCallback.isFixedLayout()) {
mWebview.getSettings().setTextZoom(fontSizePercentage);
} else {
mWebview.getSettings().setTextZoom(fontSizePercentage * 3);
}
}
private void updatePagesLeftText(int scrollY) {
try {
int totalPages = (int) Math.ceil((double) mWebview.getContentHeightVal() / mWebview.getWebviewHeight());
int currentPage = (int) (Math.ceil((double) scrollY / mWebview.getWebviewHeight()) + 1);
int pagesRemaining = totalPages - currentPage;
String pagesRemainingStrFormat =
pagesRemaining > 1 ?
getString(R.string.pages_left) : getString(R.string.page_left);
String pagesRemainingStr = String.format(Locale.US,
pagesRemainingStrFormat, pagesRemaining);
int minutesRemaining =
(int) Math.ceil((double) (pagesRemaining * mTotalMinutes) / totalPages);
String minutesRemainingStr;
if (minutesRemaining > 1) {
minutesRemainingStr =
String.format(Locale.US, getString(R.string.minutes_left),
minutesRemaining);
} else if (minutesRemaining == 1) {
minutesRemainingStr =
String.format(Locale.US, getString(R.string.minute_left),
minutesRemaining);
} else {
minutesRemainingStr = getString(R.string.less_than_minute);
}
mMinutesLeftTextView.setText(minutesRemainingStr);
mPagesLeftTextView.setText(pagesRemainingStr);
} catch (java.lang.ArithmeticException exp) {
Log.d("divide error", exp.toString());
}
}
private void initAnimations() {
mFadeInAnimation = AnimationUtils.loadAnimation(getActivity(), R.anim.fadein);
mFadeInAnimation.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
mScrollSeekbar.setVisibility(View.VISIBLE);
}
@Override
public void onAnimationEnd(Animation animation) {
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
mFadeOutAnimation = AnimationUtils.loadAnimation(getActivity(), R.anim.fadeout);
mFadeOutAnimation.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
mScrollSeekbar.setVisibility(View.INVISIBLE);
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
}
public void fadeInSeekbarIfInvisible() {
if (mScrollSeekbar.getVisibility() == View.INVISIBLE ||
mScrollSeekbar.getVisibility() == View.GONE) {
mScrollSeekbar.startAnimation(mFadeInAnimation);
}
}
private void fadeoutSeekbarIfVisible() {
if (mScrollSeekbar.getVisibility() == View.VISIBLE) {
mScrollSeekbar.startAnimation(mFadeOutAnimation);
}
}
@Override
public void onDestroyView() {
mFadeInAnimation.setAnimationListener(null);
mFadeOutAnimation.setAnimationListener(null);
super.onDestroyView();
}
@Subscribe
public void reload(ReloadData reloadData) {
if (!isAdded()) return;
mLastWebviewScrollpos = mWebview.getScrollY();
switch (reloadData.getFlag()) {
case ReloadData.FONT_SIZE:
updateTextSize();
break;
default:
mIsPageReloaded = true;
String htmlContent = getHtmlContent(mActivityCallback.getChapterHtmlContent(mPosition));
mWebview.loadDataWithBaseURL(baseUrl(), htmlContent, "text/html", "UTF-8", null);
break;
}
}
@Subscribe
public void highLightString(Integer position) {
if (isAdded()) {
if (mTextElementList != null) {
String src = mTextElementList.get(position.intValue()).getSrc();
String[] temp = src.split("#");
String textId = temp[1];
mWebview.loadUrl(String.format(getString(R.string.audio_mark_id), textId));
}
}
}
@Subscribe
public void getTextSentence(Boolean isSpeaking) {
if (isCurrentFragment()) {
mIsSpeaking = true;
mWebview.loadUrl("javascript:alert(getSentenceWithIndex('epub-media-overlay-playing'))");
}
}
@Subscribe
public void setStyle(String style) {
if (isAdded()) {
mWebview.loadUrl(String.format(getString(R.string.setmediaoverlaystyle), style));
}
}
private String getHtmlContent(String htmlContent) {
String cssPath =
String.format(getString(R.string.css_tag), "file:///android_asset/Style.css");
String jsPath =
String.format(getString(R.string.script_tag),
"file:///android_asset/Bridge.js");
jsPath =
jsPath + String.format(getString(R.string.script_tag),
"file:///android_asset/jquery-1.8.3.js");
jsPath =
jsPath + String.format(getString(R.string.script_tag),
"file:///android_asset/jpntext.js");
jsPath =
jsPath + String.format(getString(R.string.script_tag),
"file:///android_asset/rangy-core.js");
jsPath =
jsPath + String.format(getString(R.string.script_tag),
"file:///android_asset/rangy-serializer.js");
jsPath =
jsPath + String.format(getString(R.string.script_tag),
"file:///android_asset/android.selection.js");
jsPath =
jsPath + String.format(getString(R.string.script_tag_method_call),
"setMediaOverlayStyleColors('#C0ED72','#C0ED72')");
String toInject = "\n" + cssPath + "\n" + jsPath + "\n</head>";
htmlContent = htmlContent.replace("</head>", toInject);
//TODO: Remark to replace original css
// String toInject = "<head>\n" + cssPath + "\n" + jsPath + "\n</head>";
// htmlContent = htmlContent.replaceAll("(<head>)(?s).*(</head>)", toInject);
//
htmlContent = htmlContent.replaceAll("\\r|\\n", "");
htmlContent = htmlContent.replace("\t", "");
//TODO : remark to active highlight
// ArrayList<Highlight> highlights = HighLightTable.getAllHighlights(mBookTitle);
// for (Highlight highlight : highlights) {
// String searchStr = highlight.getContentPre() + highlight.getContent() + highlight.getContentPost();
// if (htmlContent.contains(searchStr)) {
// String highlightStr =
// "<highlight id=\"" + highlight.getHighlightId() +
// "\" onclick=\"callHighlightURL(this);\" class=\"" +
// highlight.getType() + "\">" + highlight.getContent() + "</highlight>";
// String replacement = highlight.getContentPre() + highlightStr + highlight.getContentPost();
// htmlContent = htmlContent.replaceFirst(Pattern.quote(searchStr), replacement);
// }
// }
// htmlContent = htmlContent.replaceAll("\\.\\.\\/", String.format("file://%s", parentPath()));
// Disable styling
htmlContent = htmlContent.replace("</body>", String.format("<script>%s</script></body>", javaScriptCSS()));
return htmlContent;
}
public String getSelectedText() {
return mSelectedText;
}
public void highlight(Highlight.HighlightStyle style, boolean isCreated) {
if (isCreated) {
mWebview.loadUrl(String.format(getString(R.string.getHighlightString),
Highlight.HighlightStyle.classForStyle(style)));
} else {
mWebview.loadUrl(String.format(getString(R.string.sethighlightstyle),
Highlight.HighlightStyle.classForStyle(style)));
}
}
public void highlightRemove() {
mWebview.loadUrl("javascript:alert(removeThisHighlight())");
}
public void showTextSelectionMenu(int x, int y, final int width, final int height) {
final ViewGroup root =
getActivity().getWindow()
.getDecorView().findViewById(android.R.id.content);
final View view = new View(getActivity());
view.setLayoutParams(new ViewGroup.LayoutParams(width, height));
view.setBackgroundColor(Color.TRANSPARENT);
root.addView(view);
view.setX(x);
view.setY(y);
final QuickAction quickAction =
new QuickAction(getActivity(), QuickAction.HORIZONTAL);
quickAction.addActionItem(new ActionItem(ACTION_ID_COPY,
getString(R.string.copy)));
quickAction.addActionItem(new ActionItem(ACTION_ID_HIGHLIGHT,
getString(R.string.highlight)));
// quickAction.addActionItem(new ActionItem(ACTION_ID_DEFINE,
// getString(R.string.define)));
quickAction.addActionItem(new ActionItem(ACTION_ID_SHARE,
getString(R.string.share)));
quickAction.setOnActionItemClickListener(new QuickAction.OnActionItemClickListener() {
@Override
public void onItemClick(QuickAction source, int pos, int actionId) {
quickAction.dismiss();
root.removeView(view);
onTextSelectionActionItemClicked(actionId, view, width, height);
}
});
quickAction.show(view, width, height);
}
private void onTextSelectionActionItemClicked(int actionId, View view, int width, int height) {
if (actionId == ACTION_ID_COPY) {
UiUtil.copyToClipboard(mContext, mSelectedText);
Toast.makeText(mContext, getString(R.string.copied), Toast.LENGTH_SHORT).show();
} else if (actionId == ACTION_ID_SHARE) {
UiUtil.share(mContext, mSelectedText);
} else if (actionId == ACTION_ID_DEFINE) {
//TODO: Check how to use define
} else if (actionId == ACTION_ID_HIGHLIGHT) {
onHighlight(view, width, height, true);
}
}
private void onHighlight(int x, int y, int width, int height) {
final View view = new View(getActivity());
view.setLayoutParams(new ViewGroup.LayoutParams(width, height));
view.setBackgroundColor(Color.TRANSPARENT);
view.setX(x);
view.setY(y);
onHighlight(view, width, height, false);
}
private void onHighlight(final View view, int width, int height, final boolean isCreated) {
ViewGroup root =
getActivity().getWindow().
getDecorView().findViewById(android.R.id.content);
ViewGroup parent = (ViewGroup) view.getParent();
if (parent == null) {
root.addView(view);
} else {
final int index = parent.indexOfChild(view);
parent.removeView(view);
parent.addView(view, index);
}
final QuickAction quickAction = new QuickAction(getActivity(), QuickAction.HORIZONTAL);
quickAction.addActionItem(new ActionItem(ACTION_ID_HIGHLIGHT_COLOR,
ContextCompat.getDrawable(getActivity(), R.drawable.colors_marker)));
quickAction.addActionItem(new ActionItem(ACTION_ID_DELETE,
ContextCompat.getDrawable(getActivity(), R.drawable.ic_action_discard)));
quickAction.addActionItem(new ActionItem(ACTION_ID_SHARE,
ContextCompat.getDrawable(getActivity(), R.drawable.ic_action_share)));
final ViewGroup finalRoot = root;
quickAction.setOnActionItemClickListener(new QuickAction.OnActionItemClickListener() {
@Override
public void onItemClick(QuickAction source, int pos, int actionId) {
quickAction.dismiss();
finalRoot.removeView(view);
onHighlightActionItemClicked(actionId, view, isCreated);
}
});
quickAction.show(view, width, height);
}
private void onHighlightActionItemClicked(int actionId, View view, boolean isCreated) {
if (actionId == ACTION_ID_HIGHLIGHT_COLOR) {
onHighlightColors(view, isCreated);
} else if (actionId == ACTION_ID_SHARE) {
UiUtil.share(mContext, mSelectedText);
} else if (actionId == ACTION_ID_DELETE) {
highlightRemove();
}
}
private void onHighlightColors(final View view, final boolean isCreated) {
ViewGroup root =
getActivity().getWindow()
.getDecorView().findViewById(android.R.id.content);
ViewGroup parent = (ViewGroup) view.getParent();
if (parent == null) {
root.addView(view);
} else {
final int index = parent.indexOfChild(view);
parent.removeView(view);
parent.addView(view, index);
}
final QuickAction quickAction = new QuickAction(getActivity(), QuickAction.HORIZONTAL);
quickAction.addActionItem(new ActionItem(ACTION_ID_HIGHLIGHT_YELLOW,
ContextCompat.getDrawable(getActivity(), R.drawable.ic_yellow_marker)));
quickAction.addActionItem(new ActionItem(ACTION_ID_HIGHLIGHT_GREEN,
ContextCompat.getDrawable(getActivity(), R.drawable.ic_green_marker)));
quickAction.addActionItem(new ActionItem(ACTION_ID_HIGHLIGHT_BLUE,
ContextCompat.getDrawable(getActivity(), R.drawable.ic_blue_marker)));
quickAction.addActionItem(new ActionItem(ACTION_ID_HIGHLIGHT_PINK,
ContextCompat.getDrawable(getActivity(), R.drawable.ic_pink_marker)));
quickAction.addActionItem(new ActionItem(ACTION_ID_HIGHLIGHT_UNDERLINE,
ContextCompat.getDrawable(getActivity(), R.drawable.ic_underline_marker)));
final ViewGroup finalRoot = root;
quickAction.setOnActionItemClickListener(new QuickAction.OnActionItemClickListener() {
@Override
public void onItemClick(QuickAction source, int pos, int actionId) {
quickAction.dismiss();
finalRoot.removeView(view);
onHighlightColorsActionItemClicked(actionId, view, isCreated);
}
});
quickAction.show(view);
}
private void onHighlightColorsActionItemClicked(int actionId, View view, boolean isCreated) {
if (actionId == ACTION_ID_HIGHLIGHT_YELLOW) {
highlight(Highlight.HighlightStyle.Yellow, isCreated);
} else if (actionId == ACTION_ID_HIGHLIGHT_GREEN) {
highlight(Highlight.HighlightStyle.Green, isCreated);
} else if (actionId == ACTION_ID_HIGHLIGHT_BLUE) {
highlight(Highlight.HighlightStyle.Blue, isCreated);
} else if (actionId == ACTION_ID_HIGHLIGHT_PINK) {
highlight(Highlight.HighlightStyle.Pink, isCreated);
} else if (actionId == ACTION_ID_HIGHLIGHT_UNDERLINE) {
highlight(Highlight.HighlightStyle.Underline, isCreated);
}
}
@JavascriptInterface
public void getHighlightJson(String mJsonResponse) {
if (mJsonResponse != null) {
mHighlightMap = AppUtil.stringToJsonMap(mJsonResponse);
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
mWebview.loadUrl("javascript:alert(getHTML())");
}
});
}
}
@JavascriptInterface
public void getHtmlAndSaveHighlight(String html) {
if (html != null && mHighlightMap != null) {
Highlight highlight =
HighlightUtil.matchHighlight(html, mHighlightMap.get("id"), mBookTitle, mPosition);
highlight.setCurrentWebviewScrollPos(mWebview.getScrollY());
highlight = ((FolioActivity) getActivity()).setCurrentPagerPostion(highlight);
HighLightTable.insertHighlight(highlight);
}
}
public void setWebViewPosition(final int position) {
mWebview.postDelayed(new Runnable() {
@Override
public void run() {
mWebview.scrollTo(0, position);
}
}, 300);
}
@JavascriptInterface
public void getRemovedHighlightId(String id) {
if (id != null) {
HighLightTable.deleteHighlight(id);
}
}
@JavascriptInterface
public void getUpdatedHighlightId(String id, String style) {
if (id != null) {
HighLightTable.updateHighlightStyle(id, style);
}
}
public void removeCallback() {
mHandler.removeCallbacks(mHideSeekbarRunnable);
}
public void startCallback() {
mHandler.postDelayed(mHideSeekbarRunnable, 3000);
}
@Subscribe
public void resetCurrentIndex(RewindIndex resetIndex) {
if (isCurrentFragment()) {
mWebview.loadUrl("javascript:alert(rewindCurrentIndex())");
}
}
private boolean isCurrentFragment() {
return isAdded() && ((FolioActivity) getActivity()).getmChapterPosition() == mPos;
}
public void setFragmentPos(int pos) {
mPos = pos;
}
@Subscribe
public void setTextElementList(ArrayList<TextElement> textElementList) {
if (textElementList != null && textElementList.size() > 0) {
mIsSmilAvailable = true;
mTextElementList = textElementList;
}
}
@Subscribe
public void setWebviewToHighlightPos(final WebViewPosition webViewPosition) {
mWebviewposition = webViewPosition;
if (isAdded()) {
setWebViewPosition(mWebviewposition.getWebviewPos());
}
}
public interface FolioPageFragmentCallback {
String getChapterHtmlContent(int position);
String getPageHref(int position);
void hideOrshowToolBar();
void hideToolBarIfVisible();
void setPagerToPosition(String href);
void setLastWebViewPosition(int position);
boolean isFixedLayout();
}
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
isFragmentVisible.postValue(isVisibleToUser);
}
}Editor is loading...