![]() |
VOOZH | about |
Note: After saving, you have to bypass your browser's cache to see the changes.
Google Chrome, Firefox, Microsoft Edge, and Safari: Hold down the key and click the Reload toolbar button.
For details and instructions about other browsers, see Wikipedia:Bypass your cache.
/** * Scripts placed here are loaded on both desktop and mobile views. * * Desktop-only scripts should go in [[MediaWiki:Common.js]] * Mobile-only scripts should go in [[MediaWiki:Minerva.js]]. */ (function(){ 'use strict'; /* Variables for interface text used throughout the script, for ease of translating */ vari18n={ // Collapsible elements and page loader hideText:'hide', showText:'show', loadErrorTitle:'An error occurred loading the content' }; /* Fired whenever wiki content is added. (#mw-content-text, live preview, load page, etc.) */ mw.hook('wikipage.content').add(function($wikipageContent){ /** * Collapsible elements * * Add the "collapsible" class to an element and the child element with class "collapsible-content" * (or everything but the header row if a table) will be hidden when the element is collapsed. * * * Add the class "collapsed" to the element to make it start out collapsed. * * Add either "collapsetoggle-left" or "collapsetoggle-inline" to the element to choose the collapse * toggle alignment (defaults to right). * * Add an ID in the format of "collapsible-<x>" to the element to make any element with the class * "collapsetoggle-custom" and a matching class in the format of "collapsible-<x>-toggle" control * the collapsing instead of the standard button. * If the custom toggle contains an element with the "jslink" class, only that will be clickable. */ (function(){ var$collapsibles=$wikipageContent.find('.collapsible'); if(!$collapsibles.length){ return; } var$toggleTemplate=$('<span>').addClass('collapsetoggle').append( '[',$('<span>').addClass('jslink'),']' ); $collapsibles.each(function(){ var$collapsible=$(this); if($collapsible.data('made-collapsible')){ returntrue; } var$children=$collapsible.children(); varshowText=$collapsible.data('expandtext')||i18n.showText; varhideText=$collapsible.data('collapsetext')||i18n.hideText; // If there is no content area, add it if(!$collapsible.is('table')&&!$children.filter('.collapsible-content').length){ if($collapsible.is('tr.collapsible-rows')){ var$collapsibleRows=$collapsible.nextUntil('.collapsible-rows'); if($collapsibleRows.hasClass('collapsible-row')){ $collapsibleRows=$collapsibleRows.filter('collapsible-row'); }else{ $collapsibleRows.addClass('collapsible-row'); } if($collapsible.hasClass('collapsed')&&!$collapsibleRows.hasClass('collapsed')){ $collapsibleRows.addClass('collapsed'); } $collapsible=$collapsible.add($collapsibleRows); }elseif($collapsible.is('tr')){ $children.addClass('collapsible-content'); }else{ $collapsible.wrapInner('<div class="collapsible-content">'); $children=$collapsible.children(); } } var$toggle; varid=$collapsible.attr('id'); if(id&&id.match(/^collapsible-./)){ $toggle=$($wikipageContent[0].getElementsByClassName(id+'-toggle')) .filter('.collapsetoggle-custom').css('visibility','visible'); } // Create and insert the toggle button if there is no custom one if(!$toggle||!$toggle.length){ var$toggleContainer; if($collapsible.is('table')){ var$rows=$children.filter('thead').children(); if(!$rows.length){ $rows=$children.filter('tbody').first().children(); if(!$rows.length){ $rows=$children.filter('tr'); } } $toggleContainer=$rows.first().children().last(); }else{ $toggleContainer=$children.first(); if($toggleContainer.hasClass('collapsible-content')){ $toggleContainer=$collapsible; } } $toggle=$toggleTemplate.clone(); if( $toggleContainer!==$collapsible&&( $collapsible.hasClass('collapsetoggle-inline')|| $collapsible.hasClass('collapse-button-none') )){ $toggleContainer.append($toggle); }else{ $toggleContainer.prepend($toggle); } } var$toggleLink=$toggle.find('.jslink'); if(!$toggleLink.length){ $toggleLink=$toggle; } $toggleLink.attr('tabindex',0).text(hideText); // Find max toggle size, and set its min-width to it varhideWidth=$toggle.width(); $toggleLink.text(showText); varshowWidth=$toggle.width(); if(hideWidth!==showWidth){ $toggle.css('min-width',hideWidth>showWidth?hideWidth:showWidth); } // Set the text back to hide if it's not collapsed to begin with if(!$collapsible.first().hasClass('collapsed')){ $toggleLink.text(hideText); } $toggleLink.on('click keydown',function(e){ // Only trigger on enter press if(e.keyCode&&e.keyCode!==13){ return; } // Don't toggle when clicking buttons or links inside the toggle var$target=$(e.target); if($target.is('button')||$target.is('a')){ return; } $collapsible.toggleClass('collapsed'); if($collapsible.first().hasClass('collapsed')){ $toggleLink.text(showText); }else{ $toggleLink.text(hideText); } // Stop table sorting activating when clicking the link e.stopPropagation(); }); $collapsible.data('made-collapsible',true); }); }()); /** * Page loader * * Allows a page to be downloaded and displayed on demand. * Use with [[Template:LoadPage]] and [[Template:LoadBox]] */ (function(){ var$loadPage=$wikipageContent.find('.load-page'); if(!$loadPage.length){ return; } // We need the spinner to show loading is happening, but we don't want // to have a delay while the module downloads, so we'll load this now, // regardless of if something is clicked mw.loader.load('jquery.spinner'); // Create button starting with hide text // Will be changed to the show text while calculating the maximum button size var$buttonTemplate=$('<span>').addClass('mw-editsection-like load-page-button') .append('[',$('<span>').addClass('jslink').text(i18n.hideText),']'); varextractList=function($contentContainer,listClass){ var$content=$contentContainer.find('.mw-parser-output > ul > li > ul').children(); if(listClass){ $content.addClass(listClass); } return$content; }; $loadPage.each(function(){ var$body=$(this); varpage=$body.data('page'); if(!page){ return; } vartemplate=$body.data('template'); vartreeview=$body.data('treeview'); vartreeviewClass=$body.data('treeviewclass'); var$heading; var$contentContainer; var$content; var$button=$buttonTemplate.clone(); var$buttonLink=$button.find('.jslink'); if(treeview){ $heading=$body; $contentContainer=$('<div>'); }else{ $heading=$body.children().first(); $contentContainer=$body.find('.load-page-content'); } // Add the button $heading.append($button); // Move the edit button to the right spot $contentContainer.find('.mw-editsection, .mw-editsection-like').insertAfter($button); // Find max button width, and set its min-width to it varhideWidth=$button.width(); $buttonLink.text(i18n.showText); varshowWidth=$button.width(); if(hideWidth!==showWidth){ $button.css('min-width',hideWidth>showWidth?hideWidth:showWidth); } $buttonLink.click(function(){ if($body.hasClass('pageloader-contentloaded')){ if($buttonLink.text()===i18n.showText){ if(treeview){ $content.insertAfter($body); }else{ $contentContainer.show(); } $buttonLink.text(i18n.hideText); }else{ if(treeview){ $content.children(".load-page-button").children(".jslink").each(function(){ if($(this).text()===i18n.hideText)this.click(); }); $content.detach(); }else{ $contentContainer.hide(); } $buttonLink.text(i18n.showText); } return; } // See if this was loaded elsewhere before making a request vargotContent; $('.pageloader-contentloaded').each(function(){ var$fLoader=$(this); if($fLoader.data('page')===page&&$fLoader.data('mw-pageloader-content')){ $contentContainer.html($fLoader.data('mw-pageloader-content')).removeClass('noscript'); mw.hook('wikipage.content').fire($contentContainer); if(treeview){ $body.find('.noscript').remove(); $content=extractList($contentContainer,treeviewClass); $content.insertAfter($body); } $buttonLink.text(i18n.hideText); $body.addClass('pageloader-contentloaded'); gotContent=true; returnfalse; } }); if(gotContent){ return; } // Just in-case the spinner module is still not ready yet var$spinner=$(); mw.loader.using('jquery.spinner',function(){ // $spinner will be false if the content somehow loaded before the module did if($spinner){ $spinner=$.createSpinner().addClass('mw-editsection-like') .css('min-width',$button.css('min-width')); $button.hide().after($spinner); } }); varrequestData={ action:'parse', prop:'text|modules|jsconfigvars', redirects:true }; if(template){ requestData.page=page; }else{ requestData.title=mw.config.get('wgPageName'); requestData.text='{'+'{:'+page+'}}'; } newmw.Api().get(requestData).done(function(data){ // Add config and modules if(data.parse.jsconfigvars){ mw.config.set(data.parse.jsconfigvars); } if(data.parse.modules){ mw.loader.load(data.parse.modules.concat( data.parse.modulescripts, data.parse.modulestyles )); } varhtml=data.parse.text['*']; $contentContainer.html(html).removeClass('noscript'); // Resolve self-links if(template){ varcurPage='/'+mw.config.get('wgPageName'); $contentContainer.find('a').each(function(){ var$link=$(this); if($link.attr('href')===curPage){ $link.replaceWith($('<strong>').addClass('selflink').append($link.contents())); } }); html=$contentContainer.html(); } $body.data('mw-pageloader-content',html); // Fire content hook on the new content, running all this stuff again and more :) mw.hook('wikipage.content').fire($contentContainer); if(treeview){ $body.find('.noscript').remove(); $content=extractList($contentContainer,treeviewClass); $content.insertAfter($body); } $spinner.remove(); $spinner=false; $buttonLink.text(i18n.hideText); $button.show(); $body.addClass('pageloader-contentloaded'); }).fail(function(_,error){ $spinner.remove(); $spinner=false; $button.show(); $body.find('.noscript').removeClass('noscript'); varerrorText=''; if(error.textStatus){ errorText=error.textStatus; }elseif(error.error){ errorText=error.error.info; } mw.notify(errorText,{title:i18n.loadErrorTitle,autoHide:false}); }); }); }); }()); /** * Set minimum height for animations to prevent moving the page if the frames * differ in height */ (function(){$(function(){ // Set frames to be visible for measuring height var$animated=$wikipageContent.find('.animated').addClass('animated-visible'); // Group frames per animation varanimateds=[]; $animated.each(function(){ animateds.push({ $:$(this).find('> .animated-subframe').addBack() .find('> *:not(.animated-subframe)'), }); }); // Get highest frame for each animation (if heights differ) $.each(animateds,function(){ varminHeight=0,differentHeights; this.$.each(function(){ varheight=this.offsetHeight; differentHeights=differentHeights||minHeight&&height!==minHeight; minHeight=Math.max(height,minHeight); }); if(differentHeights){ this.height=minHeight; } }); // Set animation to be at least as tall as the tallest frame, // and set the non-active frames to be hidden again $animated.each(function(i){ $(this).css('min-height',animateds[i].height); }).removeClass('animated-visible'); // Load all images in the animation as soon as the animated content becomes visible varanimatedObserver=newIntersectionObserver(function(entries){ entries.forEach(function(entry){ if(entry.isIntersecting&&!entry.target.classList.contains('animated-lazyloaded')){ $(entry.target).find('img').attr('loading','eager'); entry.target.classList.add('animated-lazyloaded'); animatedObserver.unobserve(entry.target); } }); }); // Observe every animation $animated.each(function(){ animatedObserver.observe(this); }); });}()); }); /* End wiki content hook */ /* Fires when DOM is ready */ $(function(){ /** * Element animator * * Cycles through a set of elements (or "frames") on a 2 second timer per frame * Add the "animated" class to the frame containing the elements to animate. * Optionally, add the "animated-active" class to the frame to display first. * Optionally, add the "animated-subframe" class to a frame, and the * "animated-active" class to a subframe within, in order to designate a set of * subframes which will only be cycled every time the parent frame is displayed. * Animations with the "animated-paused" class will be skipped each interval. * * Requires some styling from [[MediaWiki:Gadget-site-styles.css]]. */ (function(){ var$content=$('#mw-content-text'); varadvanceFrame=function(parentElem,parentSelector){ varcurFrame=parentElem.querySelector(parentSelector+' > .animated-active'); $(curFrame).removeClass('animated-active'); var$nextFrame=$(curFrame&&curFrame.nextElementSibling||parentElem.firstElementChild); return$nextFrame.addClass('animated-active'); }; // Set the name of the hidden property varhidden; if(typeofdocument.hidden!=='undefined'){ hidden='hidden'; }elseif(typeofdocument.msHidden!=='undefined'){ hidden='msHidden'; }elseif(typeofdocument.webkitHidden!=='undefined'){ hidden='webkitHidden'; } setInterval(function(){ if(hidden&&document[hidden]){ return; } $content.find('.animated').each(function(){ if($(this).hasClass('animated-paused')){ return; } var$nextFrame=advanceFrame(this,'.animated'); if($nextFrame.hasClass('animated-subframe')){ advanceFrame($nextFrame[0],'.animated-subframe'); } }); },2000); }()); }); /* End DOM ready */ }());