User:Jeblad/common.js
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)
- Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
- Opera: Press Ctrl-F5.
console.log('inside common.js' );
// keep the previous position, marging, padding, and border
// as this is only a single element there is no need for a more involved structure
var previousLeft;
var previousMarginLeft;
var previousPaddingLeft;
var previousBorderLeft;
var $previousElevated = $([]);
// helper for testing whether set is empty
var isEmpty = function( $elements ) {
console.log('isEmpty: ', $elements.length );
return $elements.length === 0;
};
// helper for testing whether set is good
var isGood = function( $elements ) {
$grandParents = jQuery.merge(
$elements.parent( '.mw-parser-output' ).parent( '#mw-content-text' ),
$elements.parent( 'dl, ul, ol' ).parent( '.mw-parser-output' ).parent( '#mw-content-text' ) );
console.log('isGood: ', $elements.length );
return $grandParents.length !== 0;
};
// helper to set position
// ie. this has side effects
var update = function( $elevated ) {
console.log('inside update' );
// calculate the left offset
var offsetLeft = $elevated.offset().left - mw.util.$content.offset().left;
console.log('offset: ', offsetLeft );
// dispatch on tag name
switch ( $elevated.prop( 'tagName' ).toLowerCase() ) {
case 'dt':
case 'p':
// keep for later
previousLeft = null;
previousMarginLeft = $elevated.css('margin-left');
previousPaddingLeft = $elevated.css('padding-left');
previousBorderLeft = $elevated.css('border-left');
// adjust
$elevated.css('margin-left', 'calc(-'+offsetLeft+'px + 0.4px)');
$elevated.css('padding-left', 'calc('+offsetLeft+'px - 0.4px - 0.18rem)');
$elevated.css('border-left', '0.18rem solid #0645ad');
break;
case 'h1':
case 'h2':
case 'h3':
case 'h4':
case 'h5':
case 'h6':
$before = $elevated.children('::before');
console.log('before: ', $before.length );
// keep for later
previousLeft = $before.css('margin-left');
previousMarginLeft = null;
previousPaddingLeft = null;
previousBorderLeft = $before.css('border-left');
// adjust
$before.css('left', 'calc(-'+offsetLeft+'px + 0.4px)');
$before.css('border-left', '0.18rem solid #0645ad');
break;
}
// keep for later
$previousElevated = $elevated;
};
var addMarker = function() {
console.log('inside on load' );
// get parent block
var $elevated = $(':target').closest('h1,h2,h3,h4,h5,h6,p,dt,dd,li,[style*="display:block"],[style*="display:block"]');
// early return on empty set
if ( isEmpty( $elevated ) ) {
return;
}
// early return on hard to handle cases
// ie. cases where target is inside nested blocks
if ( !isGood( $elevated ) ) {
return;
}
// add class for non-positional styling
$elevated.addClass('mw-elevated-target');
// update the position
update( $elevated );
};
// this is done during the initial load
$(window).on('load', addMarker);
var moveMarker = function() {
console.log('inside on hashchange' );
// reset old values
if ( $previousElevated.length !== 0 ) {
if ( previousLeft !== null ) $previousElevated.css( 'left', previousLeft );
if ( previousMarginLeft !== null ) $previousElevated.css( 'margin-left', previousMarginLeft );
if ( previousPaddingLeft !== null ) $previousElevated.css( 'padding-left', previousPaddingLeft );
if ( previousBorderLeft !== null ) $previousElevated.css( 'border-left', previousBorderLeft );
}
// remove class for non-positional styling
if ( $previousElevated.length !== 0 ) {
$previousElevated.removeClass('mw-elevated-target');
}
// get parent block
$elevated = $(':target').closest('h1,h2,h3,h4,h5,h6,p,dt,dd,li,[style*="display:block"],[style*="display:block"]');
// early return on empty set
if ( isEmpty( $elevated ) ) {
return;
}
// early return on hard to handle cases
// ie. cases where target is inside nested blocks
if ( !isGood( $elevated ) ) {
return;
}
// add class for non-positional styling
$elevated.addClass('mw-elevated-target');
// update the position
update( $elevated );
};
// this is done when the fragment changes without a new load being triggered
$(window).on('hashchange', moveMarker);
// this is done when the window size changes
$(window).on('resize', moveMarker);