MediaWiki:Common.js: Difference between revisions
Aparência da Noite
Lógica de desclassificação por data/status e botão de ferramenta no editor |
Adicionada barra de ferramentas rápida gótica e integração WikiEditor |
||
| Line 1: | Line 1: | ||
/* ========================================================================== | /* ========================================================================== | ||
VAMPIRO: A MÁSCARA — SCRIPTS | VAMPIRO: A MÁSCARA — SCRIPTS GLOBAIS, INTERATIVIDADE & BOTÕES DO EDITOR | ||
========================================================================== */ | ========================================================================== */ | ||
| Line 6: | Line 6: | ||
'use strict'; | 'use strict'; | ||
// 1. LÓGICA DE REVELAÇÃO | // ------------------------------------------------------------------------ | ||
// 1. LÓGICA DE CENSURA & REVELAÇÃO DINÂMICA ({{Segredo}}) | |||
// ------------------------------------------------------------------------ | |||
function initVtmSecrets() { | function initVtmSecrets() { | ||
var secretElements = document.querySelectorAll('[data-vtm-secret="true"]'); | var secretElements = document.querySelectorAll('[data-vtm-secret="true"]'); | ||
| Line 26: | Line 28: | ||
tooltipText = '🔒 [ARQUIVO CLASSIFICADO' + (dica ? ' // ' + dica : '') + ' - LIBERAÇÃO RESTRITA]'; | tooltipText = '🔒 [ARQUIVO CLASSIFICADO' + (dica ? ' // ' + dica : '') + ' - LIBERAÇÃO RESTRITA]'; | ||
} else if (dateStr) { | } else if (dateStr) { | ||
var targetDate = null; | var targetDate = null; | ||
if (dateStr.indexOf('/') !== -1) { | if (dateStr.indexOf('/') !== -1) { | ||
| Line 51: | Line 52: | ||
} | } | ||
} else { | } else { | ||
isRevealed = false; | isRevealed = false; | ||
} | } | ||
| Line 67: | Line 67: | ||
} | } | ||
// 2. | // ------------------------------------------------------------------------ | ||
// 2. FERRAMENTAS DO EDITOR (BARRA RÁPIDA GÓTICA + WIKIEDITOR + VISUALEDITOR) | |||
// ------------------------------------------------------------------------ | |||
// A) Barra Rápida Gótica (Injetada diretamente acima da área de texto) | |||
$(' | function initVtmQuickToolbar() { | ||
var textbox = document.getElementById('wpTextbox1'); | |||
if (!textbox) return; | |||
if (document.getElementById('vtm-editor-quickbar')) return; | |||
var bar = document.createElement('div'); | |||
bar.id = 'vtm-editor-quickbar'; | |||
bar.className = 'vtm-editor-quickbar'; | |||
bar.style.cssText = 'display:flex; gap:8px; align-items:center; padding:8px 12px; margin-bottom:8px; background:linear-gradient(90deg, #181014 0%, #0d0d12 100%); 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,0.6);'; | |||
// Rótulo da Barra | |||
var label = document.createElement('span'); | |||
label.style.cssText = 'color:#c5a059; font-size:0.82em; font-weight:700; text-transform:uppercase; letter-spacing:1px; margin-right:4px;'; | |||
label.innerHTML = '🩸 Ferramentas Góticas:'; | |||
bar.appendChild(label); | |||
// Botão 1: Inserir Tarja de Censura / Segredo Inline | |||
var btnInline = document.createElement('button'); | |||
btnInline.type = 'button'; | |||
btnInline.className = 'vtm-quick-btn'; | |||
btnInline.style.cssText = 'background:#240c12; color:#ffffff; border:1px solid #ff2a3f; border-radius:3px; padding:4px 10px; font-size:0.8em; font-weight:700; cursor:pointer; display:flex; align-items:center; gap:6px; transition:all 0.2s ease; box-shadow:0 0 8px rgba(201,24,43,0.4);'; | |||
btnInline.innerHTML = '🔒 Inserir Tarja de Censura (Segredo)'; | |||
btnInline.title = 'Envolve o texto selecionado na predefinição {{Segredo}} com bloqueio anti-spoiler'; | |||
btnInline.addEventListener('mouseover', function () { | |||
btnInline.style.background = '#4a0f1b'; | |||
btnInline.style.boxShadow = '0 0 14px rgba(255,42,63,0.8)'; | |||
}); | |||
btnInline.addEventListener('mouseout', function () { | |||
btnInline.style.background = '#240c12'; | |||
btnInline.style.boxShadow = '0 0 8px rgba(201,24,43,0.4)'; | |||
}); | |||
btnInline.addEventListener('click', function (e) { | |||
e.preventDefault(); | |||
insertSecretTemplate(textbox, false); | |||
}); | |||
bar.appendChild(btnInline); | |||
// Botão 2: Inserir Bloco Dossiê Confidencial | |||
var btnBlock = document.createElement('button'); | |||
btnBlock.type = 'button'; | |||
btnBlock.className = 'vtm-quick-btn'; | |||
btnBlock.style.cssText = 'background:#181822; color:#c5a059; border:1px solid #3d0a12; border-radius:3px; padding:4px 10px; font-size:0.8em; font-weight:700; cursor:pointer; display:flex; align-items:center; gap:6px; transition:all 0.2s ease;'; | |||
btnBlock.innerHTML = '📁 Dossiê Confidencial (Bloco)'; | |||
btnBlock.title = 'Insere uma caixa completa de relatório confidencial em bloco'; | |||
btnBlock.addEventListener('mouseover', function () { | |||
btnBlock.style.background = '#281c20'; | |||
btnBlock.style.borderColor = '#c5a059'; | |||
}); | |||
btnBlock.addEventListener('mouseout', function () { | |||
btnBlock.style.background = '#181822'; | |||
btnBlock.style.borderColor = '#3d0a12'; | |||
}); | |||
btnBlock.addEventListener('click', function (e) { | |||
e.preventDefault(); | |||
insertSecretTemplate(textbox, true); | |||
}); | |||
bar.appendChild(btnBlock); | |||
// Insere antes do textarea ou da toolbar existente | |||
var parent = textbox.parentNode; | |||
parent.insertBefore(bar, textbox); | |||
} | |||
// Função auxiliar de inserção no textarea | |||
function insertSecretTemplate(textbox, isBlock) { | |||
var start = textbox.selectionStart; | |||
var end = textbox.selectionEnd; | |||
var text = textbox.value; | |||
var selected = text.substring(start, end); | |||
var pre = isBlock ? '\n{{Segredo|tipo=bloco|nivel=RELATÓRIO SAD // CONFIDENCIAL|data=AAAA-MM-DD|dica=Alvo Restrito|\n' : '{{Segredo|'; | |||
var defaultText = selected || (isBlock ? 'Escreva aqui o relatório confidencial...' : 'Texto sensível a ser censurado'); | |||
var post = isBlock ? '\n}}\n' : '|data=AAAA-MM-DD|liberado=nao}}'; | |||
var replacement = pre + defaultText + post; | |||
textbox.value = text.substring(0, start) + replacement + text.substring(end); | |||
// Posiciona o cursor de volta | |||
var newCursor = start + pre.length; | |||
textbox.focus(); | |||
textbox.setSelectionRange(newCursor, newCursor + defaultText.length); | |||
// Dispara evento de input para o MediaWiki registrar a mudança | |||
if (window.$) { | |||
$(textbox).trigger('input').trigger('change'); | |||
} | |||
} | |||
// B) Integração nativa no WikiEditor (Barra oficial do MediaWiki) | |||
function setupWikiEditorIntegration() { | |||
if (!window.mw || !window.$) return; | |||
mw.loader.using('ext.wikiEditor', function () { | |||
var $textbox = $('#wpTextbox1'); | |||
if (!$textbox.length) return; | |||
var toolConfig = { | |||
section: 'main', | section: 'main', | ||
group: 'format', | group: 'format', | ||
tools: { | tools: { | ||
vtmSecret: { | vtmSecret: { | ||
label: 'Inserir Tarja de Censura / Segredo | label: 'Inserir Tarja de Censura / Segredo', | ||
type: 'button', | 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 | icon: 'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24"><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: { | action: { | ||
type: 'encapsulate', | type: 'encapsulate', | ||
options: { | options: { | ||
pre: '{{Segredo|', | pre: '{{Segredo|', | ||
peri: 'Texto | peri: 'Texto confidencial', | ||
post: '|data=AAAA-MM-DD|liberado=nao}}' | post: '|data=AAAA-MM-DD|liberado=nao}}' | ||
} | } | ||
| Line 90: | Line 191: | ||
} | } | ||
} | } | ||
}); | }; | ||
$textbox.wikiEditor('addToToolbar', toolConfig); | |||
}); | }); | ||
} | } | ||
// ------------------------------------------------------------------------ | |||
// 3. ANIMAÇÃO DE CASCATA DAS SEÇÕES (.vtm-section-block) | // 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'); | ||
| Line 113: | Line 218: | ||
child.classList.contains('mw-category-generated') || | child.classList.contains('mw-category-generated') || | ||
child.tagName === 'SCRIPT' || | child.tagName === 'SCRIPT' || | ||
child.tagName === 'STYLE' | child.tagName === 'STYLE' || | ||
child.id === 'vtm-editor-quickbar' | |||
) { | ) { | ||
if (currentSection.length > 0) { | if (currentSection.length > 0) { | ||
| Line 150: | Line 256: | ||
} | } | ||
// | // ------------------------------------------------------------------------ | ||
// INICIALIZAÇÃO GLOBAL | |||
// ------------------------------------------------------------------------ | |||
function initAll() { | function initAll() { | ||
initVtmSecrets(); | initVtmSecrets(); | ||
initSectionAnimation(); | initSectionAnimation(); | ||
initVtmQuickToolbar(); | |||
setupWikiEditorIntegration(); | |||
} | } | ||
| Line 167: | Line 276: | ||
initVtmSecrets(); | initVtmSecrets(); | ||
initSectionAnimation(); | initSectionAnimation(); | ||
}); | |||
window.mw.hook('wikiEditor.toolbarReady').add(function () { | |||
setupWikiEditorIntegration(); | |||
}); | }); | ||
} | } | ||
})(); | })(); | ||
Revision as of 19:26, 1 September 2026
/* ==========================================================================
VAMPIRO: A MÁSCARA — SCRIPTS GLOBAIS, INTERATIVIDADE & BOTÕES DO EDITOR
========================================================================== */
(function () {
'use strict';
// ------------------------------------------------------------------------
// 1. LÓGICA DE CENSURA & REVELAÇÃO 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) {
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 {
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. FERRAMENTAS DO EDITOR (BARRA RÁPIDA GÓTICA + WIKIEDITOR + VISUALEDITOR)
// ------------------------------------------------------------------------
// A) Barra Rápida Gótica (Injetada diretamente acima da área de texto)
function initVtmQuickToolbar() {
var textbox = document.getElementById('wpTextbox1');
if (!textbox) return;
if (document.getElementById('vtm-editor-quickbar')) return;
var bar = document.createElement('div');
bar.id = 'vtm-editor-quickbar';
bar.className = 'vtm-editor-quickbar';
bar.style.cssText = 'display:flex; gap:8px; align-items:center; padding:8px 12px; margin-bottom:8px; background:linear-gradient(90deg, #181014 0%, #0d0d12 100%); 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,0.6);';
// Rótulo da Barra
var label = document.createElement('span');
label.style.cssText = 'color:#c5a059; font-size:0.82em; font-weight:700; text-transform:uppercase; letter-spacing:1px; margin-right:4px;';
label.innerHTML = '🩸 Ferramentas Góticas:';
bar.appendChild(label);
// Botão 1: Inserir Tarja de Censura / Segredo Inline
var btnInline = document.createElement('button');
btnInline.type = 'button';
btnInline.className = 'vtm-quick-btn';
btnInline.style.cssText = 'background:#240c12; color:#ffffff; border:1px solid #ff2a3f; border-radius:3px; padding:4px 10px; font-size:0.8em; font-weight:700; cursor:pointer; display:flex; align-items:center; gap:6px; transition:all 0.2s ease; box-shadow:0 0 8px rgba(201,24,43,0.4);';
btnInline.innerHTML = '🔒 Inserir Tarja de Censura (Segredo)';
btnInline.title = 'Envolve o texto selecionado na predefinição {{Segredo}} com bloqueio anti-spoiler';
btnInline.addEventListener('mouseover', function () {
btnInline.style.background = '#4a0f1b';
btnInline.style.boxShadow = '0 0 14px rgba(255,42,63,0.8)';
});
btnInline.addEventListener('mouseout', function () {
btnInline.style.background = '#240c12';
btnInline.style.boxShadow = '0 0 8px rgba(201,24,43,0.4)';
});
btnInline.addEventListener('click', function (e) {
e.preventDefault();
insertSecretTemplate(textbox, false);
});
bar.appendChild(btnInline);
// Botão 2: Inserir Bloco Dossiê Confidencial
var btnBlock = document.createElement('button');
btnBlock.type = 'button';
btnBlock.className = 'vtm-quick-btn';
btnBlock.style.cssText = 'background:#181822; color:#c5a059; border:1px solid #3d0a12; border-radius:3px; padding:4px 10px; font-size:0.8em; font-weight:700; cursor:pointer; display:flex; align-items:center; gap:6px; transition:all 0.2s ease;';
btnBlock.innerHTML = '📁 Dossiê Confidencial (Bloco)';
btnBlock.title = 'Insere uma caixa completa de relatório confidencial em bloco';
btnBlock.addEventListener('mouseover', function () {
btnBlock.style.background = '#281c20';
btnBlock.style.borderColor = '#c5a059';
});
btnBlock.addEventListener('mouseout', function () {
btnBlock.style.background = '#181822';
btnBlock.style.borderColor = '#3d0a12';
});
btnBlock.addEventListener('click', function (e) {
e.preventDefault();
insertSecretTemplate(textbox, true);
});
bar.appendChild(btnBlock);
// Insere antes do textarea ou da toolbar existente
var parent = textbox.parentNode;
parent.insertBefore(bar, textbox);
}
// Função auxiliar de inserção no textarea
function insertSecretTemplate(textbox, isBlock) {
var start = textbox.selectionStart;
var end = textbox.selectionEnd;
var text = textbox.value;
var selected = text.substring(start, end);
var pre = isBlock ? '\n{{Segredo|tipo=bloco|nivel=RELATÓRIO SAD // CONFIDENCIAL|data=AAAA-MM-DD|dica=Alvo Restrito|\n' : '{{Segredo|';
var defaultText = selected || (isBlock ? 'Escreva aqui o relatório confidencial...' : 'Texto sensível a ser censurado');
var post = isBlock ? '\n}}\n' : '|data=AAAA-MM-DD|liberado=nao}}';
var replacement = pre + defaultText + post;
textbox.value = text.substring(0, start) + replacement + text.substring(end);
// Posiciona o cursor de volta
var newCursor = start + pre.length;
textbox.focus();
textbox.setSelectionRange(newCursor, newCursor + defaultText.length);
// Dispara evento de input para o MediaWiki registrar a mudança
if (window.$) {
$(textbox).trigger('input').trigger('change');
}
}
// B) Integração nativa no WikiEditor (Barra oficial do MediaWiki)
function setupWikiEditorIntegration() {
if (!window.mw || !window.$) return;
mw.loader.using('ext.wikiEditor', function () {
var $textbox = $('#wpTextbox1');
if (!$textbox.length) return;
var toolConfig = {
section: 'main',
group: 'format',
tools: {
vtmSecret: {
label: 'Inserir Tarja de Censura / Segredo',
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"><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 confidencial',
post: '|data=AAAA-MM-DD|liberado=nao}}'
}
}
}
}
};
$textbox.wikiEditor('addToToolbar', toolConfig);
});
}
// ------------------------------------------------------------------------
// 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' ||
child.id === 'vtm-editor-quickbar'
) {
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 GLOBAL
// ------------------------------------------------------------------------
function initAll() {
initVtmSecrets();
initSectionAnimation();
initVtmQuickToolbar();
setupWikiEditorIntegration();
}
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('wikiEditor.toolbarReady').add(function () {
setupWikiEditorIntegration();
});
}
})();