User:Udays108/common.js: Difference between revisions
Appearance
No edit summary |
No edit summary |
||
| Line 3: | Line 3: | ||
* Paste into: User:USERNAME/common.js | * Paste into: User:USERNAME/common.js | ||
* Promoted to: MediaWiki:Common.js (by sysop) | * Promoted to: MediaWiki:Common.js (by sysop) | ||
* | |||
* Injects: topbar, page-hero, horizontal nav w/ dropdowns. | |||
* Enhances: TOC styling, smooth scroll, table auto-class. | |||
*/ | */ | ||
| Line 8: | Line 11: | ||
'use strict'; | 'use strict'; | ||
/* ── | /* ── Nav definition (mirrors about.html) ───────────────────── */ | ||
function | var NAV_ITEMS = [ | ||
var | { | ||
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 ───────────────────────────────────────── */ | |||
var | 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' ) || | |||
body. | 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 | |||
var | } ) ); | ||
if ( | } 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. | /* ── 3. Inject Page Hero ────────────────────────────────────── */ | ||
function | function injectPageHero() { | ||
var | // Get page title from MediaWiki's firstHeading | ||
var | 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: '›' } ), | |||
href. | document.createTextNode( titleText ) | ||
) { | ] ); | ||
var | |||
if ( | 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() { | function styleUnstyledTables() { | ||
var tables = document.querySelectorAll( | var tables = document.querySelectorAll( | ||
'.mw-parser-output table:not(.wikitable):not(.infobox):not(.navbox)' | '.mw-parser-output table:not(.wikitable):not(.infobox):not(.navbox):not(.toc)' | ||
); | ); | ||
tables.forEach( function ( | tables.forEach( function ( t ) { t.classList.add( 'wikitable' ); } ); | ||
} | } | ||
/* ── | /* ── Entry point ────────────────────────────────────────────── */ | ||
mw.hook( 'wikipage.content' ).add( function () { | mw.hook( 'wikipage.content' ).add( function () { | ||
injectTopbar(); | |||
injectHorizontalNav(); | |||
injectPageHero(); | |||
rewriteFooter(); | |||
initSmoothScroll(); | initSmoothScroll(); | ||
styleUnstyledTables(); | styleUnstyledTables(); | ||
} ); | } ); | ||
} )(); | } )(); | ||
Revision as of 21:53, 8 May 2026
/**
* 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();
} );
} )();