Add "mediawiki.page.teleportTarget" module to core

Introduces a new ResourceLoader module, "mediawiki.page.teleportTarget".
This script creates a new empty div with an ID and appends it to
the end of the document body. An accompanying stylesheet has also
been added that sets this element's z-index to that of the
@z-index-overlay token. Skins can override this z-index value if
necessary.

This is done in order to provide a stable target that client-side
UI code can use if a dialog or similar modal element needs to be
teleported without causing collisions with other elements on the page.

This module has been added as a dependency of the MW Vue module.
The custom Vue.createMWApp method now provides the appended DOM
element under the "CdxTeleportTarget" key so that components like
Codex Dialog will use it automatically.

MW Skins should consider applying skinStyles to this element
to ensure that it's styles match those of the page body text elements.

Bug: T343476
Change-Id: Ia79b76c0e73890dd18477e5c3ea307d753cedb3a
This commit is contained in:
Eric Gardner 2023-08-04 09:40:54 -07:00
parent ccb111eefd
commit ca61eb768f
5 changed files with 51 additions and 1 deletions

View file

@ -24,7 +24,8 @@
"resources/src/es6-polyfills",
"resources/src/vue",
"resources/src/codex",
"resources/src/codex-search"
"resources/src/codex-search",
"resources/src/mediawiki.page.teleportTarget.js"
],
"--": [
"maintenance/jsduck/external.js",

View file

@ -553,6 +553,9 @@ return [
],
],
'dependencies' => [
'mediawiki.page.teleportTarget'
]
],
// Alias for 'vue', for backwards compatibility
@ -1716,6 +1719,16 @@ return [
'mediawiki.page.media' => [
'scripts' => 'resources/src/mediawiki.page.media.js',
],
'mediawiki.page.teleportTarget' => [
'localBasePath' => MW_INSTALL_PATH . '/resources/src',
'remoteBasePath' => "$wgResourceBasePath/resources/src",
'packageFiles' => [
'mediawiki.page.teleportTarget.js',
],
'skinStyles' => [
'default' => 'mediawiki.page.teleportTarget.less'
]
],
/* MediaWiki Special pages */

View file

@ -0,0 +1,28 @@
/**
* Setup a dedicated container element for any modal or dialog
* elements which may need to be displayed on the page. This
* script appends an empty div to the end of the body tag
* that can be used by Codex Dialogs and similar components.
*
* Skins should apply body content styles to this element so that
* dialogs will use the same styles (font sizes, etc).
*
* When this script runs, it immediately adds the div to the
* end of the body tag. Additionally, it makes the created
* DOM node available via module.exports, in case other code
* needs to require it (to spare developers from remembering
* the exact HTML ID for example).
*/
( function () {
const ID = 'mw-teleport-target';
// Create an empty div with appropriate ID
const target = document.createElement( 'div' );
target.setAttribute( 'id', ID );
// Append the node to the body
document.body.appendChild( target );
// Export the node in case other code needs to reference it
module.exports = target;
}() );

View file

@ -0,0 +1,6 @@
@import 'mediawiki.skin.variables.less';
#mw-teleport-target {
position: absolute;
z-index: @z-index-overlay;
}

View file

@ -2,6 +2,7 @@
const Vue = require( '../../lib/vue/vue.js' );
const errorLogger = require( './errorLogger.js' );
const i18n = require( './i18n.js' );
const teleportTarget = require( 'mediawiki.page.teleportTarget' );
/**
* Replace the given DOM element with its children.
@ -43,6 +44,7 @@
const app = Vue.createApp( options, ...otherArgs );
app.use( errorLogger );
app.use( i18n );
app.provide( 'CdxTeleportTarget', teleportTarget );
if ( options.store ) {
// Provide backwards compatibility for callers expecting Vuex 3