|
Tags: Manual revert Reverted |
| Line 1: |
Line 1: |
| $( function () {
| |
| // sidebar-chunk only applies to desktop-small, but the toggles are hidden at
| |
| // other resolutions regardless and the css overrides any visible effects.
| |
| var $dropdowns = $( '#personal, #p-variants-desktop, .sidebar-chunk' );
| |
|
| |
| /**
| |
| * Desktop menu click-toggling
| |
| *
| |
| * We're not even checking if it's desktop because the classes in play have no effect
| |
| * on mobile regardless... this may break things at some point, though.
| |
| */
| |
|
| |
| /**
| |
| * Close all dropdowns
| |
| */
| |
| function closeOpen() {
| |
| $dropdowns.removeClass( 'dropdown-active' );
| |
| }
| |
|
| |
| /**
| |
| * Click behaviour
| |
| */
| |
| $dropdowns.on( 'click', function ( e ) {
| |
| // Check if it's already open so we don't open it again
| |
| // eslint-disable-next-line no-jquery/no-class-state
| |
| if ( $( this ).hasClass( 'dropdown-active' ) ) {
| |
| if ( $( e.target ).closest( $( 'h2, #p-variants-desktop h3' ) ).length > 0 ) {
| |
| // treat reclick on the header as a toggle
| |
| closeOpen();
| |
| }
| |
| // Clicked inside an open menu; don't do anything
| |
| } else {
| |
| closeOpen();
| |
| e.stopPropagation(); // stop hiding it!
| |
| $( this ).addClass( 'dropdown-active' );
| |
| }
| |
| } );
| |
| $( document ).on( 'click', function ( e ) {
| |
| if ( $( e.target ).closest( $dropdowns ).length > 0 ) {
| |
| // Clicked inside an open menu; don't close anything
| |
| } else {
| |
| closeOpen();
| |
| }
| |
| } );
| |
| } );
| |
|
| |
| mw.hook( 'wikipage.content' ).add( function ( $content ) {
| |
| // Gotta wrap them for this to work; maybe later the parser etc will do this for us?!
| |
| $content.find( 'div > table:not( table table )' ).wrap( '<div class="content-table-wrapper"><div class="content-table"></div></div>' );
| |
| $content.find( '.content-table-wrapper' ).prepend( '<div class="content-table-left"></div><div class="content-table-right"></div>' );
| |
|
| |
| /**
| |
| * Set up borders for experimental overflowing table scrolling
| |
| *
| |
| * I have no idea what I'm doing.
| |
| *
| |
| * @param {jQuery} $table
| |
| */
| |
| function setScrollClass( $table ) {
| |
| var $tableWrapper = $table.parent(),
| |
| // wtf browser rtl implementations
| |
| scroll = Math.abs( $tableWrapper.scrollLeft() );
| |
|
| |
| $tableWrapper.parent()
| |
| // 1 instead of 0 because of weird rtl rounding errors or something
| |
| .toggleClass( 'scroll-left', scroll > 1 )
| |
| .toggleClass( 'scroll-right', $table.outerWidth() - $tableWrapper.innerWidth() - scroll > 1 );
| |
| }
| |
|
| |
| $content.find( '.content-table' ).on( 'scroll', function () {
| |
| setScrollClass( $( this ).children( 'table' ).first() );
| |
|
| |
| if ( $content.attr( 'dir' ) === 'rtl' ) {
| |
| $( this ).find( 'caption' ).css( 'margin-right', Math.abs( $( this ).scrollLeft() ) + 'px' );
| |
| } else {
| |
| $( this ).find( 'caption' ).css( 'margin-left', $( this ).scrollLeft() + 'px' );
| |
| }
| |
| } );
| |
|
| |
| /**
| |
| * Mark overflowed tables for scrolling
| |
| */
| |
| function unOverflowTables() {
| |
| $content.find( '.content-table > table' ).each( function () {
| |
| var $table = $( this ),
| |
| $wrapper = $table.parent().parent();
| |
| if ( $table.outerWidth() > $wrapper.outerWidth() ) {
| |
| $wrapper.addClass( 'overflowed' );
| |
| setScrollClass( $table );
| |
| } else {
| |
| $wrapper.removeClass( 'overflowed scroll-left scroll-right fixed-scrollbar-container' );
| |
| }
| |
| } );
| |
|
| |
| // Set up sticky captions
| |
| $content.find( '.content-table > table > caption' ).each( function () {
| |
| var $container, tableHeight,
| |
| $table = $( this ).parent(),
| |
| $wrapper = $table.parent().parent();
| |
|
| |
| if ( $table.outerWidth() > $wrapper.outerWidth() ) {
| |
| $container = $( this ).parents( '.content-table-wrapper' );
| |
| $( this ).width( $content.width() );
| |
| tableHeight = $container.innerHeight() - $( this ).outerHeight();
| |
|
| |
| $container.find( '.content-table-left' ).height( tableHeight );
| |
| $container.find( '.content-table-right' ).height( tableHeight );
| |
| }
| |
| } );
| |
| }
| |
|
| |
| unOverflowTables();
| |
| $( window ).on( 'resize', unOverflowTables );
| |
|
| |
| /**
| |
| * Sticky scrollbars maybe?!
| |
| */
| |
| $content.find( '.content-table' ).each( function () {
| |
| var $table, $tableWrapper, $spoof, $scrollbar;
| |
|
| |
| $tableWrapper = $( this );
| |
| $table = $tableWrapper.children( 'table' ).first();
| |
|
| |
| // Assemble our silly crap and add to page
| |
| $scrollbar = $( '<div>' ).addClass( 'content-table-scrollbar inactive' ).width( $content.width() );
| |
| $spoof = $( '<div>' ).addClass( 'content-table-spoof' ).width( $table.outerWidth() );
| |
| $tableWrapper.parent().prepend( $scrollbar.prepend( $spoof ) );
| |
| } );
| |
|
| |
| /**
| |
| * Scoll table when scrolling scrollbar and visa-versa lololol wut
| |
| */
| |
| $content.find( '.content-table' ).on( 'scroll', function () {
| |
| // Only do this here if we're not already mirroring the spoof
| |
| var $mirror = $( this ).siblings( '.inactive' ).first();
| |
|
| |
| $mirror.scrollLeft( $( this ).scrollLeft() );
| |
| } );
| |
| $content.find( '.content-table-scrollbar' ).on( 'scroll', function () {
| |
| var $mirror = $( this ).siblings( '.content-table' ).first();
| |
|
| |
| // Only do this here if we're not already mirroring the table
| |
| // eslint-disable-next-line no-jquery/no-class-state
| |
| if ( !$( this ).hasClass( 'inactive' ) ) {
| |
| $mirror.scrollLeft( $( this ).scrollLeft() );
| |
| }
| |
| } );
| |
|
| |
| /**
| |
| * Set active when actually over the table it applies to...
| |
| */
| |
| function determineActiveSpoofScrollbars() {
| |
| $content.find( '.overflowed .content-table' ).each( function () {
| |
| var $scrollbar = $( this ).siblings( '.content-table-scrollbar' ).first();
| |
|
| |
| // Skip caption
| |
| var captionHeight = $( this ).find( 'caption' ).outerHeight() || 0;
| |
| if ( captionHeight ) {
| |
| // Pad slightly for reasons
| |
| captionHeight += 8;
| |
| }
| |
|
| |
| var tableTop = $( this ).offset().top,
| |
| tableBottom = tableTop + $( this ).outerHeight(),
| |
| viewBottom = window.scrollY + document.documentElement.clientHeight,
| |
| active = tableTop + captionHeight < viewBottom && tableBottom > viewBottom;
| |
| $scrollbar.toggleClass( 'inactive', !active );
| |
| } );
| |
| }
| |
|
| |
| determineActiveSpoofScrollbars();
| |
| $( window ).on( 'scroll resize', determineActiveSpoofScrollbars );
| |
|
| |
|
| |
| function showContent(id) {
| |
| const conteudos = document.querySelectorAll('.nav-content');
| |
| conteudos.forEach((div) => {
| |
| div.classList.remove('show-content');
| |
| });
| |
| document.getElementById(id).classList.add('show-content');
| |
| }
| |
|
| |
| /**
| |
| * Make sure tablespoofs remain correctly-sized?
| |
| */
| |
| $( window ).on( 'resize', function () {
| |
| $content.find( '.content-table-scrollbar' ).each( function () {
| |
| var width = $( this ).siblings().first().find( 'table' ).first().width();
| |
| $( this ).find( '.content-table-spoof' ).first().width( width );
| |
| $( this ).width( $content.width() );
| |
| } );
| |
| } );
| |
| } );
| |
| /* Popout menus (header) */
| |
|
| |
| /* eslint-disable no-jquery/no-fade */
| |
|
| |
| $( function () {
| |
| var toggleTime = 200;
| |
|
| |
| // Open the various menus
| |
| $( '#user-tools h2' ).on( 'click', function () {
| |
| if ( $( window ).width() < 851 ) {
| |
| $( '#personal-inner, #menus-cover' ).fadeToggle( toggleTime );
| |
| }
| |
| } );
| |
| $( '#site-navigation h2' ).on( 'click', function () {
| |
| if ( $( window ).width() < 851 ) {
| |
| $( '#site-navigation .sidebar-inner, #menus-cover' ).fadeToggle( toggleTime );
| |
| }
| |
| } );
| |
| $( '#site-tools h2' ).on( 'click', function () {
| |
| if ( $( window ).width() < 851 ) {
| |
| $( '#site-tools .sidebar-inner, #menus-cover' ).fadeToggle( toggleTime );
| |
| }
| |
| } );
| |
| $( '#ca-more' ).on( 'click', function () {
| |
| $( '#page-tools .sidebar-inner' ).css( 'top', $( '#ca-more' ).offset().top + 25 );
| |
| if ( $( window ).width() < 851 ) {
| |
| $( '#page-tools .sidebar-inner, #menus-cover' ).fadeToggle( toggleTime );
| |
| }
| |
| } );
| |
| $( '#ca-languages' ).on( 'click', function () {
| |
| $( '#other-languages .sidebar-inner' ).css( 'top', $( '#ca-languages' ).offset().top + 25 );
| |
| if ( $( window ).width() < 851 ) {
| |
| $( '#other-languages .sidebar-inner, #menus-cover' ).fadeToggle( toggleTime );
| |
| }
| |
| } );
| |
|
| |
| // Close menus on click outside
| |
| $( document ).on( 'click touchstart', function ( e ) {
| |
| if ( $( e.target ).closest( '#menus-cover' ).length > 0 ) {
| |
| $( '#personal-inner' ).fadeOut( toggleTime );
| |
| $( '.sidebar-inner' ).fadeOut( toggleTime );
| |
| $( '#menus-cover' ).fadeOut( toggleTime );
| |
| }
| |
| } );
| |
| } );
| |
|
| |
| // Melhoria do comportamento dos submenus multi-coluna
| |
| $(document).ready(function() {
| |
|
| |
| // Função para aplicar classes de coluna dinamicamente se necessário
| |
| function adjustSubmenuColumns() {
| |
| $('.submenu').each(function() {
| |
| const $submenu = $(this);
| |
| const itemCount = $submenu.find('li').length;
| |
|
| |
| // Remove classes existentes
| |
| $submenu.removeClass('submenu-2-columns submenu-3-columns submenu-4-columns');
| |
|
| |
| // Aplica classe baseada na quantidade de itens
| |
| if (itemCount > 20) {
| |
| $submenu.addClass('submenu-4-columns');
| |
| } else if (itemCount > 12) {
| |
| $submenu.addClass('submenu-3-columns');
| |
| } else if (itemCount > 6) {
| |
| $submenu.addClass('submenu-2-columns');
| |
| }
| |
| });
| |
| }
| |
|
| |
| // Aplica as classes na inicialização
| |
| adjustSubmenuColumns();
| |
|
| |
| // Comportamento móvel para submenus
| |
| if ($(window).width() <= 850) {
| |
| $('li.has-submenu > a').on('click', function(e) {
| |
| e.preventDefault();
| |
| var $parent = $(this).parent();
| |
|
| |
| if ($parent.hasClass('active')) {
| |
| $parent.removeClass('active');
| |
| } else {
| |
| // Fecha outros menus abertos
| |
| $('li.has-submenu.active').removeClass('active');
| |
| $parent.addClass('active');
| |
| }
| |
| });
| |
| }
| |
|
| |
| // Força aplicação de colunas em navegadores específicos
| |
| function forceColumnLayout() {
| |
| // Verifica se as colunas não estão sendo aplicadas corretamente
| |
| $('.submenu.submenu-2-columns').each(function() {
| |
| const $this = $(this);
| |
| if ($this.is(':visible')) {
| |
| const width = $this.width();
| |
| const items = $this.find('li');
| |
|
| |
| // Se parece que não está em colunas, força o CSS
| |
| if (items.length > 6 && width < 400) {
| |
| $this.css({
| |
| 'column-count': '2',
| |
| 'column-gap': '20px',
| |
| 'min-width': '450px'
| |
| });
| |
| }
| |
| }
| |
| });
| |
|
| |
| $('.submenu.submenu-3-columns').each(function() {
| |
| const $this = $(this);
| |
| if ($this.is(':visible')) {
| |
| const width = $this.width();
| |
| const items = $this.find('li');
| |
|
| |
| if (items.length > 12 && width < 550) {
| |
| $this.css({
| |
| 'column-count': '3',
| |
| 'column-gap': '20px',
| |
| 'min-width': '600px'
| |
| });
| |
| }
| |
| }
| |
| });
| |
|
| |
| $('.submenu.submenu-4-columns').each(function() {
| |
| const $this = $(this);
| |
| if ($this.is(':visible')) {
| |
| const width = $this.width();
| |
| const items = $this.find('li');
| |
|
| |
| if (items.length > 20 && width < 700) {
| |
| $this.css({
| |
| 'column-count': '4',
| |
| 'column-gap': '20px',
| |
| 'min-width': '750px'
| |
| });
| |
| }
| |
| }
| |
| });
| |
| }
| |
|
| |
| // Aplica verificação quando submenus são mostrados
| |
| $('li.has-submenu').on('mouseenter', function() {
| |
| setTimeout(forceColumnLayout, 50);
| |
| });
| |
|
| |
| // Reaplica classes quando a janela é redimensionada
| |
| $(window).on('resize', function() {
| |
| adjustSubmenuColumns();
| |
| setTimeout(forceColumnLayout, 100);
| |
| });
| |
|
| |
| // Garante que o comportamento seja aplicado em conteúdo carregado dinamicamente
| |
| if (typeof MutationObserver !== 'undefined') {
| |
| const observer = new MutationObserver(function(mutations) {
| |
| mutations.forEach(function(mutation) {
| |
| if (mutation.addedNodes.length) {
| |
| // Verifica se algum dos nós adicionados contém submenus
| |
| $(mutation.addedNodes).find('.submenu').each(function() {
| |
| adjustSubmenuColumns();
| |
| });
| |
| }
| |
| });
| |
| });
| |
|
| |
| observer.observe(document.body, { childList: true, subtree: true });
| |
| }
| |
|
| |
| // Função de debug para verificar se as colunas estão funcionando
| |
| window.debugSubmenus = function() {
| |
| $('.submenu').each(function() {
| |
| const $this = $(this);
| |
| const itemCount = $this.find('li').length;
| |
| const isVisible = $this.is(':visible');
| |
| const columnCount = $this.css('column-count');
| |
| const width = $this.width();
| |
|
| |
| console.log('Submenu:', {
| |
| items: itemCount,
| |
| visible: isVisible,
| |
| columnCount: columnCount,
| |
| width: width,
| |
| classes: $this.attr('class')
| |
| });
| |
| });
| |
| };
| |
| });
| |
| // Adiciona efeitos de interação
| |
| document.addEventListener('DOMContentLoaded', function() {
| |
| const guideItems = document.querySelectorAll('.mw-guide-item');
| |
|
| |
| guideItems.forEach(item => {
| |
| item.addEventListener('mouseenter', function() {
| |
| this.style.transform = 'translateY(-3px)';
| |
| });
| |
|
| |
| item.addEventListener('mouseleave', function() {
| |
| this.style.transform = 'translateY(0)';
| |
| });
| |
|
| |
| item.addEventListener('click', function(e) {
| |
| // Adiciona efeito de clique
| |
| this.style.transform = 'translateY(1px)';
| |
| setTimeout(() => {
| |
| this.style.transform = 'translateY(-3px)';
| |
| }, 100);
| |
| });
| |
| });
| |
| });
| |
| // JavaScript para Cards com Imagem - compatível com sistema existente
| |
| $(document).ready(function() {
| |
|
| |
| // Função para gerenciar cards com imagem (reutiliza lógica existente)
| |
| function initImageCards() {
| |
| const imageCards = $('.mw-image-card');
| |
|
| |
| // Aplica os mesmos efeitos dos guias existentes
| |
| imageCards.each(function() {
| |
| const $card = $(this);
| |
|
| |
| // Efeitos hover melhorados
| |
| $card.on('mouseenter', function() {
| |
| $(this).css({
| |
| 'transform': 'translateY(-8px) scale(1.02)',
| |
| 'transition': 'all 0.3s ease'
| |
| });
| |
| });
| |
|
| |
| $card.on('mouseleave', function() {
| |
| $(this).css({
| |
| 'transform': 'translateY(0) scale(1)',
| |
| 'transition': 'all 0.3s ease'
| |
| });
| |
| });
| |
|
| |
| // Efeito de clique
| |
| $card.on('click', function() {
| |
| $(this).css('transform', 'translateY(-2px) scale(0.98)');
| |
| setTimeout(() => {
| |
| $(this).css('transform', 'translateY(-8px) scale(1.02)');
| |
| }, 150);
| |
| });
| |
| });
| |
| }
| |
|
| |
| // Função para gerenciar carregamento de imagens
| |
| function handleImageLoading() {
| |
| $('.mw-card-image img').each(function() {
| |
| const $img = $(this);
| |
| const $container = $img.parent();
| |
|
| |
| // Adiciona classe de loading
| |
| $container.addClass('loading');
| |
|
| |
| // Quando a imagem carregar
| |
| $img.on('load', function() {
| |
| $container.removeClass('loading');
| |
| });
| |
|
| |
| // Se a imagem falhar ao carregar
| |
| $img.on('error', function() {
| |
| $container.removeClass('loading');
| |
| // Mantém o gradiente de fundo como fallback
| |
| $img.hide();
| |
| });
| |
|
| |
| // Se a imagem já estiver carregada (cache)
| |
| if (this.complete) {
| |
| $container.removeClass('loading');
| |
| }
| |
| });
| |
| }
| |
|
| |
| // Função de responsividade para cards com imagem
| |
| function adjustImageGrid() {
| |
| const imageGrid = $('.mw-image-grid');
| |
| const width = $(window).innerWidth;
| |
|
| |
| if (width < 480) {
| |
| imageGrid.css('grid-template-columns', '1fr');
| |
| } else if (width < 768) {
| |
| imageGrid.css('grid-template-columns', 'repeat(auto-fit, minmax(250px, 1fr))');
| |
| } else {
| |
| imageGrid.css('grid-template-columns', 'repeat(auto-fit, minmax(300px, 1fr))');
| |
| }
| |
| }
| |
|
| |
| // Função para lazy loading de imagens (opcional)
| |
| function lazyLoadImages() {
| |
| if ('IntersectionObserver' in window) {
| |
| const imageObserver = new IntersectionObserver((entries, observer) => {
| |
| entries.forEach(entry => {
| |
| if (entry.isIntersecting) {
| |
| const img = entry.target;
| |
| const dataSrc = img.getAttribute('data-src');
| |
| if (dataSrc) {
| |
| img.src = dataSrc;
| |
| img.removeAttribute('data-src');
| |
| imageObserver.unobserve(img);
| |
| }
| |
| }
| |
| });
| |
| });
| |
|
| |
| $('.mw-card-image img[data-src]').each(function() {
| |
| imageObserver.observe(this);
| |
| });
| |
| }
| |
| }
| |
|
| |
| // Integração com sistema existente de guias
| |
| function integrateWithExistingSystem() {
| |
| // Estende a funcionalidade existente para incluir cards de imagem
| |
| if (typeof window.adjustGuideGrid === 'function') {
| |
| const originalAdjustGuideGrid = window.adjustGuideGrid;
| |
| window.adjustGuideGrid = function() {
| |
| originalAdjustGuideGrid();
| |
| adjustImageGrid();
| |
| };
| |
| } else {
| |
| window.adjustGuideGrid = adjustImageGrid;
| |
| }
| |
|
| |
| // Adiciona cards de imagem ao sistema de debug existente
| |
| if (typeof window.debugSubmenus === 'function') {
| |
| const originalDebug = window.debugSubmenus;
| |
| window.debugImageCards = function() {
| |
| $('.mw-image-card').each(function() {
| |
| const $card = $(this);
| |
| const text = $card.find('.mw-card-text').text();
| |
| const hasImage = $card.find('img').length > 0;
| |
| const imageLoaded = hasImage ? $card.find('img')[0].complete : false;
| |
|
| |
| console.log('Image Card:', {
| |
| text: text,
| |
| hasImage: hasImage,
| |
| imageLoaded: imageLoaded,
| |
| dimensions: {
| |
| width: $card.width(),
| |
| height: $card.height()
| |
| }
| |
| });
| |
| });
| |
|
| |
| // Chama debug original se existir
| |
| if (originalDebug) originalDebug();
| |
| };
| |
| }
| |
| }
| |
|
| |
| // Inicialização
| |
| initImageCards();
| |
| handleImageLoading();
| |
| adjustImageGrid();
| |
| lazyLoadImages();
| |
| integrateWithExistingSystem();
| |
|
| |
| // Event listeners
| |
| $(window).on('resize', function() {
| |
| adjustImageGrid();
| |
| });
| |
|
| |
| // Observa mudanças no DOM para novos cards adicionados dinamicamente
| |
| if (typeof MutationObserver !== 'undefined') {
| |
| const observer = new MutationObserver(function(mutations) {
| |
| mutations.forEach(function(mutation) {
| |
| if (mutation.addedNodes.length) {
| |
| $(mutation.addedNodes).find('.mw-image-card').each(function() {
| |
| initImageCards();
| |
| handleImageLoading();
| |
| });
| |
| }
| |
| });
| |
| });
| |
|
| |
| observer.observe(document.body, { childList: true, subtree: true });
| |
| }
| |
| });
| |
|
| |
| // Função global para adicionar novos cards dinamicamente
| |
| window.addImageCard = function(container, link, imageSrc, text, bgClass) {
| |
| const cardHtml = `
| |
| <a href="${link}" class="mw-image-card">
| |
| <div class="mw-card-image ${bgClass || ''}">
| |
| <img src="${imageSrc}" alt="${text}" />
| |
| </div>
| |
| <div class="mw-card-text">${text}</div>
| |
| </a>
| |
| `;
| |
|
| |
| $(container).find('.mw-image-grid').append(cardHtml);
| |
|
| |
| // Reinicializa funcionalidades para o novo card
| |
| const $newCard = $(container).find('.mw-image-card').last();
| |
| $newCard.trigger('initImageCard');
| |
| };
| |
|
| |
| // Função para tornar todas as tabelas responsivas
| |
| function makeTablesResponsive() {
| |
| // Seleciona todas as tabelas da página
| |
| const tables = document.querySelectorAll('table');
| |
|
| |
| tables.forEach(table => {
| |
| // Verifica se a tabela tem cabeçalhos (th)
| |
| let headers = Array.from(table.querySelectorAll('th')).map(th => th.textContent.trim());
| |
|
| |
| // Se não houver cabeçalhos, tenta usar a primeira linha como cabeçalho
| |
| if (headers.length === 0) {
| |
| const firstRow = table.querySelector('tr');
| |
| if (firstRow) {
| |
| const cells = firstRow.querySelectorAll('td');
| |
| headers.push(...Array.from(cells).map(cell => cell.textContent.trim()));
| |
| }
| |
| }
| |
|
| |
| // Para tabelas com cabeçalhos em múltiplas linhas, tentamos capturar todos
| |
| if (table.querySelectorAll('thead tr').length > 1) {
| |
| // Para tabelas com cabeçalhos complexos, usamos a última linha de cabeçalhos
| |
| const headerRows = table.querySelectorAll('thead tr');
| |
| const lastHeaderRow = headerRows[headerRows.length - 1];
| |
| headers = Array.from(lastHeaderRow.querySelectorAll('th')).map(th => th.textContent.trim());
| |
| }
| |
|
| |
| // Para cada linha da tabela, adiciona atributos data-label às células
| |
| const rows = table.querySelectorAll('tr');
| |
|
| |
| // Começa a partir da primeira linha após os cabeçalhos
| |
| // Se estamos em uma tabela sem thead ou com th, começamos nas linhas de tbody
| |
| // Se tabela tiver thead, ignoramos as linhas de cabeçalho
| |
| let startRow = 0;
| |
| if (table.querySelector('thead')) {
| |
| startRow = table.querySelectorAll('thead tr').length;
| |
| } else if (headers.length > 0 && table.querySelectorAll('th').length > 0) {
| |
| // Se não tem thead mas tem th, assumimos primeira linha como cabeçalho
| |
| startRow = 1;
| |
| }
| |
|
| |
| for (let i = startRow; i < rows.length; i++) {
| |
| const cells = rows[i].querySelectorAll('td');
| |
| cells.forEach((cell, index) => {
| |
| if (index < headers.length && headers[index]) {
| |
| cell.setAttribute('data-label', headers[index]);
| |
| }
| |
| });
| |
| }
| |
| });
| |
| }
| |
|
| |
| // Executa quando o DOM estiver pronto
| |
| if (document.readyState === 'loading') {
| |
| document.addEventListener('DOMContentLoaded', makeTablesResponsive);
| |
| } else {
| |
| makeTablesResponsive();
| |
| }
| |
|
| |
| // Verifica novamente após o carregamento da página (para conteúdo carregado dinamicamente)
| |
| window.addEventListener('load', makeTablesResponsive);
| |
|
| |
| // Para lidar com conteúdo adicionado dinamicamente (como em edições AJAX)
| |
| // Observe mutações no DOM
| |
| if (typeof MutationObserver !== 'undefined') {
| |
| const observer = new MutationObserver(function(mutations) {
| |
| mutations.forEach(function(mutation) {
| |
| if (mutation.addedNodes.length) {
| |
| makeTablesResponsive();
| |
| }
| |
| });
| |
| });
| |
|
| |
| // Observe mudanças no corpo do documento
| |
| observer.observe(document.body, { childList: true, subtree: true });
| |
| }
| |
| mw.loader.state({
| |
| "skins.timeless.js": "ready"
| |
| });
| |
| /* | | /* |
| VortanMU - Timeless sidebar behavior (v3) | | VortanMU - Timeless sidebar behavior (v3) |