Untitled
unknown
plain_text
4 years ago
44 kB
4
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...