From: Bartosz DziewoƄski Date: Tue, 26 Jul 2016 12:12:21 +0000 (+0200) Subject: Do not automatically infuse any OOjs UI widgets X-Git-Tag: 1.31.0-rc.0~5984^2 X-Git-Url: https://git.cyclocoop.org/%27.%24link.%27?a=commitdiff_plain;h=f50cee1375201a5d3fd76c0c262cfc7e66bd5d42;p=lhc%2Fweb%2Fwiklou.git Do not automatically infuse any OOjs UI widgets This is not really what we had in mind when developing the infusion feature and I think it's not helpful. Most of the time there is just no benefit; a ButtonWidget generated in PHP and in JS behaves and looks pretty much the same, and rebuilding it through infusion is a small performance hit. If you're not adding any event handlers, it only makes sense for various dropdowns, which have themed styling. For the primary use case of adding JS behaviors to PHP widgets you need to call OO.ui.infuse() anyway to get a reference to the JS widget, and not infusing automatically should make it easier to reason about your code. Infusion tries to be very transparent, but it can't hide the fact that the DOM is re-built, making your references to DOM nodes from before infusion useless and losing anything from PHP that wasn't included in the config (e.g. custom attributes). This commit removes automated infusion from mediawiki.page.ready and adds some custom code in mediawiki.special.movePage and mediawiki.htmlform. I see only two extensions using infusable OOjs UI widgets in Gerrit (ArticlePlaceholder and ExtensionDistributor) and neither should be affected by this change. Change-Id: I56608c537fc57c5c54960b0603694f2612f45618 --- diff --git a/RELEASE-NOTES-1.28 b/RELEASE-NOTES-1.28 index f6c3530316..ee5b394044 100644 --- a/RELEASE-NOTES-1.28 +++ b/RELEASE-NOTES-1.28 @@ -111,6 +111,9 @@ changes to languages because of Phabricator reports. * AuthenticationRequest::$required is now changed from REQUIRED to PRIMARY_REQUIRED on requests needed by primary providers even if all primaries need them. Primary providers are discouraged from returning multiple REQUIRED requests. +* OOjs UI PHP widgets constructed with the `'infusable' => true` config option + will no longer be automatically infused. You should call `OO.ui.infuse()` + on them yourself from your JavaScript code. == Compatibility == diff --git a/includes/htmlform/HTMLFormField.php b/includes/htmlform/HTMLFormField.php index 5f6460d3df..b47bfa06ca 100644 --- a/includes/htmlform/HTMLFormField.php +++ b/includes/htmlform/HTMLFormField.php @@ -626,6 +626,11 @@ abstract class HTMLFormField { 'infusable' => $infusable, ]; + if ( $infusable && $this->shouldInfuseOOUI() ) { + $this->mParent->getOutput()->addModules( 'oojs-ui-core' ); + $config['classes'][] = 'mw-htmlform-field-autoinfuse'; + } + // the element could specify, that the label doesn't need to be added $label = $this->getLabel(); if ( $label ) { @@ -655,6 +660,18 @@ abstract class HTMLFormField { return new OOUI\FieldLayout( $inputField, $config ); } + /** + * Whether the field should be automatically infused. Note that all OOjs UI HTMLForm fields are + * infusable (you can call OO.ui.infuse() on them), but not all are infused by default, since + * there is no benefit in doing it e.g. for buttons and it's a small performance hit on page load. + * + * @return bool + */ + protected function shouldInfuseOOUI() { + // Always infuse fields with help text, since the interface for it is nicer with JS + return $this->getHelpText() !== null; + } + /** * Get the complete raw fields for the input, including help text, * labels, and whatever. diff --git a/includes/htmlform/fields/HTMLComboboxField.php b/includes/htmlform/fields/HTMLComboboxField.php index 778aedbc8a..0c3bc5a913 100644 --- a/includes/htmlform/fields/HTMLComboboxField.php +++ b/includes/htmlform/fields/HTMLComboboxField.php @@ -56,4 +56,8 @@ class HTMLComboboxField extends HTMLTextField { 'disabled' => $disabled, ] + $attribs ); } + + protected function shouldInfuseOOUI() { + return true; + } } diff --git a/includes/htmlform/fields/HTMLRadioField.php b/includes/htmlform/fields/HTMLRadioField.php index e5b5e68f20..976befe4c2 100644 --- a/includes/htmlform/fields/HTMLRadioField.php +++ b/includes/htmlform/fields/HTMLRadioField.php @@ -57,6 +57,10 @@ class HTMLRadioField extends HTMLFormField { ) ); } + protected function shouldInfuseOOUI() { + return true; + } + function formatOptions( $options, $value ) { global $wgUseMediaWikiUIEverywhere; diff --git a/includes/htmlform/fields/HTMLSelectField.php b/includes/htmlform/fields/HTMLSelectField.php index b6ad46c5ae..40b31b58f5 100644 --- a/includes/htmlform/fields/HTMLSelectField.php +++ b/includes/htmlform/fields/HTMLSelectField.php @@ -65,4 +65,8 @@ class HTMLSelectField extends HTMLFormField { 'disabled' => $disabled, ] + $attribs ); } + + protected function shouldInfuseOOUI() { + return true; + } } diff --git a/includes/htmlform/fields/HTMLSelectNamespace.php b/includes/htmlform/fields/HTMLSelectNamespace.php index ef219690fd..ffa25003b0 100644 --- a/includes/htmlform/fields/HTMLSelectNamespace.php +++ b/includes/htmlform/fields/HTMLSelectNamespace.php @@ -33,4 +33,8 @@ class HTMLSelectNamespace extends HTMLFormField { 'includeAllValue' => $this->mAllValue, ] ); } + + protected function shouldInfuseOOUI() { + return true; + } } diff --git a/includes/htmlform/fields/HTMLTitleTextField.php b/includes/htmlform/fields/HTMLTitleTextField.php index fcf721a57b..5d5d76565f 100644 --- a/includes/htmlform/fields/HTMLTitleTextField.php +++ b/includes/htmlform/fields/HTMLTitleTextField.php @@ -81,6 +81,10 @@ class HTMLTitleTextField extends HTMLTextField { return new TitleInputWidget( $params ); } + protected function shouldInfuseOOUI() { + return true; + } + 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 5a7e0b9b85..f21b53d91e 100644 --- a/includes/htmlform/fields/HTMLUserTextField.php +++ b/includes/htmlform/fields/HTMLUserTextField.php @@ -45,6 +45,10 @@ class HTMLUserTextField extends HTMLTextField { return new UserInputWidget( $params ); } + protected function shouldInfuseOOUI() { + return true; + } + 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/includes/specials/SpecialMovepage.php b/includes/specials/SpecialMovepage.php index d0c44c33fd..9cc6745b26 100644 --- a/includes/specials/SpecialMovepage.php +++ b/includes/specials/SpecialMovepage.php @@ -353,6 +353,7 @@ class MovePageForm extends UnlistedSpecialPage { 'help' => new OOUI\HtmlSnippet( $this->msg( 'movepagetalktext' )->parseAsBlock() ), 'align' => 'inline', 'infusable' => true, + 'id' => 'wpMovetalk-field', ] ); } diff --git a/resources/Resources.php b/resources/Resources.php index 1372a8e8f0..3a5b002b84 100644 --- a/resources/Resources.php +++ b/resources/Resources.php @@ -1071,6 +1071,7 @@ return [ 'scripts' => [ 'resources/src/mediawiki/htmlform/htmlform.js', 'resources/src/mediawiki/htmlform/autocomplete.js', + 'resources/src/mediawiki/htmlform/autoinfuse.js', 'resources/src/mediawiki/htmlform/checkmatrix.js', 'resources/src/mediawiki/htmlform/cloner.js', 'resources/src/mediawiki/htmlform/hide-if.js', diff --git a/resources/src/mediawiki.special/mediawiki.special.movePage.js b/resources/src/mediawiki.special/mediawiki.special.movePage.js index 6d88c51c5a..9af81b8e94 100644 --- a/resources/src/mediawiki.special/mediawiki.special.movePage.js +++ b/resources/src/mediawiki.special/mediawiki.special.movePage.js @@ -2,6 +2,10 @@ * JavaScript for Special:MovePage */ jQuery( function () { + // Infuse for pretty dropdown OO.ui.infuse( 'wpNewTitle' ); + // Limit to 255 bytes, not characters OO.ui.infuse( 'wpReason' ).$input.byteLimit(); + // Infuse for nicer "help" popup + OO.ui.infuse( 'wpMovetalk-field' ); } ); diff --git a/resources/src/mediawiki/htmlform/autoinfuse.js b/resources/src/mediawiki/htmlform/autoinfuse.js new file mode 100644 index 0000000000..f77e36720b --- /dev/null +++ b/resources/src/mediawiki/htmlform/autoinfuse.js @@ -0,0 +1,38 @@ +/* + * HTMLForm enhancements: + * Infuse some OOjs UI HTMLForm fields (those which benefit from always being infused). + */ +( function ( mw ) { + + mw.hook( 'htmlform.enhance' ).add( function ( $root ) { + var $oouiNodes, modules; + + $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 = [ 'oojs-ui-core' ]; + 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' ); + } + mw.loader.using( modules ).done( function () { + $oouiNodes.each( function () { + OO.ui.infuse( this ); + } ); + } ); + } + + } ); + +}( mediaWiki ) ); diff --git a/resources/src/mediawiki/page/ready.js b/resources/src/mediawiki/page/ready.js index 3b779d19af..d228f3e302 100644 --- a/resources/src/mediawiki/page/ready.js +++ b/resources/src/mediawiki/page/ready.js @@ -36,7 +36,7 @@ // Things outside the wikipage content $( function () { - var $nodes, $oouiNodes; + var $nodes; if ( !supportsPlaceholder ) { // Exclude content to avoid hitting it twice for the (first) wikipage content @@ -46,21 +46,6 @@ // Add accesskey hints to the tooltips $( '[accesskey]' ).updateTooltipAccessKeys(); - // Infuse OOUI widgets, if any are present - $oouiNodes = $( '[data-ooui]' ); - if ( $oouiNodes.length ) { - // FIXME: We should only load the widgets that are being infused - mw.loader.using( [ - 'mediawiki.widgets', - 'mediawiki.widgets.UserInputWidget', - 'mediawiki.widgets.SearchInputWidget' - ] ).done( function () { - $oouiNodes.each( function () { - OO.ui.infuse( this ); - } ); - } ); - } - $nodes = $( '.catlinks[data-mw="interface"]' ); if ( $nodes.length ) { /**