Difference between revisions of "MediaWiki:Common.js"
From Future Of Mankind
Line 42: | Line 42: | ||
// do stuff | // do stuff | ||
console.log('btnHideGerman does not exist'); | console.log('btnHideGerman does not exist'); | ||
+ | } | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | /** | ||
+ | * @module referencePreview | ||
+ | */ | ||
+ | |||
+ | import { renderPopup } from '../popup/popup'; | ||
+ | import { createNodeFromTemplate, escapeHTML } from '../templateUtil'; | ||
+ | |||
+ | const templateHTML = ` | ||
+ | <div class="mwe-popups-container"> | ||
+ | <div class="mwe-popups-extract"> | ||
+ | <div class="mwe-popups-scroll"> | ||
+ | <strong class="mwe-popups-title"> | ||
+ | <span class="mw-ui-icon mw-ui-icon-element"></span> | ||
+ | <span class="mwe-popups-title-placeholder"></span> | ||
+ | </strong> | ||
+ | <div class="mw-parser-output"></div> | ||
+ | </div> | ||
+ | <div class="mwe-popups-fade"></div> | ||
+ | </div> | ||
+ | <footer> | ||
+ | <div class="mwe-popups-settings"></div> | ||
+ | </footer> | ||
+ | </div>`; | ||
+ | |||
+ | const LOGGING_SCHEMA = 'event.ReferencePreviewsPopups'; | ||
+ | let isTracking = false; | ||
+ | $( () => { | ||
+ | if ( mw.config.get( 'wgPopupsReferencePreviews' ) && | ||
+ | navigator.sendBeacon && | ||
+ | mw.config.get( 'wgIsArticle' ) && | ||
+ | !isTracking | ||
+ | ) { | ||
+ | isTracking = true; | ||
+ | mw.track( LOGGING_SCHEMA, { action: 'pageview' } ); | ||
+ | } | ||
+ | } ); | ||
+ | |||
+ | /** | ||
+ | * @param {ext.popups.ReferencePreviewModel} model | ||
+ | * @return {JQuery} | ||
+ | */ | ||
+ | export function renderReferencePreview( | ||
+ | model | ||
+ | ) { | ||
+ | const type = model.referenceType || 'generic'; | ||
+ | // The following messages are used here: | ||
+ | // * popups-refpreview-book | ||
+ | // * popups-refpreview-journal | ||
+ | // * popups-refpreview-news | ||
+ | // * popups-refpreview-note | ||
+ | // * popups-refpreview-web | ||
+ | let titleMsg = mw.message( `popups-refpreview-${type}` ); | ||
+ | if ( !titleMsg.exists() ) { | ||
+ | titleMsg = mw.message( 'popups-refpreview-reference' ); | ||
+ | } | ||
+ | |||
+ | const $el = renderPopup( model.type, createNodeFromTemplate( templateHTML ) ); | ||
+ | $el.find( '.mwe-popups-title-placeholder' ) | ||
+ | .replaceWith( escapeHTML( titleMsg.text() ) ); | ||
+ | // The following classes are used here: | ||
+ | // * mw-ui-icon-reference-generic | ||
+ | // * mw-ui-icon-reference-book | ||
+ | // * mw-ui-icon-reference-journal | ||
+ | // * mw-ui-icon-reference-news | ||
+ | // * mw-ui-icon-reference-note | ||
+ | // * mw-ui-icon-reference-web | ||
+ | $el.find( '.mwe-popups-title .mw-ui-icon' ) | ||
+ | .addClass( `mw-ui-icon-reference-${type}` ); | ||
+ | $el.find( '.mw-parser-output' ) | ||
+ | .html( model.extract ); | ||
+ | |||
+ | // Make sure to not destroy existing targets, if any | ||
+ | $el.find( '.mwe-popups-extract a[href][class~="external"]:not([target])' ).each( ( i, a ) => { | ||
+ | a.target = '_blank'; | ||
+ | // Don't let the external site access and possibly manipulate window.opener.location | ||
+ | a.rel = `${a.rel ? `${a.rel} ` : ''}noopener`; | ||
+ | } ); | ||
+ | |||
+ | // We assume elements that benefit from being collapsible are to large for the popup | ||
+ | $el.find( '.mw-collapsible' ).replaceWith( $( '<div>' ) | ||
+ | .addClass( 'mwe-collapsible-placeholder' ) | ||
+ | .append( | ||
+ | $( '<span>' ) | ||
+ | .addClass( 'mw-ui-icon mw-ui-icon-element mw-ui-icon-infoFilled' ), | ||
+ | $( '<div>' ) | ||
+ | .addClass( 'mwe-collapsible-placeholder-label' ) | ||
+ | .text( mw.msg( 'popups-refpreview-collapsible-placeholder' ) ) | ||
+ | ) | ||
+ | ); | ||
+ | |||
+ | // Undo remaining effects from the jquery.tablesorter.js plugin | ||
+ | $el.find( 'table.sortable' ).removeClass( 'sortable jquery-tablesorter' ) | ||
+ | .find( '.headerSort' ).removeClass( 'headerSort' ).attr( { tabindex: null, title: null } ); | ||
+ | |||
+ | // TODO: Remove when not in Beta any more | ||
+ | if ( !mw.config.get( 'wgPopupsReferencePreviewsBetaFeature' ) ) { | ||
+ | // TODO: Do not remove this but move it up into the templateHTML constant! | ||
+ | $el.find( '.mwe-popups-settings' ).append( | ||
+ | $( '<a>' ) | ||
+ | .addClass( 'mwe-popups-settings-icon' ) | ||
+ | .append( | ||
+ | $( '<span>' ) | ||
+ | .addClass( 'mw-ui-icon mw-ui-icon-element mw-ui-icon-small mw-ui-icon-settings' ) | ||
+ | ) | ||
+ | ); | ||
+ | } else { | ||
+ | // Change the styling when there is no content in the footer (to prevent empty space) | ||
+ | $el.find( '.mwe-popups-container' ).addClass( 'footer-empty' ); | ||
+ | } | ||
+ | |||
+ | if ( isTracking ) { | ||
+ | $el.find( '.mw-parser-output' ).on( 'click', 'a', () => { | ||
+ | mw.track( LOGGING_SCHEMA, { | ||
+ | action: 'clickedReferencePreviewsContentLink' | ||
+ | } ); | ||
+ | } ); | ||
+ | } | ||
+ | |||
+ | $el.find( '.mwe-popups-scroll' ).on( 'scroll', function ( e ) { | ||
+ | const element = e.target, | ||
+ | // We are dealing with floating point numbers here when the page is zoomed! | ||
+ | scrolledToBottom = element.scrollTop >= element.scrollHeight - element.clientHeight - 1; | ||
+ | |||
+ | if ( isTracking ) { | ||
+ | if ( !element.isOpenRecorded ) { | ||
+ | mw.track( LOGGING_SCHEMA, { | ||
+ | action: 'poppedOpen', | ||
+ | scrollbarsPresent: element.scrollHeight > element.clientHeight | ||
+ | } ); | ||
+ | element.isOpenRecorded = true; | ||
+ | } | ||
+ | |||
+ | if ( | ||
+ | element.scrollTop > 0 && | ||
+ | !element.isScrollRecorded | ||
+ | ) { | ||
+ | mw.track( LOGGING_SCHEMA, { | ||
+ | action: 'scrolled' | ||
+ | } ); | ||
+ | element.isScrollRecorded = true; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | if ( !scrolledToBottom && element.isScrolling ) { | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | const $extract = $( element ).parent(), | ||
+ | hasHorizontalScroll = element.scrollWidth > element.clientWidth, | ||
+ | scrollbarHeight = element.offsetHeight - element.clientHeight, | ||
+ | hasVerticalScroll = element.scrollHeight > element.clientHeight, | ||
+ | scrollbarWidth = element.offsetWidth - element.clientWidth; | ||
+ | $extract.find( '.mwe-popups-fade' ).css( { | ||
+ | bottom: hasHorizontalScroll ? `${scrollbarHeight}px` : 0, | ||
+ | right: hasVerticalScroll ? `${scrollbarWidth}px` : 0 | ||
+ | } ); | ||
+ | |||
+ | element.isScrolling = !scrolledToBottom; | ||
+ | $extract.toggleClass( 'mwe-popups-fade-out', element.isScrolling ); | ||
+ | } ); | ||
+ | |||
+ | return $el; | ||
} | } |
Revision as of 11:37, 6 March 2023
/* Any JavaScript here will be loaded for all users on every page load. */ //collapsible table column test, based on: https://codepen.io/feger/pen/eDybC $("#btnHideEnglish").click(function(){ console.log ('Hiding first column of table with an id of report'); $( "table#collapsible_report > tbody:last-child > tr > th:first-child" ).toggle(); $( "table#collapsible_report > tbody:last-child > tr > td:first-child" ).toggle(); if ($(this).text() == "Hide English"){ $(this).text("Show English"); } else { $(this).text("Hide English"); } }); $("#btnHideHigh-German").click(function(){ console.log ('Hiding second column of table with an id of report'); $( "table#collapsible_report > tbody:last-child > tr > th:last-child" ).toggle(); $( "table#collapsible_report > tbody:last-child > tr > td:last-child" ).toggle(); if ($(this).text() == "Hide High German"){ $(this).text("Show High German"); } else { $(this).text("Hide High German"); } }); $("#btnHideGerman").click(function(){ console.log ('Hiding second column of table with an id of report'); $( "table#collapsible_report > tbody:last-child > tr > th:last-child" ).toggle(); $( "table#collapsible_report > tbody:last-child > tr > td:last-child" ).toggle(); if ($(this).text() == "Hide German"){ $(this).text("Show German"); } else { $(this).text("Hide German"); } }); // hide the german by default, on page load, but only if the btnHideGerman element exists on the page if (document.getElementById("btnHideGerman")) { console.log('btnHideGerman exists'); //$("#btnHideGerman").click(); } else { // do stuff console.log('btnHideGerman does not exist'); } /** * @module referencePreview */ import { renderPopup } from '../popup/popup'; import { createNodeFromTemplate, escapeHTML } from '../templateUtil'; const templateHTML = ` <div class="mwe-popups-container"> <div class="mwe-popups-extract"> <div class="mwe-popups-scroll"> <strong class="mwe-popups-title"> <span class="mw-ui-icon mw-ui-icon-element"></span> <span class="mwe-popups-title-placeholder"></span> </strong> <div class="mw-parser-output"></div> </div> <div class="mwe-popups-fade"></div> </div> <footer> <div class="mwe-popups-settings"></div> </footer> </div>`; const LOGGING_SCHEMA = 'event.ReferencePreviewsPopups'; let isTracking = false; $( () => { if ( mw.config.get( 'wgPopupsReferencePreviews' ) && navigator.sendBeacon && mw.config.get( 'wgIsArticle' ) && !isTracking ) { isTracking = true; mw.track( LOGGING_SCHEMA, { action: 'pageview' } ); } } ); /** * @param {ext.popups.ReferencePreviewModel} model * @return {JQuery} */ export function renderReferencePreview( model ) { const type = model.referenceType || 'generic'; // The following messages are used here: // * popups-refpreview-book // * popups-refpreview-journal // * popups-refpreview-news // * popups-refpreview-note // * popups-refpreview-web let titleMsg = mw.message( `popups-refpreview-${type}` ); if ( !titleMsg.exists() ) { titleMsg = mw.message( 'popups-refpreview-reference' ); } const $el = renderPopup( model.type, createNodeFromTemplate( templateHTML ) ); $el.find( '.mwe-popups-title-placeholder' ) .replaceWith( escapeHTML( titleMsg.text() ) ); // The following classes are used here: // * mw-ui-icon-reference-generic // * mw-ui-icon-reference-book // * mw-ui-icon-reference-journal // * mw-ui-icon-reference-news // * mw-ui-icon-reference-note // * mw-ui-icon-reference-web $el.find( '.mwe-popups-title .mw-ui-icon' ) .addClass( `mw-ui-icon-reference-${type}` ); $el.find( '.mw-parser-output' ) .html( model.extract ); // Make sure to not destroy existing targets, if any $el.find( '.mwe-popups-extract a[href][class~="external"]:not([target])' ).each( ( i, a ) => { a.target = '_blank'; // Don't let the external site access and possibly manipulate window.opener.location a.rel = `${a.rel ? `${a.rel} ` : ''}noopener`; } ); // We assume elements that benefit from being collapsible are to large for the popup $el.find( '.mw-collapsible' ).replaceWith( $( '<div>' ) .addClass( 'mwe-collapsible-placeholder' ) .append( $( '<span>' ) .addClass( 'mw-ui-icon mw-ui-icon-element mw-ui-icon-infoFilled' ), $( '<div>' ) .addClass( 'mwe-collapsible-placeholder-label' ) .text( mw.msg( 'popups-refpreview-collapsible-placeholder' ) ) ) ); // Undo remaining effects from the jquery.tablesorter.js plugin $el.find( 'table.sortable' ).removeClass( 'sortable jquery-tablesorter' ) .find( '.headerSort' ).removeClass( 'headerSort' ).attr( { tabindex: null, title: null } ); // TODO: Remove when not in Beta any more if ( !mw.config.get( 'wgPopupsReferencePreviewsBetaFeature' ) ) { // TODO: Do not remove this but move it up into the templateHTML constant! $el.find( '.mwe-popups-settings' ).append( $( '<a>' ) .addClass( 'mwe-popups-settings-icon' ) .append( $( '<span>' ) .addClass( 'mw-ui-icon mw-ui-icon-element mw-ui-icon-small mw-ui-icon-settings' ) ) ); } else { // Change the styling when there is no content in the footer (to prevent empty space) $el.find( '.mwe-popups-container' ).addClass( 'footer-empty' ); } if ( isTracking ) { $el.find( '.mw-parser-output' ).on( 'click', 'a', () => { mw.track( LOGGING_SCHEMA, { action: 'clickedReferencePreviewsContentLink' } ); } ); } $el.find( '.mwe-popups-scroll' ).on( 'scroll', function ( e ) { const element = e.target, // We are dealing with floating point numbers here when the page is zoomed! scrolledToBottom = element.scrollTop >= element.scrollHeight - element.clientHeight - 1; if ( isTracking ) { if ( !element.isOpenRecorded ) { mw.track( LOGGING_SCHEMA, { action: 'poppedOpen', scrollbarsPresent: element.scrollHeight > element.clientHeight } ); element.isOpenRecorded = true; } if ( element.scrollTop > 0 && !element.isScrollRecorded ) { mw.track( LOGGING_SCHEMA, { action: 'scrolled' } ); element.isScrollRecorded = true; } } if ( !scrolledToBottom && element.isScrolling ) { return; } const $extract = $( element ).parent(), hasHorizontalScroll = element.scrollWidth > element.clientWidth, scrollbarHeight = element.offsetHeight - element.clientHeight, hasVerticalScroll = element.scrollHeight > element.clientHeight, scrollbarWidth = element.offsetWidth - element.clientWidth; $extract.find( '.mwe-popups-fade' ).css( { bottom: hasHorizontalScroll ? `${scrollbarHeight}px` : 0, right: hasVerticalScroll ? `${scrollbarWidth}px` : 0 } ); element.isScrolling = !scrolledToBottom; $extract.toggleClass( 'mwe-popups-fade-out', element.isScrolling ); } ); return $el; }