Decathlon — 탭 제목 변경 방지

페이지가 숨겨져 있을 때(탭 전환 시) Decathlon이 탭 제목을 바꾸지 못하게 합니다.

이 스크립트를 설치하려면 Tampermonkey, Greasemonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램을 설치해야 합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Userscripts와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 유저 스크립트 관리자 확장 프로그램이 필요합니다.

(이미 유저 스크립트 관리자가 설치되어 있습니다. 설치를 진행합니다!)

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

(이미 유저 스타일 관리자가 설치되어 있습니다. 설치를 진행합니다!)

// ==UserScript==

// @name              Decathlon — Stop tab title changes
// @name:fr           Decathlon — Empêcher le changement du titre de l’onglet
// @name:es           Decathlon — Evitar cambios en el título de la pestaña
// @name:de           Decathlon — Tab-Titeländerungen verhindern
// @name:it           Decathlon — Blocca il cambio del titolo della scheda
// @name:nl           Decathlon — Stop tabtitel-wijzigingen
// @name:pt           Decathlon — Impedir alterações no título do separador
// @name:pt-BR        Decathlon — Impedir mudanças no título da aba
// @name:pl           Decathlon — Zatrzymaj zmiany tytułu karty
// @name:cs           Decathlon — Zabránit změnám názvu karty
// @name:sk           Decathlon — Zabraň zmenám názvu karty
// @name:hu           Decathlon — A lapcím módosításának letiltása
// @name:ro           Decathlon — Oprește schimbarea titlului filei
// @name:bg           Decathlon — Спри промяната на заглавието на раздела
// @name:el           Decathlon — Αποτροπή αλλαγών στον τίτλο της καρτέλας
// @name:hr           Decathlon — Zaustavi promjene naslova kartice
// @name:sr           Decathlon — Spreči promene naslova taba
// @name:sl           Decathlon — Ustavi spremembe naslova zavihka
// @name:sv           Decathlon — Förhindra ändring av fliktitel
// @name:tr           Decathlon — Sekme başlığı değişimini engelle
// @name:uk           Decathlon — Заборонити зміну заголовка вкладки
// @name:ru           Decathlon — Запретить смену заголовка вкладки
// @name:ar           Decathlon — منع تغيير عنوان علامة التبويب
// @name:he           Decathlon — מניעת שינוי כותרת לשונית
// @name:ja           Decathlon — タブタイトル変更を防止
// @name:ko           Decathlon — 탭 제목 변경 방지
// @name:zh-CN        Decathlon — 阻止更改标签页标题
// @name:zh-TW        Decathlon — 防止更改分頁標題
// @name:id           Decathlon — Cegah perubahan judul tab
// @name:ms           Decathlon — Halang perubahan tajuk tab
// @name:vi           Decathlon — Ngăn đổi tiêu đề tab
// @name:th           Decathlon — ป้องกันการเปลี่ยนชื่อแท็บ
// @name:tl           Decathlon — Pigilan ang pagpapalit ng pamagat ng tab
// @name:km           Decathlon — ទប់ស្កាត់ការផ្លាស់ប្តូរចំណងជើងផ្ទាំង
// @name:hi           Decathlon — टैब शीर्षक बदलना रोकें
//
// @description       Prevent Decathlon from changing the tab title when the page is hidden (tab switched).
// @description:fr    Empêche Decathlon de changer le titre de l’onglet quand la page est masquée (changement d’onglet).
// @description:es    Evita que Decathlon cambie el título de la pestaña cuando la página está oculta (al cambiar de pestaña).
// @description:de    Verhindert, dass Decathlon den Tab-Titel ändert, wenn die Seite im Hintergrund ist (Tab gewechselt).
// @description:it    Impedisce a Decathlon di cambiare il titolo della scheda quando la pagina è nascosta (cambio scheda).
// @description:nl    Voorkomt dat Decathlon de tabtitel wijzigt wanneer de pagina verborgen is (tabblad wisselen).
// @description:pt    Impede que a Decathlon altere o título do separador quando a página está oculta (ao mudar de separador).
// @description:pt-BR Impede que a Decathlon altere o título da aba quando a página está oculta (ao trocar de aba).
// @description:pl    Zapobiega zmianie tytułu karty przez Decathlon, gdy strona jest ukryta (przełączenie karty).
// @description:cs    Zabrání Decathlonu měnit název karty, když je stránka skrytá (přepnutí karty).
// @description:sk    Zabráni Decathlonu meniť názov karty, keď je stránka skrytá (prepnutie karty).
// @description:hu    Megakadályozza, hogy a Decathlon megváltoztassa a böngészőfül címét, amikor az oldal rejtve van (fülváltás).
// @description:ro    Împiedică Decathlon să schimbe titlul filei când pagina este ascunsă (când schimbi fila).
// @description:bg    Предотвратява Decathlon да променя заглавието на раздела, когато страницата е скрита (при смяна на раздел).
// @description:el    Αποτρέπει τη Decathlon από το να αλλάζει τον τίτλο της καρτέλας όταν η σελίδα είναι κρυφή (αλλαγή καρτέλας).
// @description:hr    Sprječava Decathlon da mijenja naslov kartice kada je stranica skrivena (promjena kartice).
// @description:sr    Sprečava Decathlon da menja naslov taba kada je stranica sakrivena (promena taba).
// @description:sl    Prepreči, da Decathlon spremeni naslov zavihka, ko je stran skrita (preklop zavihka).
// @description:sv    Förhindrar att Decathlon ändrar flikens titel när sidan är dold (byter flik).
// @description:tr    Sayfa gizliyken (sekme değiştirince) Decathlon'un sekme başlığını değiştirmesini engeller.
// @description:uk    Запобігає зміні заголовка вкладки Decathlon, коли сторінка прихована (перемикання вкладок).
// @description:ru    Предотвращает изменение заголовка вкладки Decathlon, когда страница скрыта (переключение вкладки).
// @description:ar    يمنع ديكاتلون من تغيير عنوان علامة التبويب عندما تكون الصفحة مخفية (عند تبديل علامة التبويب).
// @description:he    מונע מדקטלון לשנות את כותרת הלשונית כשהדף מוסתר (בעת מעבר לשונית).
// @description:ja    ページが非表示(タブ切り替え)時にDecathlonがタブのタイトルを変更するのを防ぎます。
// @description:ko    페이지가 숨겨져 있을 때(탭 전환 시) Decathlon이 탭 제목을 바꾸지 못하게 합니다.
// @description:zh-CN 阻止迪卡侬在页面隐藏(切换标签页)时更改标签页标题。
// @description:zh-TW 防止迪卡儂在頁面隱藏(切換分頁)時更改分頁標題。
// @description:id    Mencegah Decathlon mengubah judul tab saat halaman tersembunyi (saat berpindah tab).
// @description:ms    Menghalang Decathlon daripada menukar tajuk tab apabila halaman tersembunyi (bertukar tab).
// @description:vi    Ngăn Decathlon thay đổi tiêu đề tab khi trang bị ẩn (khi chuyển tab).
// @description:th    ป้องกันไม่ให้ Decathlon เปลี่ยนชื่อแท็บเมื่อหน้าเว็บถูกซ่อน (สลับแท็บ).
// @description:tl    Pinipigilan ang Decathlon na palitan ang pamagat ng tab kapag nakatago ang pahina (paglipat ng tab).
// @description:km    ទប់ស្កាត់ Decathlon មិនឲ្យផ្លាស់ប្តូរចំណងជើងផ្ទាំង (tab) ពេលទំព័រត្រូវបានលាក់ (ប្ដូរផ្ទាំង)។
// @description:hi    पेज छिपा होने (टैब बदलने) पर Decathlon को टैब शीर्षक बदलने से रोकता है।
//
// @author            NWP
// @namespace         https://greasyfork.org/users/877912
// @version           1.0.0
// @license           MIT
//
// @include           *://decathlon.*/*
// @include           *://www.decathlon.*/*
// @include           *://*.decathlon.*/*
//
// @run-at            document-start
// @grant             none
// ==/UserScript==

(() => {
  'use strict';

  // Set to true to freeze the title permanently (even while visible).
  const LOCK_ALWAYS = false;

  const desc = Object.getOwnPropertyDescriptor(Document.prototype, 'title');
  if (!desc || typeof desc.get !== 'function' || typeof desc.set !== 'function') return;

  let lastGoodTitle = '';

  const getTitle = () => {
    try { return desc.get.call(document) || ''; } catch { return document.title || ''; }
  };

  const setTitle = (t) => {
    try { desc.set.call(document, t); } catch { document.title = t; }
    const el = document.querySelector('title');
    if (el && el.textContent !== t) el.textContent = t;
  };

  const shouldLockNow = () => LOCK_ALWAYS || document.hidden;

  const rememberIfVisible = () => {
    if (!document.hidden && !LOCK_ALWAYS) lastGoodTitle = getTitle();
  };

  const enforce = () => {
    if (!lastGoodTitle) lastGoodTitle = getTitle();
    if (shouldLockNow() && getTitle() !== lastGoodTitle) setTitle(lastGoodTitle);
  };

  // Intercept JS attempts to set document.title
  try {
    Object.defineProperty(Document.prototype, 'title', {
      configurable: true,
      enumerable: true,
      get() { return desc.get.call(this); },
      set(v) {
        if (!lastGoodTitle) lastGoodTitle = getTitle();
        if (shouldLockNow()) {
          setTitle(lastGoodTitle);
          return;
        }
        desc.set.call(this, v);
        lastGoodTitle = getTitle();
      }
    });
  } catch {
    // If redefining fails, the observer below will still revert changes.
  }

  // Catch direct <title> text changes
  const startObserver = () => {
    const head = document.head || document.documentElement;
    const mo = new MutationObserver(() => {
      if (shouldLockNow()) enforce();
      else rememberIfVisible();
    });
    mo.observe(head, { subtree: true, childList: true, characterData: true });
  };

  document.addEventListener('visibilitychange', () => {
    if (!document.hidden && !LOCK_ALWAYS) lastGoodTitle = getTitle();
    enforce();
  });

  queueMicrotask(() => {
    lastGoodTitle = getTitle();
    startObserver();
    enforce();
  });

  // Safety: some sites hammer title changes
  setInterval(enforce, 1000);
})();