mirror of
https://gerrit.wikimedia.org/r/mediawiki/skins/MinervaNeue
synced 2024-09-23 18:28:34 +00:00
Use eslint rule "no-var": "error" and replace all var
Change-Id: I67acf88e1b8de55054248d7cf8ca622d5772ea6f
This commit is contained in:
parent
a73e2d2d19
commit
effd4fe133
|
@ -35,7 +35,7 @@
|
|||
}
|
||||
],
|
||||
"no-underscore-dangle": "off",
|
||||
"no-var": "off",
|
||||
"no-var": "error",
|
||||
"object-property-newline": "error",
|
||||
"unit-disallowed-list": "off"
|
||||
},
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* a predefined bucket ("unsampled", "control", or "treatment") and starts an AB-test.
|
||||
*/
|
||||
( function ( mwExperiments ) {
|
||||
var bucket = {
|
||||
const bucket = {
|
||||
UNSAMPLED: 'unsampled', // Old treatment: not sampled and not instrumented.
|
||||
CONTROL: 'control', // Old treatment: sampled and instrumented.
|
||||
TREATMENT: 'treatment' // New treatment: sampled and instrumented.
|
||||
|
@ -21,19 +21,18 @@
|
|||
* @constructor
|
||||
*/
|
||||
function AB( config ) {
|
||||
var
|
||||
testName = config.testName,
|
||||
samplingRate = config.samplingRate,
|
||||
sessionId = config.sessionId,
|
||||
test = {
|
||||
name: testName,
|
||||
enabled: !!samplingRate,
|
||||
buckets: {
|
||||
unsampled: 1 - samplingRate,
|
||||
control: samplingRate / 2,
|
||||
treatment: samplingRate / 2
|
||||
}
|
||||
};
|
||||
const testName = config.testName;
|
||||
const samplingRate = config.samplingRate;
|
||||
const sessionId = config.sessionId;
|
||||
const test = {
|
||||
name: testName,
|
||||
enabled: !!samplingRate,
|
||||
buckets: {
|
||||
unsampled: 1 - samplingRate,
|
||||
control: samplingRate / 2,
|
||||
treatment: samplingRate / 2
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the users AB-test bucket.
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
var scrollLeftStyle = null;
|
||||
let scrollLeftStyle = null;
|
||||
|
||||
function testScrollLeftStyle() {
|
||||
var definer, $definer;
|
||||
if ( scrollLeftStyle !== null ) {
|
||||
return scrollLeftStyle;
|
||||
}
|
||||
|
@ -9,12 +8,12 @@ function testScrollLeftStyle() {
|
|||
// Adapted from <https://github.com/othree/jquery.rtl-scroll-type>.
|
||||
// Original code copyright 2012 Wei-Ko Kao, licensed under the MIT License.
|
||||
// Adaptation copied from OO.ui.Element.static.getScrollLeft
|
||||
$definer = $( '<div>' ).attr( {
|
||||
const $definer = $( '<div>' ).attr( {
|
||||
dir: 'rtl',
|
||||
style: 'font-size: 14px; width: 4px; height: 1px; position: absolute; top: -1000px; overflow: scroll;'
|
||||
} ).text( 'ABCD' );
|
||||
$definer.appendTo( document.body );
|
||||
definer = $definer[ 0 ];
|
||||
const definer = $definer[ 0 ];
|
||||
if ( definer.scrollLeft > 0 ) {
|
||||
// Safari, Chrome
|
||||
scrollLeftStyle = 'default';
|
||||
|
@ -36,10 +35,16 @@ function testScrollLeftStyle() {
|
|||
* When tabs are present and one is selected, scroll the selected tab into view.
|
||||
*/
|
||||
function initTabsScrollPosition() {
|
||||
var selectedTab, tabContainer, $tabContainer, maxScrollLeft, leftMostChild, rightMostChild,
|
||||
dir, widthDiff, tabPosition, containerPosition, left, increaseScrollLeft,
|
||||
// eslint-disable-next-line no-jquery/no-global-selector
|
||||
$selectedTab = $( '.minerva__tab.selected' );
|
||||
// eslint-disable-next-line no-jquery/no-global-selector
|
||||
const $selectedTab = $( '.minerva__tab.selected' );
|
||||
if ( $selectedTab.length !== 1 ) {
|
||||
return;
|
||||
}
|
||||
const selectedTab = $selectedTab.get( 0 );
|
||||
const $tabContainer = $selectedTab.closest( '.minerva__tab-container' );
|
||||
const tabContainer = $tabContainer.get( 0 );
|
||||
const maxScrollLeft = tabContainer.scrollWidth - tabContainer.clientWidth;
|
||||
const dir = $tabContainer.css( 'direction' ) || 'ltr';
|
||||
|
||||
/**
|
||||
* Set tabContainer.scrollLeft, with adjustments for browser inconsistencies in RTL
|
||||
|
@ -60,18 +65,10 @@ function initTabsScrollPosition() {
|
|||
tabContainer.scrollLeft = sl;
|
||||
}
|
||||
|
||||
if ( $selectedTab.length !== 1 ) {
|
||||
return;
|
||||
}
|
||||
selectedTab = $selectedTab.get( 0 );
|
||||
$tabContainer = $selectedTab.closest( '.minerva__tab-container' );
|
||||
tabContainer = $tabContainer.get( 0 );
|
||||
maxScrollLeft = tabContainer.scrollWidth - tabContainer.clientWidth;
|
||||
dir = $tabContainer.css( 'direction' ) || 'ltr';
|
||||
leftMostChild = dir === 'ltr' ? tabContainer.firstElementChild : tabContainer.lastElementChild;
|
||||
rightMostChild = dir === 'ltr' ? tabContainer.lastElementChild : tabContainer.firstElementChild;
|
||||
const leftMostChild = dir === 'ltr' ? tabContainer.firstElementChild : tabContainer.lastElementChild;
|
||||
const rightMostChild = dir === 'ltr' ? tabContainer.lastElementChild : tabContainer.firstElementChild;
|
||||
// If the tab is wider than the container (doesn't fit), this value will be negative
|
||||
widthDiff = tabContainer.clientWidth - selectedTab.clientWidth;
|
||||
const widthDiff = tabContainer.clientWidth - selectedTab.clientWidth;
|
||||
|
||||
if ( selectedTab === leftMostChild ) {
|
||||
// The left-most tab is selected. If the tab fits, scroll all the way to the left.
|
||||
|
@ -91,14 +88,15 @@ function initTabsScrollPosition() {
|
|||
}
|
||||
} else {
|
||||
// The selected tab is not the left-most or right-most, it's somewhere in the middle
|
||||
tabPosition = $selectedTab.position();
|
||||
containerPosition = $tabContainer.position();
|
||||
const tabPosition = $selectedTab.position();
|
||||
const containerPosition = $tabContainer.position();
|
||||
// Position of the left edge of $selectedTab relative to the left edge of $tabContainer
|
||||
left = tabPosition.left - containerPosition.left;
|
||||
const left = tabPosition.left - containerPosition.left;
|
||||
// Because the calculations above use the existing .scrollLeft from the browser,
|
||||
// we should not use setScrollLeft() here. Instead, we rely on the fact that scrollLeft
|
||||
// increases to the left in the 'default' and 'negative' modes, and to the right in
|
||||
// the 'reverse' mode, so we can add/subtract a delta to/from scrollLeft accordingly.
|
||||
let increaseScrollLeft;
|
||||
if ( widthDiff >= 0 ) {
|
||||
// The tab fits, center it
|
||||
increaseScrollLeft = left - widthDiff / 2;
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
// implementation where each copy can deviate but deletion is easy. See additional discussion in
|
||||
// T218358 and I95b08e77eece5cd4dae62f6f237d492d6b0fe42b.
|
||||
( function () {
|
||||
var UriUtil = require( './UriUtil.js' );
|
||||
const UriUtil = require( './UriUtil.js' );
|
||||
|
||||
/**
|
||||
* Returns the decoded wiki page title referenced by the passed link as a string when parsable.
|
||||
|
@ -46,11 +46,8 @@
|
|||
* @return {mw.Title|null} A Title or `null`.
|
||||
*/
|
||||
function newFromUri( uri, options ) {
|
||||
var
|
||||
mwUri,
|
||||
regExp,
|
||||
matches,
|
||||
title;
|
||||
let mwUri;
|
||||
let title;
|
||||
|
||||
try {
|
||||
// uri may or may not be a Uri but the Uri constructor accepts a Uri parameter.
|
||||
|
@ -70,11 +67,11 @@
|
|||
|
||||
if ( mwUri.query.title ) {
|
||||
// True if input starts with wgScriptPath.
|
||||
regExp = new RegExp( '^' + mw.util.escapeRegExp( mw.config.get( 'wgScriptPath' ) ) + '/' );
|
||||
const regExp = new RegExp( '^' + mw.util.escapeRegExp( mw.config.get( 'wgScriptPath' ) ) + '/' );
|
||||
|
||||
// URL has a nonempty `title` query parameter like `/w/index.php?title=Foo`. The script
|
||||
// path should match.
|
||||
matches = regExp.test( mwUri.path );
|
||||
const matches = regExp.test( mwUri.path );
|
||||
if ( !matches ) {
|
||||
return null;
|
||||
}
|
||||
|
@ -84,12 +81,12 @@
|
|||
} else {
|
||||
// True if input starts with wgArticlePath and ends with a nonempty page title. The
|
||||
// first matching group (index 1) is the page title.
|
||||
regExp = new RegExp( '^' + mw.util.escapeRegExp( mw.config.get( 'wgArticlePath' ) ).replace( '\\$1', '(.+)' ) );
|
||||
const regExp = new RegExp( '^' + mw.util.escapeRegExp( mw.config.get( 'wgArticlePath' ) ).replace( '\\$1', '(.+)' ) );
|
||||
|
||||
// No title query parameter is present so the URL may be "pretty" like `/wiki/Foo`.
|
||||
// `Uri.path` should not contain query parameters or a fragment, as is assumed in
|
||||
// `Uri.getRelativePath()`. Try to isolate the title.
|
||||
matches = regExp.exec( mwUri.path );
|
||||
const matches = regExp.exec( mwUri.path );
|
||||
if ( !matches || !matches[ 1 ] ) {
|
||||
return null;
|
||||
}
|
||||
|
@ -128,7 +125,7 @@
|
|||
* @return {boolean} True if uri has no query parameters or only known parameters for reading.
|
||||
*/
|
||||
function isReadOnlyUri( uri ) {
|
||||
var length = Object.keys( uri.query ).length;
|
||||
const length = Object.keys( uri.query ).length;
|
||||
return length === ( ( 'oldid' in uri.query ? 1 : 0 ) + ( 'title' in uri.query ? 1 : 0 ) );
|
||||
}
|
||||
|
||||
|
|
|
@ -3,13 +3,13 @@
|
|||
* @return {Object} of arrays with mandatory class names for list item elements.
|
||||
*/
|
||||
function getClassesForItem( $item ) {
|
||||
const $parent = $item.parent(),
|
||||
// eslint-disable-next-line no-jquery/no-class-state
|
||||
isPageActionList = $parent.hasClass( 'page-actions-menu__list' ),
|
||||
// eslint-disable-next-line no-jquery/no-class-state
|
||||
isTabContainer = $parent.hasClass( 'minerva__tab-container' ),
|
||||
// eslint-disable-next-line no-jquery/no-class-state
|
||||
isToggleList = $parent.hasClass( 'toggle-list__list' );
|
||||
const $parent = $item.parent();
|
||||
// eslint-disable-next-line no-jquery/no-class-state
|
||||
const isPageActionList = $parent.hasClass( 'page-actions-menu__list' );
|
||||
// eslint-disable-next-line no-jquery/no-class-state
|
||||
const isTabContainer = $parent.hasClass( 'minerva__tab-container' );
|
||||
// eslint-disable-next-line no-jquery/no-class-state
|
||||
const isToggleList = $parent.hasClass( 'toggle-list__list' );
|
||||
|
||||
if ( isToggleList ) {
|
||||
return {
|
||||
|
@ -52,8 +52,8 @@ function getClassesForItem( $item ) {
|
|||
* @param {string|undefined} id for icon
|
||||
*/
|
||||
function insertIcon( $link, id ) {
|
||||
var icon = document.createElement( 'span' ),
|
||||
classes = 'minerva-icon';
|
||||
const icon = document.createElement( 'span' );
|
||||
let classes = 'minerva-icon';
|
||||
if ( id ) {
|
||||
classes += ` minerva-icon-portletlink-${ id }`;
|
||||
// FIXME: Please remove when following URL returns zero results:
|
||||
|
@ -69,16 +69,14 @@ function insertIcon( $link, id ) {
|
|||
* @param {Object} data
|
||||
*/
|
||||
function hookHandler( listItem, data ) {
|
||||
var $item, $a, classes,
|
||||
id = data.id;
|
||||
|
||||
if ( listItem && !listItem.dataset.minervaPortlet ) {
|
||||
$item = $( listItem );
|
||||
const id = data.id;
|
||||
const $item = $( listItem );
|
||||
|
||||
// add the corresponding classes
|
||||
classes = getClassesForItem( $item );
|
||||
const classes = getClassesForItem( $item );
|
||||
$item.addClass( classes.li );
|
||||
$a = $item.find( 'a' );
|
||||
const $a = $item.find( 'a' );
|
||||
$a.addClass( classes.a );
|
||||
$item.find( 'a > span' ).addClass( classes.span );
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
var mobile = require( 'mobile.startup' ),
|
||||
drawers = require( './drawers.js' ),
|
||||
CtaDrawer = mobile.CtaDrawer;
|
||||
const mobile = require( 'mobile.startup' );
|
||||
const drawers = require( './drawers.js' );
|
||||
const CtaDrawer = mobile.CtaDrawer;
|
||||
|
||||
/**
|
||||
* Initialize red links call-to-action
|
||||
|
@ -23,7 +23,7 @@ var mobile = require( 'mobile.startup' ),
|
|||
*/
|
||||
function initRedlinksCta( $redLinks ) {
|
||||
$redLinks.on( 'click', function ( ev ) {
|
||||
var drawerOptions = {
|
||||
const drawerOptions = {
|
||||
progressiveButton: {
|
||||
progressive: true,
|
||||
label: mw.msg( 'mobile-frontend-editor-redlink-create' ),
|
||||
|
@ -53,7 +53,7 @@ function initRedlinksCta( $redLinks ) {
|
|||
* @param {jQuery} $watchstar
|
||||
*/
|
||||
function initWatchstarCta( $watchstar ) {
|
||||
var watchCtaDrawer;
|
||||
let watchCtaDrawer;
|
||||
// show a CTA for anonymous users
|
||||
$watchstar.on( 'click', function ( ev ) {
|
||||
if ( !watchCtaDrawer ) {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
( function ( track ) {
|
||||
var MAX_PRINT_TIMEOUT = 3000,
|
||||
printSetTimeoutReference = 0,
|
||||
mobile = require( 'mobile.startup' );
|
||||
const MAX_PRINT_TIMEOUT = 3000;
|
||||
let printSetTimeoutReference = 0;
|
||||
const mobile = require( 'mobile.startup' );
|
||||
|
||||
/**
|
||||
* Helper function to detect iOs
|
||||
|
@ -22,7 +22,7 @@
|
|||
* @return {number|boolean} Integer version number, or false if not found
|
||||
*/
|
||||
function getAndroidVersion( userAgent ) {
|
||||
var match = userAgent.toLowerCase().match( /android\s(\d\.]*)/ );
|
||||
const match = userAgent.toLowerCase().match( /android\s(\d\.]*)/ );
|
||||
return match ? parseInt( match[ 1 ] ) : false;
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,7 @@
|
|||
* @return {number|boolean} Integer version number, or false if not found
|
||||
*/
|
||||
function getChromeVersion( userAgent ) {
|
||||
var match = userAgent.toLowerCase().match( /chrom(e|ium)\/(\d+)\./ );
|
||||
const match = userAgent.toLowerCase().match( /chrom(e|ium)\/(\d+)\./ );
|
||||
return match ? parseInt( match[ 2 ] ) : false;
|
||||
}
|
||||
|
||||
|
@ -50,8 +50,8 @@
|
|||
* @return {boolean}
|
||||
*/
|
||||
function isAvailable( windowObj, page, userAgent, supportedNamespaces ) {
|
||||
var androidVersion = getAndroidVersion( userAgent ),
|
||||
chromeVersion = getChromeVersion( userAgent );
|
||||
const androidVersion = getAndroidVersion( userAgent );
|
||||
const chromeVersion = getChromeVersion( userAgent );
|
||||
|
||||
if ( typeof window.print !== 'function' ) {
|
||||
// T309591: No window.print support
|
||||
|
@ -86,7 +86,7 @@
|
|||
* @param {Function} [loadAllImagesInPage]
|
||||
*/
|
||||
function onClick( portletItem, spinner, loadAllImagesInPage ) {
|
||||
var icon = portletItem.querySelector( '.minerva-icon--download' );
|
||||
const icon = portletItem.querySelector( '.minerva-icon--download' );
|
||||
function doPrint() {
|
||||
printSetTimeoutReference = clearTimeout( printSetTimeoutReference );
|
||||
track( 'minerva.downloadAsPDF', {
|
||||
|
@ -131,12 +131,10 @@
|
|||
* @return {jQuery|null}
|
||||
*/
|
||||
function downloadPageAction( page, supportedNamespaces, windowObj, overflowList ) {
|
||||
var
|
||||
portletLink, iconElement,
|
||||
spinner = ( overflowList ) ? mobile.spinner( {
|
||||
label: '',
|
||||
isIconOnly: false
|
||||
} ) : mobile.spinner();
|
||||
const spinner = ( overflowList ) ? mobile.spinner( {
|
||||
label: '',
|
||||
isIconOnly: false
|
||||
} ) : mobile.spinner();
|
||||
|
||||
if (
|
||||
isAvailable(
|
||||
|
@ -146,7 +144,7 @@
|
|||
) {
|
||||
// FIXME: Use p-views when cache has cleared.
|
||||
const actionID = document.querySelector( '#p-views' ) ? 'p-views' : 'page-actions';
|
||||
portletLink = mw.util.addPortletLink(
|
||||
const portletLink = mw.util.addPortletLink(
|
||||
overflowList ? 'page-actions-overflow' : actionID,
|
||||
'#',
|
||||
mw.msg( 'minerva-download' ),
|
||||
|
@ -162,7 +160,7 @@
|
|||
portletLink.addEventListener( 'click', function () {
|
||||
onClick( portletLink, spinner, mobile.loadAllImagesInPage );
|
||||
} );
|
||||
iconElement = portletLink.querySelector( '.minerva-icon' );
|
||||
const iconElement = portletLink.querySelector( '.minerva-icon' );
|
||||
if ( iconElement ) {
|
||||
iconElement.classList.add( 'minerva-icon--download' );
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
var $drawerContainer = $( document.body ),
|
||||
BODY_CLASS_SCROLL_LOCKED = 'has-drawer--with-scroll-locked';
|
||||
const $drawerContainer = $( document.body );
|
||||
const BODY_CLASS_SCROLL_LOCKED = 'has-drawer--with-scroll-locked';
|
||||
|
||||
/**
|
||||
* Discard a drawer from display on the page.
|
||||
|
|
|
@ -40,12 +40,12 @@ module.exports = function () {
|
|||
return;
|
||||
}
|
||||
|
||||
var el = ev.target.closest( PageHTMLParser.THUMB_SELECTOR );
|
||||
const el = ev.target.closest( PageHTMLParser.THUMB_SELECTOR );
|
||||
if ( !el ) {
|
||||
return;
|
||||
}
|
||||
|
||||
var thumb = currentPageHTMLParser.getThumbnail( $( el ) );
|
||||
const thumb = currentPageHTMLParser.getThumbnail( $( el ) );
|
||||
if ( !thumb ) {
|
||||
return;
|
||||
}
|
||||
|
@ -82,7 +82,7 @@ module.exports = function () {
|
|||
function initButton() {
|
||||
// This catches language selectors in page actions and in secondary actions (e.g. Main Page)
|
||||
// eslint-disable-next-line no-jquery/no-global-selector
|
||||
var $primaryBtn = $( '.language-selector' );
|
||||
const $primaryBtn = $( '.language-selector' );
|
||||
|
||||
if ( $primaryBtn.length ) {
|
||||
// We only bind the click event to the first language switcher in page
|
||||
|
@ -160,21 +160,17 @@ module.exports = function () {
|
|||
* @param {jQuery} $lastModifiedLink
|
||||
*/
|
||||
function initHistoryLink( $lastModifiedLink ) {
|
||||
var delta, $msg, $bar,
|
||||
ts, username, gender;
|
||||
|
||||
ts = $lastModifiedLink.data( 'timestamp' );
|
||||
username = $lastModifiedLink.data( 'user-name' ) || false;
|
||||
gender = $lastModifiedLink.data( 'user-gender' );
|
||||
|
||||
const ts = $lastModifiedLink.data( 'timestamp' );
|
||||
if ( ts ) {
|
||||
delta = time.getTimeAgoDelta( parseInt( ts, 10 ) );
|
||||
const username = $lastModifiedLink.data( 'user-name' ) || false;
|
||||
const gender = $lastModifiedLink.data( 'user-gender' );
|
||||
const delta = time.getTimeAgoDelta( parseInt( ts, 10 ) );
|
||||
if ( time.isRecent( delta ) ) {
|
||||
$bar = $lastModifiedLink.closest( '.last-modified-bar' );
|
||||
const $bar = $lastModifiedLink.closest( '.last-modified-bar' );
|
||||
$bar.addClass( 'active' );
|
||||
}
|
||||
|
||||
$msg = $( '<span>' )
|
||||
const $msg = $( '<span>' )
|
||||
// The new element should maintain the non-js element's CSS classes.
|
||||
.attr( 'class', $lastModifiedLink.attr( 'class' ) )
|
||||
.html(
|
||||
|
@ -192,15 +188,14 @@ module.exports = function () {
|
|||
* @param {jQuery.Event} ev
|
||||
*/
|
||||
function amcHistoryClickHandler( ev ) {
|
||||
var
|
||||
self = this,
|
||||
amcOutreach = ms.amcOutreach,
|
||||
amcCampaign = amcOutreach.loadCampaign(),
|
||||
onDismiss = function () {
|
||||
notifyOnPageReload( mw.msg( 'mobile-frontend-amc-outreach-dismissed-message' ) );
|
||||
window.location = self.href;
|
||||
},
|
||||
drawer = amcCampaign.showIfEligible( amcOutreach.ACTIONS.onHistoryLink, onDismiss, currentPage.title, 'action=history' );
|
||||
const self = this;
|
||||
const amcOutreach = ms.amcOutreach;
|
||||
const amcCampaign = amcOutreach.loadCampaign();
|
||||
const onDismiss = function () {
|
||||
notifyOnPageReload( mw.msg( 'mobile-frontend-amc-outreach-dismissed-message' ) );
|
||||
window.location = self.href;
|
||||
};
|
||||
const drawer = amcCampaign.showIfEligible( amcOutreach.ACTIONS.onHistoryLink, onDismiss, currentPage.title, 'action=history' );
|
||||
|
||||
if ( drawer ) {
|
||||
ev.preventDefault();
|
||||
|
@ -272,12 +267,10 @@ module.exports = function () {
|
|||
* @param {jQuery} [$tagline]
|
||||
*/
|
||||
function initRegistrationDate( $tagline ) {
|
||||
var msg, ts;
|
||||
|
||||
ts = $tagline.data( 'userpage-registration-date' );
|
||||
const ts = $tagline.data( 'userpage-registration-date' );
|
||||
|
||||
if ( ts ) {
|
||||
msg = time.getRegistrationMessage( ts, $tagline.data( 'userpage-gender' ) );
|
||||
const msg = time.getRegistrationMessage( ts, $tagline.data( 'userpage-gender' ) );
|
||||
$tagline.text( msg );
|
||||
}
|
||||
}
|
||||
|
@ -318,9 +311,8 @@ module.exports = function () {
|
|||
* @return {boolean}
|
||||
*/
|
||||
function isUserUri( url ) {
|
||||
var
|
||||
title = TitleUtil.newFromUri( url ),
|
||||
namespace = title ? title.getNamespaceId() : undefined;
|
||||
const title = TitleUtil.newFromUri( url );
|
||||
const namespace = title ? title.getNamespaceId() : undefined;
|
||||
return namespace === namespaceIDs.user;
|
||||
}
|
||||
|
||||
|
@ -334,7 +326,7 @@ module.exports = function () {
|
|||
// Filter out non-User namespace pages.
|
||||
return isUserUri( element.href );
|
||||
} ).each( function ( _, element ) {
|
||||
var uri = new mw.Uri( element.href );
|
||||
const uri = new mw.Uri( element.href );
|
||||
if ( uri.query.action !== 'edit' ) {
|
||||
// Nothing to strip.
|
||||
return;
|
||||
|
@ -371,12 +363,11 @@ module.exports = function () {
|
|||
}
|
||||
|
||||
$( function () {
|
||||
var
|
||||
// eslint-disable-next-line no-jquery/no-global-selector
|
||||
$watch = $( '#page-actions-watch' ),
|
||||
toolbarElement = document.querySelector( Toolbar.selector ),
|
||||
userMenu = document.querySelector( '.minerva-user-menu' ), // See UserMenuDirector.
|
||||
navigationDrawer = document.querySelector( '.navigation-drawer' );
|
||||
// eslint-disable-next-line no-jquery/no-global-selector
|
||||
const $watch = $( '#page-actions-watch' );
|
||||
const toolbarElement = document.querySelector( Toolbar.selector );
|
||||
const userMenu = document.querySelector( '.minerva-user-menu' ); // See UserMenuDirector.
|
||||
const navigationDrawer = document.querySelector( '.navigation-drawer' );
|
||||
|
||||
// The `minerva-animations-ready` class can be used by clients to prevent unwanted
|
||||
// CSS transitions from firing on page load in some browsers (see
|
||||
|
@ -388,7 +379,7 @@ module.exports = function () {
|
|||
|
||||
// eslint-disable-next-line no-jquery/no-global-selector
|
||||
$( '.mw-mf-page-center__mask' ).on( 'click', function ( ev ) {
|
||||
var path = router.getPath();
|
||||
const path = router.getPath();
|
||||
// avoid jumping to the top of the page and polluting history by avoiding the
|
||||
// resetting of the hash unless the hash is being utilised (T237015).
|
||||
if ( !path ) {
|
||||
|
@ -423,7 +414,7 @@ module.exports = function () {
|
|||
}
|
||||
if ( navigationDrawer ) {
|
||||
ToggleList.bind( window, navigationDrawer );
|
||||
var navigationDrawerMask = navigationDrawer.querySelector( '.main-menu-mask' );
|
||||
const navigationDrawerMask = navigationDrawer.querySelector( '.main-menu-mask' );
|
||||
// The 'for' attribute is used to close the drawer when the mask is clicked without JS
|
||||
// Since we are using JS to enhance the drawer behavior, we need to
|
||||
// remove the attribute to prevent the drawer from being toggled twice
|
||||
|
@ -454,12 +445,12 @@ module.exports = function () {
|
|||
}
|
||||
|
||||
// Mutate TOC.
|
||||
var $toctitle = $container.find( '.toctitle' );
|
||||
const $toctitle = $container.find( '.toctitle' );
|
||||
$( '<span>' ).addClass( 'toc-title-icon' ).prependTo( $toctitle );
|
||||
$( '<span>' ).addClass( 'toc-title-state-icon' ).appendTo( $toctitle );
|
||||
|
||||
// Init red links.
|
||||
var $redLinks = currentPageHTMLParser.getRedLinks();
|
||||
const $redLinks = currentPageHTMLParser.getRedLinks();
|
||||
ctaDrawers.initRedlinksCta(
|
||||
$redLinks.filter( function ( _, element ) {
|
||||
// Filter out local User namespace pages.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
var BODY_NOTIFICATIONS_REVEAL_CLASS = 'navigation-enabled secondary-navigation-enabled';
|
||||
const BODY_NOTIFICATIONS_REVEAL_CLASS = 'navigation-enabled secondary-navigation-enabled';
|
||||
|
||||
/**
|
||||
* Wire up the main menu
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
var drawers = require( './drawers.js' );
|
||||
const drawers = require( './drawers.js' );
|
||||
|
||||
/*
|
||||
* Warn people if they're trying to switch to desktop but have cookies disabled.
|
||||
|
@ -52,24 +52,23 @@ module.exports = function ( amcOutreach, currentPage ) {
|
|||
* @return {boolean|undefined}
|
||||
*/
|
||||
function amcDesktopClickHandler( ev ) {
|
||||
var
|
||||
self = this,
|
||||
executeWrappedEvent = function () {
|
||||
if ( desktopViewClick() === false ) {
|
||||
return false;
|
||||
}
|
||||
const self = this;
|
||||
const executeWrappedEvent = function () {
|
||||
if ( desktopViewClick() === false ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
window.location = self.href;
|
||||
},
|
||||
amcCampaign = amcOutreach.loadCampaign(),
|
||||
onDismiss = function () {
|
||||
executeWrappedEvent();
|
||||
},
|
||||
drawer = amcCampaign.showIfEligible(
|
||||
amcOutreach.ACTIONS.onDesktopLink,
|
||||
onDismiss,
|
||||
currentPage.title
|
||||
);
|
||||
window.location = self.href;
|
||||
};
|
||||
const amcCampaign = amcOutreach.loadCampaign();
|
||||
const onDismiss = function () {
|
||||
executeWrappedEvent();
|
||||
};
|
||||
const drawer = amcCampaign.showIfEligible(
|
||||
amcOutreach.ACTIONS.onDesktopLink,
|
||||
onDismiss,
|
||||
currentPage.title
|
||||
);
|
||||
|
||||
if ( drawer ) {
|
||||
ev.preventDefault();
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
/** @typedef {Object.<string, IssueSummary[]>} IssueSummaryMap */
|
||||
|
||||
var PageHTMLParser = require( 'mobile.startup' ).PageHTMLParser,
|
||||
KEYWORD_ALL_SECTIONS = 'all',
|
||||
config = mw.config,
|
||||
NS_MAIN = 0,
|
||||
NS_CATEGORY = 14,
|
||||
CURRENT_NS = config.get( 'wgNamespaceNumber' ),
|
||||
features = mw.config.get( 'wgMinervaFeatures', {} ),
|
||||
pageIssuesParser = require( './parser.js' ),
|
||||
pageIssuesOverlay = require( './overlay/pageIssuesOverlay.js' ),
|
||||
pageIssueFormatter = require( './page/pageIssueFormatter.js' ),
|
||||
// When the query string flag is set force on new treatment.
|
||||
// When wgMinervaPageIssuesNewTreatment is the default this line can be removed.
|
||||
QUERY_STRING_FLAG = mw.util.getParamValue( 'minerva-issues' ),
|
||||
newTreatmentEnabled = features.pageIssues || QUERY_STRING_FLAG;
|
||||
const PageHTMLParser = require( 'mobile.startup' ).PageHTMLParser;
|
||||
const KEYWORD_ALL_SECTIONS = 'all';
|
||||
const config = mw.config;
|
||||
const NS_MAIN = 0;
|
||||
const NS_CATEGORY = 14;
|
||||
const CURRENT_NS = config.get( 'wgNamespaceNumber' );
|
||||
const features = mw.config.get( 'wgMinervaFeatures', {} );
|
||||
const pageIssuesParser = require( './parser.js' );
|
||||
const pageIssuesOverlay = require( './overlay/pageIssuesOverlay.js' );
|
||||
const pageIssueFormatter = require( './page/pageIssueFormatter.js' );
|
||||
// When the query string flag is set force on new treatment.
|
||||
// When wgMinervaPageIssuesNewTreatment is the default this line can be removed.
|
||||
const QUERY_STRING_FLAG = mw.util.getParamValue( 'minerva-issues' );
|
||||
const newTreatmentEnabled = features.pageIssues || QUERY_STRING_FLAG;
|
||||
|
||||
/**
|
||||
* Render a banner in a containing element.
|
||||
|
@ -36,26 +36,21 @@ var PageHTMLParser = require( 'mobile.startup' ).PageHTMLParser,
|
|||
* @return {{ambox: jQuery, issueSummaries: IssueSummary[]}}
|
||||
*/
|
||||
function insertBannersOrNotice( pageHTMLParser, labelText, section, inline, overlayManager ) {
|
||||
var
|
||||
$metadata,
|
||||
issueUrl = section === KEYWORD_ALL_SECTIONS ? '#/issues/' + KEYWORD_ALL_SECTIONS : '#/issues/' + section,
|
||||
selector = [ '.ambox', '.tmbox', '.cmbox', '.fmbox' ].join( ',' ),
|
||||
issueSummaries = [];
|
||||
const issueUrl = section === KEYWORD_ALL_SECTIONS ? '#/issues/' + KEYWORD_ALL_SECTIONS : '#/issues/' + section;
|
||||
const selector = [ '.ambox', '.tmbox', '.cmbox', '.fmbox' ].join( ',' );
|
||||
const issueSummaries = [];
|
||||
|
||||
if ( section === KEYWORD_ALL_SECTIONS ) {
|
||||
$metadata = pageHTMLParser.$el.find( selector );
|
||||
} else {
|
||||
const $metadata = section === KEYWORD_ALL_SECTIONS ?
|
||||
pageHTMLParser.$el.find( selector ) :
|
||||
// find heading associated with the section
|
||||
$metadata = pageHTMLParser.findChildInSectionLead( parseInt( section, 10 ), selector );
|
||||
}
|
||||
pageHTMLParser.findChildInSectionLead( parseInt( section, 10 ), selector );
|
||||
// clean it up a little
|
||||
$metadata.find( '.NavFrame' ).remove();
|
||||
$metadata.each( function () {
|
||||
var issueSummary,
|
||||
$this = $( this );
|
||||
const $this = $( this );
|
||||
|
||||
if ( $this.find( selector ).length === 0 ) {
|
||||
issueSummary = pageIssuesParser.extract( $this );
|
||||
const issueSummary = pageIssuesParser.extract( $this );
|
||||
// Some issues after "extract" has been run will have no text.
|
||||
// For example in Template:Talk header the table will be removed and no issue found.
|
||||
// These should not be rendered.
|
||||
|
@ -67,10 +62,10 @@ function insertBannersOrNotice( pageHTMLParser, labelText, section, inline, over
|
|||
|
||||
if ( inline ) {
|
||||
issueSummaries.forEach( function ( issueSummary, i ) {
|
||||
var isGrouped = issueSummary.issue.grouped,
|
||||
lastIssueIsGrouped = issueSummaries[ i - 1 ] &&
|
||||
issueSummaries[ i - 1 ].issue.grouped,
|
||||
multiple = isGrouped && !lastIssueIsGrouped;
|
||||
const isGrouped = issueSummary.issue.grouped;
|
||||
const lastIssueIsGrouped = issueSummaries[ i - 1 ] &&
|
||||
issueSummaries[ i - 1 ].issue.grouped;
|
||||
const multiple = isGrouped && !lastIssueIsGrouped;
|
||||
// only render the first grouped issue of each group
|
||||
pageIssueFormatter.insertPageIssueBanner(
|
||||
issueSummary,
|
||||
|
@ -122,14 +117,12 @@ function getIssues( allIssues, section ) {
|
|||
* @param {PageHTMLParser} pageHTMLParser
|
||||
*/
|
||||
function initPageIssues( overlayManager, pageHTMLParser ) {
|
||||
var
|
||||
section,
|
||||
issueSummaries = [],
|
||||
allIssues = {},
|
||||
label,
|
||||
$lead = pageHTMLParser.getLeadSectionElement(),
|
||||
issueOverlayShowAll = CURRENT_NS === NS_CATEGORY || !$lead,
|
||||
inline = newTreatmentEnabled && CURRENT_NS === 0;
|
||||
let section;
|
||||
let issueSummaries = [];
|
||||
const allIssues = {};
|
||||
const $lead = pageHTMLParser.getLeadSectionElement();
|
||||
const issueOverlayShowAll = CURRENT_NS === NS_CATEGORY || !$lead;
|
||||
const inline = newTreatmentEnabled && CURRENT_NS === 0;
|
||||
|
||||
// set A-B test class.
|
||||
// When wgMinervaPageIssuesNewTreatment is the default this can be removed.
|
||||
|
@ -144,7 +137,7 @@ function initPageIssues( overlayManager, pageHTMLParser ) {
|
|||
section, inline, overlayManager ).issueSummaries;
|
||||
allIssues[ section ] = issueSummaries;
|
||||
} else if ( CURRENT_NS === NS_MAIN ) {
|
||||
label = mw.msg( 'mobile-frontend-meta-data-issues-header' );
|
||||
const label = mw.msg( 'mobile-frontend-meta-data-issues-header' );
|
||||
if ( issueOverlayShowAll ) {
|
||||
section = KEYWORD_ALL_SECTIONS;
|
||||
issueSummaries = insertBannersOrNotice(
|
||||
|
@ -163,10 +156,10 @@ function initPageIssues( overlayManager, pageHTMLParser ) {
|
|||
// for sections.
|
||||
pageHTMLParser.$el.find( PageHTMLParser.HEADING_SELECTOR ).each(
|
||||
function ( i, headingEl ) {
|
||||
var $headingEl = $( headingEl ),
|
||||
// section number is absent on protected pages, when this is the case
|
||||
// use i, otherwise icon will not show (T340910)
|
||||
sectionNum = $headingEl.find( '.edit-page' ).data( 'section' ) || i;
|
||||
const $headingEl = $( headingEl );
|
||||
// section number is absent on protected pages, when this is the case
|
||||
// use i, otherwise icon will not show (T340910)
|
||||
const sectionNum = $headingEl.find( '.edit-page' ).data( 'section' ) || i;
|
||||
|
||||
// Note certain headings matched using
|
||||
// PageHTMLParser.HEADING_SELECTOR may not be headings and will
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
const
|
||||
Overlay = require( 'mobile.startup' ).Overlay,
|
||||
IssueList = require( './IssueList.js' ),
|
||||
KEYWORD_ALL_SECTIONS = 'all',
|
||||
NS_MAIN = 0,
|
||||
NS_CATEGORY = 14;
|
||||
const Overlay = require( 'mobile.startup' ).Overlay;
|
||||
const IssueList = require( './IssueList.js' );
|
||||
const KEYWORD_ALL_SECTIONS = 'all';
|
||||
const NS_MAIN = 0;
|
||||
const NS_CATEGORY = 14;
|
||||
|
||||
/**
|
||||
* Overlay for displaying page issues
|
||||
|
@ -14,15 +13,14 @@ const
|
|||
* @return {Overlay}
|
||||
*/
|
||||
function pageIssuesOverlay( issues, section, namespaceID ) {
|
||||
var overlay,
|
||||
// Note only the main namespace is expected to make use of section issues, so the
|
||||
// heading will always be minerva-meta-data-issues-section-header regardless of
|
||||
// namespace.
|
||||
headingText = section === '0' || section === KEYWORD_ALL_SECTIONS ?
|
||||
getNamespaceHeadingText( namespaceID ) :
|
||||
mw.msg( 'minerva-meta-data-issues-section-header' );
|
||||
// Note only the main namespace is expected to make use of section issues, so the
|
||||
// heading will always be minerva-meta-data-issues-section-header regardless of
|
||||
// namespace.
|
||||
const headingText = section === '0' || section === KEYWORD_ALL_SECTIONS ?
|
||||
getNamespaceHeadingText( namespaceID ) :
|
||||
mw.msg( 'minerva-meta-data-issues-section-header' );
|
||||
|
||||
overlay = new Overlay( {
|
||||
const overlay = new Overlay( {
|
||||
className: 'overlay overlay-issues',
|
||||
heading: '<strong>' + headingText + '</strong>'
|
||||
} );
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
( function () {
|
||||
var
|
||||
newPageIssueLink = require( './PageIssueLink.js' ),
|
||||
newPageIssueLearnMoreLink = require( './PageIssueLearnMoreLink.js' );
|
||||
const newPageIssueLink = require( './PageIssueLink.js' );
|
||||
const newPageIssueLearnMoreLink = require( './PageIssueLearnMoreLink.js' );
|
||||
|
||||
/**
|
||||
* Modifies the `issue` DOM to create a banner designed for single / multiple issue templates,
|
||||
|
@ -14,11 +13,11 @@
|
|||
* @param {boolean} [multiple]
|
||||
*/
|
||||
function insertPageIssueBanner( issue, msg, overlayUrl, overlayManager, multiple ) {
|
||||
var $learnMoreEl = newPageIssueLearnMoreLink( msg ),
|
||||
$issueContainer = multiple ?
|
||||
issue.$el.parents( '.mbox-text-span, .mbox-text-div' ) :
|
||||
issue.$el.find( '.mbox-text' ),
|
||||
$clickContainer = multiple ? issue.$el.parents( '.mbox-text' ) : issue.$el;
|
||||
const $learnMoreEl = newPageIssueLearnMoreLink( msg );
|
||||
const $issueContainer = multiple ?
|
||||
issue.$el.parents( '.mbox-text-span, .mbox-text-div' ) :
|
||||
issue.$el.find( '.mbox-text' );
|
||||
const $clickContainer = multiple ? issue.$el.parents( '.mbox-text' ) : issue.$el;
|
||||
|
||||
$issueContainer.prepend( issue.issue.iconElement );
|
||||
$issueContainer.prepend( $learnMoreEl );
|
||||
|
@ -38,7 +37,7 @@
|
|||
* @param {string} section
|
||||
*/
|
||||
function insertPageIssueNotice( labelText, section ) {
|
||||
var $link = newPageIssueLink( labelText );
|
||||
const $link = newPageIssueLink( labelText );
|
||||
$link.attr( 'href', '#/issues/' + section );
|
||||
// eslint-disable-next-line no-jquery/no-global-selector
|
||||
$link.insertAfter( $( 'h1.mw-first-heading' ) );
|
||||
|
|
|
@ -14,102 +14,101 @@
|
|||
* @property {string} text HTML string.
|
||||
*/
|
||||
|
||||
var
|
||||
// Icons are matching the type selector below use a TYPE_* icon. When unmatched, the icon is
|
||||
// chosen by severity. Their color is always determined by severity, too.
|
||||
ICON_NAME = {
|
||||
// Generic severity icons.
|
||||
SEVERITY: {
|
||||
DEFAULT: 'issue-generic',
|
||||
LOW: 'issue-severity-low',
|
||||
MEDIUM: 'issue-severity-medium',
|
||||
HIGH: 'issue-generic'
|
||||
},
|
||||
// Icons are matching the type selector below use a TYPE_* icon. When unmatched, the icon is
|
||||
// chosen by severity. Their color is always determined by severity, too.
|
||||
const ICON_NAME = {
|
||||
// Generic severity icons.
|
||||
SEVERITY: {
|
||||
DEFAULT: 'issue-generic',
|
||||
LOW: 'issue-severity-low',
|
||||
MEDIUM: 'issue-severity-medium',
|
||||
HIGH: 'issue-generic'
|
||||
},
|
||||
|
||||
// Icons customized by type.
|
||||
TYPE: {
|
||||
MOVE: 'issue-type-move',
|
||||
POINT_OF_VIEW: 'issue-type-point-of-view'
|
||||
}
|
||||
},
|
||||
ICON_COLOR = {
|
||||
DEFAULT: 'defaultColor',
|
||||
LOW: 'lowColor',
|
||||
MEDIUM: 'mediumColor',
|
||||
HIGH: 'highColor'
|
||||
},
|
||||
// How severities order and compare from least to greatest. For the multiple issues
|
||||
// template, severity should be considered the maximum of all its contained issues.
|
||||
SEVERITY_LEVEL = {
|
||||
DEFAULT: 0,
|
||||
LOW: 1,
|
||||
MEDIUM: 2,
|
||||
HIGH: 3
|
||||
},
|
||||
// Match the template's color CSS selector to a severity level concept. Derived via the
|
||||
// Ambox templates and sub-templates for the top five wikis and tested on page issues
|
||||
// inventory:
|
||||
// - https://people.wikimedia.org/~jdrewniak/page_issues_inventory
|
||||
// - https://en.wikipedia.org/wiki/Template:Ambox
|
||||
// - https://es.wikipedia.org/wiki/Plantilla:Metaplantilla_de_avisos
|
||||
// - https://ja.wikipedia.org/wiki/Template:Ambox
|
||||
// - https://ru.wikipedia.org/wiki/Шаблон:Ambox
|
||||
// - https://it.wikipedia.org/wiki/Template:Avviso
|
||||
// Severity is the class associated with the color. The ResourceLoader config mimics the
|
||||
// idea by using severity for color variants. Severity is determined independently of icons.
|
||||
// These selectors should be migrated to their templates.
|
||||
SEVERITY_REGEX = {
|
||||
// recommended (T206177), en, it
|
||||
LOW: /mobile-issue-severity-low|ambox-style|avviso-stile/,
|
||||
// recommended, en, it
|
||||
MEDIUM: /mobile-issue-severity-medium|ambox-content|avviso-contenuto/,
|
||||
// recommended, en, en, es / ru, it
|
||||
HIGH: /mobile-issue-severity-high|ambox-speedy|ambox-delete|ambox-serious|avviso-importante/
|
||||
// ..And everything else that doesn't match should be considered DEFAULT.
|
||||
},
|
||||
// As above but used to identify specific templates requiring icon customization.
|
||||
TYPE_REGEX = {
|
||||
// recommended (opt-in) / en, es / ru, it (long term only recommended should be used)
|
||||
MOVE: /mobile-issue-move|ambox-converted|ambox-move|ambox-merge|avviso-struttura/,
|
||||
POINT_OF_VIEW: new RegExp( [
|
||||
// recommended (opt-in)
|
||||
'mobile-issue-pov',
|
||||
// FIXME: en classes: plan to remove these provided can get adoption of recommended
|
||||
'ambox-Advert',
|
||||
'ambox-autobiography',
|
||||
'ambox-believerpov',
|
||||
'ambox-COI',
|
||||
'ambox-coverage',
|
||||
'ambox-criticism',
|
||||
'ambox-fanpov',
|
||||
'ambox-fringe-theories',
|
||||
'ambox-geographical-imbalance',
|
||||
'ambox-globalize',
|
||||
'ambox-npov-language',
|
||||
'ambox-POV',
|
||||
'ambox-pseudo',
|
||||
'ambox-systemic-bias',
|
||||
'ambox-unbalanced',
|
||||
'ambox-usgovtpov'
|
||||
].join( '|' ) )
|
||||
// ..And everything else that doesn't match is mapped to a "SEVERITY" type.
|
||||
},
|
||||
GROUPED_PARENT_REGEX = /mw-collapsible-content/,
|
||||
// Variants supported by specific types. The "severity icon" supports all severities but the
|
||||
// type icons only support one each by ResourceLoader.
|
||||
TYPE_SEVERITY = {
|
||||
MOVE: 'DEFAULT',
|
||||
POINT_OF_VIEW: 'MEDIUM'
|
||||
};
|
||||
// Icons customized by type.
|
||||
TYPE: {
|
||||
MOVE: 'issue-type-move',
|
||||
POINT_OF_VIEW: 'issue-type-point-of-view'
|
||||
}
|
||||
};
|
||||
const ICON_COLOR = {
|
||||
DEFAULT: 'defaultColor',
|
||||
LOW: 'lowColor',
|
||||
MEDIUM: 'mediumColor',
|
||||
HIGH: 'highColor'
|
||||
};
|
||||
// How severities order and compare from least to greatest. For the multiple issues
|
||||
// template, severity should be considered the maximum of all its contained issues.
|
||||
const SEVERITY_LEVEL = {
|
||||
DEFAULT: 0,
|
||||
LOW: 1,
|
||||
MEDIUM: 2,
|
||||
HIGH: 3
|
||||
};
|
||||
// Match the template's color CSS selector to a severity level concept. Derived via the
|
||||
// Ambox templates and sub-templates for the top five wikis and tested on page issues
|
||||
// inventory:
|
||||
// - https://people.wikimedia.org/~jdrewniak/page_issues_inventory
|
||||
// - https://en.wikipedia.org/wiki/Template:Ambox
|
||||
// - https://es.wikipedia.org/wiki/Plantilla:Metaplantilla_de_avisos
|
||||
// - https://ja.wikipedia.org/wiki/Template:Ambox
|
||||
// - https://ru.wikipedia.org/wiki/Шаблон:Ambox
|
||||
// - https://it.wikipedia.org/wiki/Template:Avviso
|
||||
// Severity is the class associated with the color. The ResourceLoader config mimics the
|
||||
// idea by using severity for color variants. Severity is determined independently of icons.
|
||||
// These selectors should be migrated to their templates.
|
||||
const SEVERITY_REGEX = {
|
||||
// recommended (T206177), en, it
|
||||
LOW: /mobile-issue-severity-low|ambox-style|avviso-stile/,
|
||||
// recommended, en, it
|
||||
MEDIUM: /mobile-issue-severity-medium|ambox-content|avviso-contenuto/,
|
||||
// recommended, en, en, es / ru, it
|
||||
HIGH: /mobile-issue-severity-high|ambox-speedy|ambox-delete|ambox-serious|avviso-importante/
|
||||
// ..And everything else that doesn't match should be considered DEFAULT.
|
||||
};
|
||||
// As above but used to identify specific templates requiring icon customization.
|
||||
const TYPE_REGEX = {
|
||||
// recommended (opt-in) / en, es / ru, it (long term only recommended should be used)
|
||||
MOVE: /mobile-issue-move|ambox-converted|ambox-move|ambox-merge|avviso-struttura/,
|
||||
POINT_OF_VIEW: new RegExp( [
|
||||
// recommended (opt-in)
|
||||
'mobile-issue-pov',
|
||||
// FIXME: en classes: plan to remove these provided can get adoption of recommended
|
||||
'ambox-Advert',
|
||||
'ambox-autobiography',
|
||||
'ambox-believerpov',
|
||||
'ambox-COI',
|
||||
'ambox-coverage',
|
||||
'ambox-criticism',
|
||||
'ambox-fanpov',
|
||||
'ambox-fringe-theories',
|
||||
'ambox-geographical-imbalance',
|
||||
'ambox-globalize',
|
||||
'ambox-npov-language',
|
||||
'ambox-POV',
|
||||
'ambox-pseudo',
|
||||
'ambox-systemic-bias',
|
||||
'ambox-unbalanced',
|
||||
'ambox-usgovtpov'
|
||||
].join( '|' ) )
|
||||
// ..And everything else that doesn't match is mapped to a "SEVERITY" type.
|
||||
};
|
||||
const GROUPED_PARENT_REGEX = /mw-collapsible-content/;
|
||||
// Variants supported by specific types. The "severity icon" supports all severities but the
|
||||
// type icons only support one each by ResourceLoader.
|
||||
const TYPE_SEVERITY = {
|
||||
MOVE: 'DEFAULT',
|
||||
POINT_OF_VIEW: 'MEDIUM'
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {Element} box
|
||||
* @return {string} An SEVERITY_SELECTOR key.
|
||||
*/
|
||||
function parseSeverity( box ) {
|
||||
var severity, identified;
|
||||
identified = Object.keys( SEVERITY_REGEX ).some( function ( key ) {
|
||||
var regex = SEVERITY_REGEX[ key ];
|
||||
let severity;
|
||||
const identified = Object.keys( SEVERITY_REGEX ).some( function ( key ) {
|
||||
const regex = SEVERITY_REGEX[ key ];
|
||||
severity = key;
|
||||
return regex.test( box.className );
|
||||
} );
|
||||
|
@ -122,9 +121,9 @@
|
|||
* @return {{name: string, severity: string}} An ICON_NAME.
|
||||
*/
|
||||
function parseType( box, severity ) {
|
||||
var identified, identifiedType;
|
||||
identified = Object.keys( TYPE_REGEX ).some( function ( type ) {
|
||||
var regex = TYPE_REGEX[ type ];
|
||||
let identifiedType;
|
||||
const identified = Object.keys( TYPE_REGEX ).some( function ( type ) {
|
||||
const regex = TYPE_REGEX[ type ];
|
||||
identifiedType = type;
|
||||
return regex.test( box.className );
|
||||
} );
|
||||
|
@ -148,7 +147,7 @@
|
|||
* @return {string} A severity or type ISSUE_ICON.
|
||||
*/
|
||||
function iconName( box, severity ) {
|
||||
var nameSeverity = parseType( box, severity );
|
||||
const nameSeverity = parseType( box, severity );
|
||||
// The icon with color variant as expected by ResourceLoader,
|
||||
// {iconName}-{severityColorVariant}.
|
||||
return nameSeverity.name + '-' + ICON_COLOR[ nameSeverity.severity ];
|
||||
|
@ -187,23 +186,21 @@
|
|||
* @return {IssueSummary}
|
||||
*/
|
||||
function extract( $box ) {
|
||||
var SELECTOR = '.mbox-text, .ambox-text',
|
||||
$container = $( '<div>' ),
|
||||
pageIssue;
|
||||
const SELECTOR = '.mbox-text, .ambox-text';
|
||||
const $container = $( '<div>' );
|
||||
|
||||
$box.find( SELECTOR ).each( function () {
|
||||
var contents,
|
||||
$this = $( this );
|
||||
const $this = $( this );
|
||||
// Clean up talk page boxes
|
||||
$this.find( 'table, .noprint' ).remove();
|
||||
contents = $this.html();
|
||||
const contents = $this.html();
|
||||
|
||||
if ( contents ) {
|
||||
$( '<p>' ).html( contents ).appendTo( $container );
|
||||
}
|
||||
} );
|
||||
|
||||
pageIssue = parse( $box.get( 0 ) );
|
||||
const pageIssue = parse( $box.get( 0 ) );
|
||||
|
||||
return {
|
||||
issue: pageIssue,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
module.exports = function () {
|
||||
var menus = require( './menu.js' );
|
||||
const menus = require( './menu.js' );
|
||||
|
||||
// setup main menu
|
||||
menus.init();
|
||||
|
@ -8,18 +8,16 @@ module.exports = function () {
|
|||
// If the user has been redirected, then show them a toast message (see
|
||||
// https://phabricator.wikimedia.org/T146596).
|
||||
|
||||
var redirectedFrom, $msg, title;
|
||||
|
||||
if ( wgRedirectedFrom === null ) {
|
||||
return;
|
||||
}
|
||||
|
||||
redirectedFrom = mw.Title.newFromText( wgRedirectedFrom );
|
||||
const redirectedFrom = mw.Title.newFromText( wgRedirectedFrom );
|
||||
|
||||
if ( redirectedFrom ) {
|
||||
// mw.Title.getPrefixedText includes the human-readable namespace prefix.
|
||||
title = redirectedFrom.getPrefixedText();
|
||||
$msg = $( '<div>' ).html(
|
||||
const title = redirectedFrom.getPrefixedText();
|
||||
const $msg = $( '<div>' ).html(
|
||||
mw.message( 'mobile-frontend-redirected-from', title ).parse()
|
||||
);
|
||||
$msg.find( 'a' ).attr( 'href', mw.util.getUrl( title, { redirect: 'no' } ) );
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
var drawers = require( './drawers.js' );
|
||||
const drawers = require( './drawers.js' );
|
||||
|
||||
module.exports = function () {
|
||||
|
||||
var mobile = require( 'mobile.startup' ),
|
||||
references = mobile.references,
|
||||
currentPage = mobile.currentPage(),
|
||||
currentPageHTMLParser = mobile.currentPageHTMLParser(),
|
||||
ReferencesHtmlScraperGateway = mobile.references.ReferencesHtmlScraperGateway,
|
||||
gateway = new ReferencesHtmlScraperGateway( new mw.Api() );
|
||||
const mobile = require( 'mobile.startup' );
|
||||
const references = mobile.references;
|
||||
const currentPage = mobile.currentPage();
|
||||
const currentPageHTMLParser = mobile.currentPageHTMLParser();
|
||||
const ReferencesHtmlScraperGateway = mobile.references.ReferencesHtmlScraperGateway;
|
||||
const gateway = new ReferencesHtmlScraperGateway( new mw.Api() );
|
||||
|
||||
/**
|
||||
* Event handler to show reference when a reference link is clicked
|
||||
|
@ -16,14 +16,14 @@ module.exports = function () {
|
|||
* @param {jQuery.Event} ev Click event of the reference element
|
||||
*/
|
||||
function showReference( ev ) {
|
||||
var $dest = $( ev.currentTarget ),
|
||||
href = $dest.attr( 'href' );
|
||||
const $dest = $( ev.currentTarget );
|
||||
let href = $dest.attr( 'href' );
|
||||
|
||||
ev.preventDefault();
|
||||
|
||||
// If necessary strip the URL portion of the href so we are left with the
|
||||
// fragment
|
||||
var i = href.indexOf( '#' );
|
||||
const i = href.indexOf( '#' );
|
||||
if ( i > 0 ) {
|
||||
href = href.slice( i );
|
||||
}
|
||||
|
|
|
@ -1,17 +1,16 @@
|
|||
module.exports = function () {
|
||||
var
|
||||
mobile = require( 'mobile.startup' ),
|
||||
SearchOverlay = mobile.search.SearchOverlay,
|
||||
SearchGateway = mobile.search.SearchGateway,
|
||||
overlayManager = mobile.getOverlayManager(),
|
||||
// eslint-disable-next-line no-jquery/no-global-selector
|
||||
$searchInput = $( '#searchInput' ),
|
||||
placeholder = $searchInput.attr( 'placeholder' ),
|
||||
defaultSearchPage = $searchInput.siblings( 'input[name=title]' ).val(),
|
||||
// eslint-disable-next-line no-jquery/no-global-selector
|
||||
$searchBar = $( '#searchInput, #searchIcon, .skin-minerva-search-trigger' ),
|
||||
searchRoute = new RegExp( /\/search/ ),
|
||||
searchOverlayInstance;
|
||||
const mobile = require( 'mobile.startup' );
|
||||
const SearchOverlay = mobile.search.SearchOverlay;
|
||||
const SearchGateway = mobile.search.SearchGateway;
|
||||
const overlayManager = mobile.getOverlayManager();
|
||||
// eslint-disable-next-line no-jquery/no-global-selector
|
||||
const $searchInput = $( '#searchInput' );
|
||||
const placeholder = $searchInput.attr( 'placeholder' );
|
||||
const defaultSearchPage = $searchInput.siblings( 'input[name=title]' ).val();
|
||||
// eslint-disable-next-line no-jquery/no-global-selector
|
||||
const $searchBar = $( '#searchInput, #searchIcon, .skin-minerva-search-trigger' );
|
||||
const searchRoute = new RegExp( /\/search/ );
|
||||
let searchOverlayInstance;
|
||||
|
||||
// Only continue on mobile devices as it breaks desktop search
|
||||
// See https://phabricator.wikimedia.org/T108432
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
var SEARCH_CLASS = 'search-enabled';
|
||||
const SEARCH_CLASS = 'search-enabled';
|
||||
|
||||
module.exports = function () {
|
||||
// eslint-disable-next-line no-jquery/no-global-selector
|
||||
$( '#searchIcon' ).on( 'click', function () {
|
||||
// eslint-disable-next-line no-jquery/no-global-selector
|
||||
var $input = $( '#searchInput' ),
|
||||
$body = $( document.body );
|
||||
const $input = $( '#searchInput' );
|
||||
const $body = $( document.body );
|
||||
|
||||
// eslint-disable-next-line no-jquery/no-sizzle
|
||||
if ( !$input.is( ':visible' ) ) {
|
||||
|
|
|
@ -2,15 +2,15 @@
|
|||
* This setups the Minerva skin.
|
||||
* It should run without errors even if MobileFrontend is not installed.
|
||||
*/
|
||||
var ms = require( 'mobile.startup' ),
|
||||
reportIfNightModeWasDisabledOnPage = require( './reportIfNightModeWasDisabledOnPage.js' ),
|
||||
addPortletLink = require( './addPortletLink.js' ),
|
||||
teleportTarget = require( 'mediawiki.page.ready' ).teleportTarget;
|
||||
const ms = require( 'mobile.startup' );
|
||||
const reportIfNightModeWasDisabledOnPage = require( './reportIfNightModeWasDisabledOnPage.js' );
|
||||
const addPortletLink = require( './addPortletLink.js' );
|
||||
const teleportTarget = require( 'mediawiki.page.ready' ).teleportTarget;
|
||||
|
||||
function init() {
|
||||
var permissions = mw.config.get( 'wgMinervaPermissions' ) || {},
|
||||
// eslint-disable-next-line no-jquery/no-global-selector
|
||||
$watch = $( '#page-actions-watch' );
|
||||
const permissions = mw.config.get( 'wgMinervaPermissions' ) || {};
|
||||
// eslint-disable-next-line no-jquery/no-global-selector
|
||||
const $watch = $( '#page-actions-watch' );
|
||||
|
||||
if ( permissions.watch ) {
|
||||
require( './watchstar.js' ).init( $watch );
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
var watchstar = require( 'mediawiki.page.watch.ajax' ).watchstar;
|
||||
const watchstar = require( 'mediawiki.page.watch.ajax' ).watchstar;
|
||||
|
||||
( function () {
|
||||
|
||||
var
|
||||
WATCHED_ICON_CLASS = 'minerva-icon--unStar-progressive',
|
||||
TEMP_WATCHED_ICON_CLASS = 'minerva-icon--halfStar-progressive',
|
||||
UNWATCHED_ICON_CLASS = 'minerva-icon--star-base20';
|
||||
const WATCHED_ICON_CLASS = 'minerva-icon--unStar-progressive';
|
||||
const TEMP_WATCHED_ICON_CLASS = 'minerva-icon--halfStar-progressive';
|
||||
const UNWATCHED_ICON_CLASS = 'minerva-icon--star-base20';
|
||||
|
||||
/**
|
||||
* Tweaks the global watchstar handler in core to use the correct classes for Minerva.
|
||||
|
@ -13,7 +12,7 @@ var watchstar = require( 'mediawiki.page.watch.ajax' ).watchstar;
|
|||
* @param {jQuery} $icon
|
||||
*/
|
||||
function init( $icon ) {
|
||||
var $watchlink = $icon.find( 'a' );
|
||||
const $watchlink = $icon.find( 'a' );
|
||||
watchstar( $watchlink, mw.config.get( 'wgRelevantPageName' ), toggleClasses );
|
||||
}
|
||||
|
||||
|
@ -23,10 +22,10 @@ var watchstar = require( 'mediawiki.page.watch.ajax' ).watchstar;
|
|||
* @param {string} expiry
|
||||
*/
|
||||
function toggleClasses( $link, isWatched, expiry ) {
|
||||
var $icon = $link.find( '.minerva-icon' );
|
||||
const $icon = $link.find( '.minerva-icon' );
|
||||
$icon.removeClass( [ WATCHED_ICON_CLASS, UNWATCHED_ICON_CLASS, TEMP_WATCHED_ICON_CLASS ] )
|
||||
.addClass( function () {
|
||||
var classes = UNWATCHED_ICON_CLASS;
|
||||
let classes = UNWATCHED_ICON_CLASS;
|
||||
if ( isWatched ) {
|
||||
if ( expiry !== null && expiry !== undefined && expiry !== 'infinity' ) {
|
||||
classes = TEMP_WATCHED_ICON_CLASS;
|
||||
|
|
|
@ -7,6 +7,6 @@
|
|||
"rules": {
|
||||
"no-jquery/no-parse-html-literal": "off",
|
||||
"no-restricted-properties": "off",
|
||||
"no-var": "off"
|
||||
"no-var": "error"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,30 +1,27 @@
|
|||
( function () {
|
||||
|
||||
var AB = require( '../../../resources/skins.minerva.scripts/AB.js' ),
|
||||
defaultConfig = {
|
||||
testName: 'WME.MinervaABTest',
|
||||
samplingRate: 0.5,
|
||||
sessionId: mw.user.generateRandomSessionId()
|
||||
};
|
||||
const AB = require( '../../../resources/skins.minerva.scripts/AB.js' );
|
||||
const defaultConfig = {
|
||||
testName: 'WME.MinervaABTest',
|
||||
samplingRate: 0.5,
|
||||
sessionId: mw.user.generateRandomSessionId()
|
||||
};
|
||||
|
||||
QUnit.module( 'Minerva AB-test' );
|
||||
|
||||
QUnit.test( 'Bucketing test', function ( assert ) {
|
||||
var userBuckets = {
|
||||
unsampled: 0,
|
||||
control: 0,
|
||||
treatment: 0
|
||||
},
|
||||
maxUsers = 1000,
|
||||
bucketingTest,
|
||||
config,
|
||||
i;
|
||||
const userBuckets = {
|
||||
unsampled: 0,
|
||||
control: 0,
|
||||
treatment: 0
|
||||
};
|
||||
const maxUsers = 1000;
|
||||
|
||||
for ( i = 0; i < maxUsers; i++ ) {
|
||||
config = Object.assign( {}, defaultConfig, {
|
||||
for ( let i = 0; i < maxUsers; i++ ) {
|
||||
const config = Object.assign( {}, defaultConfig, {
|
||||
sessionId: mw.user.generateRandomSessionId()
|
||||
} );
|
||||
bucketingTest = new AB( config );
|
||||
const bucketingTest = new AB( config );
|
||||
if ( bucketingTest.isControl() ) {
|
||||
++userBuckets.control;
|
||||
} else if ( bucketingTest.isTreatment() ) {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
( function () {
|
||||
var TitleUtil = require( '../../../resources/skins.minerva.scripts/TitleUtil.js' );
|
||||
var mwUriOrg = mw.Uri;
|
||||
const TitleUtil = require( '../../../resources/skins.minerva.scripts/TitleUtil.js' );
|
||||
const mwUriOrg = mw.Uri;
|
||||
|
||||
QUnit.module( 'Minerva TitleUtil', QUnit.newMwEnvironment( {
|
||||
beforeEach: function () {
|
||||
|
@ -76,7 +76,7 @@
|
|||
empty: '',
|
||||
metawiki: 'https://meta.wikimedia.org'
|
||||
}, function ( assert, authority ) {
|
||||
var validateReadOnlyLink = { validateReadOnlyLink: true };
|
||||
const validateReadOnlyLink = { validateReadOnlyLink: true };
|
||||
assert.strictEqual(
|
||||
TitleUtil.newFromUri( authority + '/w/index.php?title=Title' ).getPrefixedDb(),
|
||||
'Title',
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
( function () {
|
||||
var UriUtil = require( '../../../resources/skins.minerva.scripts/UriUtil.js' );
|
||||
var mwUriOrg = mw.Uri;
|
||||
const UriUtil = require( '../../../resources/skins.minerva.scripts/UriUtil.js' );
|
||||
const mwUriOrg = mw.Uri;
|
||||
|
||||
QUnit.module( 'Minerva UriUtil', {
|
||||
beforeEach: function () {
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
( function () {
|
||||
var VALID_UA = 'Mozilla/5.0 (Linux; Android 5.1.1; Nexus 6 Build/LYZ28E) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Mobile Safari/537.36',
|
||||
VALID_SUPPORTED_NAMESPACES = [ 0 ],
|
||||
spinner = () => ( {
|
||||
$el: $( '<span>' )
|
||||
} ),
|
||||
Deferred = $.Deferred,
|
||||
windowChrome = { chrome: true },
|
||||
windowNotChrome = {},
|
||||
downloadAction = require( '../../../resources/skins.minerva.scripts/downloadPageAction.js' ),
|
||||
onClick = downloadAction.test.onClick,
|
||||
isAvailable = downloadAction.test.isAvailable;
|
||||
const VALID_UA = 'Mozilla/5.0 (Linux; Android 5.1.1; Nexus 6 Build/LYZ28E) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Mobile Safari/537.36';
|
||||
const VALID_SUPPORTED_NAMESPACES = [ 0 ];
|
||||
const spinner = () => ( {
|
||||
$el: $( '<span>' )
|
||||
} );
|
||||
const Deferred = $.Deferred;
|
||||
const windowChrome = { chrome: true };
|
||||
const windowNotChrome = {};
|
||||
const downloadAction = require( '../../../resources/skins.minerva.scripts/downloadPageAction.js' );
|
||||
const onClick = downloadAction.test.onClick;
|
||||
const isAvailable = downloadAction.test.isAvailable;
|
||||
|
||||
class Page {
|
||||
constructor( options ) {
|
||||
|
@ -28,7 +28,7 @@
|
|||
QUnit.module( 'Minerva DownloadIcon', {
|
||||
beforeEach: function () {
|
||||
this.getOnClickHandler = function ( onLoadAllImages ) {
|
||||
var portletLink = document.createElement( 'li' );
|
||||
const portletLink = document.createElement( 'li' );
|
||||
|
||||
return function () {
|
||||
onClick( portletLink, spinner(), onLoadAllImages );
|
||||
|
@ -91,7 +91,7 @@
|
|||
|
||||
QUnit.module( 'isAvailable()', {
|
||||
beforeEach: function () {
|
||||
var page = new Page( {
|
||||
const page = new Page( {
|
||||
id: 0,
|
||||
title: 'Test',
|
||||
isMissing: false,
|
||||
|
@ -118,7 +118,7 @@
|
|||
} );
|
||||
|
||||
QUnit.test( 'isAvailable() handles missing pages', function ( assert ) {
|
||||
var page = new Page( {
|
||||
const page = new Page( {
|
||||
id: 0,
|
||||
title: 'Missing',
|
||||
isMissing: true
|
||||
|
@ -127,7 +127,7 @@
|
|||
} );
|
||||
|
||||
QUnit.test( 'isAvailable() handles properly main page', function ( assert ) {
|
||||
var page = new Page( {
|
||||
const page = new Page( {
|
||||
id: 0,
|
||||
title: 'Test',
|
||||
isMissing: false,
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
* @return {Element}
|
||||
*/
|
||||
function newBox( className ) {
|
||||
var box = document.createElement( 'div' );
|
||||
const box = document.createElement( 'div' );
|
||||
box.className = className;
|
||||
return box;
|
||||
}
|
||||
|
@ -58,7 +58,7 @@
|
|||
} );
|
||||
|
||||
QUnit.test( 'parseSeverity', function ( assert ) {
|
||||
var tests = [
|
||||
const tests = [
|
||||
[ '', 'DEFAULT', 'empty' ],
|
||||
[ 'foo', 'DEFAULT', 'unknown' ],
|
||||
[ 'ambox-style', 'LOW', 'style' ],
|
||||
|
@ -72,11 +72,10 @@
|
|||
// Mixed severities such as 'ambox-style ambox-content' are not prioritized.
|
||||
];
|
||||
tests.forEach( function ( params, i ) {
|
||||
var
|
||||
className = params[ 0 ],
|
||||
expect = params[ 1 ],
|
||||
test = params[ 2 ],
|
||||
box = newBox( className );
|
||||
const className = params[ 0 ];
|
||||
const expect = params[ 1 ];
|
||||
const test = params[ 2 ];
|
||||
const box = newBox( className );
|
||||
assert.strictEqual(
|
||||
pageIssuesParser.test.parseSeverity( box ),
|
||||
expect,
|
||||
|
@ -86,7 +85,7 @@
|
|||
} );
|
||||
|
||||
QUnit.test( 'parseType', function ( assert ) {
|
||||
var tests = [
|
||||
const tests = [
|
||||
[ '', 'DEFAULT', 'issue-generic', 'empty' ],
|
||||
[ 'foo', 'DEFAULT', 'issue-generic', 'unknown' ],
|
||||
[ 'ambox-move', 'DEFAULT', 'issue-type-move', 'move' ],
|
||||
|
@ -97,15 +96,14 @@
|
|||
[ '', 'HIGH', 'issue-generic', 'HIGH severity' ]
|
||||
];
|
||||
tests.forEach( function ( params, i ) {
|
||||
var
|
||||
className = params[ 0 ],
|
||||
severity = params[ 1 ],
|
||||
expect = {
|
||||
name: params[ 2 ],
|
||||
severity: severity
|
||||
},
|
||||
test = params[ 3 ],
|
||||
box = newBox( className );
|
||||
const className = params[ 0 ];
|
||||
const severity = params[ 1 ];
|
||||
const expect = {
|
||||
name: params[ 2 ],
|
||||
severity: severity
|
||||
};
|
||||
const test = params[ 3 ];
|
||||
const box = newBox( className );
|
||||
assert.propEqual(
|
||||
pageIssuesParser.test.parseType( box, severity ),
|
||||
expect,
|
||||
|
@ -115,20 +113,18 @@
|
|||
} );
|
||||
|
||||
QUnit.test( 'parseGroup', function ( assert ) {
|
||||
var tests = [
|
||||
const tests = [
|
||||
[ undefined, false, 'orphaned' ],
|
||||
[ '', false, 'ungrouped' ],
|
||||
[ 'mw-collapsible-content', true, 'grouped' ]
|
||||
];
|
||||
tests.forEach( function ( params, i ) {
|
||||
var
|
||||
parentClassName = params[ 0 ],
|
||||
expect = params[ 1 ],
|
||||
test = params[ 2 ],
|
||||
parent,
|
||||
box = newBox( '' );
|
||||
const parentClassName = params[ 0 ];
|
||||
const expect = params[ 1 ];
|
||||
const test = params[ 2 ];
|
||||
const box = newBox( '' );
|
||||
if ( parentClassName !== undefined ) {
|
||||
parent = document.createElement( 'div' );
|
||||
const parent = document.createElement( 'div' );
|
||||
parent.className = parentClassName;
|
||||
parent.appendChild( box );
|
||||
}
|
||||
|
@ -141,7 +137,7 @@
|
|||
} );
|
||||
|
||||
QUnit.test( 'iconName', function ( assert ) {
|
||||
var tests = [
|
||||
const tests = [
|
||||
[ '', 'DEFAULT', 'issue-generic-defaultColor' ],
|
||||
[ '', 'LOW', 'issue-severity-low-lowColor' ],
|
||||
[ '', 'MEDIUM', 'issue-severity-medium-mediumColor' ],
|
||||
|
@ -154,11 +150,10 @@
|
|||
[ 'ambox-content ambox-move', 'MEDIUM', 'issue-type-move-defaultColor' ]
|
||||
];
|
||||
tests.forEach( function ( params, i ) {
|
||||
var
|
||||
className = params[ 0 ],
|
||||
severity = params[ 1 ],
|
||||
expect = params[ 2 ],
|
||||
box = newBox( className );
|
||||
const className = params[ 0 ];
|
||||
const severity = params[ 1 ];
|
||||
const expect = params[ 2 ];
|
||||
const box = newBox( className );
|
||||
assert.strictEqual(
|
||||
pageIssuesParser.iconName( box, severity ),
|
||||
expect,
|
||||
|
@ -168,7 +163,7 @@
|
|||
} );
|
||||
|
||||
QUnit.test( 'maxSeverity', function ( assert ) {
|
||||
var tests = [
|
||||
const tests = [
|
||||
[ [], 'DEFAULT' ],
|
||||
[ [ 'DEFAULT' ], 'DEFAULT' ],
|
||||
[ [ 'DEFAULT', 'LOW' ], 'LOW' ],
|
||||
|
@ -178,8 +173,8 @@
|
|||
[ [ 'DEFAULT', 'HIGH', 'LOW', 'MEDIUM' ], 'HIGH' ]
|
||||
];
|
||||
tests.forEach( function ( params, i ) {
|
||||
var severities = params[ 0 ],
|
||||
expect = params[ 1 ];
|
||||
const severities = params[ 0 ];
|
||||
const expect = params[ 1 ];
|
||||
|
||||
assert.strictEqual(
|
||||
pageIssuesParser.maxSeverity( severities ),
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
/* eslint-disable no-jquery/no-class-state */
|
||||
( function () {
|
||||
var watchstar = require( '../../../resources/skins.minerva.scripts/watchstar.js' ),
|
||||
toggleClasses = watchstar.test.toggleClasses,
|
||||
WATCHED_CLASS = watchstar.test.WATCHED_ICON_CLASS,
|
||||
TEMP_WATCHED_CLASS = watchstar.test.TEMP_WATCHED_ICON_CLASS,
|
||||
UNWATCHED_CLASS = watchstar.test.UNWATCHED_ICON_CLASS;
|
||||
const watchstar = require( '../../../resources/skins.minerva.scripts/watchstar.js' );
|
||||
const toggleClasses = watchstar.test.toggleClasses;
|
||||
const WATCHED_CLASS = watchstar.test.WATCHED_ICON_CLASS;
|
||||
const TEMP_WATCHED_CLASS = watchstar.test.TEMP_WATCHED_ICON_CLASS;
|
||||
const UNWATCHED_CLASS = watchstar.test.UNWATCHED_ICON_CLASS;
|
||||
|
||||
QUnit.module( 'Minerva Watchstar' );
|
||||
|
||||
|
@ -14,25 +14,25 @@
|
|||
}
|
||||
|
||||
QUnit.test( 'toggleClasses() from watched to unwatched', function ( assert ) {
|
||||
var $elem = createElemWithClass( WATCHED_CLASS );
|
||||
const $elem = createElemWithClass( WATCHED_CLASS );
|
||||
toggleClasses( $elem, false );
|
||||
assert.true( $elem.find( '.minerva-icon' ).hasClass( UNWATCHED_CLASS ) );
|
||||
} );
|
||||
|
||||
QUnit.test( 'toggleClasses() from unwatched to watched', function ( assert ) {
|
||||
var $elem = createElemWithClass( UNWATCHED_CLASS );
|
||||
const $elem = createElemWithClass( UNWATCHED_CLASS );
|
||||
toggleClasses( $elem, true, null );
|
||||
assert.true( $elem.find( '.minerva-icon' ).hasClass( WATCHED_CLASS ) );
|
||||
} );
|
||||
|
||||
QUnit.test( 'toggleClasses() from unwatched to temp watched', function ( assert ) {
|
||||
var $elem = createElemWithClass( UNWATCHED_CLASS );
|
||||
const $elem = createElemWithClass( UNWATCHED_CLASS );
|
||||
toggleClasses( $elem, true, 'expiry' );
|
||||
assert.true( $elem.find( '.minerva-icon' ).hasClass( TEMP_WATCHED_CLASS ) );
|
||||
} );
|
||||
|
||||
QUnit.test( 'toggleClasses() from temp watched to watched', function ( assert ) {
|
||||
var $elem = createElemWithClass( TEMP_WATCHED_CLASS );
|
||||
const $elem = createElemWithClass( TEMP_WATCHED_CLASS );
|
||||
toggleClasses( $elem, true, null );
|
||||
assert.true( $elem.find( '.minerva-icon' ).hasClass( WATCHED_CLASS ) );
|
||||
} );
|
||||
|
|
Loading…
Reference in a new issue