Difference between revisions of "MediaWiki:Common.js"
Jump to navigation
Jump to search
Line 1: | Line 1: | ||
− | /* Auto- | + | /* MediaWiki common.js - Versão otimizada */ |
+ | |||
+ | /* ======= Parte 1: Auto-expansão de seções ao clicar em links âncora ======= */ | ||
$(function() { | $(function() { | ||
− | + | console.log("Inicializando script de expansão automática para links âncora"); | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | // Função | + | // Função que expande as seções colapsáveis baseadas no hash da URL |
− | function expandSectionForAnchor(hash) { | + | function expandSectionForAnchor(hash, scrollToElement = true) { |
− | // Remover | + | // Remover o # do início se existir |
if (hash.startsWith('#')) { | if (hash.startsWith('#')) { | ||
hash = hash.substring(1); | hash = hash.substring(1); | ||
Line 27: | Line 14: | ||
console.log("Procurando elemento com ID: " + hash); | console.log("Procurando elemento com ID: " + hash); | ||
− | // | + | if (!hash) return; // Sair se não houver hash |
− | var targetElement = $('#' + hash); | + | |
− | if (targetElement.length) { | + | // Encontra o elemento alvo |
− | console.log("Elemento encontrado | + | var $targetElement = $('#' + hash); |
+ | |||
+ | if ($targetElement.length) { | ||
+ | console.log("Elemento encontrado com ID: " + hash); | ||
+ | |||
+ | // Encontre todas as seções colapsáveis que contêm o elemento | ||
+ | var $collapsibleAncestors = $targetElement.parents('.mw-collapsible.mw-collapsed'); | ||
− | // | + | // Também pegar tabelas wikitable colapsáveis |
− | var | + | var $wikitableAncestors = $targetElement.parents('.wikitable.mw-collapsible.mw-collapsed'); |
− | |||
− | // Se o elemento | + | // Unir os conjuntos de elementos |
− | if ( | + | $collapsibleAncestors = $collapsibleAncestors.add($wikitableAncestors); |
+ | |||
+ | console.log("Seções colapsáveis encontradas: " + $collapsibleAncestors.length); | ||
+ | |||
+ | // Se houver seções colapsáveis contendo o elemento | ||
+ | if ($collapsibleAncestors.length > 0) { | ||
+ | console.log("Expandindo seções colapsáveis..."); | ||
+ | |||
// Expandir cada seção de fora para dentro | // Expandir cada seção de fora para dentro | ||
− | + | $collapsibleAncestors.each(function() { | |
var $section = $(this); | var $section = $(this); | ||
− | + | ||
+ | // Remover classe de colapsado | ||
$section.removeClass('mw-collapsed'); | $section.removeClass('mw-collapsed'); | ||
− | // | + | // Tentar diferentes métodos para expandir: |
+ | |||
+ | // 1. Método nativo do MediaWiki | ||
+ | if (typeof mw !== 'undefined' && typeof mw.loader !== 'undefined') { | ||
+ | mw.loader.using('jquery.makeCollapsible', function() { | ||
+ | $section.makeCollapsible(); | ||
+ | }); | ||
+ | } | ||
+ | |||
+ | // 2. Ou usar os togglers existentes | ||
var $toggle = $section.find('.mw-collapsible-toggle').first(); | var $toggle = $section.find('.mw-collapsible-toggle').first(); | ||
if ($toggle.length) { | if ($toggle.length) { | ||
− | $toggle.click | + | console.log("Clicando no botão toggle"); |
− | } | + | $toggle.trigger('click'); |
− | + | } | |
− | + | ||
+ | // 3. Ou forçar a exibição do conteúdo diretamente | ||
+ | $section.find('.mw-collapsible-content').show(); | ||
+ | |||
+ | // 4. Para tabelas wikitable especificamente | ||
+ | if ($section.hasClass('wikitable')) { | ||
+ | $section.find('tr:not(:first-child)').show(); | ||
} | } | ||
+ | |||
+ | // 5. Remover quaisquer estilos que possam estar escondendo o conteúdo | ||
+ | $section.find('.mw-collapsible-content, tr:not(:first-child)').css({ | ||
+ | 'display': 'table-row', | ||
+ | 'visibility': 'visible', | ||
+ | 'height': 'auto', | ||
+ | 'opacity': '1' | ||
+ | }); | ||
}); | }); | ||
// Também verificar se o próprio elemento está em um colapsível | // Também verificar se o próprio elemento está em um colapsível | ||
− | var directCollapsible = targetElement.closest('.mw-collapsible.mw-collapsed'); | + | var $directCollapsible = $targetElement.closest('.mw-collapsible.mw-collapsed'); |
− | if (directCollapsible.length) { | + | if ($directCollapsible.length) { |
console.log("Expandindo o contêiner direto"); | console.log("Expandindo o contêiner direto"); | ||
− | directCollapsible.removeClass('mw-collapsed'); | + | $directCollapsible.removeClass('mw-collapsed'); |
− | + | ||
− | + | // Se for uma tabela, mostrar todas as linhas | |
− | + | if ($directCollapsible.hasClass('wikitable')) { | |
+ | $directCollapsible.find('tr:not(:first-child)').show(); | ||
} else { | } else { | ||
− | directCollapsible.find('.mw-collapsible-content').show(); | + | $directCollapsible.find('.mw-collapsible-content').show(); |
} | } | ||
} | } | ||
+ | |||
+ | // Dar um tempo para as animações terminarem antes de rolar | ||
+ | setTimeout(function() { | ||
+ | if (scrollToElement) { | ||
+ | console.log("Rolando até o elemento"); | ||
+ | $('html, body').animate({ | ||
+ | scrollTop: $targetElement.offset().top - 100 | ||
+ | }, 200); | ||
+ | } | ||
+ | }, 500); // Aumentado para 500ms para dar mais tempo para expansão | ||
+ | } else if (scrollToElement) { | ||
+ | // Se não houver seções colapsáveis, apenas role até o elemento | ||
+ | console.log("Rolando até o elemento sem expansão necessária"); | ||
+ | $('html, body').animate({ | ||
+ | scrollTop: $targetElement.offset().top - 100 | ||
+ | }, 200); | ||
} | } | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} else { | } else { | ||
console.log("Elemento com ID '" + hash + "' não encontrado"); | console.log("Elemento com ID '" + hash + "' não encontrado"); | ||
} | } | ||
} | } | ||
− | |||
− | |||
− | |||
− | // | + | // Verificar se há hash na URL quando a página carrega |
+ | if (window.location.hash) { | ||
+ | console.log("Página carregada com hash: " + window.location.hash); | ||
+ | // Usar setTimeout para garantir que o DOM esteja completamente carregado | ||
+ | setTimeout(function() { | ||
+ | expandSectionForAnchor(window.location.hash); | ||
+ | }, 500); // Aumentado para 500ms para garantir carregamento completo | ||
+ | } | ||
+ | |||
+ | // Lidar com cliques em links âncora dentro da página | ||
+ | $(document).on('click', 'a[href^="#"]', function(event) { | ||
+ | var hash = $(this).attr('href'); | ||
+ | console.log("Clique em link interno: " + hash); | ||
+ | |||
+ | // Se já estamos na mesma página, expandir seções e prevenir comportamento padrão | ||
+ | if (hash && hash.startsWith('#')) { | ||
+ | event.preventDefault(); | ||
+ | expandSectionForAnchor(hash); | ||
+ | |||
+ | // Atualizar a URL sem recarregar a página | ||
+ | if (history.pushState) { | ||
+ | history.pushState(null, null, hash); | ||
+ | } else { | ||
+ | location.hash = hash; | ||
+ | } | ||
+ | } | ||
+ | }); | ||
+ | |||
+ | // Adicionar um hook para quando o conteúdo da página for modificado | ||
if (typeof mw !== 'undefined' && mw.hook) { | if (typeof mw !== 'undefined' && mw.hook) { | ||
− | mw.hook('wikipage.content').add(function() { | + | mw.hook('wikipage.content').add(function($content) { |
− | console.log("Conteúdo da Wiki atualizado, reinicializando manipuladores | + | console.log("Conteúdo da Wiki atualizado, reinicializando manipuladores"); |
− | |||
− | // Se houver | + | // Se houver hash na URL, expandir as seções relevantes |
if (window.location.hash) { | if (window.location.hash) { | ||
− | expandSectionForAnchor(window.location.hash); | + | setTimeout(function() { |
+ | expandSectionForAnchor(window.location.hash); | ||
+ | }, 300); | ||
} | } | ||
}); | }); | ||
Line 95: | Line 155: | ||
}); | }); | ||
− | + | /* ======= Parte 2: Funcionalidade de cópia ======= */ | |
− | /* | + | $(function() { |
− | + | // Função principal para inicializar funcionalidade de cópia | |
+ | function initializeCopyFunctionality() { | ||
+ | console.log("Inicializando funcionalidade de cópia"); | ||
+ | |||
// Remover manipuladores de eventos anteriores para evitar duplicação | // Remover manipuladores de eventos anteriores para evitar duplicação | ||
− | $ | + | $('.warp-copy').off('click'); |
// Adiciona funcionalidade aos elementos com a classe warp-copy | // Adiciona funcionalidade aos elementos com a classe warp-copy | ||
− | $ | + | $('.warp-copy').on('click', function(e) { |
− | + | e.preventDefault(); // Previne navegação se estiver dentro de um link | |
− | + | ||
− | + | // Pega o texto do atributo data-copy ou usa o texto do elemento | |
− | + | var textToCopy = $(this).attr('data-copy') || $(this).text(); | |
− | + | ||
− | + | copyTextToClipboard(textToCopy, $(this)); | |
− | + | ||
− | + | return false; // Impede comportamento padrão | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
}); | }); | ||
− | + | ||
− | + | // Identifica os links dentro dos containers de imagem de NPCs | |
− | + | $('.contents-equipment .tile-top.tile-image a').each(function() { | |
− | |||
− | |||
− | |||
− | // Identifica os links dentro dos containers de imagem | ||
− | $ | ||
var $link = $(this); | var $link = $(this); | ||
var linkHref = $link.attr('href') || ''; | var linkHref = $link.attr('href') || ''; | ||
Line 158: | Line 185: | ||
if (npcId) { | if (npcId) { | ||
+ | // Remove manipuladores existentes para evitar duplicação | ||
+ | $link.off('mousedown.warpcopy'); | ||
+ | |||
// Adiciona um handler de clique que irá copiar o texto | // Adiciona um handler de clique que irá copiar o texto | ||
− | $link.on('mousedown', function(e) { | + | $link.on('mousedown.warpcopy', function(e) { |
// Texto que será copiado - usa o ID específico do NPC | // Texto que será copiado - usa o ID específico do NPC | ||
var textToCopy = "@warp " + npcId; | var textToCopy = "@warp " + npcId; | ||
− | + | copyTextToClipboard(textToCopy); | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
// Permite que o evento continue normalmente | // Permite que o evento continue normalmente | ||
Line 191: | Line 200: | ||
} | } | ||
}); | }); | ||
− | } | + | } |
− | + | ||
− | + | // Função auxiliar para copiar texto para a área de transferência | |
− | + | function copyTextToClipboard(text, $element) { | |
− | + | // Cria um elemento temporário para copiar o texto | |
− | |||
− | // Função para | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | // | ||
var tempInput = document.createElement('textarea'); | var tempInput = document.createElement('textarea'); | ||
− | tempInput.value = | + | tempInput.value = text; |
document.body.appendChild(tempInput); | document.body.appendChild(tempInput); | ||
tempInput.select(); | tempInput.select(); | ||
try { | try { | ||
− | + | // Executa o comando de cópia | |
− | + | var successful = document.execCommand('copy'); | |
+ | |||
+ | // Feedback visual temporário ao usuário | ||
+ | if (successful) { | ||
+ | if ($element) { | ||
+ | $element.addClass('copied'); | ||
+ | |||
+ | // Mostra o feedback por 1.5 segundos | ||
+ | setTimeout(function() { | ||
+ | $element.removeClass('copied'); | ||
+ | }, 1500); | ||
+ | } | ||
− | + | // Feedback visual adicional | |
− | + | $('<div class="copy-notification" style="position:fixed;bottom:20px;right:20px;background:#4CAF50;color:white;padding:10px;border-radius:5px;z-index:9999;">Copiado: ' + text + '</div>') | |
− | + | .appendTo('body') | |
− | + | .delay(1500) | |
− | + | .fadeOut(300, function() { $(this).remove(); }); | |
− | + | } | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
} catch (err) { | } catch (err) { | ||
− | + | console.error('Erro ao copiar texto: ', err); | |
} | } | ||
− | // | + | // Remove o elemento temporário |
document.body.removeChild(tempInput); | document.body.removeChild(tempInput); | ||
− | + | } | |
− | } | + | |
+ | // Inicializar quando o DOM estiver pronto | ||
+ | initializeCopyFunctionality(); | ||
+ | |||
+ | // Também inicializar quando o conteúdo da wiki for carregado/atualizado | ||
+ | if (typeof mw !== 'undefined' && mw.hook) { | ||
+ | mw.hook('wikipage.content').add(function() { | ||
+ | console.log("Conteúdo da wiki atualizado, reinicializando funcionalidade de cópia"); | ||
+ | initializeCopyFunctionality(); | ||
+ | }); | ||
+ | } | ||
+ | }); | ||
− | // | + | /* ======= Parte 3: Tooltips para elementos copiáveis ======= */ |
− | $( | + | $(function() { |
− | + | // Função para inicializar tooltips nos elementos .warp-copy | |
+ | function initializeWarpCopyTooltips() { | ||
+ | console.log("Inicializando tooltips para elementos .warp-copy"); | ||
+ | |||
+ | // Selecionar todos os elementos com classe .warp-copy | ||
+ | var copyElements = document.querySelectorAll('.warp-copy'); | ||
− | // Também inicializar quando o conteúdo da wiki for carregado/atualizado | + | copyElements.forEach(function(element) { |
− | + | // Garantir que o elemento tenha os atributos necessários para o tooltip | |
− | + | if (!element.getAttribute('title')) { | |
− | + | element.setAttribute('title', 'Copy'); | |
− | + | } | |
− | + | }); | |
− | + | } | |
+ | |||
+ | // Inicializar quando o DOM estiver pronto | ||
+ | initializeWarpCopyTooltips(); | ||
+ | |||
+ | // Também inicializar quando o conteúdo da wiki for carregado/atualizado | ||
+ | if (typeof mw !== 'undefined' && mw.hook) { | ||
+ | mw.hook('wikipage.content').add(function() { | ||
+ | console.log("Conteúdo da wiki atualizado, reinicializando tooltips"); | ||
+ | initializeWarpCopyTooltips(); | ||
+ | }); | ||
+ | } | ||
}); | }); |
Revision as of 17:00, 29 April 2025
/* MediaWiki common.js - Versão otimizada */ /* ======= Parte 1: Auto-expansão de seções ao clicar em links âncora ======= */ $(function() { console.log("Inicializando script de expansão automática para links âncora"); // Função que expande as seções colapsáveis baseadas no hash da URL function expandSectionForAnchor(hash, scrollToElement = true) { // Remover o # do início se existir if (hash.startsWith('#')) { hash = hash.substring(1); } console.log("Procurando elemento com ID: " + hash); if (!hash) return; // Sair se não houver hash // Encontra o elemento alvo var $targetElement = $('#' + hash); if ($targetElement.length) { console.log("Elemento encontrado com ID: " + hash); // Encontre todas as seções colapsáveis que contêm o elemento var $collapsibleAncestors = $targetElement.parents('.mw-collapsible.mw-collapsed'); // Também pegar tabelas wikitable colapsáveis var $wikitableAncestors = $targetElement.parents('.wikitable.mw-collapsible.mw-collapsed'); // Unir os conjuntos de elementos $collapsibleAncestors = $collapsibleAncestors.add($wikitableAncestors); console.log("Seções colapsáveis encontradas: " + $collapsibleAncestors.length); // Se houver seções colapsáveis contendo o elemento if ($collapsibleAncestors.length > 0) { console.log("Expandindo seções colapsáveis..."); // Expandir cada seção de fora para dentro $collapsibleAncestors.each(function() { var $section = $(this); // Remover classe de colapsado $section.removeClass('mw-collapsed'); // Tentar diferentes métodos para expandir: // 1. Método nativo do MediaWiki if (typeof mw !== 'undefined' && typeof mw.loader !== 'undefined') { mw.loader.using('jquery.makeCollapsible', function() { $section.makeCollapsible(); }); } // 2. Ou usar os togglers existentes var $toggle = $section.find('.mw-collapsible-toggle').first(); if ($toggle.length) { console.log("Clicando no botão toggle"); $toggle.trigger('click'); } // 3. Ou forçar a exibição do conteúdo diretamente $section.find('.mw-collapsible-content').show(); // 4. Para tabelas wikitable especificamente if ($section.hasClass('wikitable')) { $section.find('tr:not(:first-child)').show(); } // 5. Remover quaisquer estilos que possam estar escondendo o conteúdo $section.find('.mw-collapsible-content, tr:not(:first-child)').css({ 'display': 'table-row', 'visibility': 'visible', 'height': 'auto', 'opacity': '1' }); }); // Também verificar se o próprio elemento está em um colapsível var $directCollapsible = $targetElement.closest('.mw-collapsible.mw-collapsed'); if ($directCollapsible.length) { console.log("Expandindo o contêiner direto"); $directCollapsible.removeClass('mw-collapsed'); // Se for uma tabela, mostrar todas as linhas if ($directCollapsible.hasClass('wikitable')) { $directCollapsible.find('tr:not(:first-child)').show(); } else { $directCollapsible.find('.mw-collapsible-content').show(); } } // Dar um tempo para as animações terminarem antes de rolar setTimeout(function() { if (scrollToElement) { console.log("Rolando até o elemento"); $('html, body').animate({ scrollTop: $targetElement.offset().top - 100 }, 200); } }, 500); // Aumentado para 500ms para dar mais tempo para expansão } else if (scrollToElement) { // Se não houver seções colapsáveis, apenas role até o elemento console.log("Rolando até o elemento sem expansão necessária"); $('html, body').animate({ scrollTop: $targetElement.offset().top - 100 }, 200); } } else { console.log("Elemento com ID '" + hash + "' não encontrado"); } } // Verificar se há hash na URL quando a página carrega if (window.location.hash) { console.log("Página carregada com hash: " + window.location.hash); // Usar setTimeout para garantir que o DOM esteja completamente carregado setTimeout(function() { expandSectionForAnchor(window.location.hash); }, 500); // Aumentado para 500ms para garantir carregamento completo } // Lidar com cliques em links âncora dentro da página $(document).on('click', 'a[href^="#"]', function(event) { var hash = $(this).attr('href'); console.log("Clique em link interno: " + hash); // Se já estamos na mesma página, expandir seções e prevenir comportamento padrão if (hash && hash.startsWith('#')) { event.preventDefault(); expandSectionForAnchor(hash); // Atualizar a URL sem recarregar a página if (history.pushState) { history.pushState(null, null, hash); } else { location.hash = hash; } } }); // Adicionar um hook para quando o conteúdo da página for modificado if (typeof mw !== 'undefined' && mw.hook) { mw.hook('wikipage.content').add(function($content) { console.log("Conteúdo da Wiki atualizado, reinicializando manipuladores"); // Se houver hash na URL, expandir as seções relevantes if (window.location.hash) { setTimeout(function() { expandSectionForAnchor(window.location.hash); }, 300); } }); } }); /* ======= Parte 2: Funcionalidade de cópia ======= */ $(function() { // Função principal para inicializar funcionalidade de cópia function initializeCopyFunctionality() { console.log("Inicializando funcionalidade de cópia"); // Remover manipuladores de eventos anteriores para evitar duplicação $('.warp-copy').off('click'); // Adiciona funcionalidade aos elementos com a classe warp-copy $('.warp-copy').on('click', function(e) { e.preventDefault(); // Previne navegação se estiver dentro de um link // Pega o texto do atributo data-copy ou usa o texto do elemento var textToCopy = $(this).attr('data-copy') || $(this).text(); copyTextToClipboard(textToCopy, $(this)); return false; // Impede comportamento padrão }); // Identifica os links dentro dos containers de imagem de NPCs $('.contents-equipment .tile-top.tile-image a').each(function() { var $link = $(this); var linkHref = $link.attr('href') || ''; // Extrai o ID do NPC do link (remove o # do início) var npcId = linkHref.startsWith('#') ? linkHref.substring(1) : linkHref; if (npcId) { // Remove manipuladores existentes para evitar duplicação $link.off('mousedown.warpcopy'); // Adiciona um handler de clique que irá copiar o texto $link.on('mousedown.warpcopy', function(e) { // Texto que será copiado - usa o ID específico do NPC var textToCopy = "@warp " + npcId; copyTextToClipboard(textToCopy); // Permite que o evento continue normalmente return true; }); } }); } // Função auxiliar para copiar texto para a área de transferência function copyTextToClipboard(text, $element) { // Cria um elemento temporário para copiar o texto var tempInput = document.createElement('textarea'); tempInput.value = text; document.body.appendChild(tempInput); tempInput.select(); try { // Executa o comando de cópia var successful = document.execCommand('copy'); // Feedback visual temporário ao usuário if (successful) { if ($element) { $element.addClass('copied'); // Mostra o feedback por 1.5 segundos setTimeout(function() { $element.removeClass('copied'); }, 1500); } // Feedback visual adicional $('<div class="copy-notification" style="position:fixed;bottom:20px;right:20px;background:#4CAF50;color:white;padding:10px;border-radius:5px;z-index:9999;">Copiado: ' + text + '</div>') .appendTo('body') .delay(1500) .fadeOut(300, function() { $(this).remove(); }); } } catch (err) { console.error('Erro ao copiar texto: ', err); } // Remove o elemento temporário document.body.removeChild(tempInput); } // Inicializar quando o DOM estiver pronto initializeCopyFunctionality(); // Também inicializar quando o conteúdo da wiki for carregado/atualizado if (typeof mw !== 'undefined' && mw.hook) { mw.hook('wikipage.content').add(function() { console.log("Conteúdo da wiki atualizado, reinicializando funcionalidade de cópia"); initializeCopyFunctionality(); }); } }); /* ======= Parte 3: Tooltips para elementos copiáveis ======= */ $(function() { // Função para inicializar tooltips nos elementos .warp-copy function initializeWarpCopyTooltips() { console.log("Inicializando tooltips para elementos .warp-copy"); // Selecionar todos os elementos com classe .warp-copy var copyElements = document.querySelectorAll('.warp-copy'); copyElements.forEach(function(element) { // Garantir que o elemento tenha os atributos necessários para o tooltip if (!element.getAttribute('title')) { element.setAttribute('title', 'Copy'); } }); } // Inicializar quando o DOM estiver pronto initializeWarpCopyTooltips(); // Também inicializar quando o conteúdo da wiki for carregado/atualizado if (typeof mw !== 'undefined' && mw.hook) { mw.hook('wikipage.content').add(function() { console.log("Conteúdo da wiki atualizado, reinicializando tooltips"); initializeWarpCopyTooltips(); }); } });