1- From 0a5d6eeb66cbece3a1df154d126536dfab28b324 Mon Sep 17 00:00:00 2001
1+ From a4538239196ba18215f569631d4a93e954826c73 Mon Sep 17 00:00:00 2001
22From: Bart van der Braak <
[email protected] >
3- Date: Wed, 30 Apr 2025 18:09:40 +0200
3+ Date: Fri, 2 May 2025 11:31:25 +0200
44Subject: [PATCH] BLENDER: Add Line Length indicator for cursor
55
66---
7- templates/repo/editor/commit_form.tmpl | 52 ++++++++++++++++++
8- .../js/components/PullRequestMergeForm.vue | 40 +++++++++++++-
9- .../js/features/comp/ComboMarkdownEditor.ts | 54 +++++++++++++++++--
10- 3 files changed, 142 insertions(+), 4 deletions(-)
7+ templates/repo/editor/commit_form.tmpl | 52 +++++++++++++++++++
8+ .../js/components/PullRequestMergeForm.vue | 39 +++++++++++++-
9+ 2 files changed, 90 insertions(+), 1 deletion(-)
1110
1211diff --git a/templates/repo/editor/commit_form.tmpl b/templates/repo/editor/commit_form.tmpl
13- index c050324e93..2bb9395645 100644
12+ index c050324e93..402e270483 100644
1413--- a/templates/repo/editor/commit_form.tmpl
1514+++ b/templates/repo/editor/commit_form.tmpl
1615@@ -13,6 +13,58 @@
@@ -65,15 +64,15 @@ index c050324e93..2bb9395645 100644
6564+ textarea.addEventListener('input', updateStatus);
6665+ textarea.addEventListener('click', updateStatus);
6766+ textarea.addEventListener('keyup', updateStatus);
68- + updateStatus(); // Initial render
67+ + updateStatus();
6968+ })();
7069+ </script>
7170+
7271 </div>
7372 <div class="inline field">
7473 <div class="ui checkbox">
7574diff --git a/web_src/js/components/PullRequestMergeForm.vue b/web_src/js/components/PullRequestMergeForm.vue
76- index bafeec6c97..6f8bcaa6cc 100644
75+ index bafeec6c97..0c51711bc6 100644
7776--- a/web_src/js/components/PullRequestMergeForm.vue
7877+++ b/web_src/js/components/PullRequestMergeForm.vue
7978@@ -26,6 +26,12 @@ const mergeStyleAllowedCount = ref(0);
@@ -89,7 +88,7 @@ index bafeec6c97..6f8bcaa6cc 100644
8988 const mergeButtonStyleClass = computed(() => {
9089 if (mergeForm.value.allOverridableChecksOk) return 'primary';
9190 return autoMergeWhenSucceed.value ? 'primary' : 'red';
92- @@ -76,6 +82,23 @@ function switchMergeStyle(name, autoMerge = false) {
91+ @@ -76,6 +82,22 @@ function switchMergeStyle(name, autoMerge = false) {
9392 function clearMergeMessage() {
9493 mergeMessageFieldValue.value = mergeForm.value.defaultMergeMessage;
9594 }
@@ -105,15 +104,14 @@ index bafeec6c97..6f8bcaa6cc 100644
105104+ cursorLine.value = lines.length;
106105+ cursorColumn.value = lines[lines.length - 1].length + 1;
107106+
108- + // Full content stats
109107+ lineCount.value = textarea.value.split('\n').length;
110108+ wordCount.value = textarea.value.trim().split(/\s+/).filter(Boolean).length;
111109+ }
112110+
113111 </script>
114112
115113 <template>
116- @@ -105,7 +128 ,22 @@ function clearMergeMessage() {
114+ @@ -105,7 +127 ,22 @@ function clearMergeMessage() {
117115 <input type="text" name="merge_title_field" v-model="mergeTitleFieldValue">
118116 </div>
119117 <div class="field">
@@ -137,93 +135,6 @@ index bafeec6c97..6f8bcaa6cc 100644
137135 <template v-if="mergeMessageFieldValue !== mergeForm.defaultMergeMessage">
138136 <button @click.prevent="clearMergeMessage" class="btn tw-mt-1 tw-p-1 interact-fg" :data-tooltip-content="mergeForm.textClearMergeMessageHint">
139137 {{ mergeForm.textClearMergeMessage }}
140- diff --git a/web_src/js/features/comp/ComboMarkdownEditor.ts b/web_src/js/features/comp/ComboMarkdownEditor.ts
141- index bba50a1296..3252e68402 100644
142- --- a/web_src/js/features/comp/ComboMarkdownEditor.ts
143- +++ b/web_src/js/features/comp/ComboMarkdownEditor.ts
144- @@ -69,6 +69,7 @@ export class ComboMarkdownEditor {
145- easyMDE: any;
146- easyMDEToolbarActions: any;
147- easyMDEToolbarDefault: any;
148- + statusbarEl?: HTMLDivElement;
149-
150- textarea: HTMLTextAreaElement & {_giteaComboMarkdownEditor: any};
151- textareaMarkdownToolbar: HTMLElement;
152- @@ -127,10 +128,10 @@ export class ComboMarkdownEditor {
153- this.textareaMarkdownToolbar = this.container.querySelector('markdown-toolbar');
154- this.textareaMarkdownToolbar.setAttribute('for', this.textarea.id);
155- for (const el of this.textareaMarkdownToolbar.querySelectorAll('.markdown-toolbar-button')) {
156- - // upstream bug: The role code is never executed in base MarkdownButtonElement https://github.com/github/markdown-toolbar-element/issues/70
157- el.setAttribute('role', 'button');
158- - // the editor usually is in a form, so the buttons should have "type=button", avoiding conflicting with the form's submit.
159- - if (el.nodeName === 'BUTTON' && !el.getAttribute('type')) el.setAttribute('type', 'button');
160- + if (el.nodeName === 'BUTTON' && !el.getAttribute('type')) {
161- + el.setAttribute('type', 'button');
162- + }
163- }
164-
165- const monospaceButton = this.container.querySelector('.markdown-switch-monospace');
166- @@ -153,6 +154,8 @@ export class ComboMarkdownEditor {
167- easymdeButton.addEventListener('click', async (e) => {
168- e.preventDefault();
169- this.userPreferredEditor = 'easymde';
170- + // Clear statusbar if switching to EasyMDE
171- + if (this.statusbarEl) this.statusbarEl.remove();
172- await this.switchToEasyMDE();
173- });
174- }
175- @@ -161,6 +164,51 @@ export class ComboMarkdownEditor {
176-
177- initTextareaMarkdown(this.textarea);
178- initTextareaEvents(this.textarea, this.dropzone);
179- +
180- + // === Status bar setup ===
181- + const statusbar = document.createElement('div');
182- + statusbar.className = 'editor-statusbar';
183- +
184- + const autosave = document.createElement('span');
185- + autosave.className = 'autosave';
186- +
187- + const linesEl = document.createElement('span');
188- + linesEl.className = 'lines';
189- +
190- + const wordsEl = document.createElement('span');
191- + wordsEl.className = 'words';
192- +
193- + const cursorEl = document.createElement('span');
194- + cursorEl.className = 'cursor';
195- +
196- + statusbar.appendChild(autosave);
197- + statusbar.appendChild(linesEl);
198- + statusbar.appendChild(wordsEl);
199- + statusbar.appendChild(cursorEl);
200- + this.container.appendChild(statusbar);
201- + this.statusbarEl = statusbar; // So we can remove it when switching to EasyMDE
202- +
203- + const updateStatus = () => {
204- + const value = this.textarea.value;
205- + const pos = this.textarea.selectionStart;
206- +
207- + const lines = value.substr(0, pos).split('\n');
208- + const line = lines.length;
209- + const column = lines[lines.length - 1].length + 1;
210- +
211- + const totalLines = value.split('\n').length;
212- + const totalWords = (value.match(/\b\w+\b/g) || []).length;
213- +
214- + linesEl.textContent = totalLines.toString();
215- + wordsEl.textContent = totalWords.toString();
216- + cursorEl.textContent = `${line}:${column}`;
217- + };
218- +
219- + this.textarea.addEventListener('input', updateStatus);
220- + this.textarea.addEventListener('click', updateStatus);
221- + this.textarea.addEventListener('keyup', updateStatus);
222- + updateStatus();
223- +
224- }
225-
226- async setupDropzone() {
227138- -
2281392.49.0
229140
0 commit comments