mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/Popups
synced 2024-11-27 08:50:33 +00:00
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:
parent
863c442c32
commit
a3f3cf9e3f
|
@ -4,7 +4,5 @@
|
||||||
"wikimedia/server"
|
"wikimedia/server"
|
||||||
],
|
],
|
||||||
"rules": {
|
"rules": {
|
||||||
"yml/block-sequence": "warn",
|
|
||||||
"yml/plain-scalar": "warn"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
instrumentation:
|
instrumentation:
|
||||||
include-all-sources: true
|
include-all-sources: true
|
||||||
excludes: [
|
excludes:
|
||||||
"resources/dist/*", # Compiled assets
|
- "resources/dist/*" # Compiled assets
|
||||||
"*.js", # Gruntfile.js and webpack.config.js
|
- "*.js" # Gruntfile.js and webpack.config.js
|
||||||
"src/index.js", # Application entry point
|
- src/index.js # Application entry point
|
||||||
]
|
|
||||||
|
|
1574
package-lock.json
generated
1574
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -46,7 +46,7 @@
|
||||||
"bundlesize": "0.18.1",
|
"bundlesize": "0.18.1",
|
||||||
"clean-webpack-plugin": "3.0.0",
|
"clean-webpack-plugin": "3.0.0",
|
||||||
"cssjanus": "1.3.1",
|
"cssjanus": "1.3.1",
|
||||||
"eslint-config-wikimedia": "0.25.1",
|
"eslint-config-wikimedia": "0.26.0",
|
||||||
"eslint-plugin-no-jquery": "2.7.0",
|
"eslint-plugin-no-jquery": "2.7.0",
|
||||||
"expose-loader": "4.1.0",
|
"expose-loader": "4.1.0",
|
||||||
"grunt-banana-checker": "0.11.1",
|
"grunt-banana-checker": "0.11.1",
|
||||||
|
|
BIN
resources/dist/index.js.map.json
vendored
BIN
resources/dist/index.js.map.json
vendored
Binary file not shown.
|
@ -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
|
// 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
|
// footer link. This comes from the boot() action (called `initiallyEnabled` there) and
|
||||||
// the preview() reducer.
|
// the preview() reducer.
|
||||||
// If the preview type has not been enabled, we ignore it as it cannot be disabled (currently)
|
// If the preview type has not been enabled, we ignore it as it cannot be disabled
|
||||||
// by the UI.
|
// (currently) by the UI.
|
||||||
if ( isEnabled && isNewInteraction() ) {
|
if ( isEnabled && isNewInteraction() ) {
|
||||||
return dispatch( fetch( gateway, title, el, token, type ) );
|
return dispatch( fetch( gateway, title, el, token, type ) );
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,9 +47,10 @@ export default function linkTitle() {
|
||||||
restoreTitleAttr( oldLink );
|
restoreTitleAttr( oldLink );
|
||||||
|
|
||||||
// FIXME: This will not work on anything other than 'reference' or 'preview' types as
|
// 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
|
// mw.popups.register does not register the previewType as a key in
|
||||||
// This is not a problem at time of writing (November 2022) but will become a problem if we
|
// newState.preview.enabled
|
||||||
// introduce custom preview types that must remove the title attribute.
|
// 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 ] ) {
|
if ( newState.preview.enabled[ newState.preview.previewType ] ) {
|
||||||
destroyTitleAttr( newState.preview.activeLink );
|
destroyTitleAttr( newState.preview.activeLink );
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,8 @@ export default function settings( boundActions, render ) {
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
settingsObj &&
|
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.
|
// the number of settings changed so force it to be repainted.
|
||||||
settingsObj.refresh( newState.settings.previewTypesEnabled );
|
settingsObj.refresh( newState.settings.previewTypesEnabled );
|
||||||
|
|
|
@ -22,7 +22,7 @@ export default function syncUserSettings( userSettings ) {
|
||||||
return ( oldState, newState ) => {
|
return ( oldState, newState ) => {
|
||||||
Object.keys( newState.preview.enabled ).forEach( ( key ) => {
|
Object.keys( newState.preview.enabled ).forEach( ( key ) => {
|
||||||
syncIfChanged(
|
syncIfChanged(
|
||||||
oldState, newState, `preview.enabled.${key}`,
|
oldState, newState, `preview.enabled.${ key }`,
|
||||||
( value ) => {
|
( value ) => {
|
||||||
userSettings.storePreviewTypeEnabled( key, value );
|
userSettings.storePreviewTypeEnabled( key, value );
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,7 +72,7 @@ export default function createContainer() {
|
||||||
*/
|
*/
|
||||||
get( name ) {
|
get( name ) {
|
||||||
if ( !this.has( name ) ) {
|
if ( !this.has( name ) ) {
|
||||||
throw new Error( `The service "${name}" hasn't been defined.` );
|
throw new Error( `The service "${ name }" hasn't been defined.` );
|
||||||
}
|
}
|
||||||
|
|
||||||
const factory = factories[ name ];
|
const factory = factories[ name ];
|
||||||
|
|
|
@ -28,7 +28,7 @@ exports.getEditCountBucket = function getEditCountBucket( count ) {
|
||||||
bucket = '1000+';
|
bucket = '1000+';
|
||||||
}
|
}
|
||||||
|
|
||||||
return `${bucket} edits`;
|
return `${ bucket } edits`;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -58,5 +58,5 @@ exports.getPreviewCountBucket = function getPreviewCountBucket( count ) {
|
||||||
bucket = '21+';
|
bucket = '21+';
|
||||||
}
|
}
|
||||||
|
|
||||||
return bucket !== undefined ? ( `${bucket} previews` ) : 'unknown';
|
return bucket !== undefined ? ( `${ bucket } previews` ) : 'unknown';
|
||||||
};
|
};
|
||||||
|
|
|
@ -36,12 +36,13 @@ export function formatPlainTextExtract( plainTextExtract, title ) {
|
||||||
*/
|
*/
|
||||||
function makeTitleInExtractBold( extract, title ) {
|
function makeTitleInExtractBold( extract, title ) {
|
||||||
const elements = [],
|
const elements = [],
|
||||||
boldIdentifier = `<bi-${Math.random()}>`,
|
boldIdentifier = `<bi-${ Math.random() }>`,
|
||||||
snip = `<snip-${Math.random()}>`;
|
snip = `<snip-${ Math.random() }>`;
|
||||||
|
|
||||||
title = title.replace( /\s+/g, ' ' ).trim(); // Remove extra white spaces
|
title = title.replace( /\s+/g, ' ' ).trim(); // Remove extra white spaces
|
||||||
const escapedTitle = mw.util.escapeRegExp( title );
|
const escapedTitle = mw.util.escapeRegExp( title );
|
||||||
const regExp = new RegExp( `(^|\\s)(${escapedTitle})(|$)`, 'i' );
|
// eslint-disable-next-line security/detect-non-literal-regexp
|
||||||
|
const regExp = new RegExp( `(^|\\s)(${ escapedTitle })(|$)`, 'i' );
|
||||||
|
|
||||||
// Remove text in parentheses along with the parentheses
|
// Remove text in parentheses along with the parentheses
|
||||||
extract = extract.replace( /\s+/, ' ' ); // Remove extra white spaces
|
extract = extract.replace( /\s+/, ' ' ); // Remove extra white spaces
|
||||||
|
@ -51,7 +52,7 @@ function makeTitleInExtractBold( extract, title ) {
|
||||||
// Also, the title is escaped of RegExp elements thus can't have "*"
|
// Also, the title is escaped of RegExp elements thus can't have "*"
|
||||||
extract = extract.replace(
|
extract = extract.replace(
|
||||||
regExp,
|
regExp,
|
||||||
`$1${snip}${boldIdentifier}$2${snip}$3`
|
`$1${ snip }${ boldIdentifier }$2${ snip }$3`
|
||||||
);
|
);
|
||||||
extract = extract.split( snip );
|
extract = extract.split( snip );
|
||||||
|
|
||||||
|
|
|
@ -15,14 +15,14 @@ export default function createReferenceGateway() {
|
||||||
* @return {HTMLElement}
|
* @return {HTMLElement}
|
||||||
*/
|
*/
|
||||||
function scrapeReferenceText( id ) {
|
function scrapeReferenceText( id ) {
|
||||||
const idSelector = `#${CSS.escape( id )}`;
|
const idSelector = `#${ CSS.escape( id ) }`;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Same alternative selectors with and without mw-… as in the RESTbased endpoint.
|
* Same alternative selectors with and without mw-… as in the RESTbased endpoint.
|
||||||
*
|
*
|
||||||
* @see https://phabricator.wikimedia.org/diffusion/GMOA/browse/master/lib/transformations/references/structureReferenceListContent.js$138
|
* @see https://phabricator.wikimedia.org/diffusion/GMOA/browse/master/lib/transformations/references/structureReferenceListContent.js$138
|
||||||
*/
|
*/
|
||||||
return document.querySelector( `${idSelector} .mw-reference-text, ${idSelector} .reference-text` );
|
return document.querySelector( `${ idSelector } .mw-reference-text, ${ idSelector } .reference-text` );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -75,7 +75,7 @@ export default function createReferenceGateway() {
|
||||||
}
|
}
|
||||||
|
|
||||||
const model = {
|
const model = {
|
||||||
url: `#${id}`,
|
url: `#${ id }`,
|
||||||
extract: referenceNode.innerHTML,
|
extract: referenceNode.innerHTML,
|
||||||
type: previewTypes.TYPE_REFERENCE,
|
type: previewTypes.TYPE_REFERENCE,
|
||||||
referenceType: scrapeReferenceType( referenceNode ),
|
referenceType: scrapeReferenceType( referenceNode ),
|
||||||
|
|
|
@ -41,7 +41,7 @@ export default function createRESTBaseGateway( ajax, config, extractParser ) {
|
||||||
return ajax( {
|
return ajax( {
|
||||||
url: endpoint + encodeURIComponent( title ),
|
url: endpoint + encodeURIComponent( title ),
|
||||||
headers: {
|
headers: {
|
||||||
Accept: `application/json; charset=utf-8; profile="${RESTBASE_PROFILE}"`,
|
Accept: `application/json; charset=utf-8; profile="${ RESTBASE_PROFILE }"`,
|
||||||
'Accept-Language': config.acceptLanguage
|
'Accept-Language': config.acceptLanguage
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
|
@ -156,7 +156,7 @@ function generateThumbnailData( thumbnail, original, thumbSize ) {
|
||||||
return originalIsSafe && original;
|
return originalIsSafe && original;
|
||||||
}
|
}
|
||||||
|
|
||||||
parts[ parts.length - 1 ] = `${width}px-${filename}`;
|
parts[ parts.length - 1 ] = `${ width }px-${ filename }`;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
source: parts.join( '/' ),
|
source: parts.join( '/' ),
|
||||||
|
|
|
@ -154,7 +154,7 @@ function handleDOMEventIfEligible( handler ) {
|
||||||
// If the closest method is not defined, let's return early and
|
// If the closest method is not defined, let's return early and
|
||||||
// understand this better by logging an error. (T340081)
|
// understand this better by logging an error. (T340081)
|
||||||
if ( target && !target.closest ) {
|
if ( target && !target.closest ) {
|
||||||
const err = new Error( `T340081: Unexpected DOM element ${target.tagName} with nodeType ${target.nodeType}` );
|
const err = new Error( `T340081: Unexpected DOM element ${ target.tagName } with nodeType ${ target.nodeType }` );
|
||||||
mw.errorLogger.logError( err, 'error.web-team' );
|
mw.errorLogger.logError( err, 'error.web-team' );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -245,7 +245,7 @@ function handleDOMEventIfEligible( handler ) {
|
||||||
// Register default preview type
|
// Register default preview type
|
||||||
mw.popups.register( {
|
mw.popups.register( {
|
||||||
type: previewTypes.TYPE_PAGE,
|
type: previewTypes.TYPE_PAGE,
|
||||||
selector: `#mw-content-text a[href][title]:not(${excludedLinksSelector})`,
|
selector: `#mw-content-text a[href][title]:not(${ excludedLinksSelector })`,
|
||||||
delay: FETCH_COMPLETE_TARGET_DELAY - FETCH_START_DELAY,
|
delay: FETCH_COMPLETE_TARGET_DELAY - FETCH_START_DELAY,
|
||||||
gateway: pagePreviewGateway,
|
gateway: pagePreviewGateway,
|
||||||
renderFn: createPagePreview,
|
renderFn: createPagePreview,
|
||||||
|
|
|
@ -9,7 +9,7 @@ import { previewTypes } from '../preview/model';
|
||||||
* @return {boolean} whether the preview type supports being disabled/enabled.
|
* @return {boolean} whether the preview type supports being disabled/enabled.
|
||||||
*/
|
*/
|
||||||
function canShowSettingForPreviewType( type ) {
|
function canShowSettingForPreviewType( type ) {
|
||||||
return mw.message( `popups-settings-option-${type}` ).exists();
|
return mw.message( `popups-settings-option-${ type }` ).exists();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -19,7 +19,8 @@ function canShowSettingForPreviewType( type ) {
|
||||||
* @param {Redux.Store} store Popups store
|
* @param {Redux.Store} store Popups store
|
||||||
* @param {Function} registerModel allows extensions to register custom preview handlers.
|
* @param {Function} registerModel allows extensions to register custom preview handlers.
|
||||||
* @param {Function} registerPreviewUI allows extensions to register custom preview renderers.
|
* @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 {Function} registerSetting
|
||||||
* @param {UserSettings} userSettings
|
* @param {UserSettings} userSettings
|
||||||
* @return {Object} external Popups interface
|
* @return {Object} external Popups interface
|
||||||
|
@ -40,16 +41,19 @@ export default function createMwPopups( store, registerModel, registerPreviewUI,
|
||||||
*
|
*
|
||||||
* @typedef {Object} PopupSubtype
|
* @typedef {Object} PopupSubtype
|
||||||
* @property {string} type A unique string for identifying the subtype of a page preview
|
* @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.
|
* @property {function(ext.popups.PreviewModel): ext.popups.Preview}[renderFn] How the
|
||||||
* If not provided default renderer is used.
|
* custom preview type will render the preview. If not provided default renderer is used.
|
||||||
*
|
*
|
||||||
* @typedef {Object} PopupModule
|
* @typedef {Object} PopupModule
|
||||||
* @property {string} type A unique string for identifying the type of page preview
|
* @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 {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.
|
* 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.
|
* @property {number} [delay] optional delay between hovering and displaying preview.
|
||||||
* If not defined, delay will be zero.
|
* If not defined, delay will be zero.
|
||||||
*/
|
*/
|
||||||
|
@ -75,7 +79,7 @@ export default function createMwPopups( store, registerModel, registerPreviewUI,
|
||||||
doNotRequireSummary } = module;
|
doNotRequireSummary } = module;
|
||||||
if ( !type || !selector || !gateway ) {
|
if ( !type || !selector || !gateway ) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`Registration of Popups custom preview type "${type}" failed: You must specify a type, a selector, and a gateway.`
|
`Registration of Popups custom preview type "${ type }" failed: You must specify a type, a selector, and a gateway.`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
registerModel( type, selector, delay );
|
registerModel( type, selector, delay );
|
||||||
|
@ -86,13 +90,17 @@ export default function createMwPopups( store, registerModel, registerPreviewUI,
|
||||||
registerSetting( type, userSettings.isPreviewTypeEnabled( type ) );
|
registerSetting( type, userSettings.isPreviewTypeEnabled( type ) );
|
||||||
} else {
|
} else {
|
||||||
mw.log.warn(
|
mw.log.warn(
|
||||||
`[Popups] No setting for ${type} registered.
|
`[Popups] No setting for ${ type } registered.
|
||||||
Please create message with key "popups-settings-option-${type}" if this is a mistake.`
|
Please create message with key "popups-settings-option-${ type }" if this is a mistake.`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if ( subTypes ) {
|
if ( subTypes ) {
|
||||||
subTypes.forEach( function ( subTypePreview ) {
|
subTypes.forEach( function ( subTypePreview ) {
|
||||||
registerPreviewUI( subTypePreview.type, subTypePreview.renderFn, subTypePreview.doNotRequireSummary );
|
registerPreviewUI(
|
||||||
|
subTypePreview.type,
|
||||||
|
subTypePreview.renderFn,
|
||||||
|
subTypePreview.doNotRequireSummary
|
||||||
|
);
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
// Run initialization function if provided.
|
// Run initialization function if provided.
|
||||||
|
|
|
@ -144,7 +144,9 @@ const registeredPreviewTypes = [];
|
||||||
* @return {string|null} One of the previewTypes.TYPE_… constants
|
* @return {string|null} One of the previewTypes.TYPE_… constants
|
||||||
*/
|
*/
|
||||||
export function getPreviewType( el ) {
|
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 the filter returned some possibilities, use the last registered one.
|
||||||
if ( candidates.length > 0 ) {
|
if ( candidates.length > 0 ) {
|
||||||
|
|
|
@ -44,6 +44,7 @@ export function getTitle( href, config ) {
|
||||||
// No query params (pretty URL)
|
// No query params (pretty URL)
|
||||||
if ( !queryLength ) {
|
if ( !queryLength ) {
|
||||||
const pattern = mw.util.escapeRegExp( config.get( 'wgArticlePath' ) ).replace( '\\$1', '([^?#]+)' ),
|
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 );
|
matches = new RegExp( pattern ).exec( linkHref.path );
|
||||||
|
|
||||||
// We can't be sure decodeURIComponent() is able to parse every possible match
|
// We can't be sure decodeURIComponent() is able to parse every possible match
|
||||||
|
@ -57,7 +58,7 @@ export function getTitle( href, config ) {
|
||||||
title = linkHref.query.title;
|
title = linkHref.query.title;
|
||||||
}
|
}
|
||||||
|
|
||||||
return title ? `${title}${linkHref.fragment ? `#${linkHref.fragment}` : ''}` : undefined;
|
return title ? `${ title }${ linkHref.fragment ? `#${ linkHref.fragment }` : '' }` : undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -182,7 +182,7 @@ function supportsCSSClipPath() {
|
||||||
return window.CSS &&
|
return window.CSS &&
|
||||||
typeof CSS.supports === 'function' &&
|
typeof CSS.supports === 'function' &&
|
||||||
CSS.supports( 'clip-path', 'polygon(1px 1px)' );
|
CSS.supports( 'clip-path', 'polygon(1px 1px)' );
|
||||||
/* eslint-enable compat/compat */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -547,7 +547,7 @@ export function layoutPreview(
|
||||||
thumbnail.height < predefinedLandscapeImageHeight && !supportsCSSClipPath()
|
thumbnail.height < predefinedLandscapeImageHeight && !supportsCSSClipPath()
|
||||||
) {
|
) {
|
||||||
const popupExtract = popup.querySelector( '.mwe-popups-extract' );
|
const popupExtract = popup.querySelector( '.mwe-popups-extract' );
|
||||||
popupExtract.style.marginTop = `${( thumbnail.height - pointerSpaceSize )}px`;
|
popupExtract.style.marginTop = `${ ( thumbnail.height - pointerSpaceSize ) }px`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The following classes are used here:
|
// The following classes are used here:
|
||||||
|
@ -562,9 +562,9 @@ export function layoutPreview(
|
||||||
// * mwe-popups-no-image-pointer
|
// * mwe-popups-no-image-pointer
|
||||||
popup.classList.add.apply( popup.classList, classes );
|
popup.classList.add.apply( popup.classList, classes );
|
||||||
|
|
||||||
popup.style.left = `${layout.offset.left}px`;
|
popup.style.left = `${ layout.offset.left }px`;
|
||||||
popup.style.top = flippedY ? 'auto' : `${layout.offset.top}px`;
|
popup.style.top = flippedY ? 'auto' : `${ layout.offset.top }px`;
|
||||||
popup.style.bottom = flippedY ? `${windowHeight - layout.offset.top}px` : 'auto';
|
popup.style.bottom = flippedY ? `${ windowHeight - layout.offset.top }px` : 'auto';
|
||||||
|
|
||||||
if ( hasThumbnail && !supportsCSSClipPath() ) {
|
if ( hasThumbnail && !supportsCSSClipPath() ) {
|
||||||
setThumbnailClipPath( preview, layout );
|
setThumbnailClipPath( preview, layout );
|
||||||
|
@ -610,11 +610,11 @@ export function setThumbnailClipPath(
|
||||||
const mask = document.getElementById( maskID );
|
const mask = document.getElementById( maskID );
|
||||||
mask.setAttribute(
|
mask.setAttribute(
|
||||||
'transform',
|
'transform',
|
||||||
`matrix(${matrix.scaleX} 0 0 1 ${matrix.translateX} 0)`
|
`matrix(${ matrix.scaleX } 0 0 1 ${ matrix.translateX } 0)`
|
||||||
);
|
);
|
||||||
|
|
||||||
el.querySelector( 'image' )
|
el.querySelector( 'image' )
|
||||||
.setAttribute( 'clip-path', `url(#${maskID})` );
|
.setAttribute( 'clip-path', `url(#${ maskID })` );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,11 +17,11 @@ export function createSettingsDialog( previewTypesEnabled ) {
|
||||||
// This can produce:
|
// This can produce:
|
||||||
// * popups-settings-option-preview
|
// * popups-settings-option-preview
|
||||||
// * popups-settings-option-reference
|
// * popups-settings-option-reference
|
||||||
name: mw.msg( `popups-settings-option-${id}` ),
|
name: mw.msg( `popups-settings-option-${ id }` ),
|
||||||
// This can produce:
|
// This can produce:
|
||||||
// * popups-settings-option-preview-description
|
// * popups-settings-option-preview-description
|
||||||
// * popups-settings-option-reference-description
|
// * popups-settings-option-reference-description
|
||||||
description: mw.msg( `popups-settings-option-${id}-description` ),
|
description: mw.msg( `popups-settings-option-${ id }-description` ),
|
||||||
isChecked: previewTypesEnabled[ id ]
|
isChecked: previewTypesEnabled[ id ]
|
||||||
}
|
}
|
||||||
) );
|
) );
|
||||||
|
|
|
@ -120,7 +120,7 @@ export default function createSettingsDialogRenderer() {
|
||||||
*/
|
*/
|
||||||
setEnabled( enabled ) {
|
setEnabled( enabled ) {
|
||||||
Object.keys( enabled ).forEach( ( type ) => {
|
Object.keys( enabled ).forEach( ( type ) => {
|
||||||
const node = dialog.querySelector( `#mwe-popups-settings-${type}` );
|
const node = dialog.querySelector( `#mwe-popups-settings-${ type }` );
|
||||||
if ( node ) {
|
if ( node ) {
|
||||||
node.checked = enabled[ type ];
|
node.checked = enabled[ type ];
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,5 +78,5 @@ export { defaultExtractWidth }; // for testing
|
||||||
* used for the extract
|
* used for the extract
|
||||||
*/
|
*/
|
||||||
export function getExtractWidth( thumbnail ) {
|
export function getExtractWidth( thumbnail ) {
|
||||||
return thumbnail && thumbnail.isNarrow ? `${defaultExtractWidth + thumbnail.offset}px` : '';
|
return thumbnail && thumbnail.isNarrow ? `${ defaultExtractWidth + thumbnail.offset }px` : '';
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ export function renderPopup( type, container ) {
|
||||||
// * mwe-popups-type-unknown
|
// * mwe-popups-type-unknown
|
||||||
// * mwe-popups-type-generic
|
// * mwe-popups-type-generic
|
||||||
// * mwe-popups-type-disambiguation
|
// * mwe-popups-type-disambiguation
|
||||||
element.className = `mwe-popups mwe-popups-type-${type}`;
|
element.className = `mwe-popups mwe-popups-type-${ type }`;
|
||||||
container.className = 'mwe-popups-container';
|
container.className = 'mwe-popups-container';
|
||||||
element.appendChild( container );
|
element.appendChild( container );
|
||||||
return element;
|
return element;
|
||||||
|
|
|
@ -38,7 +38,7 @@ export function renderPreview(
|
||||||
// * popups-icon--preview-unknown
|
// * popups-icon--preview-unknown
|
||||||
// * popups-icon--preview-generic
|
// * popups-icon--preview-generic
|
||||||
// * popups-icon--preview-disambiguation
|
// * popups-icon--preview-disambiguation
|
||||||
popup.querySelector( '.popups-icon' ).classList.add( `popups-icon--preview-${model.type}` );
|
popup.querySelector( '.popups-icon' ).classList.add( `popups-icon--preview-${ model.type }` );
|
||||||
popup.querySelector( '.mwe-popups-extract' ).setAttribute( 'href', model.url );
|
popup.querySelector( '.mwe-popups-extract' ).setAttribute( 'href', model.url );
|
||||||
const messageElement = popup.querySelector( '.mwe-popups-message' );
|
const messageElement = popup.querySelector( '.mwe-popups-message' );
|
||||||
if ( message ) {
|
if ( message ) {
|
||||||
|
|
|
@ -49,7 +49,7 @@ export function renderReferencePreview(
|
||||||
// * popups-refpreview-news
|
// * popups-refpreview-news
|
||||||
// * popups-refpreview-note
|
// * popups-refpreview-note
|
||||||
// * popups-refpreview-web
|
// * popups-refpreview-web
|
||||||
let titleMsg = mw.message( `popups-refpreview-${type}` );
|
let titleMsg = mw.message( `popups-refpreview-${ type }` );
|
||||||
if ( !titleMsg.exists() ) {
|
if ( !titleMsg.exists() ) {
|
||||||
titleMsg = mw.message( 'popups-refpreview-reference' );
|
titleMsg = mw.message( 'popups-refpreview-reference' );
|
||||||
}
|
}
|
||||||
|
@ -64,7 +64,7 @@ export function renderReferencePreview(
|
||||||
// * popups-icon--reference-note
|
// * popups-icon--reference-note
|
||||||
// * popups-icon--reference-web
|
// * popups-icon--reference-web
|
||||||
el.querySelector( '.mwe-popups-title .popups-icon' )
|
el.querySelector( '.mwe-popups-title .popups-icon' )
|
||||||
.classList.add( `popups-icon--reference-${type}` );
|
.classList.add( `popups-icon--reference-${ type }` );
|
||||||
el.querySelector( '.mw-parser-output' )
|
el.querySelector( '.mw-parser-output' )
|
||||||
.innerHTML = model.extract;
|
.innerHTML = model.extract;
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ export function renderReferencePreview(
|
||||||
( a ) => {
|
( a ) => {
|
||||||
a.target = '_blank';
|
a.target = '_blank';
|
||||||
// Don't let the external site access and possibly manipulate window.opener.location
|
// Don't let the external site access and possibly manipulate window.opener.location
|
||||||
a.rel = `${a.rel ? `${a.rel} ` : ''}noopener`;
|
a.rel = `${ a.rel ? `${ a.rel } ` : '' }noopener`;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -160,8 +160,8 @@ export function renderReferencePreview(
|
||||||
hasVerticalScroll = element.scrollHeight > element.clientHeight,
|
hasVerticalScroll = element.scrollHeight > element.clientHeight,
|
||||||
scrollbarWidth = element.offsetWidth - element.clientWidth;
|
scrollbarWidth = element.offsetWidth - element.clientWidth;
|
||||||
const fade = extract.querySelector( '.mwe-popups-fade' );
|
const fade = extract.querySelector( '.mwe-popups-fade' );
|
||||||
fade.style.bottom = hasHorizontalScroll ? `${scrollbarHeight}px` : 0;
|
fade.style.bottom = hasHorizontalScroll ? `${ scrollbarHeight }px` : 0;
|
||||||
fade.style.right = hasVerticalScroll ? `${scrollbarWidth}px` : 0;
|
fade.style.right = hasVerticalScroll ? `${ scrollbarWidth }px` : 0;
|
||||||
|
|
||||||
element.isScrolling = !scrolledToBottom;
|
element.isScrolling = !scrolledToBottom;
|
||||||
extract.classList.toggle( 'mwe-popups-fade-out', element.isScrolling );
|
extract.classList.toggle( 'mwe-popups-fade-out', element.isScrolling );
|
||||||
|
|
|
@ -60,36 +60,36 @@ export function renderSettingsDialog( model ) {
|
||||||
<div>
|
<div>
|
||||||
<button class='cdx-button cdx-button--weight-quiet cdx-button--icon-only'>
|
<button class='cdx-button cdx-button--weight-quiet cdx-button--icon-only'>
|
||||||
<span class='popups-icon popups-icon--close close'></span>
|
<span class='popups-icon popups-icon--close close'></span>
|
||||||
<span>${closeLabel}</span>
|
<span>${ closeLabel }</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<h1>${heading}</h1>
|
<h1>${ heading }</h1>
|
||||||
<div>
|
<div>
|
||||||
<button class='save cdx-button cdx-button--weight-primary cdx-button--action-progressive'>${saveLabel}</button>
|
<button class='save cdx-button cdx-button--weight-primary cdx-button--action-progressive'>${ saveLabel }</button>
|
||||||
<button class='okay cdx-button cdx-button--weight-primary cdx-button--action-progressive' style='display:none;'>${okLabel}</button>
|
<button class='okay cdx-button cdx-button--weight-primary cdx-button--action-progressive' style='display:none;'>${ okLabel }</button>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
<main id='mwe-popups-settings-form'>
|
<main id='mwe-popups-settings-form'>
|
||||||
<form>
|
<form>
|
||||||
${choices.map( ( { id, name, description, isChecked } ) => `
|
${ choices.map( ( { id, name, description, isChecked } ) => `
|
||||||
<p class="cdx-checkbox">
|
<p class="cdx-checkbox">
|
||||||
<input
|
<input
|
||||||
${isChecked ? 'checked' : ''}
|
${ isChecked ? 'checked' : '' }
|
||||||
value='${id}'
|
value='${ id }'
|
||||||
type='checkbox'
|
type='checkbox'
|
||||||
id='mwe-popups-settings-${id}'
|
id='mwe-popups-settings-${ id }'
|
||||||
class='cdx-checkbox__input'>
|
class='cdx-checkbox__input'>
|
||||||
<span class="cdx-checkbox__icon"> </span>
|
<span class="cdx-checkbox__icon"> </span>
|
||||||
<label class="cdx-checkbox__label" for='mwe-popups-settings-${id}'>
|
<label class="cdx-checkbox__label" for='mwe-popups-settings-${ id }'>
|
||||||
<span>${name}</span>
|
<span>${ name }</span>
|
||||||
${description}
|
${ description }
|
||||||
</label>
|
</label>
|
||||||
</p>` ).join( '' )}
|
</p>` ).join( '' ) }
|
||||||
</form>
|
</form>
|
||||||
</main>
|
</main>
|
||||||
<div class='mwe-popups-settings-help' style='display:none;'>
|
<div class='mwe-popups-settings-help' style='display:none;'>
|
||||||
<div class="popups-icon popups-icon--footer"></div>
|
<div class="popups-icon popups-icon--footer"></div>
|
||||||
<p>${helpText}</p>
|
<p>${ helpText }</p>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
`.trim();
|
`.trim();
|
||||||
|
|
|
@ -130,7 +130,7 @@ function createThumbnailImg( url ) {
|
||||||
* Sets multiple attributes on a node.
|
* Sets multiple attributes on a node.
|
||||||
*
|
*
|
||||||
* @param {HTMLElement} node
|
* @param {HTMLElement} node
|
||||||
* @param {Record<String, String>} attrs
|
* @param {Record<string, string>} attrs
|
||||||
*/
|
*/
|
||||||
const addAttributes = ( node, attrs ) => {
|
const addAttributes = ( node, attrs ) => {
|
||||||
Object.keys( attrs ).forEach( ( key ) => {
|
Object.keys( attrs ).forEach( ( key ) => {
|
||||||
|
|
|
@ -41,9 +41,11 @@ export default function createUserSettings( storage ) {
|
||||||
*
|
*
|
||||||
* @method
|
* @method
|
||||||
* @param {string} previewType
|
* @param {string} previewType
|
||||||
|
*
|
||||||
|
* @return {boolean}
|
||||||
*/
|
*/
|
||||||
isPreviewTypeEnabled( previewType ) {
|
isPreviewTypeEnabled( previewType ) {
|
||||||
const storageKey = `mwe-popups-${previewType}-enabled`;
|
const storageKey = `mwe-popups-${ previewType }-enabled`;
|
||||||
const value = storage.get( storageKey );
|
const value = storage.get( storageKey );
|
||||||
return value === null;
|
return value === null;
|
||||||
},
|
},
|
||||||
|
@ -63,7 +65,7 @@ export default function createUserSettings( storage ) {
|
||||||
action: enabled ? 'anonymousEnabled' : 'anonymousDisabled'
|
action: enabled ? 'anonymousEnabled' : 'anonymousDisabled'
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
const storageKey = `mwe-popups-${previewType}-enabled`;
|
const storageKey = `mwe-popups-${ previewType }-enabled`;
|
||||||
if ( enabled ) {
|
if ( enabled ) {
|
||||||
storage.remove( storageKey );
|
storage.remove( storageKey );
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -6,9 +6,6 @@
|
||||||
],
|
],
|
||||||
"rules": {
|
"rules": {
|
||||||
"no-jquery/no-class-state": "off",
|
"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"
|
"es-x/no-hashbang": "warn"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,9 @@ QUnit.module( 'ext.popups/changeListeners/footerLink @integration', {
|
||||||
// Stub internal usage of mw.message
|
// Stub internal usage of mw.message
|
||||||
mw.message = ( str ) =>
|
mw.message = ( str ) =>
|
||||||
( {
|
( {
|
||||||
text() { return str; }
|
text() {
|
||||||
|
return str;
|
||||||
|
}
|
||||||
} );
|
} );
|
||||||
|
|
||||||
boundActions.showSettings = this.showSettingsSpy = this.sandbox.spy();
|
boundActions.showSettings = this.showSettingsSpy = this.sandbox.spy();
|
||||||
|
|
|
@ -34,7 +34,9 @@ QUnit.module( 'ext.popups/pageviews', {
|
||||||
// Stub internal usage of mw.Title.newFromText
|
// Stub internal usage of mw.Title.newFromText
|
||||||
mw.Title.newFromText = ( str ) => {
|
mw.Title.newFromText = ( str ) => {
|
||||||
return {
|
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 ) {
|
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;
|
delete noPageviewState.pageviews.pageview;
|
||||||
|
|
||||||
this.changeListener( undefined, newState );
|
this.changeListener( undefined, newState );
|
||||||
|
|
|
@ -39,7 +39,9 @@ QUnit.test( '#get', function ( assert ) {
|
||||||
// ---
|
// ---
|
||||||
|
|
||||||
assert.throws(
|
assert.throws(
|
||||||
() => { this.container.get( 'bar' ); },
|
() => {
|
||||||
|
this.container.get( 'bar' );
|
||||||
|
},
|
||||||
/The service "bar" hasn't been defined./,
|
/The service "bar" hasn't been defined./,
|
||||||
'The container throws an error when no factory exists.'
|
'The container throws an error when no factory exists.'
|
||||||
);
|
);
|
||||||
|
|
|
@ -26,7 +26,7 @@ QUnit.test( '#getEditCountBucket', ( assert ) => {
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
bucket,
|
bucket,
|
||||||
cases[ i ][ 1 ],
|
cases[ i ][ 1 ],
|
||||||
`Edit count bucket is "${bucket}" when edit count is ${count}.`
|
`Edit count bucket is "${ bucket }" when edit count is ${ count }.`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
|
@ -57,7 +57,7 @@ QUnit.test( '#getPreviewCountBucket', ( assert ) => {
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
bucket,
|
bucket,
|
||||||
cases[ i ][ 1 ],
|
cases[ i ][ 1 ],
|
||||||
`Preview count bucket is "${bucket}" when preview count is ${count}.`
|
`Preview count bucket is "${ bucket }" when preview count is ${ count }.`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
|
|
|
@ -65,7 +65,7 @@ QUnit.module( 'ext.popups/gateway/mediawiki', {
|
||||||
} );
|
} );
|
||||||
|
|
||||||
QUnit.test( 'MediaWiki API gateway is called with correct arguments', function ( assert ) {
|
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'
|
acceptLanguage: 'pl'
|
||||||
} );
|
} );
|
||||||
const spy = this.sandbox.spy(),
|
const spy = this.sandbox.spy(),
|
||||||
|
@ -136,8 +136,10 @@ QUnit.test( 'MediaWiki API gateway is correctly extracting the page data from th
|
||||||
|
|
||||||
errorCases.forEach( ( data, i ) => {
|
errorCases.forEach( ( data, i ) => {
|
||||||
assert.throws(
|
assert.throws(
|
||||||
() => { gateway.extractPageFromResponse( data ); },
|
() => {
|
||||||
`Case ${i}: the gateway throws an error.`
|
gateway.extractPageFromResponse( data );
|
||||||
|
},
|
||||||
|
`Case ${ i }: the gateway throws an error.`
|
||||||
);
|
);
|
||||||
} );
|
} );
|
||||||
|
|
||||||
|
@ -145,7 +147,7 @@ QUnit.test( 'MediaWiki API gateway is correctly extracting the page data from th
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
gateway.extractPageFromResponse( data[ 0 ] ),
|
gateway.extractPageFromResponse( data[ 0 ] ),
|
||||||
data[ 1 ],
|
data[ 1 ],
|
||||||
`Case ${i}: the gateway extracts the response.`
|
`Case ${ i }: the gateway extracts the response.`
|
||||||
);
|
);
|
||||||
} );
|
} );
|
||||||
} );
|
} );
|
||||||
|
@ -237,7 +239,9 @@ QUnit.test( 'MediaWiki API gateway is abortable', function ( assert ) {
|
||||||
deferred = $.Deferred(),
|
deferred = $.Deferred(),
|
||||||
api = {
|
api = {
|
||||||
get: this.sandbox.stub().returns(
|
get: this.sandbox.stub().returns(
|
||||||
deferred.promise( { abort() { deferred.reject( 'http' ); } } )
|
deferred.promise( { abort() {
|
||||||
|
deferred.reject( 'http' );
|
||||||
|
} } )
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
gateway = createMediaWikiApiGateway( api, DEFAULT_CONSTANTS );
|
gateway = createMediaWikiApiGateway( api, DEFAULT_CONSTANTS );
|
||||||
|
|
|
@ -6,9 +6,9 @@ QUnit.module( 'ext.popups/gateway/reference', {
|
||||||
global.CSS = {
|
global.CSS = {
|
||||||
escape: ( str ) => $.escapeSelector( str )
|
escape: ( str ) => $.escapeSelector( str )
|
||||||
};
|
};
|
||||||
mw.msg = ( key ) => `<${key}>`;
|
mw.msg = ( key ) => `<${ key }>`;
|
||||||
mw.message = ( key ) => {
|
mw.message = ( key ) => {
|
||||||
return { exists: () => !key.endsWith( 'generic' ), text: () => `<${key}>` };
|
return { exists: () => !key.endsWith( 'generic' ), text: () => `<${ key }>` };
|
||||||
};
|
};
|
||||||
|
|
||||||
this.$sourceElement = $( '<a>' ).appendTo(
|
this.$sourceElement = $( '<a>' ).appendTo(
|
||||||
|
|
|
@ -170,13 +170,13 @@ const DEFAULT_CONSTANTS = {
|
||||||
);
|
);
|
||||||
|
|
||||||
function provideParsedExtract( page ) {
|
function provideParsedExtract( page ) {
|
||||||
return `!${page.extract}!`;
|
return `!${ page.extract }!`;
|
||||||
}
|
}
|
||||||
|
|
||||||
QUnit.module( 'gateway/rest', {
|
QUnit.module( 'gateway/rest', {
|
||||||
beforeEach() {
|
beforeEach() {
|
||||||
mw.Title = function ( title ) {
|
mw.Title = function ( title ) {
|
||||||
this.getUrl = () => `url/${title}`;
|
this.getUrl = () => `url/${ title }`;
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
afterEach() {
|
afterEach() {
|
||||||
|
@ -185,7 +185,7 @@ QUnit.module( 'gateway/rest', {
|
||||||
} );
|
} );
|
||||||
|
|
||||||
QUnit.test( 'RESTBase gateway is called with correct arguments', function ( assert ) {
|
QUnit.test( 'RESTBase gateway is called with correct arguments', function ( assert ) {
|
||||||
const config = $.extend( {}, DEFAULT_CONSTANTS, {
|
const config = Object.assign( {}, DEFAULT_CONSTANTS, {
|
||||||
acceptLanguage: 'pl'
|
acceptLanguage: 'pl'
|
||||||
} );
|
} );
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,9 @@ QUnit.module( 'ext.popups.preview.settingsBehavior', {
|
||||||
beforeEach() {
|
beforeEach() {
|
||||||
function newFromText( title ) {
|
function newFromText( title ) {
|
||||||
return {
|
return {
|
||||||
getUrl() { return `url/${title}`; }
|
getUrl() {
|
||||||
|
return `url/${ title }`;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@ require( '@babel/register' )( {
|
||||||
} );
|
} );
|
||||||
|
|
||||||
require.extensions[ '.svg' ] = ( module, filename ) => {
|
require.extensions[ '.svg' ] = ( module, filename ) => {
|
||||||
|
// eslint-disable-next-line security/detect-non-literal-fs-filename
|
||||||
const svg = fs.readFileSync( filename, { encoding: 'utf8' } );
|
const svg = fs.readFileSync( filename, { encoding: 'utf8' } );
|
||||||
// eslint-disable-next-line no-underscore-dangle
|
// eslint-disable-next-line no-underscore-dangle
|
||||||
module._compile( svgInlineLoader( svg ), filename );
|
module._compile( svgInlineLoader( svg ), filename );
|
||||||
|
|
|
@ -72,7 +72,7 @@ export function createStubTitle( namespace, name, fragment = null ) {
|
||||||
return {
|
return {
|
||||||
namespace,
|
namespace,
|
||||||
getPrefixedDb() {
|
getPrefixedDb() {
|
||||||
return ( namespace ? `Namespace ${namespace}:` : '' ) + name;
|
return ( namespace ? `Namespace ${ namespace }:` : '' ) + name;
|
||||||
},
|
},
|
||||||
getMainText() {
|
getMainText() {
|
||||||
return name;
|
return name;
|
||||||
|
@ -81,7 +81,7 @@ export function createStubTitle( namespace, name, fragment = null ) {
|
||||||
return namespace;
|
return namespace;
|
||||||
},
|
},
|
||||||
getUrl() {
|
getUrl() {
|
||||||
return `/wiki/${this.getPrefixedDb()}`;
|
return `/wiki/${ this.getPrefixedDb() }`;
|
||||||
},
|
},
|
||||||
getFragment() {
|
getFragment() {
|
||||||
return fragment;
|
return fragment;
|
||||||
|
|
|
@ -41,9 +41,9 @@ QUnit.module( 'ext.popups#renderer', {
|
||||||
beforeEach() {
|
beforeEach() {
|
||||||
this.sandbox.stub( constants.default, 'BRACKETED_DEVICE_PIXEL_RATIO' ).value( 1 );
|
this.sandbox.stub( constants.default, 'BRACKETED_DEVICE_PIXEL_RATIO' ).value( 1 );
|
||||||
|
|
||||||
mw.msg = ( key ) => `<${key}>`;
|
mw.msg = ( key ) => `<${ key }>`;
|
||||||
mw.message = ( key ) => {
|
mw.message = ( key ) => {
|
||||||
return { exists: () => !key.endsWith( 'generic' ), text: () => `<${key}>` };
|
return { exists: () => !key.endsWith( 'generic' ), text: () => `<${ key }>` };
|
||||||
};
|
};
|
||||||
|
|
||||||
mw.html = {
|
mw.html = {
|
||||||
|
@ -77,7 +77,7 @@ QUnit.test( 'getExtractWidth', ( assert ) => {
|
||||||
],
|
],
|
||||||
[ {
|
[ {
|
||||||
isNarrow: true, offset: 10
|
isNarrow: true, offset: 10
|
||||||
}, `${pagePreview.defaultExtractWidth + 10}px` ],
|
}, `${ pagePreview.defaultExtractWidth + 10 }px` ],
|
||||||
[ {
|
[ {
|
||||||
// Fall back to css stylesheet for non-narrow thumbs.
|
// Fall back to css stylesheet for non-narrow thumbs.
|
||||||
isNarrow: false, offset: 100
|
isNarrow: false, offset: 100
|
||||||
|
@ -88,7 +88,7 @@ QUnit.test( 'getExtractWidth', ( assert ) => {
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
pagePreview.getExtractWidth( case_[ 0 ] ),
|
pagePreview.getExtractWidth( case_[ 0 ] ),
|
||||||
case_[ 1 ],
|
case_[ 1 ],
|
||||||
`Case ${i}: the expected extract width matches.`
|
`Case ${ i }: the expected extract width matches.`
|
||||||
);
|
);
|
||||||
} );
|
} );
|
||||||
} );
|
} );
|
||||||
|
@ -106,9 +106,9 @@ QUnit.test( 'createPointerMasks', ( assert ) => {
|
||||||
|
|
||||||
cases.forEach( ( case_, i ) => {
|
cases.forEach( ( case_, i ) => {
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
$container.find( `${case_[ 0 ]} path` ).attr( 'd' ),
|
$container.find( `${ case_[ 0 ] } path` ).attr( 'd' ),
|
||||||
case_[ 1 ],
|
case_[ 1 ],
|
||||||
`Case ${i}: the SVG's polygons match.`
|
`Case ${ i }: the SVG's polygons match.`
|
||||||
);
|
);
|
||||||
} );
|
} );
|
||||||
} );
|
} );
|
||||||
|
@ -637,7 +637,7 @@ QUnit.test( '#createLayout - portrait preview, mouse event, link is on the top l
|
||||||
flippedY: false,
|
flippedY: false,
|
||||||
dir
|
dir
|
||||||
},
|
},
|
||||||
`Case ${i}: the layout is correct.`
|
`Case ${ i }: the layout is correct.`
|
||||||
);
|
);
|
||||||
} );
|
} );
|
||||||
} );
|
} );
|
||||||
|
@ -685,7 +685,7 @@ QUnit.test( '#createLayout - tall preview, mouse event, link is on the bottom ce
|
||||||
flippedY: true,
|
flippedY: true,
|
||||||
dir
|
dir
|
||||||
},
|
},
|
||||||
`Case ${i}: the layout is correct. Y is flipped.`
|
`Case ${ i }: the layout is correct. Y is flipped.`
|
||||||
);
|
);
|
||||||
} );
|
} );
|
||||||
} );
|
} );
|
||||||
|
@ -730,7 +730,7 @@ QUnit.test( '#createLayout - empty preview, keyboard event, link is on the cente
|
||||||
flippedY: true,
|
flippedY: true,
|
||||||
dir
|
dir
|
||||||
},
|
},
|
||||||
`Case ${i}: the layout is correct. Both X and Y are flipped.`
|
`Case ${ i }: the layout is correct. Both X and Y are flipped.`
|
||||||
);
|
);
|
||||||
} );
|
} );
|
||||||
} );
|
} );
|
||||||
|
@ -778,7 +778,7 @@ QUnit.test( '#createLayout - empty preview, mouse event, popup pointer is in the
|
||||||
flippedY: false,
|
flippedY: false,
|
||||||
dir
|
dir
|
||||||
},
|
},
|
||||||
`Case ${i}: the layout is correct.`
|
`Case ${ i }: the layout is correct.`
|
||||||
);
|
);
|
||||||
} );
|
} );
|
||||||
} );
|
} );
|
||||||
|
@ -1045,12 +1045,12 @@ QUnit.test( '#layoutPreview - no thumbnail', ( assert ) => {
|
||||||
|
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
$( preview.el ).css( 'top' ),
|
$( preview.el ).css( 'top' ),
|
||||||
`${layout.offset.top}px`,
|
`${ layout.offset.top }px`,
|
||||||
'Top is correct.'
|
'Top is correct.'
|
||||||
);
|
);
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
$( preview.el ).css( 'left' ),
|
$( preview.el ).css( 'left' ),
|
||||||
`${layout.offset.left}px`,
|
`${ layout.offset.left }px`,
|
||||||
'Left is correct.'
|
'Left is correct.'
|
||||||
);
|
);
|
||||||
} );
|
} );
|
||||||
|
@ -1080,12 +1080,12 @@ QUnit.test( '#layoutPreview - tall preview, flipped X, has thumbnail', function
|
||||||
);
|
);
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
$( preview.el ).css( 'top' ),
|
$( preview.el ).css( 'top' ),
|
||||||
`${layout.offset.top}px`,
|
`${ layout.offset.top }px`,
|
||||||
'Top is correct.'
|
'Top is correct.'
|
||||||
);
|
);
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
$( preview.el ).css( 'left' ),
|
$( preview.el ).css( 'left' ),
|
||||||
`${layout.offset.left}px`,
|
`${ layout.offset.left }px`,
|
||||||
'Left is correct.'
|
'Left is correct.'
|
||||||
);
|
);
|
||||||
assert.false(
|
assert.false(
|
||||||
|
@ -1124,17 +1124,17 @@ QUnit.test( '#layoutPreview - portrait preview, flipped X, has thumbnail, small
|
||||||
);
|
);
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
$( preview.el ).css( 'top' ),
|
$( preview.el ).css( 'top' ),
|
||||||
`${layout.offset.top}px`,
|
`${ layout.offset.top }px`,
|
||||||
'Top is correct.'
|
'Top is correct.'
|
||||||
);
|
);
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
$( preview.el ).css( 'left' ),
|
$( preview.el ).css( 'left' ),
|
||||||
`${layout.offset.left}px`,
|
`${ layout.offset.left }px`,
|
||||||
'Left is correct.'
|
'Left is correct.'
|
||||||
);
|
);
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
$( preview.el ).find( '.mwe-popups-extract' ).css( 'margin-top' ),
|
$( preview.el ).find( '.mwe-popups-extract' ).css( 'margin-top' ),
|
||||||
`${199 - 8}px`, // thumb height - pointer size
|
`${ 199 - 8 }px`, // thumb height - pointer size
|
||||||
'Extract margin top has been set when preview height is smaller than the predefined landscape image height.'
|
'Extract margin top has been set when preview height is smaller than the predefined landscape image height.'
|
||||||
);
|
);
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
|
@ -1169,12 +1169,12 @@ QUnit.test( '#layoutPreview - portrait preview, flipped X, has thumbnail, big he
|
||||||
);
|
);
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
$( preview.el ).css( 'top' ),
|
$( preview.el ).css( 'top' ),
|
||||||
`${layout.offset.top}px`,
|
`${ layout.offset.top }px`,
|
||||||
'Top is correct.'
|
'Top is correct.'
|
||||||
);
|
);
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
$( preview.el ).css( 'left' ),
|
$( preview.el ).css( 'left' ),
|
||||||
`${layout.offset.left}px`,
|
`${ layout.offset.left }px`,
|
||||||
'Left is correct.'
|
'Left is correct.'
|
||||||
);
|
);
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
|
@ -1329,13 +1329,13 @@ QUnit.test( '#layoutPreview - tall preview, has thumbnail, flipped Y', ( assert
|
||||||
|
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
$( preview.el ).css( 'bottom' ),
|
$( preview.el ).css( 'bottom' ),
|
||||||
`${windowHeight - layout.offset.top}px`,
|
`${ windowHeight - layout.offset.top }px`,
|
||||||
'Bottom is correct.'
|
'Bottom is correct.'
|
||||||
);
|
);
|
||||||
|
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
$( preview.el ).css( 'left' ),
|
$( preview.el ).css( 'left' ),
|
||||||
`${layout.offset.left}px`,
|
`${ layout.offset.left }px`,
|
||||||
'Left is correct.'
|
'Left is correct.'
|
||||||
);
|
);
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
|
@ -1370,12 +1370,12 @@ QUnit.test( '#layoutPreview - tall preview, has thumbnail, flipped X and Y', fun
|
||||||
);
|
);
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
$( preview.el ).css( 'left' ),
|
$( preview.el ).css( 'left' ),
|
||||||
`${layout.offset.left}px`,
|
`${ layout.offset.left }px`,
|
||||||
'Left is correct.'
|
'Left is correct.'
|
||||||
);
|
);
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
$( preview.el ).css( 'bottom' ),
|
$( preview.el ).css( 'bottom' ),
|
||||||
`${windowHeight - layout.offset.top}px`,
|
`${ windowHeight - layout.offset.top }px`,
|
||||||
'Bottom is correct.'
|
'Bottom is correct.'
|
||||||
);
|
);
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
|
@ -1406,12 +1406,12 @@ QUnit.test( '#layoutPreview - portrait preview, has thumbnail, flipped X and Y',
|
||||||
);
|
);
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
$( preview.el ).css( 'left' ),
|
$( preview.el ).css( 'left' ),
|
||||||
`${layout.offset.left}px`,
|
`${ layout.offset.left }px`,
|
||||||
'Left is correct.'
|
'Left is correct.'
|
||||||
);
|
);
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
$( preview.el ).css( 'bottom' ),
|
$( preview.el ).css( 'bottom' ),
|
||||||
`${windowHeight - layout.offset.top}px`,
|
`${ windowHeight - layout.offset.top }px`,
|
||||||
'Bottom is correct.'
|
'Bottom is correct.'
|
||||||
);
|
);
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
|
@ -1458,7 +1458,7 @@ QUnit.test( '#setThumbnailClipPath', function ( assert ) {
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
clipPath.getAttribute( 'transform' ),
|
clipPath.getAttribute( 'transform' ),
|
||||||
expected,
|
expected,
|
||||||
`Transform is correct for: { isTall: ${isTall}, dir: ${dir} }.`
|
`Transform is correct for: { isTall: ${ isTall }, dir: ${ dir } }.`
|
||||||
);
|
);
|
||||||
} );
|
} );
|
||||||
} );
|
} );
|
||||||
|
@ -1478,7 +1478,7 @@ QUnit.test( '#getThumbnailClipPathID', ( assert ) => {
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
renderer.getThumbnailClipPathID( isTall, flippedY, flippedX ),
|
renderer.getThumbnailClipPathID( isTall, flippedY, flippedX ),
|
||||||
expected,
|
expected,
|
||||||
`Correct element ID is returned for: { flippedY: ${flippedY}, flippedX: ${flippedX}, isTall: ${isTall} }.`
|
`Correct element ID is returned for: { flippedY: ${ flippedY }, flippedX: ${ flippedX }, isTall: ${ isTall } }.`
|
||||||
);
|
);
|
||||||
} );
|
} );
|
||||||
} );
|
} );
|
||||||
|
|
|
@ -88,42 +88,42 @@ QUnit.test( 'createThumbnail - tall image element', ( assert ) => {
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
+$( thumbnail.el ).find( 'image' ).attr( 'x' ),
|
+$( thumbnail.el ).find( 'image' ).attr( 'x' ),
|
||||||
case_.expectedX,
|
case_.expectedX,
|
||||||
`Image element x coordinate is correct. ${case_.message}`
|
`Image element x coordinate is correct. ${ case_.message }`
|
||||||
);
|
);
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
+$( thumbnail.el ).find( 'image' ).attr( 'y' ),
|
+$( thumbnail.el ).find( 'image' ).attr( 'y' ),
|
||||||
case_.expectedY,
|
case_.expectedY,
|
||||||
`Image element y coordinate is correct. ${case_.message}`
|
`Image element y coordinate is correct. ${ case_.message }`
|
||||||
);
|
);
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
+$( thumbnail.el ).find( 'image' ).attr( 'width' ),
|
+$( thumbnail.el ).find( 'image' ).attr( 'width' ),
|
||||||
case_.width,
|
case_.width,
|
||||||
`Image element width is correct. ${case_.message}`
|
`Image element width is correct. ${ case_.message }`
|
||||||
);
|
);
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
+$( thumbnail.el ).find( 'image' ).attr( 'height' ),
|
+$( thumbnail.el ).find( 'image' ).attr( 'height' ),
|
||||||
case_.height,
|
case_.height,
|
||||||
`Image element height is correct. ${case_.message}`
|
`Image element height is correct. ${ case_.message }`
|
||||||
);
|
);
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
+$( thumbnail.el ).attr( 'width' ),
|
+$( thumbnail.el ).attr( 'width' ),
|
||||||
case_.expectedSVGWidth,
|
case_.expectedSVGWidth,
|
||||||
`Image SVG width is correct. ${case_.message}`
|
`Image SVG width is correct. ${ case_.message }`
|
||||||
);
|
);
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
+$( thumbnail.el ).attr( 'height' ),
|
+$( thumbnail.el ).attr( 'height' ),
|
||||||
case_.expectedSVGHeight,
|
case_.expectedSVGHeight,
|
||||||
`Image SVG height is correct. ${case_.message}`
|
`Image SVG height is correct. ${ case_.message }`
|
||||||
);
|
);
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
thumbnail.isNarrow,
|
thumbnail.isNarrow,
|
||||||
case_.expectedIsNarrow,
|
case_.expectedIsNarrow,
|
||||||
`Image isNarrow is correct. ${case_.message}`
|
`Image isNarrow is correct. ${ case_.message }`
|
||||||
);
|
);
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
thumbnail.offset,
|
thumbnail.offset,
|
||||||
case_.expectedOffset,
|
case_.expectedOffset,
|
||||||
`Image offset is correct. ${case_.message}`
|
`Image offset is correct. ${ case_.message }`
|
||||||
);
|
);
|
||||||
} );
|
} );
|
||||||
} );
|
} );
|
||||||
|
@ -210,32 +210,32 @@ QUnit.test( 'createThumbnail - landscape image element', ( assert ) => {
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
+$( thumbnail.el ).find( 'image' ).attr( 'x' ),
|
+$( thumbnail.el ).find( 'image' ).attr( 'x' ),
|
||||||
case_.expectedX,
|
case_.expectedX,
|
||||||
`Image x coordinate is correct. ${case_.message}`
|
`Image x coordinate is correct. ${ case_.message }`
|
||||||
);
|
);
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
+$( thumbnail.el ).find( 'image' ).attr( 'y' ),
|
+$( thumbnail.el ).find( 'image' ).attr( 'y' ),
|
||||||
case_.expectedY,
|
case_.expectedY,
|
||||||
`Image y coordinate is correct. ${case_.message}`
|
`Image y coordinate is correct. ${ case_.message }`
|
||||||
);
|
);
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
+$( thumbnail.el ).find( 'image' ).attr( 'width' ),
|
+$( thumbnail.el ).find( 'image' ).attr( 'width' ),
|
||||||
case_.width,
|
case_.width,
|
||||||
`Image element width is correct. ${case_.message}`
|
`Image element width is correct. ${ case_.message }`
|
||||||
);
|
);
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
+$( thumbnail.el ).find( 'image' ).attr( 'height' ),
|
+$( thumbnail.el ).find( 'image' ).attr( 'height' ),
|
||||||
case_.height,
|
case_.height,
|
||||||
`Image element height is correct. ${case_.message}`
|
`Image element height is correct. ${ case_.message }`
|
||||||
);
|
);
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
+$( thumbnail.el ).attr( 'width' ),
|
+$( thumbnail.el ).attr( 'width' ),
|
||||||
case_.expectedSVGWidth,
|
case_.expectedSVGWidth,
|
||||||
`Image SVG width is correct. ${case_.message}`
|
`Image SVG width is correct. ${ case_.message }`
|
||||||
);
|
);
|
||||||
assert.strictEqual(
|
assert.strictEqual(
|
||||||
+$( thumbnail.el ).attr( 'height' ),
|
+$( thumbnail.el ).attr( 'height' ),
|
||||||
case_.expectedSVGHeight,
|
case_.expectedSVGHeight,
|
||||||
`Image SVG height is correct. ${case_.message}`
|
`Image SVG height is correct. ${ case_.message }`
|
||||||
);
|
);
|
||||||
} );
|
} );
|
||||||
} );
|
} );
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
"mw": "readonly"
|
"mw": "readonly"
|
||||||
},
|
},
|
||||||
"rules": {
|
"rules": {
|
||||||
"no-jquery/no-jquery-constructor": "off",
|
|
||||||
"wdio/no-pause": "warn"
|
"wdio/no-pause": "warn"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ const
|
||||||
POPUPS_MODULE_NAME = 'ext.popups.main';
|
POPUPS_MODULE_NAME = 'ext.popups.main';
|
||||||
|
|
||||||
async function makePage( title, path ) {
|
async function makePage( title, path ) {
|
||||||
|
// eslint-disable-next-line security/detect-non-literal-fs-filename
|
||||||
const content = fs.readFileSync( path, 'utf-8' );
|
const content = fs.readFileSync( path, 'utf-8' );
|
||||||
const bot = await Api.bot();
|
const bot = await Api.bot();
|
||||||
await bot.edit( title, content );
|
await bot.edit( title, content );
|
||||||
|
@ -24,16 +25,16 @@ async function makePage( title, path ) {
|
||||||
class PopupsPage extends Page {
|
class PopupsPage extends Page {
|
||||||
async setupPagePreviews() {
|
async setupPagePreviews() {
|
||||||
return browser.call( async () => {
|
return browser.call( async () => {
|
||||||
const path = `${__dirname}/../fixtures/`;
|
const path = `${ __dirname }/../fixtures/`;
|
||||||
await makePage( `${TEST_PAGE_POPUPS_TITLE} 2`, `${path}test_page_2.wikitext` );
|
await makePage( `${ TEST_PAGE_POPUPS_TITLE } 2`, `${ path }test_page_2.wikitext` );
|
||||||
await makePage( TEST_PAGE_POPUPS_TITLE, `${path}test_page.wikitext` );
|
await makePage( TEST_PAGE_POPUPS_TITLE, `${ path }test_page.wikitext` );
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
|
|
||||||
async setupReferencePreviews() {
|
async setupReferencePreviews() {
|
||||||
return browser.call( async () => {
|
return browser.call( async () => {
|
||||||
const path = `${__dirname}/../fixtures/`;
|
const path = `${ __dirname }/../fixtures/`;
|
||||||
await makePage( TEST_REFERENCE_POPUPS_TITLE, `${path}test_page.wikitext` );
|
await makePage( TEST_REFERENCE_POPUPS_TITLE, `${ path }test_page.wikitext` );
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,7 +68,7 @@ class PopupsPage extends Page {
|
||||||
}
|
}
|
||||||
|
|
||||||
async dwellReferenceLink( id ) {
|
async dwellReferenceLink( id ) {
|
||||||
await this.dwellLink( `#${id} a` );
|
await this.dwellLink( `#${ id } a` );
|
||||||
}
|
}
|
||||||
|
|
||||||
async dwellReferenceInceptionLink() {
|
async dwellReferenceInceptionLink() {
|
||||||
|
|
|
@ -95,9 +95,9 @@ module.exports = ( env, argv ) => ( {
|
||||||
|
|
||||||
// Rename source map extensions. Per T173491 files with a .map extension cannot be served
|
// Rename source map extensions. Per T173491 files with a .map extension cannot be served
|
||||||
// from prod.
|
// from prod.
|
||||||
sourceMapFilename: `[file]${srcMapExt}`,
|
sourceMapFilename: `[file]${ srcMapExt }`,
|
||||||
|
|
||||||
devtoolModuleFilenameTemplate: `${PUBLIC_PATH}/[resource-path]`
|
devtoolModuleFilenameTemplate: `${ PUBLIC_PATH }/[resource-path]`
|
||||||
},
|
},
|
||||||
|
|
||||||
// Accurate source maps at the expense of build time. The source map is intentionally exposed
|
// Accurate source maps at the expense of build time. The source map is intentionally exposed
|
||||||
|
|
Loading…
Reference in a new issue