diff --git a/app/src/main/assets/scroll-sync/scroll-sync.js b/app/src/main/assets/scroll-sync/scroll-sync.js new file mode 100644 index 00000000000..17e65cabc7b --- /dev/null +++ b/app/src/main/assets/scroll-sync/scroll-sync.js @@ -0,0 +1,65 @@ +/** + * Scroll to the target element by source line number (generally the first visible line number). + * Params: lineNumber - the line number of source code in the editor. + */ +function edit2Preview(lineNumber) { + let increment = 0; + let direction = 0; + let number = lineNumber; + while (number > 0) { + if (direction > 0) { + number = lineNumber + increment; + direction = -1; + } else if (direction < 0) { + number = lineNumber - increment; + direction = 1; + increment++; + } else { + direction = 1; + increment++; + } + + const elements = document.querySelectorAll("[data-line='" + number + "']"); + if (elements == null) { + continue; + } + + let completed = false; + for (let i = 0; i < elements.length; i++) { + const element = elements[i]; + if (element.offsetHeight > 0) { + element.scrollIntoView(); + completed = true; + break; + } + } + + if (completed) { + break; + } + } +} + +/** + * Find the target line number, that is the value of data-line attribute of target element (generally the first visible element). + * Return: -1 if the target element cannot not be found. + */ +function preview2Edit() { + const elements = document.querySelectorAll("[data-line]"); + if (elements == null) { + return -1; + } + + const TOP_MARGIN = -20; + const BOTTOM_MARGIN = window.innerHeight; + for (let i = 0; i < elements.length; i++) { + const element = elements[i]; + const top = element.getBoundingClientRect().top; + const bottom = element.getBoundingClientRect().bottom; + if (top > TOP_MARGIN && bottom > 0 && bottom < BOTTOM_MARGIN) { + return parseInt(element.getAttribute("data-line")); + } + } + + return -1; +} diff --git a/app/src/main/java/net/gsantner/markor/activity/DocumentEditAndViewFragment.java b/app/src/main/java/net/gsantner/markor/activity/DocumentEditAndViewFragment.java index 49ae64042d7..8cbd64e5354 100644 --- a/app/src/main/java/net/gsantner/markor/activity/DocumentEditAndViewFragment.java +++ b/app/src/main/java/net/gsantner/markor/activity/DocumentEditAndViewFragment.java @@ -63,15 +63,17 @@ import net.gsantner.opoc.util.GsContextUtils; import net.gsantner.opoc.util.GsCoolExperimentalStuff; import net.gsantner.opoc.web.GsWebViewChromeClient; +import net.gsantner.opoc.web.GsWebViewClient; import net.gsantner.opoc.wrapper.GsTextWatcherAdapter; import java.io.File; +import java.util.Collections; @SuppressWarnings({"UnusedReturnValue"}) @SuppressLint("NonConstantResourceId") public class DocumentEditAndViewFragment extends MarkorBaseFragment implements FormatRegistry.TextFormatApplier { public static final String FRAGMENT_TAG = "DocumentEditAndViewFragment"; - public static final String SAVESTATE_DOCUMENT = "DOCUMENT"; + public static final String SAVE_STATE_DOCUMENT = "DOCUMENT"; public static final String START_PREVIEW = "START_PREVIEW"; public static DocumentEditAndViewFragment newInstance(final @NonNull Document document, final Integer lineNumber, final Boolean preview) { @@ -103,6 +105,7 @@ public static DocumentEditAndViewFragment newInstance(final @NonNull Document do private MenuItem _saveMenuItem, _undoMenuItem, _redoMenuItem; private boolean _isPreviewVisible; private boolean _nextConvertToPrintMode = false; + private int _firstVisibleLineNumber = 1; public DocumentEditAndViewFragment() { @@ -113,8 +116,8 @@ public DocumentEditAndViewFragment() { public void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); final Bundle args = getArguments(); - if (savedInstanceState != null && savedInstanceState.containsKey(SAVESTATE_DOCUMENT)) { - _document = (Document) savedInstanceState.getSerializable(SAVESTATE_DOCUMENT); + if (savedInstanceState != null && savedInstanceState.containsKey(SAVE_STATE_DOCUMENT)) { + _document = (Document) savedInstanceState.getSerializable(SAVE_STATE_DOCUMENT); } else if (args != null && args.containsKey(Document.EXTRA_DOCUMENT)) { _document = (Document) args.get(Document.EXTRA_DOCUMENT); } @@ -153,6 +156,16 @@ public void onViewCreated(@NonNull View view, Bundle savedInstanceState) { } _webViewClient = new MarkorWebViewClient(_webView, activity); + _webViewClient.setOnPageFinishedListener(new GsWebViewClient.OnPageFinishedListener() { + @Override + public void onPageFinished(WebView v) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) { + return; + } + _firstVisibleLineNumber = _hlEditor.getFirstVisibleLineNumber(); + _webView.evaluateJavascript("edit2Preview(" + _firstVisibleLineNumber + ");", null); + } + }); _webView.setWebChromeClient(new GsWebViewChromeClient(_webView, activity, view.findViewById(R.id.document__fragment_fullscreen_overlay))); _webView.setWebViewClient(_webViewClient); _webView.addJavascriptInterface(this, "Android"); @@ -286,7 +299,15 @@ public void onPause() { _appSettings.setDocumentPreviewState(_document.path, _isPreviewVisible); _appSettings.setLastEditPosition(_document.path, TextViewUtils.getSelection(_hlEditor)[0]); - if(_document.path.equals(_appSettings.getTodoFile().getAbsolutePath())){ + int y; + if (_webView.isShown()) { + y = _webView.getScrollY(); + } else { + y = _webViewClient.getRestoreScrollY(); + } + _appSettings.setLastViewPositionY(_document.path, y); + + if (_document.path.equals(_appSettings.getTodoFile().getAbsolutePath())) { TodoWidgetProvider.updateTodoWidgets(); } super.onPause(); @@ -294,7 +315,7 @@ public void onPause() { @Override public void onSaveInstanceState(@NonNull Bundle outState) { - outState.putSerializable(SAVESTATE_DOCUMENT, _document); + outState.putSerializable(SAVE_STATE_DOCUMENT, _document); super.onSaveInstanceState(outState); } @@ -861,17 +882,26 @@ public void setViewModeVisibility(boolean show, final boolean animate) { if (show) { updateViewModeText(); _cu.showSoftKeyboard(activity, false, _hlEditor); - _hlEditor.clearFocus(); _hlEditor.postDelayed(() -> _cu.showSoftKeyboard(activity, false, _hlEditor), 300); + _webView.requestFocus(); GsContextUtils.fadeInOut(_webView, _primaryScrollView, animate); } else { _webViewClient.setRestoreScrollY(_webView.getScrollY()); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { + _webView.evaluateJavascript("preview2Edit();", result -> { + if (Character.isDigit(result.charAt(0))) { + final int lineNumber = Integer.parseInt(result); + if (lineNumber > 0 && (lineNumber < _firstVisibleLineNumber - 2 || lineNumber > _firstVisibleLineNumber + 2)) { + TextViewUtils.selectLines(_hlEditor, false, Collections.singletonList(lineNumber)); + } + } + }); + } + _hlEditor.requestFocus(); GsContextUtils.fadeInOut(_primaryScrollView, _webView, animate); } - - _nextConvertToPrintMode = false; _isPreviewVisible = show; - + _nextConvertToPrintMode = false; ((AppCompatActivity) activity).supportInvalidateOptionsMenu(); } @@ -896,7 +926,15 @@ protected void onToolbarClicked(View v) { @Override protected boolean onToolbarLongClicked(View v) { if (isVisible() && isResumed()) { - _format.getActions().runJumpBottomTopAction(_isPreviewVisible ? ActionButtonBase.ActionItem.DisplayMode.VIEW : ActionButtonBase.ActionItem.DisplayMode.EDIT); + if (_isPreviewVisible) { + if (_webViewClient.getRestoreScrollY() < 1) { + final int y = _appSettings.getLastViewPositionY(_document.path, 1); + _webViewClient.setRestoreScrollY(y); + } + _webViewClient.restoreScrollY(_webView); + } else { + _format.getActions().runJumpBottomTopAction(ActionButtonBase.ActionItem.DisplayMode.EDIT); + } return true; } return false; diff --git a/app/src/main/java/net/gsantner/markor/format/ActionButtonBase.java b/app/src/main/java/net/gsantner/markor/format/ActionButtonBase.java index d6927d9e299..28d8e6ed2e0 100644 --- a/app/src/main/java/net/gsantner/markor/format/ActionButtonBase.java +++ b/app/src/main/java/net/gsantner/markor/format/ActionButtonBase.java @@ -1007,10 +1007,16 @@ public static void selectWholeLines(final @Nullable Spannable text) { public void runJumpBottomTopAction(ActionItem.DisplayMode displayMode) { if (displayMode == ActionItem.DisplayMode.EDIT) { - int pos = _hlEditor.getSelectionStart(); - _hlEditor.setSelection(pos == 0 ? _hlEditor.getText().length() : 0); + final int pos = _hlEditor.getSelectionStart(); + if (pos < 1) { + _hlEditor.setSelection(_hlEditor.getText().length()); + } else if (pos == _hlEditor.getText().length()) { + _hlEditor.setSelection(0); + } else { + TextViewUtils.showSelection(_hlEditor); + } } else if (displayMode == ActionItem.DisplayMode.VIEW) { - boolean top = _webView.getScrollY() > 100; + final boolean top = _webView.getScrollY() > 100; _webView.scrollTo(0, top ? 0 : _webView.getContentHeight()); if (!top) { _webView.scrollBy(0, 1000); @@ -1018,5 +1024,4 @@ public void runJumpBottomTopAction(ActionItem.DisplayMode displayMode) { } } } - } diff --git a/app/src/main/java/net/gsantner/markor/format/TextConverterBase.java b/app/src/main/java/net/gsantner/markor/format/TextConverterBase.java index e5d9bbde0a3..e68a10cd2e0 100644 --- a/app/src/main/java/net/gsantner/markor/format/TextConverterBase.java +++ b/app/src/main/java/net/gsantner/markor/format/TextConverterBase.java @@ -11,6 +11,7 @@ import android.content.Context; import android.net.Uri; import android.text.format.DateFormat; +import android.util.Log; import android.webkit.WebView; import androidx.annotation.NonNull; diff --git a/app/src/main/java/net/gsantner/markor/format/markdown/MarkdownTextConverter.java b/app/src/main/java/net/gsantner/markor/format/markdown/MarkdownTextConverter.java index 1c8d084fb86..55084fb3bb2 100644 --- a/app/src/main/java/net/gsantner/markor/format/markdown/MarkdownTextConverter.java +++ b/app/src/main/java/net/gsantner/markor/format/markdown/MarkdownTextConverter.java @@ -345,6 +345,9 @@ public String convertMarkup(String markup, Context context, boolean lightMode, b onLoadJs += "enableLineNumbers(); adjustLineNumbers();"; } + // For scroll sync + head += JS_PREFIX + "scroll-sync/scroll-sync.js" + JS_POSTFIX; + // Deliver result return putContentIntoTemplate(context, converted, lightMode, file, onLoadJs, head); } @@ -386,7 +389,7 @@ private String getViewHlPrismIncludes(final String theme, final boolean isLineNu sb.append(CSS_PREFIX + "prism/plugins/toolbar/prism-toolbar.css" + CSS_POSTFIX); sb.append(JS_PREFIX + "prism/prism.js" + JS_POSTFIX); - sb.append(JS_PREFIX + "prism/main.js" + JS_POSTFIX); + sb.append(JS_PREFIX + "prism/util.js" + JS_POSTFIX); sb.append(JS_PREFIX + "prism/plugins/autoloader/prism-autoloader.min.js" + JS_POSTFIX); sb.append(JS_PREFIX + "prism/plugins/toolbar/prism-toolbar.min.js" + JS_POSTFIX); sb.append(JS_PREFIX + "prism/plugins/copy-to-clipboard/prism-copy-to-clipboard.js" + JS_POSTFIX); @@ -394,7 +397,7 @@ private String getViewHlPrismIncludes(final String theme, final boolean isLineNu if (isLineNumbersEnabled) { sb.append(CSS_PREFIX + "prism/plugins/line-numbers/style.css" + CSS_POSTFIX); sb.append(JS_PREFIX + "prism/plugins/line-numbers/prism-line-numbers.min.js" + JS_POSTFIX); - sb.append(JS_PREFIX + "prism/plugins/line-numbers/main.js" + JS_POSTFIX); + sb.append(JS_PREFIX + "prism/plugins/line-numbers/util.js" + JS_POSTFIX); } return sb.toString(); @@ -457,8 +460,8 @@ private static class LineNumberIdProvider implements AttributeProvider { @Override public void setAttributes(Node node, AttributablePart part, Attributes attributes) { final Document document = node.getDocument(); - final int lineNumber = document.getLineNumber(node.getStartOffset()); - attributes.addValue("line", "" + lineNumber); + final int lineNumber = document.getLineNumber(node.getStartOffset()) + 1; + attributes.addValue("data-line", "" + lineNumber); } } diff --git a/app/src/main/java/net/gsantner/markor/frontend/DraggableScrollbarScrollView.java b/app/src/main/java/net/gsantner/markor/frontend/DraggableScrollbarScrollView.java index 839b642ca2e..661db69b210 100644 --- a/app/src/main/java/net/gsantner/markor/frontend/DraggableScrollbarScrollView.java +++ b/app/src/main/java/net/gsantner/markor/frontend/DraggableScrollbarScrollView.java @@ -2,7 +2,6 @@ import android.annotation.SuppressLint; import android.content.Context; -import android.os.Build; import android.util.AttributeSet; import android.util.DisplayMetrics; import android.view.MotionEvent; @@ -83,9 +82,7 @@ private void computeThumbHeight() { protected void onAttachedToWindow() { super.onAttachedToWindow(); setSmoothScrollingEnabled(true); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { - _ltr = getLayoutDirection() == View.LAYOUT_DIRECTION_LTR; - } + _ltr = getLayoutDirection() == View.LAYOUT_DIRECTION_LTR; final DisplayMetrics displayMetrics = getContext().getResources().getDisplayMetrics(); _grabWidth = (int) (1.5 * (float) getVerticalScrollbarWidth() * displayMetrics.density); } diff --git a/app/src/main/java/net/gsantner/markor/frontend/MarkorDialogFactory.java b/app/src/main/java/net/gsantner/markor/frontend/MarkorDialogFactory.java index e34b8e79ac7..79141cfc213 100644 --- a/app/src/main/java/net/gsantner/markor/frontend/MarkorDialogFactory.java +++ b/app/src/main/java/net/gsantner/markor/frontend/MarkorDialogFactory.java @@ -834,12 +834,19 @@ public static void showHeadlineDialog( dopt.positionCallback = result -> { final int index = filtered.get(result.get(0)); - final int line = headings.get(index).line; + final int line = headings.get(index).line + 1; - TextViewUtils.selectLines(edit, line); - final String jumpJs = "document.querySelector('[line=\"" + line + "\"]').scrollIntoView();"; - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { - webView.evaluateJavascript(jumpJs, null); + if (edit.isShown()) { + TextViewUtils.selectLines(edit, false, Collections.singletonList(line)); + } + + if (webView.isShown()) { + final String jumpJs = "document.querySelector(\"[data-line='" + line + "']\").scrollIntoView();"; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { + webView.evaluateJavascript(jumpJs, null); + } else { + webView.loadUrl("javascript:" + jumpJs); + } } }; diff --git a/app/src/main/java/net/gsantner/markor/frontend/textview/HighlightingEditor.java b/app/src/main/java/net/gsantner/markor/frontend/textview/HighlightingEditor.java index 38f2e1f12e7..cfe145f669b 100644 --- a/app/src/main/java/net/gsantner/markor/frontend/textview/HighlightingEditor.java +++ b/app/src/main/java/net/gsantner/markor/frontend/textview/HighlightingEditor.java @@ -297,6 +297,32 @@ private int rowEnd(final int y) { return layout.getLineEnd(line); } + public int getFirstVisibleLineNumber() { + final Rect visibleRect = new Rect(); + if (!getLocalVisibleRect(visibleRect)) { + return -1; + } + + final CharSequence text = getText(); + final Layout layout = getLayout(); + if (text == null || layout == null) { + return -1; + } + + // Calculate the first visible line number + final int count = layout.getLineCount(); + for (int i = 1, number = 1; i < count; i++) { + if (text.charAt(layout.getLineStart(i) - 1) == '\n') { + if (layout.getLineTop(i) > visibleRect.top) { + return number; + } + number++; + } + } + + return 1; + } + // Various overrides // --------------------------------------------------------------------------------------------- public void setSaveInstanceState(final boolean save) { diff --git a/app/src/main/java/net/gsantner/markor/frontend/textview/TextViewUtils.java b/app/src/main/java/net/gsantner/markor/frontend/textview/TextViewUtils.java index 725ff3ba7ab..5e71b73bd88 100644 --- a/app/src/main/java/net/gsantner/markor/frontend/textview/TextViewUtils.java +++ b/app/src/main/java/net/gsantner/markor/frontend/textview/TextViewUtils.java @@ -33,7 +33,6 @@ import java.lang.reflect.Array; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Locale; @@ -254,11 +253,6 @@ public static int getIndexFromLineOffset(final CharSequence s, final int l, fina return i; } - - public static void selectLines(final EditText edit, final Integer... positions) { - selectLines(edit, Arrays.asList(positions)); - } - /** * Select the given indices. * Case 1: Only one index -> Put cursor on that line @@ -267,14 +261,14 @@ public static void selectLines(final EditText edit, final Integer... positions) * * @param positions: Line indices to select */ - public static void selectLines(final EditText edit, final List positions) { + public static void selectLines(final EditText edit, final boolean setSelection, final List positions) { if (!edit.hasFocus()) { edit.requestFocus(); } final CharSequence text = edit.getText(); if (positions.size() == 1) { // Case 1 index - final int posn = TextViewUtils.getIndexFromLineOffset(text, positions.get(0), 0); - setSelectionAndShow(edit, posn); + final int sel = TextViewUtils.getIndexFromLineOffset(text, positions.get(0), 0); + setSelectionAndShow(edit, setSelection, sel); } else if (positions.size() > 1) { final TreeSet pSet = new TreeSet<>(positions); final int selStart, selEnd; @@ -298,12 +292,11 @@ public static void selectLines(final EditText edit, final List position } } - public static void showSelection(final TextView text) { - showSelection(text, text.getSelectionStart(), text.getSelectionEnd()); + public static void selectLines(final EditText edit, final List positions) { + selectLines(edit, true, positions); } public static void showSelection(final TextView text, final int start, final int end) { - // Get view info // ------------------------------------------------------------ final Layout layout = text.getLayout(); @@ -352,7 +345,11 @@ public static void showSelection(final TextView text, final int start, final int text.requestRectangleOnScreen(region); } - public static void setSelectionAndShow(final EditText edit, final int... sel) { + public static void showSelection(final TextView text) { + showSelection(text, text.getSelectionStart(), text.getSelectionEnd()); + } + + public static void setSelectionAndShow(final EditText edit, boolean setSelection, final int... sel) { if (sel == null || sel.length == 0) { return; } @@ -364,12 +361,17 @@ public static void setSelectionAndShow(final EditText edit, final int... sel) { if (!edit.hasFocus() && edit.getVisibility() != View.GONE) { edit.requestFocus(); } - - edit.setSelection(start, end); + if (setSelection) { + edit.setSelection(start, end); + } showSelection(edit, start, end); } } + public static void setSelectionAndShow(final EditText edit, final int... sel) { + setSelectionAndShow(edit, true, sel); + } + /** * Snippets are evaluated in the following order: * 1. {{*}} style placeholders are replaced (except {{cursor}}) diff --git a/app/src/main/java/net/gsantner/markor/model/AppSettings.java b/app/src/main/java/net/gsantner/markor/model/AppSettings.java index 13a4a2a8366..63986679cdf 100644 --- a/app/src/main/java/net/gsantner/markor/model/AppSettings.java +++ b/app/src/main/java/net/gsantner/markor/model/AppSettings.java @@ -377,6 +377,7 @@ public void toggleFavouriteFile(File file) { } private static final String PREF_PREFIX_EDIT_POS_CHAR = "PREF_PREFIX_EDIT_POS_CHAR"; + private static final String PREF_PREFIX_LAST_VIEW_POS_Y = "PREF_PREFIX_LAST_VIEW_POS_Y"; private static final String PREF_PREFIX_WRAP_STATE = "PREF_PREFIX_WRAP_STATE"; private static final String PREF_PREFIX_HIGHLIGHT_STATE = "PREF_PREFIX_HIGHLIGHT_STATE"; private static final String PREF_PREFIX_PREVIEW_STATE = "PREF_PREFIX_PREVIEW_STATE"; @@ -428,6 +429,19 @@ public void setLastViewPosition(File file, int scrollX, int scrollY) { } } + public void setLastViewPositionY(final String path, final int scrollY) { + if (fexists(path)) { + setInt(PREF_PREFIX_LAST_VIEW_POS_Y + path, scrollY); + } + } + + public int getLastViewPositionY(final String path, final int defaultValue) { + if (fexists(path)) { + return getInt(PREF_PREFIX_LAST_VIEW_POS_Y + path, defaultValue); + } + return defaultValue; + } + public void setDocumentWrapState(final String path, final boolean state) { if (fexists(path)) { setBool(PREF_PREFIX_WRAP_STATE + path, state); diff --git a/app/src/main/java/net/gsantner/opoc/web/GsWebViewClient.java b/app/src/main/java/net/gsantner/opoc/web/GsWebViewClient.java index 20b636533a2..cd31e2baf3b 100644 --- a/app/src/main/java/net/gsantner/opoc/web/GsWebViewClient.java +++ b/app/src/main/java/net/gsantner/opoc/web/GsWebViewClient.java @@ -17,6 +17,7 @@ @SuppressWarnings({"unused", "FieldCanBeLocal"}) public class GsWebViewClient extends WebViewClient { + protected OnPageFinishedListener m_onPageFinishedListener; protected final WeakReference m_webView; public GsWebViewClient(final WebView webView) { @@ -26,6 +27,7 @@ public GsWebViewClient(final WebView webView) { @Override public void onPageFinished(final WebView webView, final String url) { __onPageFinished_restoreScrollY(webView, url); + m_onPageFinishedListener.onPageFinished(webView); super.onPageFinished(webView, url); } @@ -41,21 +43,46 @@ public void onPageFinished(final WebView webView, final String url) { */ protected void __onPageFinished_restoreScrollY(final WebView webView, final String url) { if (m_restoreScrollYEnabled.getAndSet(false)) { - for (int dt : new int[]{50, 100, 150, 200, 250, 300}) { - webView.postDelayed(() -> webView.setScrollY(m_restoreScrollY), dt); - } + restoreScrollY(webView); } } /** * Apply vertical scroll position on next page load * - * @param scrollY scroll position from {@link WebView#getScrollY()} + * @param scrollY scroll position from {@link WebView#getScrollY()}.
+ * disable scroll position restoration on page finished if the value is negative. */ public void setRestoreScrollY(final int scrollY) { m_restoreScrollY = scrollY; - m_restoreScrollYEnabled.set(scrollY >= 0); + } + + public int getRestoreScrollY() { + return m_restoreScrollY; + } + + public void setRestoreScrollYonPageFinished(final boolean enabled) { + m_restoreScrollYEnabled.set(enabled); + } + + public void restoreScrollY(final WebView webView) { + for (int dt : new int[]{50, 100, 150, 200, 250, 300}) { + webView.postDelayed(() -> webView.setScrollY(m_restoreScrollY), dt); + } } //////////////////////////////////////////////////////////////////////////////////// + + public interface OnPageFinishedListener { + /** + * Called when a page has finished loading. + * + * @param v The view that loaded the page. + */ + void onPageFinished(WebView v); + } + + public void setOnPageFinishedListener(OnPageFinishedListener listener) { + m_onPageFinishedListener = listener; + } } diff --git a/app/src/main/res/values/string-not_translatable.xml b/app/src/main/res/values/string-not_translatable.xml index b84dc19ae0f..21b088c5930 100644 --- a/app/src/main/res/values/string-not_translatable.xml +++ b/app/src/main/res/values/string-not_translatable.xml @@ -33,7 +33,6 @@ work. If not, see . Markdown Backup Front Matter - MIME type sans-serif-regular Start @@ -103,7 +102,6 @@ work. If not, see . Tag Tags - .dotfiles Tagging Regex Multiline diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f70f1a10d01..0534f932a69 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -95,7 +95,9 @@ work. If not, see . Date Name Size + MIME type Reverse order + Hidden files Contribute Project page Press \'Back\' again to exit diff --git a/app/thirdparty/assets/prism/plugins/line-numbers/main.js b/app/thirdparty/assets/prism/plugins/line-numbers/util.js similarity index 100% rename from app/thirdparty/assets/prism/plugins/line-numbers/main.js rename to app/thirdparty/assets/prism/plugins/line-numbers/util.js diff --git a/app/thirdparty/assets/prism/main.js b/app/thirdparty/assets/prism/util.js similarity index 100% rename from app/thirdparty/assets/prism/main.js rename to app/thirdparty/assets/prism/util.js