# Preview Tab - Removed the jQuery AJAX call and replaced with our fetch wrapper - Tested the preview tab functionality and it works as before # Diff Tab - Removed the jQuery AJAX call and replaced with htmx - Tested the diff tab functionality and it works as before ## htmx Attributes - `hx-post="{{.RepoLink}}..."`: make a POST request to the endpoint - `hx-indicator=".tab[data-tab='diff']"`: attach the loading indicator to the tab body - `hx-target=".tab[data-tab='diff']"`: target the tab body for swapping with the response - `hx-swap="innerHTML"`: swap the target's inner HTML - `hx-include="#edit_area"`: include the value of the textarea (content) in the request body - `hx-vals='{"context":"{{.BranchLink}}"}'`: include the context in the request body - `hx-params="context,content"`: include only these keys in the request body # Demo using `fetch` and `htmx` instead of jQuery AJAX ![demo](https://github.com/go-gitea/gitea/assets/20454870/585cd6e8-f329-4c9e-ab53-a540acbd7988) --------- Signed-off-by: Yarden Shoham <git@yardenshoham.com> Co-authored-by: silverwind <me@silverwind.io>tags/v1.22.0-rc0
@@ -30,7 +30,7 @@ | |||
<a class="active item" data-tab="write">{{svg "octicon-code"}} {{if .IsNewFile}}{{ctx.Locale.Tr "repo.editor.new_file"}}{{else}}{{ctx.Locale.Tr "repo.editor.edit_file"}}{{end}}</a> | |||
<a class="item" data-tab="preview" data-url="{{.Repository.Link}}/markup" data-context="{{.RepoLink}}/src/{{.BranchNameSubURL}}" data-markup-mode="file">{{svg "octicon-eye"}} {{ctx.Locale.Tr "preview"}}</a> | |||
{{if not .IsNewFile}} | |||
<a class="item" data-tab="diff" data-url="{{.RepoLink}}/_preview/{{.BranchName | PathEscapeSegments}}/{{.TreePath | PathEscapeSegments}}" data-context="{{.BranchLink}}">{{svg "octicon-diff"}} {{ctx.Locale.Tr "repo.editor.preview_changes"}}</a> | |||
<a class="item" data-tab="diff" hx-params="context,content" hx-vals='{"context":"{{.BranchLink}}"}' hx-include="#edit_area" hx-swap="innerHTML" hx-target=".tab[data-tab='diff']" hx-indicator=".tab[data-tab='diff']" hx-post="{{.RepoLink}}/_preview/{{.BranchName | PathEscapeSegments}}/{{.TreePath | PathEscapeSegments}}">{{svg "octicon-diff"}} {{ctx.Locale.Tr "repo.editor.preview_changes"}}</a> | |||
{{end}} | |||
</div> | |||
<div class="ui bottom attached active tab segment" data-tab="write"> | |||
@@ -45,7 +45,7 @@ | |||
{{ctx.Locale.Tr "loading"}} | |||
</div> | |||
<div class="ui bottom attached tab segment diff edit-diff" data-tab="diff"> | |||
{{ctx.Locale.Tr "loading"}} | |||
<div class="tw-p-16"></div> | |||
</div> | |||
</div> | |||
{{template "repo/editor/commit_form" .}} |
@@ -4,15 +4,14 @@ import {createCodeEditor} from './codeeditor.js'; | |||
import {hideElem, showElem} from '../utils/dom.js'; | |||
import {initMarkupContent} from '../markup/content.js'; | |||
import {attachRefIssueContextPopup} from './contextpopup.js'; | |||
const {csrfToken} = window.config; | |||
import {POST} from '../modules/fetch.js'; | |||
function initEditPreviewTab($form) { | |||
const $tabMenu = $form.find('.tabular.menu'); | |||
$tabMenu.find('.item').tab(); | |||
const $previewTab = $tabMenu.find(`.item[data-tab="${$tabMenu.data('preview')}"]`); | |||
if ($previewTab.length) { | |||
$previewTab.on('click', function () { | |||
$previewTab.on('click', async function () { | |||
const $this = $(this); | |||
let context = `${$this.data('context')}/`; | |||
const mode = $this.data('markup-mode') || 'comment'; | |||
@@ -21,43 +20,30 @@ function initEditPreviewTab($form) { | |||
context += treePathEl.val(); | |||
} | |||
context = context.substring(0, context.lastIndexOf('/')); | |||
$.post($this.data('url'), { | |||
_csrf: csrfToken, | |||
mode, | |||
context, | |||
text: $form.find(`.tab[data-tab="${$tabMenu.data('write')}"] textarea`).val(), | |||
file_path: treePathEl.val(), | |||
}, (data) => { | |||
const formData = new FormData(); | |||
formData.append('mode', mode); | |||
formData.append('context', context); | |||
formData.append('text', $form.find(`.tab[data-tab="${$tabMenu.data('write')}"] textarea`).val()); | |||
formData.append('file_path', treePathEl.val()); | |||
try { | |||
const response = await POST($this.data('url'), {data: formData}); | |||
const data = await response.text(); | |||
const $previewPanel = $form.find(`.tab[data-tab="${$tabMenu.data('preview')}"]`); | |||
renderPreviewPanelContent($previewPanel, data); | |||
}); | |||
} catch (error) { | |||
console.error('Error:', error); | |||
} | |||
}); | |||
} | |||
} | |||
function initEditDiffTab($form) { | |||
const $tabMenu = $form.find('.tabular.menu'); | |||
$tabMenu.find('.item').tab(); | |||
$tabMenu.find(`.item[data-tab="${$tabMenu.data('diff')}"]`).on('click', function () { | |||
const $this = $(this); | |||
$.post($this.data('url'), { | |||
_csrf: csrfToken, | |||
context: $this.data('context'), | |||
content: $form.find(`.tab[data-tab="${$tabMenu.data('write')}"] textarea`).val(), | |||
}, (data) => { | |||
const $diffPreviewPanel = $form.find(`.tab[data-tab="${$tabMenu.data('diff')}"]`); | |||
$diffPreviewPanel.html(data); | |||
}); | |||
}); | |||
} | |||
function initEditorForm() { | |||
if ($('.repository .edit.form').length === 0) { | |||
return; | |||
} | |||
initEditPreviewTab($('.repository .edit.form')); | |||
initEditDiffTab($('.repository .edit.form')); | |||
} | |||
function getCursorPosition($e) { |