메뉴 여닫기
환경 설정 메뉴 여닫기
개인 메뉴 여닫기
로그인하지 않음
만약 지금 편집한다면 당신의 IP 주소가 공개될 수 있습니다.

미디어위키:Common.js: 두 판 사이의 차이

novawiki
편집 요약 없음
편집 요약 없음
2번째 줄: 2번째 줄:


/**
/**
  * Aggressive autofocus for Citizen search
  * Citizen search: open + focus immediately on user gesture (iOS-friendly)
  * - Remembers user intent even during page load
  * - Intercepts tap on the <summary> so focus stays within the gesture stack
  * - Focuses input the moment it becomes available & visible
  * - Manually opens <details> and focuses #searchInput right away
  */
  */
(function () {
(function () {
   const TOGGLE_SELECTOR =
   const DETAILS_ID = 'citizen-search-details';
    '#citizen-search-details > summary.citizen-dropdown-summary';
  const TOGGLE_SEL = '#citizen-search-details > summary.citizen-dropdown-summary';
   const INPUT_SELECTOR = '#searchInput';
   const INPUT_ID = 'searchInput';


   let wantFocus = false;
   function openAndFocus() {
  let observer = null;
    const details = document.getElementById(DETAILS_ID);
  let retryTimer = null;
    const input = document.getElementById(INPUT_ID);


  function canFocus(input) {
     if (!details || !input) return;
     if (!input) return false;
    if (input.disabled) return false;
    const rect = input.getBoundingClientRect();
    return rect.width > 0 && rect.height > 0;
  }


  function tryFocus() {
    // Open immediately (within the same user gesture)
     if (!wantFocus) return;
     if (!details.open) details.open = true;


     const input = document.querySelector(INPUT_SELECTOR);
     // Force a tiny layout sync so iOS is less flaky about focus
     if (!canFocus(input)) return;
    // (Reading offsetHeight triggers reflow; yes it's old-school, yes it works)
     void input.offsetHeight;


     input.focus({ preventScroll: true });
     input.focus({ preventScroll: true });
     input.click();
     input.click(); // helps some mobile engines trigger the keyboard
  }


     if (document.activeElement === input) {
  // Use the earliest possible gesture event
       cleanup();
  document.addEventListener(
    }
     'touchstart',
  }
    function (e) {
       const toggle = e.target.closest(TOGGLE_SEL);
      if (!toggle) return;


  function cleanup() {
      // Stop the default summary toggle so we control timing
    wantFocus = false;
      e.preventDefault();
    if (observer) observer.disconnect();
      e.stopPropagation();
    observer = null;
    if (retryTimer) clearInterval(retryTimer);
    retryTimer = null;
  }


  function startWatching() {
      openAndFocus();
     // 1) DOM 변화 감시
     },
     if (!observer) {
     { capture: true, passive: false } // passive:false is REQUIRED for preventDefault on iOS
      observer = new MutationObserver(tryFocus);
  );
      observer.observe(document.body, {
        childList: true,
        subtree: true,
        attributes: true,
      });
    }


    // 2) 혹시 Mutation이 안 잡히는 케이스 대비 폴링
  // Fallback for non-touch / weird cases
     if (!retryTimer) {
  document.addEventListener(
       retryTimer = setInterval(tryFocus, 50);
    'click',
    }
     function (e) {
  }
       const toggle = e.target.closest(TOGGLE_SEL);
      if (!toggle) return;


  function onSearchIntent() {
      e.preventDefault();
    wantFocus = true;
      e.stopPropagation();
    tryFocus();     // 즉시 한 번
    startWatching(); // 안 되면 끝까지 쫓아감
  }


  // 🔑 진짜 중요한 부분: "유저 제스처"에서 intent만 기록
       openAndFocus();
  ['touchstart', 'touchend', 'mousedown', 'click'].forEach((evt) => {
    },
    document.addEventListener(
    true
       evt,
   );
      function (e) {
        if (e.target.closest(TOGGLE_SELECTOR)) {
          onSearchIntent();
        }
      },
      true
    );
   });
})();
})();

2026년 1월 17일 (토) 18:52 판

/* 이 자바스크립트 설정은 모든 문서, 모든 사용자에게 적용됩니다. */

/**
 * Citizen search: open + focus immediately on user gesture (iOS-friendly)
 * - Intercepts tap on the <summary> so focus stays within the gesture stack
 * - Manually opens <details> and focuses #searchInput right away
 */
(function () {
  const DETAILS_ID = 'citizen-search-details';
  const TOGGLE_SEL = '#citizen-search-details > summary.citizen-dropdown-summary';
  const INPUT_ID = 'searchInput';

  function openAndFocus() {
    const details = document.getElementById(DETAILS_ID);
    const input = document.getElementById(INPUT_ID);

    if (!details || !input) return;

    // Open immediately (within the same user gesture)
    if (!details.open) details.open = true;

    // Force a tiny layout sync so iOS is less flaky about focus
    // (Reading offsetHeight triggers reflow; yes it's old-school, yes it works)
    void input.offsetHeight;

    input.focus({ preventScroll: true });
    input.click(); // helps some mobile engines trigger the keyboard
  }

  // Use the earliest possible gesture event
  document.addEventListener(
    'touchstart',
    function (e) {
      const toggle = e.target.closest(TOGGLE_SEL);
      if (!toggle) return;

      // Stop the default summary toggle so we control timing
      e.preventDefault();
      e.stopPropagation();

      openAndFocus();
    },
    { capture: true, passive: false } // passive:false is REQUIRED for preventDefault on iOS
  );

  // Fallback for non-touch / weird cases
  document.addEventListener(
    'click',
    function (e) {
      const toggle = e.target.closest(TOGGLE_SEL);
      if (!toggle) return;

      e.preventDefault();
      e.stopPropagation();

      openAndFocus();
    },
    true
  );
})();