mirror of
				https://github.com/go-gitea/gitea
				synced 2025-11-04 05:18:25 +00:00 
			
		
		
		
	Fix dynamic content loading init problem (#33748)
1. Rewrite `dirauto.ts` to `observer.ts`. 
* We have been using MutationObserver for long time, it's proven that it
is quite performant.
    * Now we extend its ability to handle more "init" works.
2. Use `observeAddedElement` to init all non-custom "dropdown".
3. Use `data-global-click` to handle click events from dynamically
loaded elements.
* By this new approach, the old fragile selector-based
(`.comment-reaction-button`) mechanism is removed.
4. By the way, remove unused `.diff-box` selector, it was abused and
never really used.
A lot of FIXMEs in "repo-diff.ts" are completely fixed, newly loaded
contents could work as expected.
			
			
This commit is contained in:
		@@ -2,6 +2,7 @@ import {GET} from '../modules/fetch.ts';
 | 
			
		||||
import {showGlobalErrorMessage} from '../bootstrap.ts';
 | 
			
		||||
import {fomanticQuery} from '../modules/fomantic/base.ts';
 | 
			
		||||
import {queryElems} from '../utils/dom.ts';
 | 
			
		||||
import {observeAddedElement} from '../modules/observer.ts';
 | 
			
		||||
 | 
			
		||||
const {appUrl} = window.config;
 | 
			
		||||
 | 
			
		||||
@@ -28,47 +29,51 @@ export function initFootLanguageMenu() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function initGlobalDropdown() {
 | 
			
		||||
  // Semantic UI modules.
 | 
			
		||||
  const $uiDropdowns = fomanticQuery('.ui.dropdown');
 | 
			
		||||
 | 
			
		||||
  // do not init "custom" dropdowns, "custom" dropdowns are managed by their own code.
 | 
			
		||||
  $uiDropdowns.filter(':not(.custom)').dropdown({hideDividers: 'empty'});
 | 
			
		||||
  observeAddedElement('.ui.dropdown:not(.custom)', (el) => {
 | 
			
		||||
    const $dropdown = fomanticQuery(el);
 | 
			
		||||
    if ($dropdown.data('module-dropdown')) return; // do not re-init if other code has already initialized it.
 | 
			
		||||
 | 
			
		||||
  // The "jump" means this dropdown is mainly used for "menu" purpose,
 | 
			
		||||
  // clicking an item will jump to somewhere else or trigger an action/function.
 | 
			
		||||
  // When a dropdown is used for non-refresh actions with tippy,
 | 
			
		||||
  // it must have this "jump" class to hide the tippy when dropdown is closed.
 | 
			
		||||
  $uiDropdowns.filter('.jump').dropdown('setting', {
 | 
			
		||||
    action: 'hide',
 | 
			
		||||
    onShow() {
 | 
			
		||||
      // hide associated tooltip while dropdown is open
 | 
			
		||||
      this._tippy?.hide();
 | 
			
		||||
      this._tippy?.disable();
 | 
			
		||||
    },
 | 
			
		||||
    onHide() {
 | 
			
		||||
      this._tippy?.enable();
 | 
			
		||||
      // eslint-disable-next-line unicorn/no-this-assignment
 | 
			
		||||
      const elDropdown = this;
 | 
			
		||||
    $dropdown.dropdown('setting', {hideDividers: 'empty'});
 | 
			
		||||
 | 
			
		||||
      // hide all tippy elements of items after a while. eg: use Enter to click "Copy Link" in the Issue Context Menu
 | 
			
		||||
      setTimeout(() => {
 | 
			
		||||
        const $dropdown = fomanticQuery(elDropdown);
 | 
			
		||||
        if ($dropdown.dropdown('is hidden')) {
 | 
			
		||||
          queryElems(elDropdown, '.menu > .item', (el) => el._tippy?.hide());
 | 
			
		||||
        }
 | 
			
		||||
      }, 2000);
 | 
			
		||||
    },
 | 
			
		||||
    if (el.classList.contains('jump')) {
 | 
			
		||||
      // The "jump" means this dropdown is mainly used for "menu" purpose,
 | 
			
		||||
      // clicking an item will jump to somewhere else or trigger an action/function.
 | 
			
		||||
      // When a dropdown is used for non-refresh actions with tippy,
 | 
			
		||||
      // it must have this "jump" class to hide the tippy when dropdown is closed.
 | 
			
		||||
      $dropdown.dropdown('setting', {
 | 
			
		||||
        action: 'hide',
 | 
			
		||||
        onShow() {
 | 
			
		||||
          // hide associated tooltip while dropdown is open
 | 
			
		||||
          this._tippy?.hide();
 | 
			
		||||
          this._tippy?.disable();
 | 
			
		||||
        },
 | 
			
		||||
        onHide() {
 | 
			
		||||
          this._tippy?.enable();
 | 
			
		||||
          // eslint-disable-next-line unicorn/no-this-assignment
 | 
			
		||||
          const elDropdown = this;
 | 
			
		||||
 | 
			
		||||
          // hide all tippy elements of items after a while. eg: use Enter to click "Copy Link" in the Issue Context Menu
 | 
			
		||||
          setTimeout(() => {
 | 
			
		||||
            const $dropdown = fomanticQuery(elDropdown);
 | 
			
		||||
            if ($dropdown.dropdown('is hidden')) {
 | 
			
		||||
              queryElems(elDropdown, '.menu > .item', (el) => el._tippy?.hide());
 | 
			
		||||
            }
 | 
			
		||||
          }, 2000);
 | 
			
		||||
        },
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Special popup-directions, prevent Fomantic from guessing the popup direction.
 | 
			
		||||
    // With default "direction: auto", if the viewport height is small, Fomantic would show the popup upward,
 | 
			
		||||
    //   if the dropdown is at the beginning of the page, then the top part would be clipped by the window view.
 | 
			
		||||
    //   eg: Issue List "Sort" dropdown
 | 
			
		||||
    // But we can not set "direction: downward" for all dropdowns, because there is a bug in dropdown menu positioning when calculating the "left" position,
 | 
			
		||||
    //   which would make some dropdown popups slightly shift out of the right viewport edge in some cases.
 | 
			
		||||
    //   eg: the "Create New Repo" menu on the navbar.
 | 
			
		||||
    if (el.classList.contains('upward')) $dropdown.dropdown('setting', 'direction', 'upward');
 | 
			
		||||
    if (el.classList.contains('downward')) $dropdown.dropdown('setting', 'direction', 'downward');
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  // Special popup-directions, prevent Fomantic from guessing the popup direction.
 | 
			
		||||
  // With default "direction: auto", if the viewport height is small, Fomantic would show the popup upward,
 | 
			
		||||
  //   if the dropdown is at the beginning of the page, then the top part would be clipped by the window view.
 | 
			
		||||
  //   eg: Issue List "Sort" dropdown
 | 
			
		||||
  // But we can not set "direction: downward" for all dropdowns, because there is a bug in dropdown menu positioning when calculating the "left" position,
 | 
			
		||||
  //   which would make some dropdown popups slightly shift out of the right viewport edge in some cases.
 | 
			
		||||
  //   eg: the "Create New Repo" menu on the navbar.
 | 
			
		||||
  $uiDropdowns.filter('.upward').dropdown('setting', 'direction', 'upward');
 | 
			
		||||
  $uiDropdowns.filter('.downward').dropdown('setting', 'direction', 'downward');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function initGlobalTabularMenu() {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user