Jump to content

MediaWiki:Common.js: Difference between revisions

From Vampiro
Script de agrupamento dinâmico de seções H2 para animação em cascata sincronizada
 
Lógica de desclassificação por data/status e botão de ferramenta no editor
Line 1: Line 1:
/* ==========================================================================
/* ==========================================================================
   VAMPIRO: A MÁSCARA — SCRIPTS DE ANIMAÇÃO & CASCATA PROGRESSIVA
   VAMPIRO: A MÁSCARA — SCRIPTS DE INTERATIVIDADE & SEGREDO DINÂMICO
  Agrupa dinamicamente as seções H2 e seus conteúdos para animação fluida
   ========================================================================== */
   ========================================================================== */


Line 7: Line 6:
   'use strict';
   'use strict';


  // 1. LÓGICA DE REVELAÇÃO E CENSURA DINÂMICA ({{Segredo}})
  function initVtmSecrets() {
    var secretElements = document.querySelectorAll('[data-vtm-secret="true"]');
    if (!secretElements || secretElements.length === 0) return;
    var now = new Date();
    secretElements.forEach(function (el) {
      var liberado = (el.getAttribute('data-liberado') || '').toLowerCase().trim();
      var dateStr = (el.getAttribute('data-reveal-date') || '').trim();
      var dica = (el.getAttribute('data-dica') || '').trim();
      var isRevealed = false;
      var tooltipText = '🔒 [ARQUIVO CONFIDENCIAL - ACESSO RESTRITO]';
      if (liberado === 'sim' || liberado === 'true' || liberado === '1') {
        isRevealed = true;
      } else if (liberado === 'nao' || liberado === 'false' || liberado === '0') {
        isRevealed = false;
        tooltipText = '🔒 [ARQUIVO CLASSIFICADO' + (dica ? ' // ' + dica : '') + ' - LIBERAÇÃO RESTRITA]';
      } else if (dateStr) {
        // Tenta converter formatos AAAA-MM-DD ou DD/MM/AAAA
        var targetDate = null;
        if (dateStr.indexOf('/') !== -1) {
          var parts = dateStr.split('/');
          if (parts.length === 3) {
            targetDate = new Date(parts[2], parseInt(parts[1], 10) - 1, parts[0], 0, 0, 0);
          }
        } else {
          targetDate = new Date(dateStr);
        }
        if (targetDate && !isNaN(targetDate.getTime())) {
          if (now >= targetDate) {
            isRevealed = true;
          } else {
            isRevealed = false;
            var formatted = ('0' + targetDate.getDate()).slice(-2) + '/' +
                            ('0' + (targetDate.getMonth() + 1)).slice(-2) + '/' +
                            targetDate.getFullYear();
            tooltipText = '🔒 [CLASSIFICADO' + (dica ? ' // ' + dica : '') + ' - Desclassificação em: ' + formatted + ']';
          }
        } else {
          isRevealed = false;
        }
      } else {
        // Sem data e sem liberado=sim => Bloqueado por padrão
        isRevealed = false;
      }
      if (isRevealed) {
        el.classList.add('is-revealed');
        el.classList.remove('is-redacted');
        el.title = '🔓 [DOCUMENTO DESCLASSIFICADO' + (dica ? ' // ' + dica : '') + ']';
      } else {
        el.classList.add('is-redacted');
        el.classList.remove('is-revealed');
        el.title = tooltipText;
      }
    });
  }
  // 2. BOTÃO DE FERRAMENTA NO WIKIEDITOR (EDITOR DE CÓDIGO-FONTE)
  function initWikiEditorSecretButton() {
    if (!window.$ || !$.fn.wikiEditor) return;
    $('#wpTextbox1').on('wikiEditor-toolbar-doneInitialSections', function () {
      $('#wpTextbox1').wikiEditor('addToToolbar', {
        section: 'main',
        group: 'format',
        tools: {
          vtmSecret: {
            label: 'Inserir Tarja de Censura / Segredo (Confidencial)',
            type: 'button',
            icon: 'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="%23ff2a3f"><rect x="2" y="5" width="20" height="14" rx="2" fill="%23101015" stroke="%23ff2a3f" stroke-width="1.5"/><rect x="5" y="9" width="14" height="6" fill="%23ff2a3f"/><path d="M12 2v3M8 2h8" stroke="%23ff2a3f" stroke-width="1.5" stroke-linecap="round"/></svg>',
            action: {
              type: 'encapsulate',
              options: {
                pre: '{{Segredo|',
                peri: 'Texto sensível a ser censurado',
                post: '|data=AAAA-MM-DD|liberado=nao}}'
              }
            }
          }
        }
      });
    });
  }
  // 3. ANIMAÇÃO DE CASCATA DAS SEÇÕES (.vtm-section-block)
   function initSectionAnimation() {
   function initSectionAnimation() {
     var content = document.querySelector('.mw-parser-output');
     var content = document.querySelector('.mw-parser-output');
     if (!content || content.dataset.vtmAnimated === 'true') return;
     if (!content || content.dataset.vtmAnimated === 'true') return;


    // Respeita preferência por movimento reduzido
     if (window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
     if (window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
       return;
       return;
     }
     }


    // Marca como animado para evitar re-execução
     content.dataset.vtmAnimated = 'true';
     content.dataset.vtmAnimated = 'true';
     var children = Array.from(content.children);
     var children = Array.from(content.children);
     var sections = [];
     var sections = [];
Line 24: Line 109:


     children.forEach(function (child) {
     children.forEach(function (child) {
      // Ignora caixas de categorias, scripts e painéis de edição
       if (
       if (
         child.classList.contains('catlinks') ||
         child.classList.contains('catlinks') ||
Line 50: Line 134:
     }
     }


    // Intervalo marcado de 420ms entre cada seção completa
     sections.forEach(function (sectionElements, index) {
     sections.forEach(function (sectionElements, index) {
       var wrapper = document.createElement('div');
       var wrapper = document.createElement('div');
Line 67: Line 150:
   }
   }


   // Executa no carregamento do DOM
   // Inicialização no DOM
  function initAll() {
    initVtmSecrets();
    initSectionAnimation();
    initWikiEditorSecretButton();
  }
 
   if (document.readyState === 'loading') {
   if (document.readyState === 'loading') {
     document.addEventListener('DOMContentLoaded', initSectionAnimation);
     document.addEventListener('DOMContentLoaded', initAll);
   } else {
   } else {
     initSectionAnimation();
     initAll();
   }
   }


  // Suporte a carregamento assíncrono do MediaWiki (ex: navegação via AJAX / VisualEditor)
   if (window.mw && window.mw.hook) {
   if (window.mw && window.mw.hook) {
     window.mw.hook('wikipage.content').add(function () {
     window.mw.hook('wikipage.content').add(function () {
      initVtmSecrets();
       initSectionAnimation();
       initSectionAnimation();
     });
     });
   }
   }
})();
})();

Revision as of 19:23, 1 September 2026

/* ==========================================================================
   VAMPIRO: A MÁSCARA — SCRIPTS DE INTERATIVIDADE & SEGREDO DINÂMICO
   ========================================================================== */

(function () {
  'use strict';

  // 1. LÓGICA DE REVELAÇÃO E CENSURA DINÂMICA ({{Segredo}})
  function initVtmSecrets() {
    var secretElements = document.querySelectorAll('[data-vtm-secret="true"]');
    if (!secretElements || secretElements.length === 0) return;

    var now = new Date();

    secretElements.forEach(function (el) {
      var liberado = (el.getAttribute('data-liberado') || '').toLowerCase().trim();
      var dateStr = (el.getAttribute('data-reveal-date') || '').trim();
      var dica = (el.getAttribute('data-dica') || '').trim();
      var isRevealed = false;
      var tooltipText = '🔒 [ARQUIVO CONFIDENCIAL - ACESSO RESTRITO]';

      if (liberado === 'sim' || liberado === 'true' || liberado === '1') {
        isRevealed = true;
      } else if (liberado === 'nao' || liberado === 'false' || liberado === '0') {
        isRevealed = false;
        tooltipText = '🔒 [ARQUIVO CLASSIFICADO' + (dica ? ' // ' + dica : '') + ' - LIBERAÇÃO RESTRITA]';
      } else if (dateStr) {
        // Tenta converter formatos AAAA-MM-DD ou DD/MM/AAAA
        var targetDate = null;
        if (dateStr.indexOf('/') !== -1) {
          var parts = dateStr.split('/');
          if (parts.length === 3) {
            targetDate = new Date(parts[2], parseInt(parts[1], 10) - 1, parts[0], 0, 0, 0);
          }
        } else {
          targetDate = new Date(dateStr);
        }

        if (targetDate && !isNaN(targetDate.getTime())) {
          if (now >= targetDate) {
            isRevealed = true;
          } else {
            isRevealed = false;
            var formatted = ('0' + targetDate.getDate()).slice(-2) + '/' +
                            ('0' + (targetDate.getMonth() + 1)).slice(-2) + '/' +
                            targetDate.getFullYear();
            tooltipText = '🔒 [CLASSIFICADO' + (dica ? ' // ' + dica : '') + ' - Desclassificação em: ' + formatted + ']';
          }
        } else {
          isRevealed = false;
        }
      } else {
        // Sem data e sem liberado=sim => Bloqueado por padrão
        isRevealed = false;
      }

      if (isRevealed) {
        el.classList.add('is-revealed');
        el.classList.remove('is-redacted');
        el.title = '🔓 [DOCUMENTO DESCLASSIFICADO' + (dica ? ' // ' + dica : '') + ']';
      } else {
        el.classList.add('is-redacted');
        el.classList.remove('is-revealed');
        el.title = tooltipText;
      }
    });
  }

  // 2. BOTÃO DE FERRAMENTA NO WIKIEDITOR (EDITOR DE CÓDIGO-FONTE)
  function initWikiEditorSecretButton() {
    if (!window.$ || !$.fn.wikiEditor) return;

    $('#wpTextbox1').on('wikiEditor-toolbar-doneInitialSections', function () {
      $('#wpTextbox1').wikiEditor('addToToolbar', {
        section: 'main',
        group: 'format',
        tools: {
          vtmSecret: {
            label: 'Inserir Tarja de Censura / Segredo (Confidencial)',
            type: 'button',
            icon: 'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="%23ff2a3f"><rect x="2" y="5" width="20" height="14" rx="2" fill="%23101015" stroke="%23ff2a3f" stroke-width="1.5"/><rect x="5" y="9" width="14" height="6" fill="%23ff2a3f"/><path d="M12 2v3M8 2h8" stroke="%23ff2a3f" stroke-width="1.5" stroke-linecap="round"/></svg>',
            action: {
              type: 'encapsulate',
              options: {
                pre: '{{Segredo|',
                peri: 'Texto sensível a ser censurado',
                post: '|data=AAAA-MM-DD|liberado=nao}}'
              }
            }
          }
        }
      });
    });
  }

  // 3. ANIMAÇÃO DE CASCATA DAS SEÇÕES (.vtm-section-block)
  function initSectionAnimation() {
    var content = document.querySelector('.mw-parser-output');
    if (!content || content.dataset.vtmAnimated === 'true') return;

    if (window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
      return;
    }

    content.dataset.vtmAnimated = 'true';
    var children = Array.from(content.children);
    var sections = [];
    var currentSection = [];

    children.forEach(function (child) {
      if (
        child.classList.contains('catlinks') ||
        child.classList.contains('mw-category-generated') ||
        child.tagName === 'SCRIPT' ||
        child.tagName === 'STYLE'
      ) {
        if (currentSection.length > 0) {
          sections.push(currentSection);
          currentSection = [];
        }
        return;
      }

      var isH2 = child.tagName === 'H2' || child.classList.contains('mw-heading2');
      if (isH2 && currentSection.length > 0) {
        sections.push(currentSection);
        currentSection = [];
      }
      currentSection.push(child);
    });

    if (currentSection.length > 0) {
      sections.push(currentSection);
    }

    sections.forEach(function (sectionElements, index) {
      var wrapper = document.createElement('div');
      wrapper.className = 'vtm-section-block';
      var delay = (0.12 + index * 0.42).toFixed(2);
      wrapper.style.animationDelay = delay + 's';

      var firstElem = sectionElements[0];
      if (firstElem && firstElem.parentNode) {
        firstElem.parentNode.insertBefore(wrapper, firstElem);
        sectionElements.forEach(function (el) {
          wrapper.appendChild(el);
        });
      }
    });
  }

  // Inicialização no DOM
  function initAll() {
    initVtmSecrets();
    initSectionAnimation();
    initWikiEditorSecretButton();
  }

  if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', initAll);
  } else {
    initAll();
  }

  if (window.mw && window.mw.hook) {
    window.mw.hook('wikipage.content').add(function () {
      initVtmSecrets();
      initSectionAnimation();
    });
  }
})();