/* ShareTooltip Gadget - JS Initialisation, Setup, Events. Shows a Tooltip with multiple ways to share the current page / headline See detailed documentation in Dev/mediawiki deferrable:NO -- Because other scripts are dependent on it */ (function() { // ----- // Setup const innerDom = $( ` Sharing is Caring! Click below = Copy to Clipboard We don\'t use embedded scripts This share button is completely self-hosted by this webserver. No scripts from any of the social networks are embedded on this webserver. See also Social Share Button. `); // URL-parts - for documentation see Dev/mediawiki const urlParts = { 'twitter': ['https://twitter.com/intent/tweet?url=','[data-url]','&via=','[data-project]'], 'facebook': ['https://facebook.com/sharer.php?u=','[data-url]','&text=','[data-title]'], 'telegram': ['https://t.me/share/url?url=','[data-url]'], 'reddit': ['https://reddit.com/submit?url=','[data-url]','&title=','[data-title]'], 'whatsapp': ['https://api.whatsapp.com/send?text=','[data-route]','[if-data-route] ','[data-url]'], 'linkedin': ['https://www.linkedin.com/shareArticle?mini=true&url=','[data-url]','&summary=','[data-title]'], 'ycombinator': ['https://news.ycombinator.com/submitlink?u=','[data-url]','&t=','[data-title]'], 'mastodon': ['https://fosstodon.org/share?message=','[data-route]','[if-data-route] ','[data-url]','&t=','[data-title]'], 'email': ['mailto:?subject=','[data-title]','&body=','[data-url]'], 'copy-plain': ['[data-url]'], 'copy-mediawiki': ['[[', '[data-route]', '[if-data-chapter]#','[data-anchor]', '|', '[data-title]', '[if-data-chapter] chapter ', '[data-chapter]', ']]'], 'copy-markdown': ['[','[data-title]','[if-data-chapter] chapter ','[data-chapter]',' in ','[data-project]',' wiki](','[data-url]',')'], 'copy-phpbb': ['[url=','[data-url]',']','[data-title]','[if-data-chapter] chapter ','[data-chapter]',' in ','[data-project]',' wiki[/url]'], }; const projectMap = { kicksecure: 'Kicksecure', whonix: 'Whonix', }; let urlBaseData = {}; if( window.location.href.match(/\/w\/index\.php/) ) { let search = new URLSearchParams( window.location.search ); search.delete( 'title' ); search.delete( 'stable' ); let searchString = ( Array.from(search.values()).length ? '?' + search.toString() : '' ); urlBaseData.route = ( window.location.href.match(/(?<=title\=)[^#&$]+/g) || [''] )[0]; urlBaseData.url = window.mwDev.data.app.baseUrl.match( /https:\/\/[^\/]+/g ) + '/wiki/' + urlBaseData.route + searchString; } else { urlBaseData.route = ( window.location.href.match(/(?<=\/wiki\/)[^#?$]+/g) || [''] )[0]; urlBaseData.url = window.mwDev.data.app.baseUrl; } // ---------------- // JQuery extension $.fn.shareTooltip = function( action ) { // Only allow 'init' at the moment (extendable later) if( action != 'init' ) return; $(this).each( function() { // Prevent double initialization if( $(this).hasClass('fully-enriched') ) return; let share = $(this); share.append( innerDom.clone() ); // Indicate finalization and display element (important for position calculation) share.addClass('fully-enriched'); // Setup let data = {}; if( share.attr('data-anchor') ) { data.anchor = share.attr('data-anchor'); data.chapter = share.attr('data-anchor'); // Correcting the selector by escaping common document.querySelector-unfriendly characters let domChapter = $( '#' + data.chapter.replace( /([:\/\.])/g, '\\$1' ) ); // If explicit chapter title is set use it as chapter title if( share.attr('data-chapter') ) { data.chapter = share.attr('data-chapter'); } // If id points to an element with just text use that text as the chapter title else if( domChapter.children().length == 0 && domChapter.text() ) { data.chapter = domChapter.text(); } // If all else fails then use the ID and replace '_' with space else { data.chapter = data.chapter.replace( /_/g, ' ' ); } } data.url = urlBaseData.url + ( share.attr('data-anchor') ? '#' + share.attr('data-anchor') : '' ); data.route = urlBaseData.route; data.title = $('html head title').text(); data.project = window.location.href.match(/[^:\/.]+\.[^\/#?]+/g)[0].match(/[^.]+\.[^.]+$/g)[0].match(/^[^.]+/g)[0]; data.project = projectMap[ data.project ] || data.project; // Fill Fields for social and for Copy-to-clipboard share.find('.social,.code-select').each(function() { let platform = $(this).attr('data-social'); let shareText = ''; for( const urlPart of urlParts[ platform ] ) { // If value for this part is truthy then render the rest if( urlPart.match(/\[if-data-/) ) { shareText += ( data[ urlPart.replace( /\[if-data-|\].*/g, '' ) ] ? urlPart.replace( /^[^\]]+\]/g, '' ) : '' ); } // If this part starts with '[data-' then it needs concrete data else if( urlPart.match(/\[data-/) ) { shareText += data[ urlPart.replace( /\[data-|\]/g, '' ) ] || ''; } // In any other case just use the static urlPart string else { shareText += urlPart; } } if( $(this).hasClass('social') ) { share.find('.social[data-social=' + platform + '] a').attr( 'href', encodeURI( shareText ) ); } else { share.find('.code-select[data-social=' + platform + ']').text( shareText ); } }); // Init CodeSelect and fill fields share.find('.code-select').codeSelect('init'); // Positioning (for menus who overflow the screen) let paddingRight = 10; let button = share.find('.button'); let menuOverflow = $(window).width() - button.offset().left - share.find('.menu-wrapper').outerWidth(); if( menuOverflow < 0 ) { share.find('.menu-wrapper').css('left', menuOverflow - paddingRight ); } // Event: Click privacy policy share.find('.info-selfhosted').click( function() { $(this).toggleClass('full-text'); }); }); }; // Enrichment of all Share Tooltip elements $('.share-tooltip').shareTooltip('init'); })(); /* [[Category:MultiWiki]] */