build: Update eslint 0.26.0 and apply fixes

Mainly auto fixes but also getting rid of some straight forward lint
warnings to reduce the wall of issues a bit when running the tests.

Also removing some rule exceptions that seem to got more relaxed
upstream.

Change-Id: Icb4d73374583675be74517e6df6508314d61e8c2
This commit is contained in:
WMDE-Fisch 2024-01-11 10:43:59 +01:00 committed by James D. Forrester
parent 863c442c32
commit a3f3cf9e3f
44 changed files with 1320 additions and 573 deletions

View file

@ -4,7 +4,5 @@
"wikimedia/server"
],
"rules": {
"yml/block-sequence": "warn",
"yml/plain-scalar": "warn"
}
}

View file

@ -1,7 +1,6 @@
instrumentation:
include-all-sources: true
excludes: [
"resources/dist/*", # Compiled assets
"*.js", # Gruntfile.js and webpack.config.js
"src/index.js", # Application entry point
]
excludes:
- "resources/dist/*" # Compiled assets
- "*.js" # Gruntfile.js and webpack.config.js
- src/index.js # Application entry point

1574
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -46,7 +46,7 @@
"bundlesize": "0.18.1",
"clean-webpack-plugin": "3.0.0",
"cssjanus": "1.3.1",
"eslint-config-wikimedia": "0.25.1",
"eslint-config-wikimedia": "0.26.0",
"eslint-plugin-no-jquery": "2.7.0",
"expose-loader": "4.1.0",
"grunt-banana-checker": "0.11.1",

Binary file not shown.

View file

@ -235,8 +235,8 @@ export function linkDwell( title, el, measures, gateway, generateToken, type ) {
// The `enabled` flags allow to disable individual popup types while still showing the
// footer link. This comes from the boot() action (called `initiallyEnabled` there) and
// the preview() reducer.
// If the preview type has not been enabled, we ignore it as it cannot be disabled (currently)
// by the UI.
// If the preview type has not been enabled, we ignore it as it cannot be disabled
// (currently) by the UI.
if ( isEnabled && isNewInteraction() ) {
return dispatch( fetch( gateway, title, el, token, type ) );
}

View file

@ -47,9 +47,10 @@ export default function linkTitle() {
restoreTitleAttr( oldLink );
// FIXME: This will not work on anything other than 'reference' or 'preview' types as
// mw.popups.register does not register the previewType as a key in newState.preview.enabled
// This is not a problem at time of writing (November 2022) but will become a problem if we
// introduce custom preview types that must remove the title attribute.
// mw.popups.register does not register the previewType as a key in
// newState.preview.enabled
// This is not a problem at time of writing (November 2022) but will become a problem if
// we introduce custom preview types that must remove the title attribute.
if ( newState.preview.enabled[ newState.preview.previewType ] ) {
destroyTitleAttr( newState.preview.activeLink );
}

View file

@ -15,7 +15,8 @@ export default function settings( boundActions, render ) {
}
if (
settingsObj &&
Object.keys( oldState.settings.previewTypesEnabled ).length !== Object.keys( newState.settings.previewTypesEnabled ).length
Object.keys( oldState.settings.previewTypesEnabled ).length !==
Object.keys( newState.settings.previewTypesEnabled ).length
) {
// the number of settings changed so force it to be repainted.
settingsObj.refresh( newState.settings.previewTypesEnabled );

View file

@ -41,6 +41,7 @@ function makeTitleInExtractBold( extract, title ) {
title = title.replace( /\s+/g, ' ' ).trim(); // Remove extra white spaces
const escapedTitle = mw.util.escapeRegExp( title );
// eslint-disable-next-line security/detect-non-literal-regexp
const regExp = new RegExp( `(^|\\s)(${ escapedTitle })(|$)`, 'i' );
// Remove text in parentheses along with the parentheses

View file

@ -19,7 +19,8 @@ function canShowSettingForPreviewType( type ) {
* @param {Redux.Store} store Popups store
* @param {Function} registerModel allows extensions to register custom preview handlers.
* @param {Function} registerPreviewUI allows extensions to register custom preview renderers.
* @param {Function} registerGatewayForPreviewType allows extensions to register gateways for preview types.
* @param {Function} registerGatewayForPreviewType allows extensions to register gateways for
* preview types.
* @param {Function} registerSetting
* @param {UserSettings} userSettings
* @return {Object} external Popups interface
@ -40,16 +41,19 @@ export default function createMwPopups( store, registerModel, registerPreviewUI,
*
* @typedef {Object} PopupSubtype
* @property {string} type A unique string for identifying the subtype of a page preview
* @property {function(ext.popups.PreviewModel): ext.popups.Preview}[renderFn] How the custom preview type will render the preview.
* If not provided default renderer is used.
* @property {function(ext.popups.PreviewModel): ext.popups.Preview}[renderFn] How the
* custom preview type will render the preview. If not provided default renderer is used.
*
* @typedef {Object} PopupModule
* @property {string} type A unique string for identifying the type of page preview
* @property {string} selector A CSS selector which identifies elements that will display this type of page preview
* @property {string} selector A CSS selector which identifies elements that will display
* this type of page preview
* @property {Gateway} gateway A Gateway for obtaining the preview data.
* @property {function(ext.popups.PreviewModel): ext.popups.Preview}[renderFn] How the custom preview type will render the preview.
* @property {function(ext.popups.PreviewModel): ext.popups.Preview}[renderFn] How the
* custom preview type will render the preview.
* If not provided default renderer is used.
* @property {PopupSubtype[]} subTypes this is for registering types that are subsets of the current type e.g. share the same selector.
* @property {PopupSubtype[]} subTypes this is for registering types that are subsets of
* the current type e.g. share the same selector.
* @property {number} [delay] optional delay between hovering and displaying preview.
* If not defined, delay will be zero.
*/
@ -92,7 +96,11 @@ Please create message with key "popups-settings-option-${type}" if this is a mis
}
if ( subTypes ) {
subTypes.forEach( function ( subTypePreview ) {
registerPreviewUI( subTypePreview.type, subTypePreview.renderFn, subTypePreview.doNotRequireSummary );
registerPreviewUI(
subTypePreview.type,
subTypePreview.renderFn,
subTypePreview.doNotRequireSummary
);
} );
}
// Run initialization function if provided.

View file

@ -144,7 +144,9 @@ const registeredPreviewTypes = [];
* @return {string|null} One of the previewTypes.TYPE_ constants
*/
export function getPreviewType( el ) {
const candidates = registeredPreviewTypes.filter( ( type ) => elementMatchesSelector( el, type.selector ) );
const candidates = registeredPreviewTypes.filter(
( type ) => elementMatchesSelector( el, type.selector )
);
// If the filter returned some possibilities, use the last registered one.
if ( candidates.length > 0 ) {

View file

@ -44,6 +44,7 @@ export function getTitle( href, config ) {
// No query params (pretty URL)
if ( !queryLength ) {
const pattern = mw.util.escapeRegExp( config.get( 'wgArticlePath' ) ).replace( '\\$1', '([^?#]+)' ),
// eslint-disable-next-line security/detect-non-literal-regexp
matches = new RegExp( pattern ).exec( linkHref.path );
// We can't be sure decodeURIComponent() is able to parse every possible match

View file

@ -182,7 +182,7 @@ function supportsCSSClipPath() {
return window.CSS &&
typeof CSS.supports === 'function' &&
CSS.supports( 'clip-path', 'polygon(1px 1px)' );
/* eslint-enable compat/compat */
}
/**

View file

@ -130,7 +130,7 @@ function createThumbnailImg( url ) {
* Sets multiple attributes on a node.
*
* @param {HTMLElement} node
* @param {Record<String, String>} attrs
* @param {Record<string, string>} attrs
*/
const addAttributes = ( node, attrs ) => {
Object.keys( attrs ).forEach( ( key ) => {

View file

@ -41,6 +41,8 @@ export default function createUserSettings( storage ) {
*
* @method
* @param {string} previewType
*
* @return {boolean}
*/
isPreviewTypeEnabled( previewType ) {
const storageKey = `mwe-popups-${ previewType }-enabled`;

View file

@ -6,9 +6,6 @@
],
"rules": {
"no-jquery/no-class-state": "off",
"no-jquery/no-deferred": "warn",
"no-jquery/no-when": "warn",
"no-jquery/no-extend": "warn",
"es-x/no-hashbang": "warn"
}
}

View file

@ -9,7 +9,9 @@ QUnit.module( 'ext.popups/changeListeners/footerLink @integration', {
// Stub internal usage of mw.message
mw.message = ( str ) =>
( {
text() { return str; }
text() {
return str;
}
} );
boundActions.showSettings = this.showSettingsSpy = this.sandbox.spy();

View file

@ -34,7 +34,9 @@ QUnit.module( 'ext.popups/pageviews', {
// Stub internal usage of mw.Title.newFromText
mw.Title.newFromText = ( str ) => {
return {
getPrefixedDb: () => { return str; }
getPrefixedDb: () => {
return str;
}
};
};
}
@ -67,7 +69,7 @@ QUnit.test( 'it should log the queued event', function ( assert ) {
} );
QUnit.test( 'it should not log something that is not a pageview', function ( assert ) {
const noPageviewState = $.extend( {}, newState );
const noPageviewState = Object.assign( {}, newState );
delete noPageviewState.pageviews.pageview;
this.changeListener( undefined, newState );

View file

@ -39,7 +39,9 @@ QUnit.test( '#get', function ( assert ) {
// ---
assert.throws(
() => { this.container.get( 'bar' ); },
() => {
this.container.get( 'bar' );
},
/The service "bar" hasn't been defined./,
'The container throws an error when no factory exists.'
);

View file

@ -65,7 +65,7 @@ QUnit.module( 'ext.popups/gateway/mediawiki', {
} );
QUnit.test( 'MediaWiki API gateway is called with correct arguments', function ( assert ) {
const config = $.extend( {}, DEFAULT_CONSTANTS, {
const config = Object.assign( {}, DEFAULT_CONSTANTS, {
acceptLanguage: 'pl'
} );
const spy = this.sandbox.spy(),
@ -136,7 +136,9 @@ QUnit.test( 'MediaWiki API gateway is correctly extracting the page data from th
errorCases.forEach( ( data, i ) => {
assert.throws(
() => { gateway.extractPageFromResponse( data ); },
() => {
gateway.extractPageFromResponse( data );
},
`Case ${ i }: the gateway throws an error.`
);
} );
@ -237,7 +239,9 @@ QUnit.test( 'MediaWiki API gateway is abortable', function ( assert ) {
deferred = $.Deferred(),
api = {
get: this.sandbox.stub().returns(
deferred.promise( { abort() { deferred.reject( 'http' ); } } )
deferred.promise( { abort() {
deferred.reject( 'http' );
} } )
)
},
gateway = createMediaWikiApiGateway( api, DEFAULT_CONSTANTS );

View file

@ -185,7 +185,7 @@ QUnit.module( 'gateway/rest', {
} );
QUnit.test( 'RESTBase gateway is called with correct arguments', function ( assert ) {
const config = $.extend( {}, DEFAULT_CONSTANTS, {
const config = Object.assign( {}, DEFAULT_CONSTANTS, {
acceptLanguage: 'pl'
} );

View file

@ -5,7 +5,9 @@ QUnit.module( 'ext.popups.preview.settingsBehavior', {
beforeEach() {
function newFromText( title ) {
return {
getUrl() { return `url/${title}`; }
getUrl() {
return `url/${ title }`;
}
};
}

View file

@ -16,6 +16,7 @@ require( '@babel/register' )( {
} );
require.extensions[ '.svg' ] = ( module, filename ) => {
// eslint-disable-next-line security/detect-non-literal-fs-filename
const svg = fs.readFileSync( filename, { encoding: 'utf8' } );
// eslint-disable-next-line no-underscore-dangle
module._compile( svgInlineLoader( svg ), filename );

View file

@ -7,7 +7,6 @@
"mw": "readonly"
},
"rules": {
"no-jquery/no-jquery-constructor": "off",
"wdio/no-pause": "warn"
}
}

View file

@ -17,6 +17,7 @@ const
POPUPS_MODULE_NAME = 'ext.popups.main';
async function makePage( title, path ) {
// eslint-disable-next-line security/detect-non-literal-fs-filename
const content = fs.readFileSync( path, 'utf-8' );
const bot = await Api.bot();
await bot.edit( title, content );