MediaWiki:Gadget-StickyHeader.js

From Sea of Thieves Wiki
Jump to navigation Jump to search
In other languages: Deutsch • English • Español • Français • Português • 中文
Note: After saving, 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: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Go to Menu → Settings (Opera → Preferences on a Mac) and then to Privacy & security → Clear browsing data → Cached images and files.
var I18n, instance, intersectPoint, isMobile;
var isBoundToTitle = !mw.config.get( 'wgIsMainPage' );


function StickyHeader() {
    this.$search = $( '#p-search' );
    this.$searchParent = this.$search.parent();
    
    this.isVisible = false;
    this.$stickyHeaderCnt = $( '<header id="ark-sticky-header">' )
        .insertAfter( '#wikigg-header' );
    this.$stickyName = $( '<a>' )
        .attr( 'href', mw.config.get( 'wgScriptPath' ) || '/' )
        .prepend( $( '<span class="skull-icon" />' ) )
        .append( $( '<span> ')
            .text( mw.config.get( 'wgSiteName' ) ) )
        .appendTo( $( '<div class="sticky-wiki-name">' )
            .appendTo( this.$stickyHeaderCnt ) );
    this.$stickySearchContainer = $( '<div class="sticky-search-box">' )
        .appendTo( this.$stickyHeaderCnt );
    this.$stickyButtonsCnt = $( '<div class="sticky-buttons">' )
        .appendTo( this.$stickyHeaderCnt );
    
    var $toc = $( '#toc' );
	if ( $toc.length > 0 ) {
		this.$btnToC = $( '<a role="button" id="sticky-toc" class="with-icon">' )
			.attr( 'title', I18n( 'ToC' ) )
			.append( $( '<div class="toc">' )
				.append( $toc.find( '> ul' ).clone( true ) ) )
			.appendTo( this.$stickyButtonsCnt );
	}
    
    this.$btnEdit = this.cloneButton( 'edit', 'Edit' );
    this.$btnTalk = this.cloneButton( 'talk', 'Talk' );
    this.$btnHistory = this.cloneButton( 'history', 'History' );
    
    this.$btnBackToTop = $( '<a role="button" href="#">' )
        .text( I18n( 'BackToTop' ) )
        .appendTo( this.$stickyButtonsCnt );
}


StickyHeader.prototype.cloneButton = function ( id, messageName ) {
    var $ca = $( '#ca-'+id+' > a' );
    if ( $ca.length > 0 ) {
        return $( '<a role="button" class="with-icon" id="sticky-'+id+'">' )
            .attr( {
                href: $ca.attr( 'href' ),
                title: $ca.attr( 'title' )
            } )
            .text( I18n( messageName ) )
            .appendTo( this.$stickyButtonsCnt );
    }
    return null;
}


StickyHeader.prototype.show = function () {
    isVisible = true;
    document.body.classList.add( 'is-sticky-header-visible' );
    this.$search.appendTo( this.$stickySearchContainer );
};
    

StickyHeader.prototype.hide = function () {
    isVisible = false;
    document.body.classList.remove( 'is-sticky-header-visible' );
    this.$search.appendTo( this.$searchParent );
};


function throttle( func, wait ) {
    var context, args, timeout, previous = Date.now() - wait;
    var run = function () {
        timeout = null;
        previous = Date.now();
        func.apply( context, args );
    };
    return function () {
        context = this;
        args = arguments;
        if ( !timeout ) {
            timeout = setTimeout( run, Math.max( wait - ( Date.now() - previous ), 0 ) );
        }
    };
}   


var _handleScroll = throttle( function () {
    var anchor;
    if ( screen.width > 720 ) {
        anchor = intersectPoint.getBoundingClientRect().bottom;
    } else {
        anchor = screen.height * 0.8 - scrollY;
    }
    if ( anchor < 0 ) {
        if ( !instance.isVisible ) {
            instance.show();
        }
    } else {
        instance.hide();
    }
}, 100 );


mw.loader.using( 'site', function () {
    I18n = arkCreateI18nInterface( 'StickyHeader', {
        en: {
            BackToTop: 'Back to top',
            Edit: 'Edit',
            History: 'History',
            Talk: 'Discuss',
            ToC: 'Table of contents'
        },
		fr: {
            BackToTop: 'Haut de page',
            Edit: 'Éditer',
            History: 'Historique',
            Talk: 'Discussion'
        },
        es: {
        	BackToTop: 'Volver arriba',
			Edit: 'Editar',
			History: 'Historique',
			Talk: 'Discusión',
			ToC: 'Tabla de contenido',
        }
    } );

    $( function () {
        // Initialise the sticky header
        instance = new StickyHeader();
        // Get #firstHeading or #mw-content-text as the intersection point
        intersectPoint = $( isBoundToTitle ? '#firstHeading' : '#top' ).get( 0 );
        // Set up the scroll observer
        _handleScroll();
        window.addEventListener( 'scroll', _handleScroll, {
            passive: true
        } );
    } );
} );