From 469dc4459bb7f56cf8a6daa9c234164c0889bdda Mon Sep 17 00:00:00 2001
From: silverwind <me@silverwind.io>
Date: Thu, 13 Apr 2023 21:05:06 +0200
Subject: [PATCH] Add monospace toggle button to textarea (#24034)

- Add new button to textarea to switch font. State is persisted in
localStorage.
- Change markdown-switch-easymde button from `<span>` to `<button>`
- Slightly increased monospace font globally by 5% as I think it fits
better.

For hover effect on these buttons I'm deferring to
https://github.com/go-gitea/gitea/pull/23896.


![](https://user-images.githubusercontent.com/115237/230948526-ecf8d730-0c69-4a8e-a1a5-1e5e079c754d.gif)

---------

Co-authored-by: delvh <dev.lh@web.de>
---
 options/locale/locale_en-US.ini               |  2 ++
 templates/shared/combomarkdowneditor.tmpl     |  6 ++++++
 web_src/css/editor-markdown.css               |  1 +
 web_src/css/helpers.css                       |  2 +-
 .../js/features/comp/ComboMarkdownEditor.js   | 21 +++++++++++++++++--
 5 files changed, 29 insertions(+), 3 deletions(-)

diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini
index d467204eed..f71ea824e9 100644
--- a/options/locale/locale_en-US.ini
+++ b/options/locale/locale_en-US.ini
@@ -133,6 +133,8 @@ buttons.list.task.tooltip = Add a list of tasks
 buttons.mention.tooltip = Mention a user or team
 buttons.ref.tooltip = Reference an issue or pull request
 buttons.switch_to_legacy.tooltip = Use the legacy editor instead
+buttons.enable_monospace_font = Enable monospace font
+buttons.disable_monospace_font = Disable monospace font
 
 [filter]
 string.asc = A - Z
diff --git a/templates/shared/combomarkdowneditor.tmpl b/templates/shared/combomarkdowneditor.tmpl
index 30b0de2a49..ace9d90815 100644
--- a/templates/shared/combomarkdowneditor.tmpl
+++ b/templates/shared/combomarkdowneditor.tmpl
@@ -40,12 +40,18 @@ Template Attributes:
 				<md-ref class="markdown-toolbar-button" data-tooltip-content="{{.locale.Tr "editor.buttons.ref.tooltip"}}">{{svg "octicon-cross-reference"}}</md-ref>
 			</div>
 			<div class="markdown-toolbar-group">
+				<button class="markdown-toolbar-button markdown-switch-monospace" role="switch" data-enable-text="{{.locale.Tr "editor.buttons.enable_monospace_font"}}" data-disable-text="{{.locale.Tr "editor.buttons.disable_monospace_font"}}">{{svg "octicon-typography"}}</button>
 				<button class="markdown-toolbar-button markdown-switch-easymde" data-tooltip-content="{{.locale.Tr "editor.buttons.switch_to_legacy.tooltip"}}">{{svg "octicon-arrow-switch"}}</button>
 			</div>
 		</markdown-toolbar>
 		<text-expander keys=": @">
 			<textarea class="markdown-text-editor js-quick-submit"{{if .TextareaName}} name="{{.TextareaName}}"{{end}}{{if .TextareaPlaceholder}} placeholder="{{.TextareaPlaceholder}}"{{end}}{{if .TextareaAriaLabel}} aria-label="{{.TextareaAriaLabel}}"{{end}}>{{.TextareaContent}}</textarea>
 		</text-expander>
+		<script>
+			if (localStorage?.getItem('markdown-editor-monospace') === 'true') {
+				document.querySelector('.markdown-text-editor').classList.add('gt-mono');
+			}
+		</script>
 	</div>
 	<div class="ui tab markup" data-tab-panel="markdown-previewer">
 		{{.locale.Tr "loading"}}
diff --git a/web_src/css/editor-markdown.css b/web_src/css/editor-markdown.css
index 46ced17cdc..7d6c36635d 100644
--- a/web_src/css/editor-markdown.css
+++ b/web_src/css/editor-markdown.css
@@ -24,6 +24,7 @@
   user-select: none;
   padding: 5px;
   cursor: pointer;
+  color: var(--color-text);
 }
 
 .combo-markdown-editor .markdown-toolbar-button:hover {
diff --git a/web_src/css/helpers.css b/web_src/css/helpers.css
index 834a507b68..dcec79fcf6 100644
--- a/web_src/css/helpers.css
+++ b/web_src/css/helpers.css
@@ -29,7 +29,7 @@
 
 .gt-mono {
   font-family: var(--fonts-monospace) !important;
-  font-size: .9em !important; /* compensate for monospace fonts being usually slightly larger */
+  font-size: .95em !important; /* compensate for monospace fonts being usually slightly larger */
 }
 
 .gt-bold { font-weight: 600 !important; }
diff --git a/web_src/js/features/comp/ComboMarkdownEditor.js b/web_src/js/features/comp/ComboMarkdownEditor.js
index a7d69af7b4..3eb8bf7076 100644
--- a/web_src/js/features/comp/ComboMarkdownEditor.js
+++ b/web_src/js/features/comp/ComboMarkdownEditor.js
@@ -73,8 +73,25 @@ class ComboMarkdownEditor {
       // upstream bug: The role code is never executed in base MarkdownButtonElement https://github.com/github/markdown-toolbar-element/issues/70
       el.setAttribute('role', 'button');
     }
-    this.switchToEasyMDEButton = this.container.querySelector('.markdown-switch-easymde');
-    this.switchToEasyMDEButton?.addEventListener('click', async (e) => {
+
+    const monospaceButton = this.container.querySelector('.markdown-switch-monospace');
+    const monospaceEnabled = localStorage?.getItem('markdown-editor-monospace') === 'true';
+    const monospaceText = monospaceButton.getAttribute(monospaceEnabled ? 'data-disable-text' : 'data-enable-text');
+    monospaceButton.setAttribute('data-tooltip-content', monospaceText);
+    monospaceButton.setAttribute('aria-checked', String(monospaceEnabled));
+
+    monospaceButton?.addEventListener('click', (e) => {
+      e.preventDefault();
+      const enabled = localStorage?.getItem('markdown-editor-monospace') !== 'true';
+      localStorage.setItem('markdown-editor-monospace', String(enabled));
+      this.textarea.classList.toggle('gt-mono', enabled);
+      const text = monospaceButton.getAttribute(enabled ? 'data-disable-text' : 'data-enable-text');
+      monospaceButton.setAttribute('data-tooltip-content', text);
+      monospaceButton.setAttribute('aria-checked', String(enabled));
+    });
+
+    const easymdeButton = this.container.querySelector('.markdown-switch-easymde');
+    easymdeButton?.addEventListener('click', async (e) => {
       e.preventDefault();
       this.userPreferredEditor = 'easymde';
       await this.switchToEasyMDE();