mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/Popups
synced 2024-11-23 15:16:50 +00:00
Update popups to use codex buttons over mediawiki.ui.buttons
- Provides missing accessible label for the settings button Bug: T340256 Change-Id: I86972322ae34f1d1df8d79c66daa9e34091f9dd3
This commit is contained in:
parent
67a718a5be
commit
6b659443b5
|
@ -4,10 +4,6 @@ const webpack = require( "webpack" );
|
|||
module.exports = {
|
||||
stories: ['./stories/*.stories.js' ],
|
||||
webpackFinal: async (config, { configType }) => {
|
||||
config.module.rules.push({
|
||||
test: /\.css$/,
|
||||
use: ['style-loader', 'css-loader']
|
||||
});
|
||||
config.module.rules.push({
|
||||
test: /\.less$/,
|
||||
use: ['style-loader', 'css-loader', {
|
||||
|
|
|
@ -21,6 +21,7 @@ import { storiesOf } from '@storybook/html';
|
|||
* Popups dependencies
|
||||
*/
|
||||
import { createPointerMasks } from '../../src/ui/renderer.js';
|
||||
import '../../node_modules/@wikimedia/codex/dist/codex.style.css';
|
||||
|
||||
/**
|
||||
* Popups helpers
|
||||
|
|
|
@ -25,7 +25,8 @@
|
|||
"UserGetDefaultOptions": "PopupsHooks",
|
||||
"MakeGlobalVariablesScript": "PopupsHooks",
|
||||
"LocalUserCreated": "PopupsHooks",
|
||||
"GetBetaFeaturePreferences": "PopupsHooks"
|
||||
"GetBetaFeaturePreferences": "PopupsHooks",
|
||||
"ResourceLoaderRegisterModules": "PopupsHooks"
|
||||
},
|
||||
"HookHandlers": {
|
||||
"PopupsHooks": {
|
||||
|
@ -229,12 +230,12 @@
|
|||
"mediawiki.jqueryMsg",
|
||||
"mediawiki.storage",
|
||||
"mediawiki.Title",
|
||||
"mediawiki.ui.button",
|
||||
"mediawiki.ui.checkbox",
|
||||
"mediawiki.ui.icon",
|
||||
"mediawiki.Uri",
|
||||
"mediawiki.user",
|
||||
"mediawiki.util"
|
||||
"mediawiki.util",
|
||||
"codex-search-styles"
|
||||
]
|
||||
}
|
||||
},
|
||||
|
|
|
@ -28,6 +28,8 @@ use MediaWiki\Hook\MakeGlobalVariablesScriptHook;
|
|||
use MediaWiki\MediaWikiServices;
|
||||
use MediaWiki\Preferences\Hook\GetPreferencesHook;
|
||||
use MediaWiki\ResourceLoader\Hook\ResourceLoaderGetConfigVarsHook;
|
||||
use MediaWiki\ResourceLoader\Hook\ResourceLoaderRegisterModulesHook;
|
||||
use MediaWiki\ResourceLoader\ResourceLoader;
|
||||
use MediaWiki\User\Hook\UserGetDefaultOptionsHook;
|
||||
use MediaWiki\User\UserOptionsManager;
|
||||
use OutputPage;
|
||||
|
@ -43,6 +45,7 @@ class PopupsHooks implements
|
|||
GetPreferencesHook,
|
||||
BeforePageDisplayHook,
|
||||
ResourceLoaderGetConfigVarsHook,
|
||||
ResourceLoaderRegisterModulesHook,
|
||||
MakeGlobalVariablesScriptHook,
|
||||
UserGetDefaultOptionsHook,
|
||||
LocalUserCreatedHook
|
||||
|
@ -320,4 +323,25 @@ class PopupsHooks implements
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ResourceLoaderRegisterModules hook handler.
|
||||
*
|
||||
* Provides support for MLEB where needed.
|
||||
*
|
||||
* @see https://www.mediawiki.org/wiki/Manual:Hooks/ResourceLoaderRegisterModules
|
||||
*
|
||||
* @param ResourceLoader $resourceLoader
|
||||
*/
|
||||
public function onResourceLoaderRegisterModules( ResourceLoader $resourceLoader ): void {
|
||||
if ( !$resourceLoader->getModule( 'codex-search-styles' ) ) {
|
||||
// We're running an older version of MediaWiki.
|
||||
$resourceLoader->register( [
|
||||
'codex-search-styles' => [
|
||||
'localBasePath' => dirname( __DIR__ ),
|
||||
'remoteExtPath' => 'UniversalLanguageSelector',
|
||||
'styles' => 'resources/codex.mleb.css',
|
||||
]
|
||||
] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
28
package-lock.json
generated
28
package-lock.json
generated
|
@ -18,8 +18,8 @@
|
|||
"@wdio/local-runner": "7.4.6",
|
||||
"@wdio/mocha-framework": "7.30.2",
|
||||
"@wdio/sync": "7.4.6",
|
||||
"@wikimedia/codex": "0.11.0",
|
||||
"@wikimedia/codex-icons": "0.11.0",
|
||||
"@wikimedia/codex": "0.14.0",
|
||||
"@wikimedia/codex-icons": "0.14.0",
|
||||
"@wikimedia/mw-node-qunit": "7.0.0",
|
||||
"babel-loader": "8.0.4",
|
||||
"browserslist-config-wikimedia": "0.2.0",
|
||||
|
@ -6550,9 +6550,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@wikimedia/codex": {
|
||||
"version": "0.11.0",
|
||||
"resolved": "https://registry.npmjs.org/@wikimedia/codex/-/codex-0.11.0.tgz",
|
||||
"integrity": "sha512-DYI9ewtEqNykzYp1nMcyrtbKpGbVPTWkbxV9QJIDIDe2GayA8XbfK/7u0V5cnTU90iqCLwqsEnQZiXX4QDvsWg==",
|
||||
"version": "0.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@wikimedia/codex/-/codex-0.14.0.tgz",
|
||||
"integrity": "sha512-qx3ADc2I5yDg448WVZ6TodGdV2vCs4SLgH6KdDx0obAr+1vsmBUyBhaVenJOL2WrMDq1rAxV1gx7YrbgOoU/MQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=16",
|
||||
|
@ -6563,9 +6563,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@wikimedia/codex-icons": {
|
||||
"version": "0.11.0",
|
||||
"resolved": "https://registry.npmjs.org/@wikimedia/codex-icons/-/codex-icons-0.11.0.tgz",
|
||||
"integrity": "sha512-aXpGI5UsWiWk1uag5I2+YlJinflmUVEyFoDH8IOt+Nko7t/z6EbJCHoMV482pVl9Ygbk2/ukHQ3LOFyS0Dv8xQ==",
|
||||
"version": "0.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@wikimedia/codex-icons/-/codex-icons-0.14.0.tgz",
|
||||
"integrity": "sha512-xbHV+5OMhIXrtfweeDAXO/HN69fn+bSUZtns6hbMgWsAK8t3hYyhQRzUeFJxrS0tApG4X9NQxIQ6mOmjZwz/rA==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=16",
|
||||
|
@ -32567,16 +32567,16 @@
|
|||
}
|
||||
},
|
||||
"@wikimedia/codex": {
|
||||
"version": "0.11.0",
|
||||
"resolved": "https://registry.npmjs.org/@wikimedia/codex/-/codex-0.11.0.tgz",
|
||||
"integrity": "sha512-DYI9ewtEqNykzYp1nMcyrtbKpGbVPTWkbxV9QJIDIDe2GayA8XbfK/7u0V5cnTU90iqCLwqsEnQZiXX4QDvsWg==",
|
||||
"version": "0.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@wikimedia/codex/-/codex-0.14.0.tgz",
|
||||
"integrity": "sha512-qx3ADc2I5yDg448WVZ6TodGdV2vCs4SLgH6KdDx0obAr+1vsmBUyBhaVenJOL2WrMDq1rAxV1gx7YrbgOoU/MQ==",
|
||||
"dev": true,
|
||||
"requires": {}
|
||||
},
|
||||
"@wikimedia/codex-icons": {
|
||||
"version": "0.11.0",
|
||||
"resolved": "https://registry.npmjs.org/@wikimedia/codex-icons/-/codex-icons-0.11.0.tgz",
|
||||
"integrity": "sha512-aXpGI5UsWiWk1uag5I2+YlJinflmUVEyFoDH8IOt+Nko7t/z6EbJCHoMV482pVl9Ygbk2/ukHQ3LOFyS0Dv8xQ==",
|
||||
"version": "0.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@wikimedia/codex-icons/-/codex-icons-0.14.0.tgz",
|
||||
"integrity": "sha512-xbHV+5OMhIXrtfweeDAXO/HN69fn+bSUZtns6hbMgWsAK8t3hYyhQRzUeFJxrS0tApG4X9NQxIQ6mOmjZwz/rA==",
|
||||
"dev": true
|
||||
},
|
||||
"@wikimedia/mw-node-qunit": {
|
||||
|
|
|
@ -39,8 +39,8 @@
|
|||
"@wdio/local-runner": "7.4.6",
|
||||
"@wdio/mocha-framework": "7.30.2",
|
||||
"@wdio/sync": "7.4.6",
|
||||
"@wikimedia/codex": "0.11.0",
|
||||
"@wikimedia/codex-icons": "0.11.0",
|
||||
"@wikimedia/codex": "0.14.0",
|
||||
"@wikimedia/codex-icons": "0.14.0",
|
||||
"@wikimedia/mw-node-qunit": "7.0.0",
|
||||
"babel-loader": "8.0.4",
|
||||
"browserslist-config-wikimedia": "0.2.0",
|
||||
|
|
BIN
resources/dist/index.js
vendored
BIN
resources/dist/index.js
vendored
Binary file not shown.
BIN
resources/dist/index.js.map.json
vendored
BIN
resources/dist/index.js.map.json
vendored
Binary file not shown.
|
@ -9,3 +9,15 @@
|
|||
position: absolute;
|
||||
top: -1000px;
|
||||
}
|
||||
|
||||
.cdx-button.cdx-button--icon-only {
|
||||
// Hide text in icon only buttons
|
||||
span + span {
|
||||
.mixin-screen-reader-text();
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: Remove after Iac69f7b14b732b0bbaa6ba265379ed4c4cdb3f7e is merged
|
||||
.cdx-button--fake-button {
|
||||
justify-content: center;
|
||||
}
|
||||
|
|
|
@ -306,10 +306,10 @@ export function bindBehavior( preview, behavior ) {
|
|||
|
||||
preview.el.addEventListener( 'click', behavior.click );
|
||||
|
||||
const icon = preview.el.querySelector( '.mwe-popups-settings-icon' );
|
||||
if ( icon ) {
|
||||
icon.href = behavior.settingsUrl;
|
||||
icon.addEventListener( 'click', ( event ) => {
|
||||
const button = preview.el.querySelector( '.mwe-popups-settings-button' );
|
||||
if ( button ) {
|
||||
button.href = behavior.settingsUrl;
|
||||
button.addEventListener( 'click', ( event ) => {
|
||||
event.stopPropagation();
|
||||
|
||||
behavior.showSettings( event );
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
*/
|
||||
|
||||
import { renderPopup } from '../popup/popup';
|
||||
import { createNodeFromTemplate } from '../templateUtil';
|
||||
import { escapeHTML, createNodeFromTemplate } from '../templateUtil';
|
||||
|
||||
const defaultExtractWidth = 215;
|
||||
const templateHTML = `
|
||||
|
@ -11,8 +11,9 @@ const templateHTML = `
|
|||
<a class="mwe-popups-discreet"></a>
|
||||
<a class="mwe-popups-extract"></a>
|
||||
<footer>
|
||||
<a class="mwe-popups-settings-icon">
|
||||
<span class="mw-ui-icon mw-ui-icon-element mw-ui-icon-small mw-ui-icon-settings"></span>
|
||||
<a class="cdx-button cdx-button--fake-button cdx-button--fake-button--enabled cdx-button--weight-quiet cdx-button--icon-only mwe-popups-settings-button">
|
||||
<span class="mw-ui-icon mw-ui-icon-small mw-ui-icon-settings"></span>
|
||||
<span class="mwe-popups-settings-button-label"></span>
|
||||
</a>
|
||||
</footer>
|
||||
</div>
|
||||
|
@ -37,9 +38,14 @@ export function renderPagePreview(
|
|||
extract.setAttribute( 'dir', model.languageDirection );
|
||||
extract.setAttribute( 'lang', model.languageCode );
|
||||
|
||||
el.querySelector( '.mwe-popups-settings-icon' )
|
||||
el.querySelector( '.mwe-popups-settings-button' )
|
||||
.setAttribute( 'title', linkTitle );
|
||||
|
||||
// Set label on settings icon button
|
||||
const labelText = escapeHTML( mw.msg( 'popups-settings-icon-gear-title' ) );
|
||||
const label = el.querySelector( '.mwe-popups-settings-button-label' );
|
||||
label.textContent = labelText;
|
||||
|
||||
if ( thumbnail ) {
|
||||
el.querySelector( '.mwe-popups-discreet' ).appendChild( thumbnail.el );
|
||||
} else {
|
||||
|
|
|
@ -62,25 +62,12 @@
|
|||
}
|
||||
}
|
||||
|
||||
.mwe-popups-settings-icon {
|
||||
display: block;
|
||||
.mwe-popups-settings-button {
|
||||
float: right; // positions icon near bottom right corner
|
||||
border-radius: @border-radius-base;
|
||||
opacity: 0.67;
|
||||
transition: background-color 100ms, opacity 100ms;
|
||||
|
||||
&:hover {
|
||||
// TODO: Replace by `@background-color-button-quiet--hover`
|
||||
// as soon as available in mediawiki.skin.variables.
|
||||
background-color: rgba( 0, 24, 73, 0.027 );
|
||||
}
|
||||
|
||||
&:active {
|
||||
// TODO: Replace by `@background-color-button-quiet--active`
|
||||
// as soon as available in mediawiki.skin.variables.
|
||||
background-color: rgba( 0, 24, 73, 0.082 );
|
||||
opacity: 1;
|
||||
}
|
||||
pointer-events: auto; // Overrides pointer-events: none on footer to ensure the button is interactive
|
||||
// !important needed to override 'responsive' button styles on smaller viewports defined in Vector's Button.less
|
||||
min-width: 32px !important; /* stylelint-disable-line declaration-no-important */
|
||||
min-height: 32px !important; /* stylelint-disable-line declaration-no-important */
|
||||
}
|
||||
|
||||
.mwe-popups-extract {
|
||||
|
@ -409,7 +396,7 @@
|
|||
/* @noflip */
|
||||
right: 0;
|
||||
|
||||
.mwe-popups-settings-icon {
|
||||
.mwe-popups-settings-button {
|
||||
/* @noflip */
|
||||
float: left;
|
||||
}
|
||||
|
|
|
@ -106,12 +106,15 @@ export function renderReferencePreview(
|
|||
// TODO: Remove when not in Beta any more
|
||||
if ( !mw.config.get( 'wgPopupsReferencePreviewsBetaFeature' ) ) {
|
||||
// TODO: Do not remove this but move it up into the templateHTML constant!
|
||||
const settingsIconLink = document.createElement( 'a' );
|
||||
settingsIconLink.classList.add( 'mwe-popups-settings-icon' );
|
||||
const settingsIconLabel = document.createElement( 'span' );
|
||||
settingsIconLabel.classList.add( 'mw-ui-icon', 'mw-ui-icon-element', 'mw-ui-icon-small', 'mw-ui-icon-settings' );
|
||||
settingsIconLink.append( settingsIconLabel );
|
||||
el.querySelector( '.mwe-popups-settings' ).appendChild( settingsIconLink );
|
||||
const settingsButton = document.createElement( 'button' );
|
||||
settingsButton.classList.add( 'cdx-button', 'cdx-button--fake-button', 'cdx-button--fake-button--enabled', 'cdx-button--weight-quiet', 'cdx-button--icon-only', 'mwe-popups-settings-button' );
|
||||
const settingsIcon = document.createElement( 'span' );
|
||||
settingsIcon.classList.add( 'mw-ui-icon', 'mw-ui-icon-small', 'mw-ui-icon-settings' );
|
||||
const settingsButtonLabel = document.createElement( 'span' );
|
||||
settingsButtonLabel.textContent = mw.msg( 'popups-settings-icon-gear-title' );
|
||||
settingsButton.append( settingsIcon );
|
||||
settingsButton.append( settingsButtonLabel );
|
||||
el.querySelector( '.mwe-popups-settings' ).appendChild( settingsButton );
|
||||
} else {
|
||||
// Change the styling when there is no content in the footer (to prevent empty space)
|
||||
el.querySelector( '.mwe-popups-container' ).classList.add( 'footer-empty' );
|
||||
|
|
|
@ -58,12 +58,15 @@ export function renderSettingsDialog( model ) {
|
|||
<section id='mwe-popups-settings'>
|
||||
<header>
|
||||
<div>
|
||||
<div class='mw-ui-icon mw-ui-icon-element mw-ui-icon-popups-close close'>${closeLabel}</div>
|
||||
<button class='cdx-button cdx-button--weight-quiet cdx-button--icon-only'>
|
||||
<span class='mw-ui-icon mw-ui-icon-popups-close close'></span>
|
||||
<span>${closeLabel}</span>
|
||||
</button>
|
||||
</div>
|
||||
<h1>${heading}</h1>
|
||||
<div>
|
||||
<button class='save mw-ui-button mw-ui-progressive'>${saveLabel}</button>
|
||||
<button class='okay mw-ui-button mw-ui-progressive' style='display:none;'>${okLabel}</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>
|
||||
</div>
|
||||
</header>
|
||||
<main id='mwe-popups-settings-form'>
|
||||
|
@ -83,7 +86,7 @@ export function renderSettingsDialog( model ) {
|
|||
</form>
|
||||
</main>
|
||||
<div class='mwe-popups-settings-help' style='display:none;'>
|
||||
<div class="mw-ui-icon mw-ui-icon-element mw-ui-icon-footer"></div>
|
||||
<div class="mw-ui-icon mw-ui-icon-footer"></div>
|
||||
<p>${helpText}</p>
|
||||
</div>
|
||||
</section>
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
position: relative;
|
||||
display: table;
|
||||
width: 100%;
|
||||
padding: 5px 7px 5px 0;
|
||||
padding: 5px 7px;
|
||||
|
||||
> div {
|
||||
display: table-cell;
|
||||
|
|
|
@ -18,7 +18,7 @@ function createPagePreview( isTall, hasThumbnail, thumbnail ) {
|
|||
el: $( '<div>' ).append(
|
||||
hasThumbnail ? $( '<image>' ) : '',
|
||||
$( '<a>' ).addClass( 'mwe-popups-extract' ).text( 'extract' ),
|
||||
$( '<a>' ).addClass( 'mwe-popups-settings-icon' )
|
||||
$( '<a>' ).addClass( 'mwe-popups-settings-button' )
|
||||
)[ 0 ],
|
||||
isTall,
|
||||
hasThumbnail,
|
||||
|
@ -166,7 +166,7 @@ QUnit.test( 'createPagePreview', ( assert ) => {
|
|||
'Language direction is safely espaced'
|
||||
);
|
||||
assert.strictEqual(
|
||||
$( preview.el ).find( '.mwe-popups-settings-icon' ).attr( 'title' ),
|
||||
$( preview.el ).find( '.mwe-popups-settings-button' ).attr( 'title' ),
|
||||
'<popups-settings-icon-gear-title>',
|
||||
'Title attribute is correct.'
|
||||
);
|
||||
|
@ -458,7 +458,7 @@ QUnit.test( 'bindBehavior - settings link click', function ( assert ) {
|
|||
behavior = createBehavior( this.sandbox );
|
||||
|
||||
renderer.bindBehavior( preview, behavior );
|
||||
preview.el.querySelector( '.mwe-popups-settings-icon' ).dispatchEvent( new Event( 'click' ) );
|
||||
preview.el.querySelector( '.mwe-popups-settings-button' ).dispatchEvent( new Event( 'click' ) );
|
||||
|
||||
assert.false( behavior.previewDwell.called, 'Preview dwell is NOT called.' );
|
||||
assert.false(
|
||||
|
@ -475,7 +475,7 @@ QUnit.test( 'bindBehavior - settings link URL', function ( assert ) {
|
|||
renderer.bindBehavior( preview, behavior );
|
||||
|
||||
assert.strictEqual(
|
||||
$( preview.el ).find( '.mwe-popups-settings-icon' ).attr( 'href' ),
|
||||
$( preview.el ).find( '.mwe-popups-settings-button' ).attr( 'href' ),
|
||||
behavior.settingsUrl,
|
||||
'Settings link URL is correct.'
|
||||
);
|
||||
|
|
|
@ -63,6 +63,12 @@ module.exports = ( env, argv ) => ( {
|
|||
options: {
|
||||
removeSVGTagAttrs: false // Keep width and height attributes.
|
||||
}
|
||||
}, {
|
||||
test: /\.css$/,
|
||||
use: [
|
||||
'style-loader',
|
||||
'css-loader'
|
||||
]
|
||||
} ]
|
||||
},
|
||||
optimization: {
|
||||
|
@ -112,8 +118,8 @@ module.exports = ( env, argv ) => ( {
|
|||
// Minified uncompressed size limits for chunks / assets and entrypoints. Keep these numbers
|
||||
// up-to-date and rounded to the nearest 10th of a kibibyte so that code sizing costs are
|
||||
// well understood. Related to bundlesize minified, gzipped compressed file size tests.
|
||||
maxAssetSize: 45.8 * 1024,
|
||||
maxEntrypointSize: 45.8 * 1024,
|
||||
maxAssetSize: 46.4 * 1024,
|
||||
maxEntrypointSize: 46.4 * 1024,
|
||||
|
||||
// The default filter excludes map files but we rename ours.
|
||||
assetFilter: ( filename ) => !filename.endsWith( srcMapExt )
|
||||
|
|
Loading…
Reference in a new issue