Jump to content

MediaWiki:Common.js: Difference between revisions

From Vampiro
JS completo reescrito: VE + toolbar + botoes + animacao (chaves validadas)
Tooltip alterado para INFORMAÇÃO SENSÍVEL - BLOQUEADO PELA CAMARILLA
Line 17: Line 17:
       var dica = (el.getAttribute('data-dica') || '').trim();
       var dica = (el.getAttribute('data-dica') || '').trim();
       var revealed = false;
       var revealed = false;
       var tip = '[ARQUIVO CONFIDENCIAL]';
       var tip = '[INFORMAÇÃO SENSÍVEL - BLOQUEADO PELA CAMARILLA]';


       if (lib === 'sim' || lib === 'true' || lib === '1') {
       if (lib === 'sim' || lib === 'true' || lib === '1') {
         revealed = true;
         revealed = true;
       } else if (lib === 'nao' || lib === 'false' || lib === '0') {
       } else if (lib === 'nao' || lib === 'false' || lib === '0') {
         tip = '[CLASSIFICADO' + (dica ? ' // ' + dica : '') + ']';
         tip = '[INFORMAÇÃO SENSÍVEL - BLOQUEADO PELA CAMARILLA' + (dica ? ' // ' + dica : '') + ']';
       } else if (ds) {
       } else if (ds) {
         var td = null;
         var td = null;
Line 36: Line 36:
           } else {
           } else {
             var f = ('0' + td.getDate()).slice(-2) + '/' + ('0' + (td.getMonth() + 1)).slice(-2) + '/' + td.getFullYear();
             var f = ('0' + td.getDate()).slice(-2) + '/' + ('0' + (td.getMonth() + 1)).slice(-2) + '/' + td.getFullYear();
             tip = '[CLASSIFICADO' + (dica ? ' // ' + dica : '') + ' - ' + f + ']';
             tip = '[INFORMAÇÃO SENSÍVEL - BLOQUEADO PELA CAMARILLA' + (dica ? ' // ' + dica : '') + ' - ' + f + ']';
           }
           }
         }
         }
Line 44: Line 44:
         el.classList.add('is-revealed');
         el.classList.add('is-revealed');
         el.classList.remove('is-redacted');
         el.classList.remove('is-redacted');
         el.title = '[DESCLASSIFICADO' + (dica ? ' // ' + dica : '') + ']';
         el.title = '[DESCLASSIFICADO PELA CAMARILLA' + (dica ? ' // ' + dica : '') + ']';
       } else {
       } else {
         el.classList.add('is-redacted');
         el.classList.add('is-redacted');

Revision as of 20:06, 1 September 2026

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

(function () {
  'use strict';

  /* 1. CENSURA & REVELAÇÃO DINÂMICA */
  function initVtmSecrets() {
    var els = document.querySelectorAll('[data-vtm-secret="true"]');
    if (!els || !els.length) return;
    var now = new Date();

    els.forEach(function (el) {
      var lib = (el.getAttribute('data-liberado') || '').toLowerCase().trim();
      var ds = (el.getAttribute('data-reveal-date') || '').trim();
      var dica = (el.getAttribute('data-dica') || '').trim();
      var revealed = false;
      var tip = '[INFORMAÇÃO SENSÍVEL - BLOQUEADO PELA CAMARILLA]';

      if (lib === 'sim' || lib === 'true' || lib === '1') {
        revealed = true;
      } else if (lib === 'nao' || lib === 'false' || lib === '0') {
        tip = '[INFORMAÇÃO SENSÍVEL - BLOQUEADO PELA CAMARILLA' + (dica ? ' // ' + dica : '') + ']';
      } else if (ds) {
        var td = null;
        if (ds.indexOf('/') !== -1) {
          var p = ds.split('/');
          if (p.length === 3) td = new Date(p[2], parseInt(p[1], 10) - 1, p[0]);
        } else {
          td = new Date(ds);
        }
        if (td && !isNaN(td.getTime())) {
          if (now >= td) {
            revealed = true;
          } else {
            var f = ('0' + td.getDate()).slice(-2) + '/' + ('0' + (td.getMonth() + 1)).slice(-2) + '/' + td.getFullYear();
            tip = '[INFORMAÇÃO SENSÍVEL - BLOQUEADO PELA CAMARILLA' + (dica ? ' // ' + dica : '') + ' - ' + f + ']';
          }
        }
      }

      if (revealed) {
        el.classList.add('is-revealed');
        el.classList.remove('is-redacted');
        el.title = '[DESCLASSIFICADO PELA CAMARILLA' + (dica ? ' // ' + dica : '') + ']';
      } else {
        el.classList.add('is-redacted');
        el.classList.remove('is-revealed');
        el.title = tip;
      }
    });
  }

  /* 2. BOTÕES CENSURADO/LIBERADO NO MODAL */
  function transformLiberadoInputs() {
    var inputs = document.querySelectorAll(
      '.oo-ui-windowManager input, .oo-ui-windowManager textarea, ' +
      '.oo-ui-fieldLayout input, .oo-ui-fieldLayout textarea'
    );
    inputs.forEach(function (input) {
      var container = input.closest('.oo-ui-fieldLayout') ||
                      input.closest('.ve-ui-mwParameterPage') ||
                      input.closest('.oo-ui-pageLayout') ||
                      input.parentElement;
      if (!container) return;
      var txt = (container.textContent || '').toLowerCase();
      if (txt.indexOf('liberado') === -1) return;
      if (container.querySelector('.vtm-toggle-box')) return;

      var box = document.createElement('div');
      box.className = 'vtm-toggle-box';
      box.style.cssText = 'display:flex;gap:12px;margin:10px 0 16px;width:100%;max-width:460px;';

      var btnC = mkToggle('CENSURADO');
      var btnL = mkToggle('LIBERADO');

      function paint(v) {
        var isLib = (v === 'sim' || v === '1' || v === 'true');
        btnC.style.background = isLib ? '#121218' : 'linear-gradient(180deg,#5c0f18,#2b060a)';
        btnC.style.color = isLib ? '#7a7a88' : '#fff';
        btnC.style.border = isLib ? '1px solid #2d2d38' : '2px solid #ff2a3f';
        btnC.style.boxShadow = isLib ? 'none' : '0 0 12px rgba(255,42,63,.7)';
        btnL.style.background = isLib ? 'linear-gradient(180deg,#1b5e20,#0d3814)' : '#121218';
        btnL.style.color = isLib ? '#fff' : '#7a7a88';
        btnL.style.border = isLib ? '2px solid #4caf50' : '1px solid #2d2d38';
        btnL.style.boxShadow = isLib ? '0 0 12px rgba(76,175,80,.7)' : 'none';
      }

      btnC.onclick = function (e) { e.preventDefault(); e.stopPropagation(); setVal(input, 'nao'); paint('nao'); };
      btnL.onclick = function (e) { e.preventDefault(); e.stopPropagation(); setVal(input, 'sim'); paint('sim'); };
      input.addEventListener('input', function () { paint((input.value || '').toLowerCase().trim()); });
      paint((input.value || 'nao').toLowerCase().trim());

      box.appendChild(btnC);
      box.appendChild(btnL);
      var wrap = input.closest('.oo-ui-textInputWidget') || input.closest('.oo-ui-inputWidget') || input;
      wrap.parentNode.insertBefore(box, wrap);
      wrap.style.display = 'none';
    });
  }

  function mkToggle(label) {
    var b = document.createElement('button');
    b.type = 'button';
    b.textContent = (label === 'CENSURADO' ? '\u2B1B ' : '\uD83D\uDD13 ') + label;
    b.style.cssText = 'flex:1;padding:10px 16px;border-radius:4px;font-weight:800;font-size:.9em;cursor:pointer;font-family:"Cinzel",Georgia,serif;letter-spacing:1px;transition:all .25s ease;outline:none;';
    return b;
  }

  function setVal(input, v) {
    input.value = v;
    input.dispatchEvent(new Event('input', { bubbles: true }));
    input.dispatchEvent(new Event('change', { bubbles: true }));
    if (window.$) { $(input).trigger('input').trigger('change'); }
  }

  setInterval(transformLiberadoInputs, 300);

  /* 3. BOTÃO NO MENU INSERIR DO VISUALEDITOR */
  function registerVeTool() {
    try {
      if (!window.ve || !ve.ui || !ve.ui.toolFactory) return;
      if (ve.ui.toolFactory.lookup('vtmSecret')) return;

      var tplData = {
        type: 'mwTransclusionInline',
        attributes: {
          mw: {
            parts: [
              {
                template: {
                  target: { href: 'Template:Segredo', wt: 'Segredo' },
                  params: {
                    '1': { wt: 'Texto confidencial' },
                    'liberado': { wt: 'nao' }
                  }
                }
              }
            ]
          }
        }
      };

      ve.ui.commandRegistry.register(
        new ve.ui.Command('insertVtmSecret', 'content', 'insert', {
          args: [[tplData, { type: '/mwTransclusionInline' }]],
          supportedSelections: ['linear']
        })
      );

      function VtmTool() { VtmTool.super.apply(this, arguments); }
      OO.inheritClass(VtmTool, ve.ui.Tool);
      VtmTool.static.name = 'vtmSecret';
      VtmTool.static.group = 'insert';
      VtmTool.static.icon = 'lock';
      VtmTool.static.title = 'Censura / Segredo (Confidencial)';
      VtmTool.static.commandName = 'insertVtmSecret';
      VtmTool.static.autoAddToCatchall = true;
      ve.ui.toolFactory.register(VtmTool);
    } catch (e) {
      if (window.console) console.warn('[VtM] Erro VE:', e);
    }
  }

  /* 4. BARRA DE FERRAMENTAS NO EDITOR DE CÓDIGO-FONTE */
  function initVtmQuickToolbar() {
    var tb = document.getElementById('wpTextbox1');
    if (!tb || document.getElementById('vtm-editor-quickbar')) return;

    var bar = document.createElement('div');
    bar.id = 'vtm-editor-quickbar';
    bar.style.cssText = 'display:flex;flex-wrap:wrap;gap:8px;align-items:center;padding:10px 14px;margin:10px 0;background:linear-gradient(90deg,#181014,#0d0d12);border:1px solid #3d0a12;border-left:4px solid #8b0000;border-radius:4px;font-family:"Cinzel",Georgia,serif;box-shadow:0 4px 14px rgba(0,0,0,.6);z-index:99;';

    var lbl = document.createElement('span');
    lbl.style.cssText = 'color:#c5a059;font-size:.85em;font-weight:700;text-transform:uppercase;letter-spacing:1px;margin-right:6px;';
    lbl.textContent = 'Ferramentas:';
    bar.appendChild(lbl);

    bar.appendChild(mkBtn('\u2B1B Censurar Trecho', '#240c12', '#ff2a3f', function () {
      wrapSel(tb, '{{Segredo|', '|liberado=nao}}', 'Texto censurado');
    }));
    bar.appendChild(mkBtn('\uD83D\uDD13 Inserir Liberado', '#0d2915', '#2e7d32', function () {
      wrapSel(tb, '{{Segredo|', '|liberado=sim}}', 'Texto revelado');
    }));
    bar.appendChild(mkBtn('\uD83D\uDCC1 Dossie Bloco', '#181822', '#3d0a12', function () {
      wrapSel(tb, '\n{{Segredo|tipo=bloco|nivel=CONFIDENCIAL|data=AAAA-MM-DD|dica=Operacao|\n', '\n}}\n', 'Relatorio confidencial...');
    }));
    bar.appendChild(mkBtn('\uD83D\uDDD1 Remover Censura', '#1a1a22', '#4a4a58', function () {
      removeSecret(tb);
    }));

    tb.parentNode.insertBefore(bar, tb);
  }

  function mkBtn(text, bg, border, fn) {
    var b = document.createElement('button');
    b.type = 'button'; b.textContent = text;
    b.style.cssText = 'background:' + bg + ';color:#fff;border:1px solid ' + border + ';border-radius:3px;padding:6px 12px;font-size:.82em;font-weight:700;cursor:pointer;display:inline-flex;align-items:center;gap:4px;transition:all .2s ease;';
    b.onmouseover = function () { b.style.opacity = '.85'; };
    b.onmouseout = function () { b.style.opacity = '1'; };
    b.onclick = function (e) { e.preventDefault(); fn(); };
    return b;
  }

  function wrapSel(tb, pre, post, ph) {
    var s = tb.selectionStart, e = tb.selectionEnd;
    var t = tb.value, sel = t.substring(s, e) || ph;
    tb.value = t.substring(0, s) + pre + sel + post + t.substring(e);
    tb.focus(); tb.setSelectionRange(s + pre.length, s + pre.length + sel.length);
    if (window.$) { $(tb).trigger('input').trigger('change'); }
  }

  function removeSecret(tb) {
    var s = tb.selectionStart, text = tb.value;
    var i = text.lastIndexOf('{{Segredo|', s);
    if (i === -1) { alert('Nenhum {{Segredo|...}} encontrado.\nPosicione o cursor dentro do trecho.'); return; }
    var depth = 0, j, end = -1;
    for (j = i; j < text.length - 1; j++) {
      if (text[j] === '{' && text[j + 1] === '{') { depth++; j++; }
      else if (text[j] === '}' && text[j + 1] === '}') { depth--; if (depth === 0) { end = j + 2; break; } j++; }
    }
    if (end === -1) { alert('Fechamento }} nao encontrado.'); return; }
    var inner = text.substring(i + '{{Segredo|'.length, end - 2);
    var parts = [], cur = '', d = 0;
    for (j = 0; j < inner.length; j++) {
      if (inner[j] === '{' && j + 1 < inner.length && inner[j + 1] === '{') { d++; cur += '{{'; j++; }
      else if (inner[j] === '}' && j + 1 < inner.length && inner[j + 1] === '}') { d--; cur += '}}'; j++; }
      else if (inner[j] === '|' && d === 0) { parts.push(cur); cur = ''; }
      else { cur += inner[j]; }
    }
    parts.push(cur);
    var content = '';
    for (var k = 0; k < parts.length; k++) {
      if (parts[k].trim().indexOf('=') === -1) { content = parts[k].trim(); break; }
    }
    tb.value = text.substring(0, i) + content + text.substring(end);
    tb.focus(); tb.setSelectionRange(i, i + content.length);
    if (window.$) { $(tb).trigger('input').trigger('change'); }
  }

  /* 5. ANIMAÇÃO DE CASCATA DAS SEÇÕES */
  function initSectionAnimation() {
    var c = document.querySelector('.mw-parser-output');
    if (!c || c.dataset.vtmAnimated === 'true') return;
    if (window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;
    c.dataset.vtmAnimated = 'true';
    var kids = Array.from(c.children), secs = [], cur = [];
    kids.forEach(function (ch) {
      if (ch.classList.contains('catlinks') || ch.classList.contains('mw-category-generated') ||
          ch.tagName === 'SCRIPT' || ch.tagName === 'STYLE' || ch.id === 'vtm-editor-quickbar') {
        if (cur.length) { secs.push(cur); cur = []; }
        return;
      }
      if ((ch.tagName === 'H2' || ch.classList.contains('mw-heading2')) && cur.length) { secs.push(cur); cur = []; }
      cur.push(ch);
    });
    if (cur.length) secs.push(cur);
    secs.forEach(function (items, idx) {
      var w = document.createElement('div');
      w.className = 'vtm-section-block';
      w.style.animationDelay = (0.12 + idx * 0.42).toFixed(2) + 's';
      var f = items[0];
      if (f && f.parentNode) { f.parentNode.insertBefore(w, f); items.forEach(function (el) { w.appendChild(el); }); }
    });
  }

  /* INICIALIZAÇÃO */
  function initAll() {
    initVtmSecrets();
    initSectionAnimation();
    initVtmQuickToolbar();
    registerVeTool();
  }

  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();
    });
    window.mw.hook('ve.activationComplete').add(registerVeTool);
  }
})();