--- /dev/null
+<?php
+
+/**
+ * Allows custom data specific to HTMLFormField to be set for OOjs UI forms. A matching JS widget
+ * (defined in htmlform.Element.js) picks up the extra config when constructed using OO.ui.infuse().
+ *
+ * Currently only supports passing 'hide-if' data.
+ */
+trait HTMLFormElement {
+
+ protected $hideIf = null;
+
+ public function initializeHTMLFormElement( array $config = [] ) {
+ // Properties
+ $this->hideIf = isset( $config['hideIf'] ) ? $config['hideIf'] : null;
+
+ // Initialization
+ if ( $this->hideIf ) {
+ $this->addClasses( [ 'mw-htmlform-hide-if' ] );
+ }
+ $this->registerConfigCallback( function( &$config ) {
+ if ( $this->hideIf !== null ) {
+ $config['hideIf'] = $this->hideIf;
+ }
+ } );
+ }
+}
+
+class HTMLFormFieldLayout extends OOUI\FieldLayout {
+ use HTMLFormElement;
+
+ public function __construct( $fieldWidget, array $config = [] ) {
+ // Parent constructor
+ parent::__construct( $fieldWidget, $config );
+ // Traits
+ $this->initializeHTMLFormElement( $config );
+ }
+
+ protected function getJavaScriptClassName() {
+ return 'mw.htmlform.FieldLayout';
+ }
+}
+
+class HTMLFormActionFieldLayout extends OOUI\ActionFieldLayout {
+ use HTMLFormElement;
+
+ public function __construct( $fieldWidget, $buttonWidget = false, array $config = [] ) {
+ // Parent constructor
+ parent::__construct( $fieldWidget, $buttonWidget, $config );
+ // Traits
+ $this->initializeHTMLFormElement( $config );
+ }
+
+ protected function getJavaScriptClassName() {
+ return 'mw.htmlform.ActionFieldLayout';
+ }
+}
];
if ( $infusable && $this->shouldInfuseOOUI() ) {
- $this->mParent->getOutput()->addModules( 'oojs-ui-core' );
+ $this->mParent->getOutput()->addModules( 'mediawiki.htmlform.ooui' );
$config['classes'][] = 'mw-htmlform-field-autoinfuse';
}
$config['label'] = new OOUI\HtmlSnippet( $label );
}
+ if ( $this->mHideIf ) {
+ $this->mParent->getOutput()->addModules( 'mediawiki.htmlform.ooui' );
+ $config['hideIf'] = $this->mHideIf;
+ }
+
return $this->getFieldLayoutOOUI( $inputField, $config );
}
protected function getFieldLayoutOOUI( $inputField, $config ) {
if ( isset( $this->mClassWithButton ) ) {
$buttonWidget = $this->mClassWithButton->getInputOOUI( '' );
- return new OOUI\ActionFieldLayout( $inputField, $buttonWidget, $config );
+ return new HTMLFormActionFieldLayout( $inputField, $buttonWidget, $config );
}
- return new OOUI\FieldLayout( $inputField, $config );
+ return new HTMLFormFieldLayout( $inputField, $config );
}
/**
*/
( function ( mw, $ ) {
+ /*jshint -W024*/
+
/**
* Helper function for hide-if to find the nearby form field.
*
* @private
* @param {jQuery} $el
* @param {string} name
- * @return {jQuery|null}
+ * @return {jQuery|OO.ui.Widget|null}
*/
function hideIfGetField( $el, name ) {
- var $found, $p,
+ var $found, $p, $widget,
suffix = name.replace( /^([^\[]+)/, '[$1]' );
function nameFilter() {
for ( $p = $el.parent(); $p.length > 0; $p = $p.parent() ) {
$found = $p.find( '[name]' ).filter( nameFilter );
if ( $found.length ) {
+ $widget = $found.closest( '.oo-ui-widget[data-ooui]' );
+ if ( $widget.length ) {
+ return OO.ui.Widget.static.infuse( $widget );
+ }
return $found;
}
}
* @param {jQuery} $el
* @param {Array} spec
* @return {Array}
- * @return {jQuery} return.0 Dependent fields
+ * @return {Array} return.0 Dependent fields, array of jQuery objects or OO.ui.Widgets
* @return {Function} return.1 Test function
*/
function hideIfParse( $el, spec ) {
- var op, i, l, v, $field, $fields, fields, func, funcs, getVal;
+ var op, i, l, v, field, $field, fields, func, funcs, getVal;
op = spec[ 0 ];
l = spec.length;
throw new Error( op + ' parameters must be arrays' );
}
v = hideIfParse( $el, spec[ i ] );
- fields = fields.concat( v[ 0 ].toArray() );
+ fields = fields.concat( v[ 0 ] );
funcs.push( v[ 1 ] );
}
- $fields = $( fields );
l = funcs.length;
switch ( op ) {
break;
}
- return [ $fields, func ];
+ return [ fields, func ];
case 'NOT':
if ( l !== 2 ) {
throw new Error( 'NOT parameters must be arrays' );
}
v = hideIfParse( $el, spec[ 1 ] );
- $fields = v[ 0 ];
+ fields = v[ 0 ];
func = v[ 1 ];
- return [ $fields, function () {
+ return [ fields, function () {
return !func();
} ];
if ( l !== 3 ) {
throw new Error( op + ' takes exactly two parameters' );
}
- $field = hideIfGetField( $el, spec[ 1 ] );
- if ( !$field ) {
- return [ $(), function () {
+ field = hideIfGetField( $el, spec[ 1 ] );
+ if ( !field ) {
+ return [ [], function () {
return false;
} ];
}
v = spec[ 2 ];
- if ( $field.first().prop( 'type' ) === 'radio' ||
- $field.first().prop( 'type' ) === 'checkbox'
- ) {
- getVal = function () {
- var $selected = $field.filter( ':checked' );
- return $selected.length ? $selected.val() : '';
- };
+ if ( field instanceof OO.ui.Widget ) {
+ if ( field.supports( 'isSelected' ) ) {
+ getVal = function () {
+ var selected = field.isSelected();
+ return selected ? field.getValue() : '';
+ };
+ } else {
+ getVal = function () {
+ return field.getValue();
+ };
+ }
} else {
- getVal = function () {
- return $field.val();
- };
+ $field = $( field );
+ if ( $field.prop( 'type' ) === 'radio' || $field.prop( 'type' ) === 'checkbox' ) {
+ getVal = function () {
+ var $selected = $field.filter( ':checked' );
+ return $selected.length ? $selected.val() : '';
+ };
+ } else {
+ getVal = function () {
+ return $field.val();
+ };
+ }
}
switch ( op ) {
break;
}
- return [ $field, func ];
+ return [ [ field ], func ];
default:
throw new Error( 'Unrecognized operation \'' + op + '\'' );
mw.hook( 'htmlform.enhance' ).add( function ( $root ) {
$root.find( '.mw-htmlform-hide-if' ).each( function () {
- var v, $fields, test, func,
- $el = $( this ),
- spec = $el.data( 'hideIf' );
+ var v, i, fields, test, func, spec, self, modules,
+ $el = $( this );
- if ( !spec ) {
- return;
+ 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' );
+ }
}
- v = hideIfParse( $el, spec );
- $fields = v[ 0 ];
- test = v[ 1 ];
- func = function () {
- if ( test() ) {
- $el.hide();
+ mw.loader.using( modules ).done( function () {
+ if ( $el.is( '[data-ooui]' ) ) {
+ // self should be a FieldLayout that mixes in mw.htmlform.Element
+ self = OO.ui.FieldLayout.static.infuse( $el );
+ spec = self.hideIf;
+ // The original element has been replaced with infused one
+ $el = self.$element;
} else {
- $el.show();
+ self = $el;
+ spec = $el.data( 'hideIf' );
+ }
+
+ if ( !spec ) {
+ return;
+ }
+
+ v = hideIfParse( $el, spec );
+ fields = v[ 0 ];
+ test = v[ 1 ];
+ // The .toggle() method works mostly the same for jQuery objects and OO.ui.Widget
+ func = function () {
+ self.toggle( !test() );
+ };
+ for ( i = 0; i < fields.length; i++ ) {
+ // The .on() method works mostly the same for jQuery objects and OO.ui.Widget
+ fields[ i ].on( 'change', func );
}
- };
- $fields.on( 'change', func );
- func();
+ func();
+ } );
} );
} );
--- /dev/null
+( function ( mw ) {
+
+ mw.htmlform = {};
+
+ /**
+ * Allows custom data specific to HTMLFormField to be set for OOjs UI forms. This picks up the
+ * extra config from a matching PHP widget (defined in HTMLFormElement.php) when constructed using
+ * OO.ui.infuse().
+ *
+ * Currently only supports passing 'hide-if' data.
+ *
+ * @ignore
+ */
+ mw.htmlform.Element = function ( config ) {
+ // Configuration initialization
+ config = config || {};
+
+ // Properties
+ this.hideIf = config.hideIf;
+
+ // Initialization
+ if ( this.hideIf ) {
+ this.$element.addClass( 'mw-htmlform-hide-if' );
+ }
+ };
+
+ mw.htmlform.FieldLayout = function ( config ) {
+ // Parent constructor
+ mw.htmlform.FieldLayout.parent.call( this, config );
+ // Mixin constructors
+ mw.htmlform.Element.call( this, config );
+ };
+ OO.inheritClass( mw.htmlform.FieldLayout, OO.ui.FieldLayout );
+ OO.mixinClass( mw.htmlform.FieldLayout, mw.htmlform.Element );
+
+ mw.htmlform.ActionFieldLayout = function ( config ) {
+ // Parent constructor
+ mw.htmlform.ActionFieldLayout.parent.call( this, config );
+ // Mixin constructors
+ mw.htmlform.Element.call( this, config );
+ };
+ OO.inheritClass( mw.htmlform.ActionFieldLayout, OO.ui.ActionFieldLayout );
+ OO.mixinClass( mw.htmlform.ActionFieldLayout, mw.htmlform.Element );
+
+}( mediaWiki ) );