MediaWiki:Gadget-Tabber.js: Difference between revisions
Jump to navigation
Jump to search
(Added Tabber Gadget) |
(No difference)
|
Revision as of 10:20, 18 July 2023
// Tabber implementation by User:Endilyn on Gamepedia (used with permission from Endilyn) // This code is protected under the CC BY-NC-SA license. // Source: https://feheroes.gamepedia.com/index.php?title=MediaWiki:Universal.js&oldid=511385 (function() { "use strict"; //OOUI-based tabber mw.hook( "wikipage.content" ).add( function ($content) { var $tabberElements = $content.find( ".nookipedia-tabber" ); if ($tabberElements.length > 0) { //Only load the modules and run the Javascript if there is a nookipedia-tabber in the page. mw.loader.using("oojs-ui-widgets").then(function() { var CSS_END_REGEX = /;\s*$/; var ALLOWED_MW_ATTRIBUTES_TO_ADD = ["dir","id","lang","title","itemid","itemprop","itemref","itemscope","itemtype"]; var uniqueNumber = 0; var INDEX_LAYOUT_OPTIONS = { expanded: false, autoFocus: false }; function isNotWhitespaceOnly(_, ele) { var $ele = $( ele ); return (ele.nodeType !== 3 && ( !$ele.is( "p" ) )) || /\S/.test( $ele.text() ); } var convertToOOUITabber = function(_, ele) { var $ele = $( ele ); var tabPanelLayouts = []; var $rootTabberElement; var indexLayout = new OO.ui.IndexLayout(INDEX_LAYOUT_OPTIONS); var $tabberContents = ( $ele.is( "noscript" ) ? $( $ele.text() ) : $ele.contents() ); var $currentNode; var i = $tabberContents.length-1; var j = i+1; while (i >= 0) { $currentNode = $( $tabberContents.get( i ) ); if ($currentNode.is( ".nookipedia-tab-header" )) { tabPanelLayouts.push(new OO.ui.TabPanelLayout("TB" + uniqueNumber++, { expanded: false, label: $currentNode.contents(), $content: $tabberContents.slice(i+1,j) })); j = i; } i--; } if (j !== 0) { //Add nodes that come before the first tab header into an unlabeled tab var $nodesWithoutHeader = $tabberContents.slice(i+1,j); if ($nodesWithoutHeader.is( isNotWhitespaceOnly )) { //But only if it's not completely whitespace tabPanelLayouts.push(new OO.ui.TabPanelLayout(uniqueNumber++, { expanded: false, $content: $nodesWithoutHeader })); } } i = null; j = null; tabPanelLayouts.reverse(); indexLayout.addTabPanels(tabPanelLayouts); $rootTabberElement = (new OO.ui.PanelLayout( { expanded: false, framed: false, classes: $ele.attr("class").split(/\s+/).filter(function(clas) { return clas !== "nookipedia-tabber"; }), content: [ indexLayout ] })).$element; //If it has one, adds the inline style the non-transformed element has to the new tabber element. Concatenates to the default OOUI style attribute if it exists. $rootTabberElement.attr( "style", function(_, attr) { var s = $ele.attr( "style" ); return attr ? s + (CSS_END_REGEX.test(attr) ? "" : ";") + attr : s; } ); //If it has one, add single-value attributes from the non-transformed element to the new tabber element. Completely replaces the default OOUI ones if they exist. var attributeToCheck; for (i = 0; i < ALLOWED_MW_ATTRIBUTES_TO_ADD.length; i++) { attributeToCheck = ALLOWED_MW_ATTRIBUTES_TO_ADD[i]; $rootTabberElement.attr( attributeToCheck, $ele.attr( attributeToCheck ) ); } i = null; $ele.replaceWith( $rootTabberElement ); }; do { $tabberElements.each( convertToOOUITabber ); $tabberElements = $content.find( ".nookipedia-tabber" ); } while ($tabberElements.length > 0); convertToOOUITabber = null; //Preventing closure memory leak? Hard to tell since OOUI has memory leaks of its own if (location.hash !== "") { // Re-jump to anchor after creating all tabber elements, since the insertion of elements does not accordingly scroll the browser view var temp = location.hash; location.hash = ""; location.hash = temp; } }); } } ); //End tabber })();