From: Bartosz DziewoƄski Date: Sun, 31 Jul 2016 14:56:23 +0000 (+0200) Subject: HTMLForm: Refactor loading of modules required to infuse fields X-Git-Tag: 1.31.0-rc.0~5924^2~1 X-Git-Url: http://git.cyclocoop.org/%40spipnet%40?a=commitdiff_plain;h=6a366c3300f4aed78f846c09468daea7591a3a40;p=lhc%2Fweb%2Fwiklou.git HTMLForm: Refactor loading of modules required to infuse fields Rather than have a master list in autoinfuse.js (duplicated in hide-if.js), we put this information in each field class and put it in the generated HTML as a separate 'data-' attribute. This also allows new fields defined by extensions to be correctly autoinfused. Change-Id: I3da75706209cbc16b19cc3f02b355e58ca75fec9 --- diff --git a/includes/htmlform/HTMLFormElement.php b/includes/htmlform/HTMLFormElement.php index e553218fa5..089213cff5 100644 --- a/includes/htmlform/HTMLFormElement.php +++ b/includes/htmlform/HTMLFormElement.php @@ -9,15 +9,23 @@ trait HTMLFormElement { protected $hideIf = null; + protected $modules = null; public function initializeHTMLFormElement( array $config = [] ) { // Properties $this->hideIf = isset( $config['hideIf'] ) ? $config['hideIf'] : null; + $this->modules = isset( $config['modules'] ) ? $config['modules'] : []; // Initialization if ( $this->hideIf ) { $this->addClasses( [ 'mw-htmlform-hide-if' ] ); } + if ( $this->modules ) { + // JS code must be able to read this before infusing (before OOjs UI is even loaded), + // so we put this in a separate attribute (not with the rest of the config). + // And it's not needed anymore after infusing, so we don't put it in JS config at all. + $this->setAttributes( [ 'data-mw-modules' => implode( ',', $this->modules ) ] ); + } $this->registerConfigCallback( function( &$config ) { if ( $this->hideIf !== null ) { $config['hideIf'] = $this->hideIf; diff --git a/includes/htmlform/HTMLFormField.php b/includes/htmlform/HTMLFormField.php index 3319d3b86a..dd53f5ebb5 100644 --- a/includes/htmlform/HTMLFormField.php +++ b/includes/htmlform/HTMLFormField.php @@ -626,8 +626,10 @@ abstract class HTMLFormField { 'infusable' => $infusable, ]; + $preloadModules = false; + if ( $infusable && $this->shouldInfuseOOUI() ) { - $this->mParent->getOutput()->addModules( 'mediawiki.htmlform.ooui' ); + $preloadModules = true; $config['classes'][] = 'mw-htmlform-field-autoinfuse'; } @@ -638,10 +640,17 @@ abstract class HTMLFormField { } if ( $this->mHideIf ) { - $this->mParent->getOutput()->addModules( 'mediawiki.htmlform.ooui' ); + $preloadModules = true; $config['hideIf'] = $this->mHideIf; } + $config['modules'] = $this->getOOUIModules(); + + if ( $preloadModules ) { + $this->mParent->getOutput()->addModules( 'mediawiki.htmlform.ooui' ); + $this->mParent->getOutput()->addModules( $this->getOOUIModules() ); + } + return $this->getFieldLayoutOOUI( $inputField, $config ); } @@ -677,6 +686,16 @@ abstract class HTMLFormField { return $this->getHelpText() !== null; } + /** + * Get the list of extra ResourceLoader modules which must be loaded client-side before it's + * possible to infuse this field's OOjs UI widget. + * + * @return string[] + */ + protected function getOOUIModules() { + return []; + } + /** * Get the complete raw fields for the input, including help text, * labels, and whatever. diff --git a/includes/htmlform/fields/HTMLSelectNamespace.php b/includes/htmlform/fields/HTMLSelectNamespace.php index ffa25003b0..230790dbeb 100644 --- a/includes/htmlform/fields/HTMLSelectNamespace.php +++ b/includes/htmlform/fields/HTMLSelectNamespace.php @@ -34,6 +34,11 @@ class HTMLSelectNamespace extends HTMLFormField { ] ); } + protected function getOOUIModules() { + // FIXME: NamespaceInputWidget should be in its own module (probably?) + return [ 'mediawiki.widgets' ]; + } + protected function shouldInfuseOOUI() { return true; } diff --git a/includes/htmlform/fields/HTMLTitleTextField.php b/includes/htmlform/fields/HTMLTitleTextField.php index 5d5d76565f..a15b90e333 100644 --- a/includes/htmlform/fields/HTMLTitleTextField.php +++ b/includes/htmlform/fields/HTMLTitleTextField.php @@ -73,7 +73,6 @@ class HTMLTitleTextField extends HTMLTextField { } protected function getInputWidget( $params ) { - $this->mParent->getOutput()->addModules( 'mediawiki.widgets' ); if ( $this->mParams['namespace'] !== false ) { $params['namespace'] = $this->mParams['namespace']; } @@ -85,6 +84,11 @@ class HTMLTitleTextField extends HTMLTextField { return true; } + protected function getOOUIModules() { + // FIXME: TitleInputWidget should be in its own module + return [ 'mediawiki.widgets' ]; + } + public function getInputHtml( $value ) { // add mw-searchInput class to enable search suggestions for non-OOUI, too $this->mClass .= 'mw-searchInput'; diff --git a/includes/htmlform/fields/HTMLUserTextField.php b/includes/htmlform/fields/HTMLUserTextField.php index f21b53d91e..14b5e59573 100644 --- a/includes/htmlform/fields/HTMLUserTextField.php +++ b/includes/htmlform/fields/HTMLUserTextField.php @@ -40,8 +40,6 @@ class HTMLUserTextField extends HTMLTextField { } protected function getInputWidget( $params ) { - $this->mParent->getOutput()->addModules( 'mediawiki.widgets.UserInputWidget' ); - return new UserInputWidget( $params ); } @@ -49,6 +47,10 @@ class HTMLUserTextField extends HTMLTextField { return true; } + protected function getOOUIModules() { + return [ 'mediawiki.widgets.UserInputWidget' ]; + } + public function getInputHtml( $value ) { // add the required module and css class for user suggestions in non-OOUI mode $this->mParent->getOutput()->addModules( 'mediawiki.userSuggest' ); diff --git a/resources/src/mediawiki/htmlform/autoinfuse.js b/resources/src/mediawiki/htmlform/autoinfuse.js index 8efbc69fb8..f2e0f4dd2c 100644 --- a/resources/src/mediawiki/htmlform/autoinfuse.js +++ b/resources/src/mediawiki/htmlform/autoinfuse.js @@ -2,30 +2,24 @@ * HTMLForm enhancements: * Infuse some OOjs UI HTMLForm fields (those which benefit from always being infused). */ -( function ( mw ) { +( function ( mw, $ ) { mw.hook( 'htmlform.enhance' ).add( function ( $root ) { - var $oouiNodes, modules; + var $oouiNodes, modules, extraModules; $oouiNodes = $root.find( '.mw-htmlform-field-autoinfuse' ); if ( $oouiNodes.length ) { // The modules are preloaded (added server-side in HTMLFormField, and the individual fields // which need extra ones), but this module doesn't depend on them. Wait until they're loaded. modules = [ 'mediawiki.htmlform.ooui' ]; - if ( $oouiNodes.filter( '.mw-htmlform-field-HTMLTitleTextField' ).length ) { - // FIXME: TitleInputWidget should be in its own module - modules.push( 'mediawiki.widgets' ); - } - if ( $oouiNodes.filter( '.mw-htmlform-field-HTMLUserTextField' ).length ) { - modules.push( 'mediawiki.widgets.UserInputWidget' ); - } - if ( - $oouiNodes.filter( '.mw-htmlform-field-HTMLSelectNamespace' ).length || - $oouiNodes.filter( '.mw-htmlform-field-HTMLSelectNamespaceWithButton' ).length - ) { - // FIXME: NamespaceInputWidget should be in its own module (probably?) - modules.push( 'mediawiki.widgets' ); - } + $oouiNodes.each( function () { + var data = $( this ).data( 'mw-modules' ); + if ( data ) { + // We can trust this value, 'data-mw-*' attributes are banned from user content in Sanitizer + extraModules = data.split( ',' ); + modules.push.apply( modules, extraModules ); + } + } ); mw.loader.using( modules ).done( function () { $oouiNodes.each( function () { OO.ui.infuse( this ); @@ -35,4 +29,4 @@ } ); -}( mediaWiki ) ); +}( mediaWiki, jQuery ) ); diff --git a/resources/src/mediawiki/htmlform/hide-if.js b/resources/src/mediawiki/htmlform/hide-if.js index 6460ed1497..cb717afad5 100644 --- a/resources/src/mediawiki/htmlform/hide-if.js +++ b/resources/src/mediawiki/htmlform/hide-if.js @@ -203,25 +203,17 @@ mw.hook( 'htmlform.enhance' ).add( function ( $root ) { $root.find( '.mw-htmlform-hide-if' ).each( function () { - var v, i, fields, test, func, spec, self, modules, + var v, i, fields, test, func, spec, self, modules, data,extraModules, $el = $( this ); modules = []; if ( $el.is( '[data-ooui]' ) ) { modules.push( 'mediawiki.htmlform.ooui' ); - if ( $el.filter( '.mw-htmlform-field-HTMLTitleTextField' ).length ) { - // FIXME: TitleInputWidget should be in its own module - modules.push( 'mediawiki.widgets' ); - } - if ( $el.filter( '.mw-htmlform-field-HTMLUserTextField' ).length ) { - modules.push( 'mediawiki.widgets.UserInputWidget' ); - } - if ( - $el.filter( '.mw-htmlform-field-HTMLSelectNamespace' ).length || - $el.filter( '.mw-htmlform-field-HTMLSelectNamespaceWithButton' ).length - ) { - // FIXME: NamespaceInputWidget should be in its own module (probably?) - modules.push( 'mediawiki.widgets' ); + data = $el.data( 'mw-modules' ); + if ( data ) { + // We can trust this value, 'data-mw-*' attributes are banned from user content in Sanitizer + extraModules = data.split( ',' ); + modules.push.apply( modules, extraModules ); } }