User:Udays108/common.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.
/**
* BioMicro Center Wiki — Modern UI JavaScript
* Paste into: User:USERNAME/common.js
* Promoted to: MediaWiki:Common.js (by sysop)
*
* Injects: topbar, page-hero, horizontal nav w/ dropdowns.
* Enhances: TOC styling, smooth scroll, table auto-class.
*/
( function () {
'use strict';
/* ── Nav definition (mirrors about.html) ───────────────────── */
var NAV_ITEMS = [
{
label: 'About',
href: 'http://biomicro.mit.edu/about.html',
match: [ 'BioMicroCenter', 'About' ]
},
{
label: 'News',
href: 'http://biomicro.mit.edu/news.html',
match: [ 'News' ],
dropdown: [
{ label: 'Latest News', href: 'http://biomicro.mit.edu/news.html' },
{ label: 'Seminars', href: 'http://biomicro.mit.edu/seminars.html' },
{ label: 'Classes & Training', href: 'https://igb.mit.edu/mini-courses', external: true }
]
},
{
label: 'Services',
href: 'https://bmcwiki.mit.edu/index.php/BioMicroCenter:Assisted_Services',
match: [ 'Assisted_Services', 'Walkup', 'Services' ],
dropdown: [
{ label: 'Walkup', href: 'https://bmcwiki.mit.edu/index.php/BioMicroCenter:Walkup_Instrumentation' },
{ label: 'Assisted', href: 'https://bmcwiki.mit.edu/index.php/BioMicroCenter:Assisted_Services' },
{ label: 'Consumables', href: 'http://biomicro.mit.edu/consumables.html' },
{ label: 'Training', href: 'https://igb.mit.edu/mini-courses', external: true },
{ label: 'Informatics', href: 'https://igb.mit.edu/', external: true }
]
},
{
label: 'Submission',
href: 'http://biomicro.mit.edu/submit.html',
match: [ 'Submission', 'Submit' ],
dropdown: [
{ groupLabel: 'MIT Users' },
{ label: 'Submit a Sample', href: 'http://biomicro.mit.edu/submit.html' },
{ label: 'MIT Pricing', href: 'https://bmcwiki.mit.edu/index.php/MIT:Pricing' },
{ divider: true },
{ groupLabel: 'Non-MIT Users' },
{ label: 'External Submission', href: 'http://biomicro.mit.edu/submit.html' },
{ label: 'External Pricing', href: 'http://biomicro.mit.edu/pricing_v2.html' }
]
},
{
label: 'Staff',
href: 'http://biomicro.mit.edu/staff.html',
match: [ 'Staff' ]
},
{
label: 'Resources',
href: 'https://bmcwiki.mit.edu/index.php/BioMicroCenter:FAQ',
match: [ 'FAQ', 'Resources', 'Forms', 'Acknowledgement' ],
dropdown: [
{ label: 'FAQs', href: 'https://bmcwiki.mit.edu/index.php/BioMicroCenter:FAQ' },
{ label: 'Forms', href: 'http://biomicro.mit.edu/forms.html' },
{ label: 'Grant Support & Pricing', href: 'http://biomicro.mit.edu/pricing_v2.html' },
{ label: 'Acknowledgements', href: 'https://bmcwiki.mit.edu/index.php/BioMicroCenter:Acknowledgement' }
]
}
];
/* ── Helper: create element with attrs & children ──────────── */
function el( tag, attrs, children ) {
var node = document.createElement( tag );
Object.keys( attrs || {} ).forEach( function ( k ) {
if ( k === 'className' ) {
node.className = attrs[ k ];
} else if ( k === 'textContent' ) {
node.textContent = attrs[ k ];
} else if ( k === 'innerHTML' ) {
node.innerHTML = attrs[ k ];
} else {
node.setAttribute( k, attrs[ k ] );
}
} );
( children || [] ).forEach( function ( c ) {
if ( c ) node.appendChild( c );
} );
return node;
}
/* ── 1. Inject Topbar ───────────────────────────────────────── */
function injectTopbar() {
var topbar = el( 'div', { className: 'bmc-topbar' }, [
el( 'div', { className: 'bmc-topbar-inner' }, [
el( 'a', { href: 'mailto:biomicro@mit.edu', textContent: 'biomicro@mit.edu' } ),
el( 'span', { textContent: '|' } ),
document.createTextNode( '617-715-4533' ),
el( 'span', { textContent: '|' } ),
document.createTextNode( 'Building 68-322' )
] )
] );
// Insert before the MediaWiki header element
var mwHead = document.getElementById( 'mw-head' ) ||
document.querySelector( '.vector-header' );
if ( mwHead && mwHead.parentNode ) {
mwHead.parentNode.insertBefore( topbar, mwHead );
} else {
document.body.insertBefore( topbar, document.body.firstChild );
}
// Adjust sticky header top offset to account for topbar height
var topbarH = topbar.offsetHeight;
var style = document.createElement( 'style' );
style.textContent =
'#mw-head, .vector-header, .vector-header-container { top: ' + topbarH + 'px !important; }' +
'.bmc-page-hero { margin-top: 0; }';
document.head.appendChild( style );
}
/* ── 2. Inject Horizontal Nav ───────────────────────────────── */
function buildNavItem( item, currentPage ) {
var li = document.createElement( 'li' );
// Check if this nav item is active
var isActive = ( item.match || [] ).some( function ( m ) {
return currentPage.indexOf( m ) !== -1;
} );
if ( isActive ) li.classList.add( 'bmc-active' );
var link = el( 'a', { href: item.href, textContent: item.label } );
li.appendChild( link );
if ( item.dropdown && item.dropdown.length ) {
li.classList.add( 'bmc-dropdown' );
var menu = el( 'div', { className: 'bmc-dropdown-menu' } );
item.dropdown.forEach( function ( d ) {
if ( d.divider ) {
menu.appendChild( el( 'div', { className: 'bmc-divider' } ) );
} else if ( d.groupLabel ) {
menu.appendChild( el( 'div', {
className: 'bmc-group-label',
textContent: d.groupLabel
} ) );
} else {
var a = el( 'a', { href: d.href, textContent: d.label } );
if ( d.external ) a.setAttribute( 'target', '_blank' );
menu.appendChild( a );
}
} );
li.appendChild( menu );
}
return li;
}
function injectHorizontalNav() {
var currentPage = mw.config.get( 'wgPageName' ) || '';
var ul = document.createElement( 'ul' );
NAV_ITEMS.forEach( function ( item ) {
ul.appendChild( buildNavItem( item, currentPage ) );
} );
var nav = el( 'nav', { className: 'bmc-hnav' }, [ ul ] );
// Find or create the header inner wrapper
var mwHead = document.getElementById( 'mw-head' ) ||
document.querySelector( '.vector-header' );
if ( !mwHead ) return;
// Find or create a flex inner container
var inner = mwHead.querySelector( '.bmc-header-inner' );
if ( !inner ) {
inner = el( 'div', { className: 'bmc-header-inner' } );
// Move existing header children into inner (except topbar)
Array.from( mwHead.childNodes ).forEach( function ( child ) {
inner.appendChild( child );
} );
mwHead.appendChild( inner );
}
// Build logo
var logoLink = el( 'a', {
href: 'https://bmcwiki.mit.edu/index.php/BioMicroCenter',
className: 'bmc-logo'
}, [
el( 'div', { className: 'bmc-logo-mark', textContent: 'BMC' } ),
el( 'div', { className: 'bmc-logo-text' }, [
el( 'span', { className: 'bmc-logo-name', textContent: 'MIT BioMicro Center' } ),
el( 'span', { className: 'bmc-logo-sub', textContent: 'Integrated Genomics Core Facility' } )
] )
] );
// Clear inner and rebuild with logo + nav
inner.innerHTML = '';
inner.appendChild( logoLink );
inner.appendChild( nav );
}
/* ── 3. Inject Page Hero ────────────────────────────────────── */
function injectPageHero() {
// Get page title from MediaWiki's firstHeading
var titleEl = document.getElementById( 'firstHeading' ) ||
document.querySelector( '.mw-first-heading' );
var titleText = titleEl ? titleEl.textContent.trim() : mw.config.get( 'wgTitle' );
// Build breadcrumb
var crumb = el( 'div', { className: 'bmc-breadcrumb' }, [
el( 'a', { href: 'http://biomicro.mit.edu', textContent: 'Home' } ),
el( 'span', { textContent: '›' } ),
document.createTextNode( titleText )
] );
var heroH1 = el( 'h1', { textContent: titleText } );
var heroInner = el( 'div', { className: 'bmc-hero-inner' }, [ crumb, heroH1 ] );
var hero = el( 'div', { className: 'bmc-page-hero' }, [ heroInner ] );
// Insert hero between header and content
var mwHead = document.getElementById( 'mw-head' ) ||
document.querySelector( '.vector-header' );
var content = document.getElementById( 'content' ) ||
document.querySelector( '.mw-body' ) ||
document.querySelector( '.vector-body' );
if ( mwHead && mwHead.parentNode ) {
var ref = mwHead.nextSibling;
mwHead.parentNode.insertBefore( hero, ref );
} else if ( content && content.parentNode ) {
content.parentNode.insertBefore( hero, content );
}
}
/* ── 4. Rewrite Footer ──────────────────────────────────────── */
function rewriteFooter() {
var footer = document.getElementById( 'footer' ) ||
document.querySelector( '.mw-footer' );
if ( !footer ) return;
var inner = el( 'div', { className: 'bmc-footer-inner' }, [
// Col 1: address
el( 'div', {}, [
el( 'h4', { textContent: 'MIT BioMicro Center' } ),
( function () {
var ul = document.createElement( 'ul' );
[ 'Building 68-322', 'Cambridge, MA 02139' ].forEach( function ( t ) {
ul.appendChild( el( 'li', { textContent: t } ) );
} );
var emailLi = document.createElement( 'li' );
emailLi.appendChild( el( 'a', {
href: 'mailto:biomicro@mit.edu',
textContent: 'biomicro@mit.edu'
} ) );
ul.appendChild( emailLi );
ul.appendChild( el( 'li', { textContent: '617-715-4533' } ) );
return ul;
} )()
] ),
// Col 2: services
el( 'div', {}, [
el( 'h4', { textContent: 'Services' } ),
( function () {
var ul = document.createElement( 'ul' );
[
{ label: 'Bulk Sequencing', href: 'https://bmcwiki.mit.edu/index.php/BioMicroCenter:Assisted_Services' },
{ label: 'Single Cell', href: 'https://bmcwiki.mit.edu/index.php/BioMicroCenter:Assisted_Services' },
{ label: 'Spatial Genomics', href: 'https://bmcwiki.mit.edu/index.php/BioMicroCenter:Walkup_Instrumentation' },
{ label: 'Informatics', href: 'https://igb.mit.edu/' }
].forEach( function ( item ) {
var li = document.createElement( 'li' );
li.appendChild( el( 'a', { href: item.href, textContent: item.label } ) );
ul.appendChild( li );
} );
return ul;
} )()
] ),
// Col 3: resources
el( 'div', {}, [
el( 'h4', { textContent: 'Resources' } ),
( function () {
var ul = document.createElement( 'ul' );
[
{ label: 'FAQs', href: 'https://bmcwiki.mit.edu/index.php/BioMicroCenter:FAQ' },
{ label: 'Forms', href: 'http://biomicro.mit.edu/forms.html' },
{ label: 'Grant Support & Pricing', href: 'http://biomicro.mit.edu/pricing_v2.html' },
{ label: 'Acknowledgements', href: 'https://bmcwiki.mit.edu/index.php/BioMicroCenter:Acknowledgement' }
].forEach( function ( item ) {
var li = document.createElement( 'li' );
li.appendChild( el( 'a', { href: item.href, textContent: item.label } ) );
ul.appendChild( li );
} );
return ul;
} )()
] )
] );
var bottom = el( 'div', { className: 'bmc-footer-bottom' }, [
el( 'span', { textContent: '© ' + new Date().getFullYear() + ' MIT BioMicro Center' } ),
el( 'span', {}, [
el( 'a', {
href: 'https://accessibility.mit.edu',
target: '_blank',
textContent: 'Accessibility'
} )
] )
] );
footer.innerHTML = '';
footer.appendChild( inner );
footer.appendChild( bottom );
}
/* ── 5. Smooth Scroll ───────────────────────────────────────── */
function initSmoothScroll() {
var content = document.querySelector( '.mw-parser-output' );
if ( !content ) return;
content.addEventListener( 'click', function ( e ) {
var a = e.target.closest( 'a[href^="#"]' );
if ( !a ) return;
var target = document.getElementById(
decodeURIComponent( a.getAttribute( 'href' ).slice( 1 ) )
);
if ( target ) {
e.preventDefault();
target.scrollIntoView( { behavior: 'smooth', block: 'start' } );
history.pushState( null, '', a.getAttribute( 'href' ) );
}
} );
}
/* ── 6. Auto-style plain tables ─────────────────────────────── */
function styleUnstyledTables() {
var tables = document.querySelectorAll(
'.mw-parser-output table:not(.wikitable):not(.infobox):not(.navbox):not(.toc)'
);
tables.forEach( function ( t ) { t.classList.add( 'wikitable' ); } );
}
/* ── Entry point ────────────────────────────────────────────── */
mw.hook( 'wikipage.content' ).add( function () {
injectTopbar();
injectHorizontalNav();
injectPageHero();
rewriteFooter();
initSmoothScroll();
styleUnstyledTables();
} );
} )();