diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index f774bc57ce..36b1160c20 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -49,7 +49,7 @@ Where: * **[Frederic Jacob](https://github.com/fredericjacob)**
~° Added Zim-Wiki highlighting, text actions, view mode, page creation * **[Winston Feng](https://github.com/tifish)**
~° Support spaces in URL * **[k3b](https://github.com/k3b)**
~° Added CSV-Support -* **[Li Guanglin](https://github.com/guanglinn)**
~° Added line numbers support +* **[Li Guanglin](https://github.com/guanglinn)**
~° Added support for line numbers * **[bigger124](https://github.com/bigger124)**
~° Added OrgMode-Support * **[Ayowel](https://github.com/ayowel)**
~° Mermaid update * **[Matthew White](https://github.com/mehw)**
~° Zim-Wiki link/attachment conformance 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 b5b4d6a228..8fc63ddb43 100644 --- a/app/src/main/java/net/gsantner/markor/activity/DocumentEditAndViewFragment.java +++ b/app/src/main/java/net/gsantner/markor/activity/DocumentEditAndViewFragment.java @@ -55,7 +55,7 @@ import net.gsantner.markor.frontend.MarkorDialogFactory; import net.gsantner.markor.frontend.filebrowser.MarkorFileBrowserFactory; import net.gsantner.markor.frontend.textview.HighlightingEditor; -import net.gsantner.markor.frontend.textview.LineNumbersTextView; +import net.gsantner.markor.frontend.textview.LineNumbersView; import net.gsantner.markor.frontend.textview.TextViewUtils; import net.gsantner.markor.model.AppSettings; import net.gsantner.markor.model.Document; @@ -104,7 +104,8 @@ public static DocumentEditAndViewFragment newInstance(final @NonNull Document do private DraggableScrollbarScrollView _verticalScrollView; private HorizontalScrollView _horizontalScrollView; - private LineNumbersTextView _lineNumbersView; + private LineNumbersView _lineNumbersView; + private SearchView _menuSearchViewForViewMode; private Document _document; private FormatRegistry _format; private MarkorContextUtils _cu; @@ -571,6 +572,9 @@ public void onFsViewerConfig(GsFileBrowserOptions.Options dopt) { final boolean newState = !isWrapped(); _appSettings.setDocumentWrapState(_document.path, newState); setWrapState(newState); + if (_isPreviewVisible && _webView != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { + _webView.evaluateJavascript("setWrapWords('" + newState + "');", null); + } updateMenuToggleStates(0); return true; } @@ -578,6 +582,9 @@ public void onFsViewerConfig(GsFileBrowserOptions.Options dopt) { final boolean newState = !_lineNumbersView.isLineNumbersEnabled(); _appSettings.setDocumentLineNumbersEnabled(_document.path, newState); _lineNumbersView.setLineNumbersEnabled(newState); + if (_isPreviewVisible && _webView != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { + _webView.evaluateJavascript("setLineNumbers('" + newState + "');", null); + } updateMenuToggleStates(0); return true; } @@ -607,6 +614,9 @@ public void onFsViewerConfig(GsFileBrowserOptions.Options dopt) { if (_isPreviewVisible) { if (_webView != null) { _webView.getSettings().setTextZoom((int) (newSize * VIEW_FONT_SCALE)); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && _lineNumbersView.isLineNumbersEnabled()) { + _webView.evaluateJavascript("refreshLineNumbers();", null); + } } _appSettings.setDocumentViewFontSize(_document.path, newSize); } else { 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 8438db4135..36a597b383 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 @@ -278,13 +278,10 @@ public String convertMarkup(String markup, Context context, boolean lightMode, b } } - // Enable View (block) code syntax highlighting + // Enable code block (view mode) syntax highlighting if (markup.contains("```")) { head += getViewHlPrismIncludes(GsContextUtils.instance.isDarkModeEnabled(context) ? "-tomorrow" : "", enableLineNumbers); - onLoadJs += "usePrismCodeBlock();"; - if (as.getDocumentWrapState(file.getAbsolutePath())) { - onLoadJs += "wrapCodeBlockWords();"; - } + onLoadJs += "usePrism('" + as.getDocumentWrapState(file.getAbsolutePath()) + "', '" + enableLineNumbers + "');"; } // Enable Mermaid @@ -347,11 +344,6 @@ public String convertMarkup(String markup, Context context, boolean lightMode, b } } - if (enableLineNumbers) { - // For Prism line numbers plugin - onLoadJs += "enableLineNumbers(); adjustLineNumbers();"; - } - // Deliver result return putContentIntoTemplate(context, converted, lightMode, file, onLoadJs, head); } @@ -386,7 +378,7 @@ private String escapeSpacesInLink(final String markup) { } @SuppressWarnings({"StringConcatenationInsideStringBufferAppend"}) - private String getViewHlPrismIncludes(final String theme, final boolean isLineNumbersEnabled) { + private String getViewHlPrismIncludes(final String theme, final boolean lineNumbers) { final StringBuilder sb = new StringBuilder(1000); sb.append(CSS_PREFIX + "prism/themes/prism" + theme + ".min.css" + CSS_POSTFIX); sb.append(CSS_PREFIX + "prism/prism-markor.css" + CSS_POSTFIX); @@ -399,11 +391,9 @@ private String getViewHlPrismIncludes(final String theme, final boolean isLineNu 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.min.js" + JS_POSTFIX); - if (isLineNumbersEnabled) { - sb.append(CSS_PREFIX + "prism/plugins/line-numbers/prism-line-numbers-markor.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/prism-line-numbers-markor.js" + JS_POSTFIX); - } + sb.append(CSS_PREFIX + "prism/plugins/line-numbers/prism-line-numbers-markor.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/prism-line-numbers-markor.js" + JS_POSTFIX); return sb.toString(); } diff --git a/app/src/main/java/net/gsantner/markor/frontend/textview/LineNumbersTextView.java b/app/src/main/java/net/gsantner/markor/frontend/textview/LineNumbersView.java similarity index 83% rename from app/src/main/java/net/gsantner/markor/frontend/textview/LineNumbersTextView.java rename to app/src/main/java/net/gsantner/markor/frontend/textview/LineNumbersView.java index e89c6465ba..164e74bcfa 100644 --- a/app/src/main/java/net/gsantner/markor/frontend/textview/LineNumbersTextView.java +++ b/app/src/main/java/net/gsantner/markor/frontend/textview/LineNumbersView.java @@ -13,28 +13,33 @@ import android.widget.EditText; import androidx.annotation.NonNull; -import androidx.appcompat.widget.AppCompatTextView; @SuppressWarnings("UnusedReturnValue") -public class LineNumbersTextView extends AppCompatTextView { +public class LineNumbersView extends View { private EditText editText; private LineNumbersDrawer lineNumbersDrawer; private boolean lineNumbersEnabled; - public LineNumbersTextView(Context context) { + public LineNumbersView(Context context) { super(context); } - public LineNumbersTextView(Context context, AttributeSet attrs) { + public LineNumbersView(Context context, AttributeSet attrs) { super(context, attrs); } - public LineNumbersTextView(Context context, AttributeSet attrs, int defStyleAttr) { + public LineNumbersView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override - protected void onVisibilityChanged(View changedView, int visibility) { + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + setWidth(0); // Initial width + } + + @Override + protected void onVisibilityChanged(@NonNull View changedView, int visibility) { super.onVisibilityChanged(changedView, visibility); if (isLineNumbersEnabled() && visibility == View.VISIBLE) { refresh(); @@ -42,15 +47,18 @@ protected void onVisibilityChanged(View changedView, int visibility) { } @Override - protected void onDraw(Canvas canvas) { + protected void onDraw(@NonNull Canvas canvas) { super.onDraw(canvas); if (lineNumbersEnabled) { lineNumbersDrawer.draw(canvas); } } + /** + * Refresh LineNumbersView. + */ public void refresh() { - setText(""); // To activate LineNumbersTextView refresh + invalidate(); if (getWidth() == 0) { lineNumbersDrawer.getEditText().postInvalidate(); } @@ -64,6 +72,11 @@ public void setup(final @NonNull EditText editText) { this.lineNumbersDrawer = null; } + public void setWidth(int width) { + getLayoutParams().width = width; + requestLayout(); + } + public void setLineNumbersEnabled(final boolean enabled) { lineNumbersEnabled = enabled; @@ -76,7 +89,7 @@ public void setLineNumbersEnabled(final boolean enabled) { if (lineNumbersDrawer == null) { return; } - lineNumbersDrawer.done(); + lineNumbersDrawer.cleanup(); } refresh(); } @@ -87,7 +100,7 @@ public boolean isLineNumbersEnabled() { static class LineNumbersDrawer { private final EditText editText; - private final LineNumbersTextView textView; + private final LineNumbersView lineNumbersView; private final Paint paint = new Paint(); @@ -96,8 +109,8 @@ static class LineNumbersDrawer { private static final int EDITOR_PADDING_LEFT = 8; private final int ORIGINAL_PADDING_LEFT; - private final Rect visibleArea = new Rect(); - private final Rect lineNumbersArea = new Rect(); + private final Rect visibleRect = new Rect(); + private final Rect lineNumbersRect = new Rect(); private int fenceX; private int numberX; @@ -123,7 +136,7 @@ public void onTextChanged(CharSequence s, int start, int before, int count) { @Override public void afterTextChanged(Editable editable) { if (isLayoutLineCountChanged() || isMaxNumberChanged()) { - textView.refresh(); + lineNumbersView.refresh(); } } }; @@ -136,14 +149,14 @@ public void onScrollChanged() { final long time = System.currentTimeMillis(); if (time - lastTime > 125) { lastTime = time; - textView.refresh(); + lineNumbersView.refresh(); } } }; - public LineNumbersDrawer(final @NonNull EditText editText, final @NonNull LineNumbersTextView textView) { + public LineNumbersDrawer(final @NonNull EditText editText, final @NonNull LineNumbersView lineNumbersView) { this.editText = editText; - this.textView = textView; + this.lineNumbersView = lineNumbersView; ORIGINAL_PADDING_LEFT = editText.getPaddingLeft(); paint.setColor(0xFF999999); paint.setTextAlign(Paint.Align.RIGHT); @@ -154,15 +167,15 @@ public EditText getEditText() { } private boolean isOutOfLineNumbersArea() { - final int margin = (int) (visibleArea.height() * 0.5f); - final int top = visibleArea.top - margin; - final int bottom = visibleArea.bottom + margin; + final int margin = (int) (visibleRect.height() * 0.5f); + final int top = visibleRect.top - margin; + final int bottom = visibleRect.bottom + margin; - if (top < lineNumbersArea.top || bottom > lineNumbersArea.bottom) { + if (top < lineNumbersRect.top || bottom > lineNumbersRect.bottom) { // Set line numbers area // height of line numbers area = (1.5 + 1 + 1.5) * height of visible area - lineNumbersArea.top = top - visibleArea.height(); - lineNumbersArea.bottom = bottom + visibleArea.height(); + lineNumbersRect.top = top - visibleRect.height(); + lineNumbersRect.bottom = bottom + visibleRect.height(); return true; } else { return false; @@ -262,7 +275,8 @@ private void setRefreshOnScrollChanged(final boolean enabled) { public void prepare() { setLineTracking(true); setRefreshOnScrollChanged(true); - textView.setVisibility(VISIBLE); + lineNumbersView.setWidth(0); + lineNumbersView.setVisibility(VISIBLE); editText.setPadding(EDITOR_PADDING_LEFT, editText.getPaddingTop(), editText.getPaddingRight(), editText.getPaddingBottom()); } @@ -272,7 +286,7 @@ public void prepare() { * @param canvas The canvas on which the line numbers will be drawn. */ public void draw(final Canvas canvas) { - if (!editText.getLocalVisibleRect(visibleArea)) { + if (!editText.getLocalVisibleRect(visibleRect)) { return; } @@ -286,7 +300,7 @@ public void draw(final Canvas canvas) { if (isTextSizeChanged() || isMaxNumberDigitsChanged()) { numberX = NUMBER_PADDING_LEFT + (int) paint.measureText(String.valueOf(maxNumber)); fenceX = numberX + NUMBER_PADDING_RIGHT; - textView.setWidth(fenceX + 1); + lineNumbersView.setWidth(fenceX + 1); } // If current visible area is out of current line numbers area, @@ -299,7 +313,7 @@ public void draw(final Canvas canvas) { } // Draw right border of the fence - canvas.drawLine(fenceX, lineNumbersArea.top, fenceX, lineNumbersArea.bottom, paint); + canvas.drawLine(fenceX, lineNumbersRect.top, fenceX, lineNumbersRect.bottom, paint); // Draw line numbers int i = startLine[0]; @@ -308,7 +322,7 @@ public void draw(final Canvas canvas) { final int count = layout.getLineCount(); final int offsetY = editText.getPaddingTop(); - if (y > lineNumbersArea.top) { + if (y > lineNumbersRect.top) { if (invalid) { invalid = false; startLine[0] = i; @@ -322,14 +336,14 @@ public void draw(final Canvas canvas) { for (; i < count; i++) { if (text.charAt(layout.getLineStart(i) - 1) == '\n') { y = layout.getLineBaseline(i); - if (y > lineNumbersArea.top) { + if (y > lineNumbersRect.top) { if (invalid) { invalid = false; startLine[0] = i; startLine[1] = number; } canvas.drawText(String.valueOf(number), numberX, y + offsetY, paint); - if (y > lineNumbersArea.bottom) { + if (y > lineNumbersRect.bottom) { break; } } @@ -341,12 +355,11 @@ public void draw(final Canvas canvas) { /** * Reset some states related line numbers. */ - public void done() { + public void cleanup() { setLineTracking(false); setRefreshOnScrollChanged(false); maxNumberDigits = 0; - textView.setWidth(0); - textView.setVisibility(GONE); + lineNumbersView.setVisibility(GONE); editText.setPadding(ORIGINAL_PADDING_LEFT, editText.getPaddingTop(), editText.getPaddingRight(), editText.getPaddingBottom()); } } diff --git a/app/src/main/res/layout/document__fragment__edit.xml b/app/src/main/res/layout/document__fragment__edit.xml index a258093aa1..9a25bfe26a 100644 --- a/app/src/main/res/layout/document__fragment__edit.xml +++ b/app/src/main/res/layout/document__fragment__edit.xml @@ -30,32 +30,30 @@ android:layout_height="wrap_content" android:orientation="horizontal"> - + android:layout_height="match_parent" /> @@ -79,10 +77,10 @@ + android:layout_marginBottom="@dimen/textactions_bar_height" + android:layout="@layout/document__fragment_view" /> &#@$%!]|\b_(?=[ \t]*[\r\n])/, - 'punctuation': /[{}().,:?]/ -}; - -Prism.languages.vb = Prism.languages['visual-basic']; -Prism.languages.vba = Prism.languages['visual-basic']; diff --git a/app/thirdparty/assets/prism/components/prism-visual-basic.min.js b/app/thirdparty/assets/prism/components/prism-visual-basic.min.js new file mode 100644 index 0000000000..d18b6fafe6 --- /dev/null +++ b/app/thirdparty/assets/prism/components/prism-visual-basic.min.js @@ -0,0 +1 @@ +Prism.languages["visual-basic"]={comment:{pattern:/(?:['‘’]|REM\b)(?:[^\r\n_]|_(?:\r\n?|\n)?)*/i,inside:{keyword:/^REM/i}},directive:{pattern:/#(?:Const|Else|ElseIf|End|ExternalChecksum|ExternalSource|If|Region)(?:\b_[ \t]*(?:\r\n?|\n)|.)+/i,alias:"property",greedy:!0},string:{pattern:/\$?["“”](?:["“”]{2}|[^"“”])*["“”]C?/i,greedy:!0},date:{pattern:/#[ \t]*(?:\d+([/-])\d+\1\d+(?:[ \t]+(?:\d+[ \t]*(?:AM|PM)|\d+:\d+(?::\d+)?(?:[ \t]*(?:AM|PM))?))?|\d+[ \t]*(?:AM|PM)|\d+:\d+(?::\d+)?(?:[ \t]*(?:AM|PM))?)[ \t]*#/i,alias:"number"},number:/(?:(?:\b\d+(?:\.\d+)?|\.\d+)(?:E[+-]?\d+)?|&[HO][\dA-F]+)(?:[FRD]|U?[ILS])?/i,boolean:/\b(?:False|Nothing|True)\b/i,keyword:/\b(?:AddHandler|AddressOf|Alias|And(?:Also)?|As|Boolean|ByRef|Byte|ByVal|Call|Case|Catch|C(?:Bool|Byte|Char|Date|Dbl|Dec|Int|Lng|Obj|SByte|Short|Sng|Str|Type|UInt|ULng|UShort)|Char|Class|Const|Continue|Currency|Date|Decimal|Declare|Default|Delegate|Dim|DirectCast|Do|Double|Each|Else(?:If)?|End(?:If)?|Enum|Erase|Error|Event|Exit|Finally|For|Friend|Function|Get(?:Type|XMLNamespace)?|Global|GoSub|GoTo|Handles|If|Implements|Imports|In|Inherits|Integer|Interface|Is|IsNot|Let|Lib|Like|Long|Loop|Me|Mod|Module|Must(?:Inherit|Override)|My(?:Base|Class)|Namespace|Narrowing|New|Next|Not(?:Inheritable|Overridable)?|Object|Of|On|Operator|Option(?:al)?|Or(?:Else)?|Out|Overloads|Overridable|Overrides|ParamArray|Partial|Private|Property|Protected|Public|RaiseEvent|ReadOnly|ReDim|RemoveHandler|Resume|Return|SByte|Select|Set|Shadows|Shared|short|Single|Static|Step|Stop|String|Structure|Sub|SyncLock|Then|Throw|To|Try|TryCast|Type|TypeOf|U(?:Integer|Long|Short)|Until|Using|Variant|Wend|When|While|Widening|With(?:Events)?|WriteOnly|Xor)\b/i,operator:/[+\-*/\\^<=>&#@$%!]|\b_(?=[ \t]*[\r\n])/,punctuation:/[{}().,:?]/},Prism.languages.vb=Prism.languages["visual-basic"],Prism.languages.vba=Prism.languages["visual-basic"]; \ No newline at end of file diff --git a/app/thirdparty/assets/prism/components/prism-zig.min.js b/app/thirdparty/assets/prism/components/prism-zig.min.js new file mode 100644 index 0000000000..26316b4604 --- /dev/null +++ b/app/thirdparty/assets/prism/components/prism-zig.min.js @@ -0,0 +1 @@ +!function(e){function n(e){return function(){return e}}var r=/\b(?:align|allowzero|and|anyframe|anytype|asm|async|await|break|cancel|catch|comptime|const|continue|defer|else|enum|errdefer|error|export|extern|fn|for|if|inline|linksection|nakedcc|noalias|nosuspend|null|or|orelse|packed|promise|pub|resume|return|stdcallcc|struct|suspend|switch|test|threadlocal|try|undefined|union|unreachable|usingnamespace|var|volatile|while)\b/,a="\\b(?!"+r.source+")(?!\\d)\\w+\\b",o="align\\s*\\((?:[^()]|\\([^()]*\\))*\\)",s="(?!\\s)(?:!?\\s*(?:"+"(?:\\?|\\bpromise->|(?:\\[[^[\\]]*\\]|\\*(?!\\*)|\\*\\*)(?:\\s*|\\s*const\\b|\\s*volatile\\b|\\s*allowzero\\b)*)".replace(//g,n(o))+"\\s*)*"+"(?:\\bpromise\\b|(?:\\berror\\.)?(?:\\.)*(?!\\s+))".replace(//g,n(a))+")+";e.languages.zig={comment:[{pattern:/\/\/[/!].*/,alias:"doc-comment"},/\/{2}.*/],string:[{pattern:/(^|[^\\@])c?"(?:[^"\\\r\n]|\\.)*"/,lookbehind:!0,greedy:!0},{pattern:/([\r\n])([ \t]+c?\\{2}).*(?:(?:\r\n?|\n)\2.*)*/,lookbehind:!0,greedy:!0}],char:{pattern:/(^|[^\\])'(?:[^'\\\r\n]|[\uD800-\uDFFF]{2}|\\(?:.|x[a-fA-F\d]{2}|u\{[a-fA-F\d]{1,6}\}))'/,lookbehind:!0,greedy:!0},builtin:/\B@(?!\d)\w+(?=\s*\()/,label:{pattern:/(\b(?:break|continue)\s*:\s*)\w+\b|\b(?!\d)\w+\b(?=\s*:\s*(?:\{|while\b))/,lookbehind:!0},"class-name":[/\b(?!\d)\w+(?=\s*=\s*(?:(?:extern|packed)\s+)?(?:enum|struct|union)\s*[({])/,{pattern:RegExp("(:\\s*)(?=\\s*(?:\\s*)?[=;,)])|(?=\\s*(?:\\s*)?\\{)".replace(//g,n(s)).replace(//g,n(o))),lookbehind:!0,inside:null},{pattern:RegExp("(\\)\\s*)(?=\\s*(?:\\s*)?;)".replace(//g,n(s)).replace(//g,n(o))),lookbehind:!0,inside:null}],"builtin-type":{pattern:/\b(?:anyerror|bool|c_u?(?:int|long|longlong|short)|c_longdouble|c_void|comptime_(?:float|int)|f(?:16|32|64|128)|[iu](?:8|16|32|64|128|size)|noreturn|type|void)\b/,alias:"keyword"},keyword:r,function:/\b(?!\d)\w+(?=\s*\()/,number:/\b(?:0b[01]+|0o[0-7]+|0x[a-fA-F\d]+(?:\.[a-fA-F\d]*)?(?:[pP][+-]?[a-fA-F\d]+)?|\d+(?:\.\d*)?(?:[eE][+-]?\d+)?)\b/,boolean:/\b(?:false|true)\b/,operator:/\.[*?]|\.{2,3}|[-=]>|\*\*|\+\+|\|\||(?:<<|>>|[-+*]%|[-+*/%^&|<>!=])=?|[?~]/,punctuation:/[.:,;(){}[\]]/},e.languages.zig["class-name"].forEach((function(n){null===n.inside&&(n.inside=e.languages.zig)}))}(Prism); \ No newline at end of file diff --git a/app/thirdparty/assets/prism/plugins/line-numbers/prism-line-numbers-markor.js b/app/thirdparty/assets/prism/plugins/line-numbers/prism-line-numbers-markor.js index 956dce1fd0..058814c92e 100644 --- a/app/thirdparty/assets/prism/plugins/line-numbers/prism-line-numbers-markor.js +++ b/app/thirdparty/assets/prism/plugins/line-numbers/prism-line-numbers-markor.js @@ -1,11 +1,3 @@ -function enableLineNumbers() { - let elements = document.querySelectorAll("pre:has(code)"); - elements.forEach(function (element) { - element.classList.add("line-numbers"); - }); - Prism.highlightAll(); -} - function getNumberDigits(number) { if (number < 10) { return 1; @@ -20,22 +12,19 @@ function getNumberDigits(number) { } } -function adjustLineNumbers() { - let fontWidth = -1; - const codeElements = document.querySelectorAll("pre > code"); - codeElements.forEach((element) => { - const maxNumber = element.textContent.split("\n").length - 1; - if (maxNumber == 0) { - return; - } +function getFontWidth(codeElement) { + const canvasContext = document.createElement("canvas").getContext("2d"); + canvasContext.font = window.getComputedStyle(codeElement, null).getPropertyValue("font"); + return canvasContext.measureText("0").width; +} - if (fontWidth == -1) { - const canvasContext = document.createElement("canvas").getContext("2d"); - canvasContext.font = window.getComputedStyle(element, null).getPropertyValue("font"); - fontWidth = canvasContext.measureText("0").width; - } +function preparePaddings(codeElement, codeFontWidth) { + const maxNumber = codeElement.textContent.split("\n").length - 1; + if (maxNumber == 0) { + return; + } - const digits = getNumberDigits(maxNumber); - element.parentNode.style.paddingLeft = 2 * fontWidth + digits * fontWidth - digits + "px"; - }); + const digits = getNumberDigits(maxNumber); + const padding = 14 + digits * codeFontWidth; + codeElement.parentNode.style.paddingLeft = padding + "px"; } diff --git a/app/thirdparty/assets/prism/plugins/toolbar/prism-toolbar.css b/app/thirdparty/assets/prism/plugins/toolbar/prism-toolbar.css index 503b89134d..9399a56f37 100644 --- a/app/thirdparty/assets/prism/plugins/toolbar/prism-toolbar.css +++ b/app/thirdparty/assets/prism/plugins/toolbar/prism-toolbar.css @@ -44,18 +44,19 @@ div.code-toolbar > .toolbar > .toolbar-item > a, div.code-toolbar > .toolbar > .toolbar-item > button, div.code-toolbar > .toolbar > .toolbar-item > span { color: #aaa; - font-size: 0.8em; + font-size: 0.9em; text-transform: none; background: rgba(215, 215, 215, 0.4); box-shadow: 0 2px 0 0 rgba(150, 150, 150, 0.8); - border-radius: 0.5em; + border-radius: 0.4em; display: inline-block; min-width: 80%; - max-height: 1.75em; - padding-left: 0.45em; - padding-right: 0.45em; + min-height: 1.7em; + height: 80%; + padding-left: 0.4em; + padding-right: 0.4em; padding-top: 0.1em; - padding-bottom: 0.1em; + padding-bottom: 0.15em; } div.code-toolbar > .toolbar > .toolbar-item > a:hover, diff --git a/app/thirdparty/assets/prism/prism-markor.js b/app/thirdparty/assets/prism/prism-markor.js index 9a3b9f4ba5..5abe2ca50f 100644 --- a/app/thirdparty/assets/prism/prism-markor.js +++ b/app/thirdparty/assets/prism/prism-markor.js @@ -1,18 +1,88 @@ -function usePrismCodeBlock() { - let elements = document.querySelectorAll("pre > code"); - elements.forEach(function (element) { - let attribute = element.getAttribute("class"); - if (attribute == null || attribute.indexOf("language-") == -1) { - element.classList.add("language-text"); - Prism.highlightElement(element); +function usePrism(arg1, arg2) { + const codeElements = document.querySelectorAll("pre > code"); + if (codeElements.length == 0) { + return; + } + const wrapWords = arg1 === "true"; + const lineNumbers = arg2 === "true"; + const codeFontWidth = getFontWidth(codeElements[0]); + + codeElements.forEach((codeElement) => { + codeElement.parentNode.style.paddingLeft = "8px"; + codeElement.parentNode.style.paddingRight = "8px"; + if (wrapWords) { + codeElement.parentNode.style.whiteSpace = "pre-wrap"; + codeElement.parentNode.style.overflowWrap = "break-word"; + } + + if (codeElement.getAttribute("class") == null) { + codeElement.classList.add("language-text"); + if (!lineNumbers) { + Prism.highlightElement(codeElement); + } + } + + if (lineNumbers) { + preparePaddings(codeElement, codeFontWidth); + codeElement.parentNode.classList.add("line-numbers"); + Prism.highlightElement(codeElement); } }); } -function wrapCodeBlockWords() { - let preElements = document.querySelectorAll("pre"); - preElements.forEach((element) => { - element.style.whiteSpace = "pre-wrap"; - element.style.overflowWrap = "break-word"; +function refreshLineNumbers() { + const codeElements = document.querySelectorAll("pre > code"); + if (codeElements.length == 0) { + return; + } + const codeFontWidth = getFontWidth(codeElements[0]); + codeElements.forEach((codeElement) => { + preparePaddings(codeElement, codeFontWidth); + Prism.highlightElement(codeElement); }); } + +function setLineNumbers(enabled) { + const codeElements = document.querySelectorAll("pre > code"); + if (codeElements.length == 0) { + return; + } + const lineNumbers = enabled === "true"; + + if (lineNumbers) { + const codeFontWidth = getFontWidth(codeElements[0]); + codeElements.forEach((codeElement) => { + preparePaddings(codeElement, codeFontWidth); + codeElement.parentNode.classList.add("line-numbers"); + Prism.highlightElement(codeElement); + }); + } else { + codeElements.forEach((codeElement) => { + codeElement.parentNode.classList.remove("line-numbers"); + codeElement.parentNode.style.paddingLeft = "8px"; + Prism.highlightElement(codeElement); + }); + } +} + +function setWrapWords(enabled) { + const codeElements = document.querySelectorAll("pre > code"); + if (codeElements.length == 0) { + return; + } + const wrapWords = enabled === "true"; + + if (wrapWords) { + codeElements.forEach((codeElement) => { + codeElement.parentNode.style.whiteSpace = "pre-wrap"; + codeElement.parentNode.style.overflowWrap = "break-word"; + Prism.highlightElement(codeElement); + }); + } else { + codeElements.forEach((codeElement) => { + codeElement.parentNode.style.whiteSpace = null; + codeElement.parentNode.style.overflowWrap = null; + Prism.highlightElement(codeElement); + }); + } +}