MinervaNeue/resources/skins.minerva.scripts/cleanuptemplates.js
Stephen Niedzielski 874d9c9e3b Hygiene: update JSDoc boxed and JQuery types
From TypeScript's do's and don'ts:[0]

  Don’t ever use the types Number, String, Boolean, or Object. These
  types refer to non-primitive boxed objects that are almost never used
  appropriately in JavaScript code.

Although Minerva only uses JSDocs at this time which seemingly doesn't
care about casing[1], we should endeavor to use the proper return types.

This patch lowercases typing to indicate primitive / boxed type as
appropriate.[2] As a special case, function types are uppercased for
compatibility with TypeScript type checking.

Also, JQuery types are of type "JQuery". The global JQuery object's
identifier is "jQuery". This patch uppercases J's where appropriate.

Lastly, replace unsupported type "Integer" with "number" and a comment.

[0] https://www.typescriptlang.org/docs/handbook/declaration-files/do-s-and-don-ts.html#general-types

[1] https://github.com/jsdoc3/jsdoc/issues/1046#issuecomment-126477791

[2] find resources tests -iname \*.js|
    xargs -rd\\n sed -ri '
      s%\{\s*(number|string|boolean|object|null|undefined)%{\L\1%gi;
      s%\{\s*function%{Function%g;
      s%\{\s*jquery%{JQuery%gi;
      s%\{\s*integer\s*\}%{number} An integer.%gi
    '

Change-Id: I6cbac15940e4501aee7ede8f421b77ffd027170d
2018-07-03 11:10:12 -05:00

167 lines
5.0 KiB
JavaScript

( function ( M, $ ) {
var AB = M.require( 'skins.minerva.scripts/AB' ),
isInGroupB = new AB(
'WME.PageIssuesAB',
mw.config.get( 'wgMinervaABSamplingRate', 0 ),
mw.user.sessionId()
).getBucket() === 'B',
Icon = M.require( 'mobile.startup/Icon' );
( function () {
var action = mw.config.get( 'wgAction' ),
page = M.getCurrentPage(),
getIconFromAmbox = M.require( 'skins.minerva.scripts/utils' )
.getIconFromAmbox,
overlayManager = M.require( 'skins.minerva.scripts/overlayManager' ),
CleanupOverlay = M.require( 'mobile.issues/CleanupOverlay' );
/**
* Extract a summary message from a cleanup template generated element that is
* friendly for mobile display.
* @param {object} $box element to extract the message from
* @ignore
* @typedef {object} IssueSummary
* @prop {string} icon HTML string.
* @prop {string} text HTML string.
* @return {IssueSummary}
*/
function extractMessage( $box ) {
var selector = '.mbox-text, .ambox-text',
$container = $( '<div>' );
$box.find( selector ).each( function () {
var contents,
$this = $( this );
// Clean up talk page boxes
$this.find( 'table, .noprint' ).remove();
contents = $this.html();
if ( contents ) {
$( '<p>' ).html( contents ).appendTo( $container );
}
} );
return {
icon: getIconFromAmbox( $box ).toHtmlString(),
text: $container.html()
};
}
/**
* Create a link element that opens the issues overlay.
*
* @ignore
*
* @param {string} labelText The text value of the element
* @return {JQuery}
*/
function createLinkElement( labelText ) {
return $( '<a class="cleanup mw-mf-cleanup"></a>' )
.text( labelText );
}
/**
* Render a banner in a containing element.
* @param {JQuery.Object} $container to render the page issues banner inside.
* @param {string} labelText what the label of the page issues banner should say
* @param {string} headingText the heading of the overlay that is created when the page issues banner is clicked
* @ignore
*/
function createBanner( $container, labelText, headingText ) {
var $learnMore,
selector = 'table.ambox, table.tmbox, table.cmbox, table.fmbox',
$metadata = $container.find( selector ),
issues = [],
$link;
// clean it up a little
$metadata.find( '.NavFrame' ).remove();
$metadata.each( function () {
var issue,
$this = $( this );
if ( $this.find( selector ).length === 0 ) {
issue = extractMessage( $this );
issues.push( issue );
}
} );
if ( isInGroupB ) {
new Icon( {
glyphPrefix: 'minerva',
name: 'warning',
isSmall: true
} ).prependTo( $metadata.find( '.mbox-text' ) );
$learnMore = $( '<span>' )
.addClass( 'ambox-learn-more' )
.text( mw.msg( 'skin-minerva-issue-learn-more' ) );
if ( $( '.mw-collapsible-content' ).length ) {
// e.g. Template:Multiple issues
$learnMore.insertBefore( $metadata.find( '.mw-collapsible-content' ) );
} else {
// e.g. Template:merge from
$learnMore.appendTo( $metadata.find( '.mbox-text-span' ) );
}
$metadata.find( '.mbox-text' ).click( function () {
overlayManager.router.navigate( '#/issues' );
} );
} else {
$link = createLinkElement( labelText );
$link.attr( 'href', '#/issues' );
if ( $metadata.length ) {
$link.insertAfter( $( 'h1#section_0' ) );
$metadata.remove();
}
}
overlayManager.add( /^\/issues$/, function () {
return new CleanupOverlay( {
issues: issues,
headingText: headingText
} );
} );
}
/**
* Scan an element for any known cleanup templates and replace them with a button
* that opens them in a mobile friendly overlay.
* @ignore
*/
function initPageIssues() {
var ns = mw.config.get( 'wgNamespaceNumber' ),
// Categories have no lead section
$container = ns === 14 || isInGroupB ? $( '#bodyContent' ) :
page.getLeadSectionElement();
// set A-B test class.
$( 'html' ).addClass( isInGroupB ? 'issues-group-B' : 'issues-group-A' );
if ( action === 'edit' ) {
$container = $( '#mw-content-text' );
} else if ( $container === null ) {
return;
}
if ( action === 'edit' ) {
createBanner( $container, mw.msg( 'edithelp' ),
mw.msg( 'edithelp' ) );
} else if ( ns === 0 ) {
createBanner( $container, mw.msg( 'mobile-frontend-meta-data-issues' ),
mw.msg( 'mobile-frontend-meta-data-issues-header' ) );
// Create a banner for talk pages (namespace 1) in beta mode to make them more readable.
} else if ( ns === 1 ) {
createBanner( $container, mw.msg( 'mobile-frontend-meta-data-issues-talk' ),
mw.msg( 'mobile-frontend-meta-data-issues-header-talk' ) );
} else if ( ns === 14 ) {
createBanner( $container, mw.msg( 'mobile-frontend-meta-data-issues-categories' ),
mw.msg( 'mobile-frontend-meta-data-issues-header-talk' ) );
}
}
// Setup the issues banner on the page
// Pages which dont exist (id 0) cannot have issues
if ( !page.isMissing ) {
initPageIssues();
}
}() );
}( mw.mobileFrontend, jQuery ) );