MediaWiki:Gadget-tabbedwindow.js
Appearance
Note: After publishing, you may have to bypass your browser's cache to see the changes.
- Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
- Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
- Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5.
/**
*
* tabbedWindow.js
*
* It embeds an OOUI tabbed window on all pages in the API namespace on MediaWiki.org.
* Each tab of the window contains sample code in a programming language (PHP, Javascript, Python, etc.)
* demonstrating the use of the MediaWiki Action API.
*
* @license magnet:?xt=urn:btih:1f739d935676111cfff4b4693e3816e664797050&dn=gpl-3.0.txt GPL-v3-or-Later
* @licstart The following is the entire license notice for the JavaScript code in this gadget.
*
* Copyright (C) 2019 Jay Prakash <https://meta.wikimedia.org/wiki/User:Jayprakash12345> and contributors
*
* The JavaScript/Gadget code in this page is free software: you can
* redistribute it and/or modify it under the terms of the GNU
* General Public License (GNU GPL) as published by the Free Software
* Foundation, either version 3 of the License, or (at your option)
* any later version. The code is distributed WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU GPL for more details.
*
* As additional permission under GNU GPL version 3 section 7, you
* may distribute non-source (e.g., minimized or compacted) forms of
* that code without the copy of the GNU GPL normally required by
* section 4, provided you include this license notice and a URL
* through which recipients can access the Corresponding Source.
*
* @licend The above is the entire license notice for the JavaScript/Gadget code in this gadget.
*/
( function () {
'use strict';
function trySettingTab( indexLayout, hash ) {
const possiblePanelName = hash.slice( 1 );
const possiblePanel = possiblePanelName && indexLayout.getTabPanel( possiblePanelName );
if ( possiblePanel ) {
indexLayout.setTabPanel( possiblePanelName );
indexLayout.scrollElementIntoView();
}
}
/**
* This function fetches sample code in different programming languages
* from the sub-sections of the section "Sample Code" and places
* them into an OOUI tabbed window.
*
* @param {jQuery} $tabbedWindows
*/
function makeTabWindow( $tabbedWindows ) {
$tabbedWindows.each( ( i, tabbedWindow ) => {
const indexLayout = new OO.ui.IndexLayout( {
expanded: false
} );
const tabs = [];
$( tabbedWindow ).find( 'h3, h4, h5, h6' ).each( ( j, heading ) => {
const $heading = $( heading );
let $headingWrapper, $headingText;
if ( $heading.closest( '.mw-heading' ).length ) {
$headingWrapper = $heading.closest( '.mw-heading' );
$headingText = $heading;
} else if ( $heading.find( '.mw-headline' ).length ) {
$headingWrapper = $heading;
$headingText = $heading.find( '.mw-headline' );
} else {
return;
}
const id = $headingText.attr( 'id' );
const $content = $headingWrapper.nextUntil( 'h3, h4, h5, h6, .mw-heading3, .mw-heading4, .mw-heading5, .mw-heading6' );
// Add the heading the content panel to preserve the original IDs as may be required by other tools (T350840)
$content.prepend( $headingWrapper.hide() );
const tabPanel = new OO.ui.TabPanelLayout( id, {
expanded: false,
label: $headingText.text(),
// Attach the original DOM elements directly by reference.
// This means they move directly in memory instead of getting copied/serialized/parsed as HTML.
// If we didn't move them, but instead copied and re-parsed HTML, then it would disconnect events
// and other live references from gadgets and extensions, which breaks sorting features, responsive gallery, etc.
$content: $content
} );
tabPanel.$element.css( 'padding', '0.5em' );
tabs.push( tabPanel );
} );
indexLayout.addTabPanels( tabs );
const panelLayout = new OO.ui.PanelLayout( {
expanded: false,
framed: true,
content: [ indexLayout ]
} );
$( tabbedWindow ).empty().append( panelLayout.$element );
// Workaround for T348680
mw.hook( 've.deactivationComplete' ).fire();
// Select and scroll to any initially linked item in the address
trySettingTab( indexLayout, location.hash );
// Keep address bar updated with sharable link (also makes forward/backward browser navigation work)
if ( history.replaceState ) {
indexLayout.on( 'set', ( tabPanel ) => {
history.replaceState( null, document.title, '#' + tabPanel.getName() );
} );
}
// Support anchor links on the same page (from table of Contents, or [[#Section]] links)
window.addEventListener( 'hashchange', () => {
trySettingTab( indexLayout, location.hash );
} );
} );
}
mw.hook( 'wikipage.content' ).add( ( $content ) => {
const $tabbedWindows = $content.find( '.mw-gadget-tabbedwindow' );
if ( $tabbedWindows.length > 0 ) {
// Viewing an API subject page with tabs on it, let's make them nice!
mw.loader.using( [ 'oojs-ui-widgets' ] ).then( () => {
makeTabWindow( $tabbedWindows );
} );
}
} );
}() );