mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2025-09-01 03:08:39 +02:00
feat: remove fomantic's tab module (#8587)
In similar vein of forgejo/forgejo#7416 - Fomantic's tab module is responsible for showing the right content when a tab is clicked upon. Most notably the Write/Preview tabs on the comment editor. - Remove it and replace the javascript with our own function that is able to provide everything Forgejo needs. - Replace the CSS with our own bare minimum CSS. - No functionality or visual is affected by this replacement. - E2E test added. Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/8587 Reviewed-by: Otto <otto@codeberg.org> Reviewed-by: 0ko <0ko@noreply.codeberg.org> Co-authored-by: Gusted <postmaster@gusted.xyz> Co-committed-by: Gusted <postmaster@gusted.xyz>
This commit is contained in:
parent
199d9cf65c
commit
8e4f50a909
12 changed files with 123 additions and 1093 deletions
|
@ -12,6 +12,7 @@ import {confirmModal} from './comp/ConfirmModal.js';
|
|||
import {showErrorToast} from '../modules/toast.js';
|
||||
import {request, POST, GET} from '../modules/fetch.js';
|
||||
import '../htmx.js';
|
||||
import {initTab} from '../modules/tab.ts';
|
||||
|
||||
const {appUrl, appSubUrl, csrfToken, i18n} = window.config;
|
||||
|
||||
|
@ -195,7 +196,9 @@ export function initGlobalCommon() {
|
|||
$uiDropdowns.filter('.upward').dropdown('setting', 'direction', 'upward');
|
||||
$uiDropdowns.filter('.downward').dropdown('setting', 'direction', 'downward');
|
||||
|
||||
$('.tabular.menu .item').tab();
|
||||
for (const el of document.querySelectorAll('.tabular.menu')) {
|
||||
initTab(el);
|
||||
}
|
||||
|
||||
initSubmitEventPolyfill();
|
||||
document.addEventListener('submit', formFetchAction);
|
||||
|
|
|
@ -10,6 +10,7 @@ import {easyMDEToolbarActions} from './EasyMDEToolbarActions.js';
|
|||
import {initTextExpander} from './TextExpander.js';
|
||||
import {showErrorToast, showHintToast} from '../../modules/toast.js';
|
||||
import {POST} from '../../modules/fetch.js';
|
||||
import {initTab} from '../../modules/tab.ts';
|
||||
|
||||
/**
|
||||
* validate if the given textarea is non-empty.
|
||||
|
@ -200,7 +201,8 @@ class ComboMarkdownEditor {
|
|||
|
||||
setupTab() {
|
||||
const $container = $(this.container);
|
||||
const tabs = $container[0].querySelectorAll('.switch > .item');
|
||||
const switchEl = $container[0].querySelector('.switch');
|
||||
const tabs = switchEl.querySelectorAll('.item');
|
||||
|
||||
// Fomantic Tab requires the "data-tab" to be globally unique.
|
||||
// So here it uses our defined "data-tab-for" and "data-tab-panel" to generate the "data-tab" attribute for Fomantic.
|
||||
|
@ -221,7 +223,7 @@ class ComboMarkdownEditor {
|
|||
});
|
||||
});
|
||||
|
||||
$(tabs).tab();
|
||||
initTab(switchEl);
|
||||
|
||||
this.previewUrl = tabPreviewer.getAttribute('data-preview-url');
|
||||
this.previewContext = tabPreviewer.getAttribute('data-preview-context');
|
||||
|
|
|
@ -5,10 +5,11 @@ import {hideElem, showElem, createElementFromHTML} from '../utils/dom.js';
|
|||
import {initMarkupContent} from '../markup/content.js';
|
||||
import {attachRefIssueContextPopup} from './contextpopup.js';
|
||||
import {POST} from '../modules/fetch.js';
|
||||
import {initTab} from '../modules/tab.ts';
|
||||
|
||||
function initEditPreviewTab($form) {
|
||||
const $tabMenu = $form.find('.tabular.menu');
|
||||
$tabMenu.find('.item').tab();
|
||||
initTab($tabMenu[0]);
|
||||
const $previewTab = $tabMenu.find(
|
||||
`.item[data-tab="${$tabMenu.data('preview')}"]`,
|
||||
);
|
||||
|
|
|
@ -11,9 +11,6 @@ import {initDimmer} from './dimmer.ts';
|
|||
export const fomanticMobileScreen = window.matchMedia('only screen and (max-width: 767.98px)');
|
||||
|
||||
export function initGiteaFomantic() {
|
||||
// Silence fomantic's error logging when tabs are used without a target content element
|
||||
$.fn.tab.settings.silent = true;
|
||||
|
||||
// By default, use "exact match" for full text search
|
||||
$.fn.dropdown.settings.fullTextSearch = 'exact';
|
||||
// Do not use "cursor: pointer" for dropdown labels
|
||||
|
|
36
web_src/js/modules/tab.ts
Normal file
36
web_src/js/modules/tab.ts
Normal file
|
@ -0,0 +1,36 @@
|
|||
export function initTab(parentEl: Element) {
|
||||
if (!parentEl) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Keep track of which tab is active for this element.
|
||||
let activeTabPath = parentEl.querySelector('.item.active')?.getAttribute('data-tab');
|
||||
if (!activeTabPath) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const el of parentEl.querySelectorAll('.item')) {
|
||||
el.addEventListener('click', (ev) => {
|
||||
// There's no data-tab attribute we can't do anything, ignore.
|
||||
const tabPath = el.getAttribute('data-tab');
|
||||
if (!tabPath) {
|
||||
return;
|
||||
}
|
||||
|
||||
// The item is already active, ignore.
|
||||
if (el.classList.contains('active')) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Make the current item active and the previous item inactive.
|
||||
parentEl.querySelector('.item.active').classList.remove('active');
|
||||
document.querySelector(`.tab.active[data-tab=${activeTabPath}]`).classList.remove('active');
|
||||
el.classList.add('active');
|
||||
document.querySelector(`.tab[data-tab=${tabPath}]`).classList.add('active');
|
||||
activeTabPath = tabPath;
|
||||
|
||||
// Not really sure if this is useful, it is kept from how Fomantic did it.
|
||||
ev.preventDefault();
|
||||
}, {passive: false});
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue