summaryrefslogtreecommitdiff
path: root/vendor/oojs/oojs-ui/php
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/oojs/oojs-ui/php')
-rw-r--r--vendor/oojs/oojs-ui/php/Element.php48
-rw-r--r--vendor/oojs/oojs-ui/php/HtmlSnippet.php2
-rw-r--r--vendor/oojs/oojs-ui/php/Tag.php20
-rw-r--r--vendor/oojs/oojs-ui/php/Theme.php26
-rw-r--r--vendor/oojs/oojs-ui/php/Widget.php10
-rw-r--r--vendor/oojs/oojs-ui/php/layouts/ActionFieldLayout.php55
-rw-r--r--vendor/oojs/oojs-ui/php/layouts/FieldLayout.php73
-rw-r--r--vendor/oojs/oojs-ui/php/layouts/FormLayout.php2
-rw-r--r--vendor/oojs/oojs-ui/php/layouts/HorizontalLayout.php27
-rw-r--r--vendor/oojs/oojs-ui/php/mixins/AccessKeyedElement.php76
-rw-r--r--vendor/oojs/oojs-ui/php/mixins/ButtonElement.php (renamed from vendor/oojs/oojs-ui/php/elements/ButtonElement.php)33
-rw-r--r--vendor/oojs/oojs-ui/php/mixins/FlaggedElement.php (renamed from vendor/oojs/oojs-ui/php/elements/FlaggedElement.php)0
-rw-r--r--vendor/oojs/oojs-ui/php/mixins/GroupElement.php (renamed from vendor/oojs/oojs-ui/php/elements/GroupElement.php)0
-rw-r--r--vendor/oojs/oojs-ui/php/mixins/IconElement.php (renamed from vendor/oojs/oojs-ui/php/elements/IconElement.php)0
-rw-r--r--vendor/oojs/oojs-ui/php/mixins/IndicatorElement.php (renamed from vendor/oojs/oojs-ui/php/elements/IndicatorElement.php)0
-rw-r--r--vendor/oojs/oojs-ui/php/mixins/LabelElement.php (renamed from vendor/oojs/oojs-ui/php/elements/LabelElement.php)0
-rw-r--r--vendor/oojs/oojs-ui/php/mixins/TabIndexedElement.php (renamed from vendor/oojs/oojs-ui/php/elements/TabIndexedElement.php)0
-rw-r--r--vendor/oojs/oojs-ui/php/mixins/TitledElement.php (renamed from vendor/oojs/oojs-ui/php/elements/TitledElement.php)0
-rw-r--r--vendor/oojs/oojs-ui/php/widgets/ButtonInputWidget.php14
-rw-r--r--vendor/oojs/oojs-ui/php/widgets/ButtonWidget.php2
-rw-r--r--vendor/oojs/oojs-ui/php/widgets/CheckboxInputWidget.php2
-rw-r--r--vendor/oojs/oojs-ui/php/widgets/DropdownInputWidget.php11
-rw-r--r--vendor/oojs/oojs-ui/php/widgets/IconWidget.php2
-rw-r--r--vendor/oojs/oojs-ui/php/widgets/IndicatorWidget.php2
-rw-r--r--vendor/oojs/oojs-ui/php/widgets/InputWidget.php10
-rw-r--r--vendor/oojs/oojs-ui/php/widgets/LabelWidget.php2
-rw-r--r--vendor/oojs/oojs-ui/php/widgets/RadioInputWidget.php2
-rw-r--r--vendor/oojs/oojs-ui/php/widgets/RadioSelectInputWidget.php127
-rw-r--r--vendor/oojs/oojs-ui/php/widgets/TextInputWidget.php63
29 files changed, 538 insertions, 71 deletions
diff --git a/vendor/oojs/oojs-ui/php/Element.php b/vendor/oojs/oojs-ui/php/Element.php
index eaa8c825..a7bd683a 100644
--- a/vendor/oojs/oojs-ui/php/Element.php
+++ b/vendor/oojs/oojs-ui/php/Element.php
@@ -9,7 +9,7 @@ namespace OOUI;
*/
class Element extends Tag {
- /* Static properties */
+ /* Static Properties */
/**
* HTML tag name.
@@ -29,7 +29,7 @@ class Element extends Tag {
*/
public static $defaultDir = 'ltr';
- /* Members */
+ /* Properties */
/**
* Element data.
@@ -39,9 +39,17 @@ class Element extends Tag {
protected $data = null;
/**
+ * CSS classes explicitly configured for this element (as opposed to #$classes, which contains all
+ * classes for this element).
+ *
+ * @var string[]
+ */
+ protected $ownClasses = array();
+
+ /**
* Mixins.
*
- * @var array List mixed in objects.
+ * @var ElementMixin[] List mixed in objects.
*/
protected $mixins = array();
@@ -69,7 +77,8 @@ class Element extends Tag {
$this->setData( $config['data'] );
}
if ( isset( $config['classes'] ) && is_array( $config['classes'] ) ) {
- $this->addClasses( $config['classes'] );
+ $this->ownClasses = $config['classes'];
+ $this->addClasses( $this->ownClasses );
}
if ( isset( $config['id'] ) ) {
$this->setAttributes( array( 'id' => $config['id'] ) );
@@ -121,7 +130,7 @@ class Element extends Tag {
* @return Tag|null Target property or null if not found
*/
public function __get( $name ) {
- // Search mixins for methods
+ // Search mixins for the property
foreach ( $this->mixins as $mixin ) {
if ( isset( $mixin::$targetPropertyName ) && $mixin::$targetPropertyName === $name ) {
return $mixin->target;
@@ -133,6 +142,22 @@ class Element extends Tag {
}
/**
+ * Check for existence of a mixed-in target property.
+ *
+ * @param string $name Property name
+ * @return bool Whether property exists
+ */
+ public function __isset( $name ) {
+ // Search mixins for the property
+ foreach ( $this->mixins as $mixin ) {
+ if ( isset( $mixin::$targetPropertyName ) && $mixin::$targetPropertyName === $name ) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
* Get the HTML tag name.
*
* Override this method to base the result on instance information.
@@ -220,6 +245,9 @@ class Element extends Tag {
if ( $this->data !== null ) {
$config['data'] = $this->data;
}
+ if ( $this->ownClasses !== array() ) {
+ $config['classes'] = $this->ownClasses;
+ }
return $config;
}
@@ -247,10 +275,18 @@ class Element extends Tag {
};
array_walk_recursive( $config, $replaceElements );
// Set '_' last to ensure that subclasses can't accidentally step on it.
- $config['_'] = preg_replace( '/^OOUI\\\\/', '', get_class( $this ) );
+ $config['_'] = $this->getJavaScriptClassName();
return $config;
}
+ /**
+ * The class name of the JavaScript version of this widget
+ * @return string
+ */
+ protected function getJavaScriptClassName() {
+ return str_replace( 'OOUI\\', 'OO.ui.', get_class( $this ) );
+ }
+
protected function getGeneratedAttributes() {
$attributesArray = parent::getGeneratedAttributes();
// Add `data-ooui` attribute from serialized config array.
diff --git a/vendor/oojs/oojs-ui/php/HtmlSnippet.php b/vendor/oojs/oojs-ui/php/HtmlSnippet.php
index e0889fca..adde8286 100644
--- a/vendor/oojs/oojs-ui/php/HtmlSnippet.php
+++ b/vendor/oojs/oojs-ui/php/HtmlSnippet.php
@@ -7,7 +7,7 @@ namespace OOUI;
*/
class HtmlSnippet {
- /* Members */
+ /* Properties */
/**
* HTML snippet this instance represents.
diff --git a/vendor/oojs/oojs-ui/php/Tag.php b/vendor/oojs/oojs-ui/php/Tag.php
index da8c2bfa..e5fa9df6 100644
--- a/vendor/oojs/oojs-ui/php/Tag.php
+++ b/vendor/oojs/oojs-ui/php/Tag.php
@@ -4,7 +4,7 @@ namespace OOUI;
class Tag {
- /* Members */
+ /* Properties */
/**
* Tag name for this instance.
@@ -296,23 +296,27 @@ class Tag {
// reasons to ever use 'javascript:' URLs anyway.
$protocolWhitelist = array(
// Sourced from MediaWiki's $wgUrlProtocols
+ // Keep in sync with OO.ui.isSafeUrl
'bitcoin', 'ftp', 'ftps', 'geo', 'git', 'gopher', 'http', 'https', 'irc', 'ircs',
'magnet', 'mailto', 'mms', 'news', 'nntp', 'redis', 'sftp', 'sip', 'sips', 'sms', 'ssh',
'svn', 'tel', 'telnet', 'urn', 'worldwind', 'xmpp',
+ '(protocol-relative)', '(relative)',
);
// Protocol-relative URLs are handled really badly by parse_url()
if ( substr( $value, 0, 2 ) === '//' ) {
- $url = "http:$value";
+ $scheme = '(protocol-relative)';
} else {
- $url = $value;
+ // Must suppress warnings when the value is not a valid URL. parse_url() returns false then.
+ \MediaWiki\suppressWarnings();
+ $scheme = parse_url( $value, PHP_URL_SCHEME );
+ \MediaWiki\restoreWarnings();
+ if ( $scheme === null || ( !$scheme && substr( $value, 0, 1 ) === '/' ) ) {
+ $scheme = '(relative)';
+ }
}
- // Must suppress warnings when the value is not a valid URL. parse_url() returns false then.
- // @codingStandardsIgnoreStart
- $scheme = @parse_url( $url, PHP_URL_SCHEME );
- // @codingStandardsIgnoreEnd
- if ( !( $scheme === null || in_array( strtolower( $scheme ), $protocolWhitelist ) ) ) {
+ if ( !in_array( strtolower( $scheme ), $protocolWhitelist ) ) {
throw new Exception( "Potentially unsafe '$key' attribute value. " .
"Scheme: '$scheme'; value: '$value'." );
}
diff --git a/vendor/oojs/oojs-ui/php/Theme.php b/vendor/oojs/oojs-ui/php/Theme.php
index d36b6d82..7f8eea36 100644
--- a/vendor/oojs/oojs-ui/php/Theme.php
+++ b/vendor/oojs/oojs-ui/php/Theme.php
@@ -7,18 +7,25 @@ namespace OOUI;
*
* @abstract
*/
-class Theme {
+abstract class Theme {
- /* Members */
+ /* Properties */
private static $singleton;
/* Static Methods */
- public static function setSingleton( Theme $theme ) {
+ /**
+ * @param Theme|null $theme
+ */
+ public static function setSingleton( Theme $theme = null ) {
self::$singleton = $theme;
}
+ /**
+ * @return Theme
+ * @throws Exception
+ */
public static function singleton() {
if ( !self::$singleton ) {
throw new Exception( __METHOD__ . ' was called with no singleton theme set.' );
@@ -51,8 +58,15 @@ class Theme {
public function updateElementClasses( Element $element ) {
$classes = $this->getElementClasses( $element );
- $element
- ->removeClasses( $classes['off'] )
- ->addClasses( $classes['on'] );
+ if ( isset( $element->icon ) ) {
+ $element->icon
+ ->removeClasses( $classes['off'] )
+ ->addClasses( $classes['on'] );
+ }
+ if ( isset( $element->indicator ) ) {
+ $element->indicator
+ ->removeClasses( $classes['off'] )
+ ->addClasses( $classes['on'] );
+ }
}
}
diff --git a/vendor/oojs/oojs-ui/php/Widget.php b/vendor/oojs/oojs-ui/php/Widget.php
index 04152aa5..7828a82e 100644
--- a/vendor/oojs/oojs-ui/php/Widget.php
+++ b/vendor/oojs/oojs-ui/php/Widget.php
@@ -9,6 +9,16 @@ namespace OOUI;
*/
class Widget extends Element {
+ /* Static Properties */
+
+ /**
+ * Whether this widget will behave reasonably when wrapped in a HTML `<label>`. If this is true,
+ * wrappers such as FieldLayout may use a `<label>`.
+ *
+ * @var boolean
+ */
+ public static $supportsSimpleLabel = false;
+
/* Properties */
/**
diff --git a/vendor/oojs/oojs-ui/php/layouts/ActionFieldLayout.php b/vendor/oojs/oojs-ui/php/layouts/ActionFieldLayout.php
new file mode 100644
index 00000000..bf908184
--- /dev/null
+++ b/vendor/oojs/oojs-ui/php/layouts/ActionFieldLayout.php
@@ -0,0 +1,55 @@
+<?php
+
+namespace OOUI;
+
+/**
+ * Layout made of a field, button and optional label.
+ */
+class ActionFieldLayout extends FieldLayout {
+
+ /**
+ * Button widget to be laid out.
+ *
+ * @var Widget
+ */
+ protected $buttonWidget;
+
+ /**
+ * @param Widget $fieldWidget Field widget
+ * @param ButtonWidget $buttonWidget Field widget
+ * @param array $config Configuration options
+ */
+ public function __construct( $fieldWidget, $buttonWidget = false, array $config = array() ) {
+ // Allow passing positional parameters inside the config array
+ if ( is_array( $fieldWidget ) && isset( $fieldWidget['fieldWidget'] ) ) {
+ $config = $fieldWidget;
+ $fieldWidget = $config['fieldWidget'];
+ $buttonWidget = $config['buttonWidget'];
+ }
+
+ // Parent constructor
+ parent::__construct( $fieldWidget, $config );
+
+ // Properties
+ $this->buttonWidget = $buttonWidget;
+ $this->button = new Tag( 'div' );
+ $this->input = new Tag( 'div' );
+
+ // Initialization
+ $this->addClasses( array( 'oo-ui-actionFieldLayout' ) );
+ $this->button
+ ->addClasses( array( 'oo-ui-actionFieldLayout-button' ) )
+ ->appendContent( $this->buttonWidget );
+ $this->input
+ ->addClasses( array( 'oo-ui-actionFieldLayout-input' ) )
+ ->appendContent( $this->fieldWidget );
+ $this->field
+ ->clearContent()
+ ->appendContent( $this->input, $this->button );
+ }
+
+ public function getConfig( &$config ) {
+ $config['buttonWidget'] = $this->buttonWidget;
+ return parent::getConfig( $config );
+ }
+}
diff --git a/vendor/oojs/oojs-ui/php/layouts/FieldLayout.php b/vendor/oojs/oojs-ui/php/layouts/FieldLayout.php
index ef0d4c6c..bfa25afe 100644
--- a/vendor/oojs/oojs-ui/php/layouts/FieldLayout.php
+++ b/vendor/oojs/oojs-ui/php/layouts/FieldLayout.php
@@ -31,14 +31,37 @@ class FieldLayout extends Layout {
*/
protected $fieldWidget;
- private $field, $body, $help;
+ /**
+ * Error messages.
+ *
+ * @var array
+ */
+ protected $errors;
+
+ /**
+ * Notice messages.
+ *
+ * @var array
+ */
+ protected $notices;
+
+ /**
+ * @var ButtonWidget|string
+ */
+ protected $help;
+
+ protected $field, $body, $messages;
/**
* @param Widget $fieldWidget Field widget
* @param array $config Configuration options
* @param string $config['align'] Alignment mode, either 'left', 'right', 'top' or 'inline'
* (default: 'left')
- * @param string $config['help'] Explanatory text shown as a '?' icon.
+ * @param array $config['errors'] Error messages about the widget, as strings or HtmlSnippet
+ * instances.
+ * @param array $config['notices'] Notices about the widget, as strings or HtmlSnippet instances.
+ * @param string|HtmlSnippet $config['help'] Explanatory text shown as a '?' icon.
+ * @throws Exception An exception is thrown if no widget is specified
*/
public function __construct( $fieldWidget, array $config = array() ) {
// Allow passing positional parameters inside the config array
@@ -47,7 +70,12 @@ class FieldLayout extends Layout {
$fieldWidget = $config['fieldWidget'];
}
- $hasInputWidget = $fieldWidget instanceof InputWidget;
+ // Make sure we have required constructor arguments
+ if ( $fieldWidget === null ) {
+ throw new Exception( 'Widget not found' );
+ }
+
+ $hasInputWidget = $fieldWidget::$supportsSimpleLabel;
// Config initialization
$config = array_merge( array( 'align' => 'left' ), $config );
@@ -57,7 +85,10 @@ class FieldLayout extends Layout {
// Properties
$this->fieldWidget = $fieldWidget;
+ $this->errors = isset( $config['errors'] ) ? $config['errors'] : array();
+ $this->notices = isset( $config['notices'] ) ? $config['notices'] : array();
$this->field = new Tag( 'div' );
+ $this->messages = new Tag( 'ul' );
$this->body = new Tag( $hasInputWidget ? 'label' : 'div' );
if ( isset( $config['help'] ) ) {
$this->help = new ButtonWidget( array(
@@ -72,21 +103,55 @@ class FieldLayout extends Layout {
// Mixins
$this->mixin( new LabelElement( $this, $config ) );
+ $this->mixin( new TitledElement( $this,
+ array_merge( $config, array( 'titled' => $this->label ) ) ) );
// Initialization
$this
->addClasses( array( 'oo-ui-fieldLayout' ) )
->appendContent( $this->help, $this->body );
+ if ( count( $this->errors ) || count( $this->notices ) ) {
+ $this->appendContent( $this->messages );
+ }
$this->body->addClasses( array( 'oo-ui-fieldLayout-body' ) );
+ $this->messages->addClasses( array( 'oo-ui-fieldLayout-messages' ) );
$this->field
->addClasses( array( 'oo-ui-fieldLayout-field' ) )
->toggleClasses( array( 'oo-ui-fieldLayout-disable' ), $this->fieldWidget->isDisabled() )
->appendContent( $this->fieldWidget );
+ foreach ( $this->notices as $text ) {
+ $this->messages->appendContent( $this->makeMessage( 'notice', $text ) );
+ }
+ foreach ( $this->errors as $text ) {
+ $this->messages->appendContent( $this->makeMessage( 'error', $text ) );
+ }
+
$this->setAlignment( $config['align'] );
}
/**
+ * @param string $kind 'error' or 'notice'
+ * @param string|HtmlSnippet $text
+ * @return Tag
+ */
+ private function makeMessage( $kind, $text ) {
+ $listItem = new Tag( 'li' );
+ if ( $kind === 'error' ) {
+ $icon = new IconWidget( array( 'icon' => 'alert', 'flags' => array( 'warning' ) ) );
+ } elseif ( $kind === 'notice' ) {
+ $icon = new IconWidget( array( 'icon' => 'info' ) );
+ } else {
+ $icon = null;
+ }
+ $message = new LabelWidget( array( 'label' => $text ) );
+ $listItem
+ ->appendContent( $icon, $message )
+ ->addClasses( array( "oo-ui-fieldLayout-messages-$kind" ) );
+ return $listItem;
+ }
+
+ /**
* Get the field.
*
* @return Widget Field widget
@@ -132,6 +197,8 @@ class FieldLayout extends Layout {
public function getConfig( &$config ) {
$config['fieldWidget'] = $this->fieldWidget;
$config['align'] = $this->align;
+ $config['errors'] = $this->errors;
+ $config['notices'] = $this->notices;
if ( $this->help !== '' ) {
$config['help'] = $this->help->getTitle();
}
diff --git a/vendor/oojs/oojs-ui/php/layouts/FormLayout.php b/vendor/oojs/oojs-ui/php/layouts/FormLayout.php
index ebeb89de..eadf2750 100644
--- a/vendor/oojs/oojs-ui/php/layouts/FormLayout.php
+++ b/vendor/oojs/oojs-ui/php/layouts/FormLayout.php
@@ -7,7 +7,7 @@ namespace OOUI;
*/
class FormLayout extends Layout {
- /* Static properties */
+ /* Static Properties */
public static $tagName = 'form';
diff --git a/vendor/oojs/oojs-ui/php/layouts/HorizontalLayout.php b/vendor/oojs/oojs-ui/php/layouts/HorizontalLayout.php
new file mode 100644
index 00000000..d4acb216
--- /dev/null
+++ b/vendor/oojs/oojs-ui/php/layouts/HorizontalLayout.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace OOUI;
+
+/**
+ * HorizontalLayout arranges its contents in a single line (using `display: inline-block` for its
+ * items), with small margins between them.
+ */
+class HorizontalLayout extends Layout {
+ /**
+ * @param array $config Configuration options
+ * @param Widget[]|Layout[] $config['items'] Widgets or other layouts to add to the layout.
+ */
+ public function __construct( array $config = array() ) {
+ // Parent constructor
+ parent::__construct( $config );
+
+ // Mixins
+ $this->mixin( new GroupElement( $this, array_merge( $config, array( 'group' => $this ) ) ) );
+
+ // Initialization
+ $this->addClasses( array( 'oo-ui-horizontalLayout' ) );
+ if ( isset( $config['items'] ) ) {
+ $this->addItems( $config['items'] );
+ }
+ }
+}
diff --git a/vendor/oojs/oojs-ui/php/mixins/AccessKeyedElement.php b/vendor/oojs/oojs-ui/php/mixins/AccessKeyedElement.php
new file mode 100644
index 00000000..eb4b79ea
--- /dev/null
+++ b/vendor/oojs/oojs-ui/php/mixins/AccessKeyedElement.php
@@ -0,0 +1,76 @@
+<?php
+
+namespace OOUI;
+
+/**
+ * Element with an accesskey.
+ *
+ * Accesskeys allow an user to go to a specific element by using
+ * a shortcut combination of a browser specific keys + the key
+ * set to the field.
+ *
+ * @abstract
+ */
+class AccessKeyedElement extends ElementMixin {
+ /**
+ * Accesskey
+ *
+ * @var string
+ */
+ protected $accessKey = null;
+
+ public static $targetPropertyName = 'accessKeyed';
+
+ /**
+ * @param Element $element Element being mixed into
+ * @param array $config Configuration options
+ * @param string $config['accessKey'] AccessKey. If not provided, no accesskey will be added
+ */
+ public function __construct( Element $element, array $config = array() ) {
+ // Parent constructor
+ $target = isset( $config['accessKeyed'] ) ? $config['accessKeyed'] : $element;
+ parent::__construct( $element, $target, $config );
+
+ // Initialization
+ $this->setAccessKey(
+ isset( $config['accessKey'] ) ? $config['accessKey'] : null
+ );
+ }
+
+ /**
+ * Set access key.
+ *
+ * @param string $accessKey Tag's access key, use empty string to remove
+ * @chainable
+ */
+ public function setAccessKey( $accessKey ) {
+ $accessKey = is_string( $accessKey ) && strlen( $accessKey ) ? $accessKey : null;
+
+ if ( $this->accessKey !== $accessKey ) {
+ if ( $accessKey !== null ) {
+ $this->target->setAttributes( array( 'accesskey' => $accessKey ) );
+ } else {
+ $this->target->removeAttributes( array( 'accesskey' ) );
+ }
+ $this->accessKey = $accessKey;
+ }
+
+ return $this;
+ }
+
+ /**
+ * Get AccessKey.
+ *
+ * @return string Accesskey string
+ */
+ public function getAccessKey() {
+ return $this->accessKey;
+ }
+
+ public function getConfig( &$config ) {
+ if ( $this->accessKey !== null ) {
+ $config['accessKey'] = $this->accessKey;
+ }
+ return parent::getConfig( $config );
+ }
+}
diff --git a/vendor/oojs/oojs-ui/php/elements/ButtonElement.php b/vendor/oojs/oojs-ui/php/mixins/ButtonElement.php
index f9acf2d8..b09c7941 100644
--- a/vendor/oojs/oojs-ui/php/elements/ButtonElement.php
+++ b/vendor/oojs/oojs-ui/php/mixins/ButtonElement.php
@@ -18,20 +18,12 @@ class ButtonElement extends ElementMixin {
*/
protected $framed = false;
- /**
- * Button's access key.
- *
- * @var string
- */
- protected $accessKey = null;
-
public static $targetPropertyName = 'button';
/**
* @param Element $element Element being mixed into
* @param array $config Configuration options
* @param boolean $config['framed'] Render button with a frame (default: true)
- * @param string $config['accessKey'] Button's access key
*/
public function __construct( Element $element, array $config = array() ) {
// Parent constructor
@@ -42,7 +34,6 @@ class ButtonElement extends ElementMixin {
$this->element->addClasses( array( 'oo-ui-buttonElement' ) );
$this->target->addClasses( array( 'oo-ui-buttonElement-button' ) );
$this->toggleFramed( isset( $config['framed'] ) ? $config['framed'] : true );
- $this->setAccessKey( isset( $config['accessKey'] ) ? $config['accessKey'] : null );
$this->target->setAttributes( array(
'role' => 'button',
) );
@@ -69,34 +60,10 @@ class ButtonElement extends ElementMixin {
return $this->framed;
}
- /**
- * Set access key.
- *
- * @param string $accessKey Button's access key, use empty string to remove
- * @chainable
- */
- public function setAccessKey( $accessKey ) {
- $accessKey = is_string( $accessKey ) && strlen( $accessKey ) ? $accessKey : null;
-
- if ( $this->accessKey !== $accessKey ) {
- if ( $accessKey !== null ) {
- $this->target->setAttributes( array( 'accesskey' => $accessKey ) );
- } else {
- $this->target->removeAttributes( array( 'accesskey' ) );
- }
- $this->accessKey = $accessKey;
- }
-
- return $this;
- }
-
public function getConfig( &$config ) {
if ( $this->framed !== true ) {
$config['framed'] = $this->framed;
}
- if ( $this->accessKey !== null ) {
- $config['accessKey'] = $this->accessKey;
- }
return parent::getConfig( $config );
}
}
diff --git a/vendor/oojs/oojs-ui/php/elements/FlaggedElement.php b/vendor/oojs/oojs-ui/php/mixins/FlaggedElement.php
index bd5dc80d..bd5dc80d 100644
--- a/vendor/oojs/oojs-ui/php/elements/FlaggedElement.php
+++ b/vendor/oojs/oojs-ui/php/mixins/FlaggedElement.php
diff --git a/vendor/oojs/oojs-ui/php/elements/GroupElement.php b/vendor/oojs/oojs-ui/php/mixins/GroupElement.php
index 93d3c7a1..93d3c7a1 100644
--- a/vendor/oojs/oojs-ui/php/elements/GroupElement.php
+++ b/vendor/oojs/oojs-ui/php/mixins/GroupElement.php
diff --git a/vendor/oojs/oojs-ui/php/elements/IconElement.php b/vendor/oojs/oojs-ui/php/mixins/IconElement.php
index b6d27376..b6d27376 100644
--- a/vendor/oojs/oojs-ui/php/elements/IconElement.php
+++ b/vendor/oojs/oojs-ui/php/mixins/IconElement.php
diff --git a/vendor/oojs/oojs-ui/php/elements/IndicatorElement.php b/vendor/oojs/oojs-ui/php/mixins/IndicatorElement.php
index 56238b6c..56238b6c 100644
--- a/vendor/oojs/oojs-ui/php/elements/IndicatorElement.php
+++ b/vendor/oojs/oojs-ui/php/mixins/IndicatorElement.php
diff --git a/vendor/oojs/oojs-ui/php/elements/LabelElement.php b/vendor/oojs/oojs-ui/php/mixins/LabelElement.php
index d5cf7bee..d5cf7bee 100644
--- a/vendor/oojs/oojs-ui/php/elements/LabelElement.php
+++ b/vendor/oojs/oojs-ui/php/mixins/LabelElement.php
diff --git a/vendor/oojs/oojs-ui/php/elements/TabIndexedElement.php b/vendor/oojs/oojs-ui/php/mixins/TabIndexedElement.php
index 223b5371..223b5371 100644
--- a/vendor/oojs/oojs-ui/php/elements/TabIndexedElement.php
+++ b/vendor/oojs/oojs-ui/php/mixins/TabIndexedElement.php
diff --git a/vendor/oojs/oojs-ui/php/elements/TitledElement.php b/vendor/oojs/oojs-ui/php/mixins/TitledElement.php
index 5f1317c4..5f1317c4 100644
--- a/vendor/oojs/oojs-ui/php/elements/TitledElement.php
+++ b/vendor/oojs/oojs-ui/php/mixins/TitledElement.php
diff --git a/vendor/oojs/oojs-ui/php/widgets/ButtonInputWidget.php b/vendor/oojs/oojs-ui/php/widgets/ButtonInputWidget.php
index b3bcb63b..00c17912 100644
--- a/vendor/oojs/oojs-ui/php/widgets/ButtonInputWidget.php
+++ b/vendor/oojs/oojs-ui/php/widgets/ButtonInputWidget.php
@@ -6,6 +6,15 @@ namespace OOUI;
* A button that is an input widget. Intended to be used within a FormLayout.
*/
class ButtonInputWidget extends InputWidget {
+
+ /* Static Properties */
+
+ /**
+ * Disable generating `<label>` elements for buttons. One would very rarely need additional label
+ * for a button, and it's already a big clickable target, and it causes unexpected rendering.
+ */
+ public static $supportsSimpleLabel = false;
+
/* Properties */
/**
@@ -60,8 +69,11 @@ class ButtonInputWidget extends InputWidget {
}
protected function getInputElement( $config ) {
+ $type = in_array( $config['type'], array( 'button', 'submit', 'reset' ) ) ?
+ $config['type'] :
+ 'button';
$input = new Tag( $config['useInputTag'] ? 'input' : 'button' );
- $input->setAttributes( array( 'type' => $config['type'] ) );
+ $input->setAttributes( array( 'type' => $type ) );
return $input;
}
diff --git a/vendor/oojs/oojs-ui/php/widgets/ButtonWidget.php b/vendor/oojs/oojs-ui/php/widgets/ButtonWidget.php
index f26608b1..976ac6c2 100644
--- a/vendor/oojs/oojs-ui/php/widgets/ButtonWidget.php
+++ b/vendor/oojs/oojs-ui/php/widgets/ButtonWidget.php
@@ -50,6 +50,8 @@ class ButtonWidget extends Widget {
$this->mixin( new FlaggedElement( $this, $config ) );
$this->mixin( new TabIndexedElement( $this,
array_merge( $config, array( 'tabIndexed' => $this->button ) ) ) );
+ $this->mixin( new AccessKeyedElement( $this,
+ array_merge( $config, array( 'accessKeyed' => $this->button ) ) ) );
// Initialization
$this->button->appendContent( $this->icon, $this->label, $this->indicator );
diff --git a/vendor/oojs/oojs-ui/php/widgets/CheckboxInputWidget.php b/vendor/oojs/oojs-ui/php/widgets/CheckboxInputWidget.php
index bda09c66..5d180d58 100644
--- a/vendor/oojs/oojs-ui/php/widgets/CheckboxInputWidget.php
+++ b/vendor/oojs/oojs-ui/php/widgets/CheckboxInputWidget.php
@@ -27,6 +27,8 @@ class CheckboxInputWidget extends InputWidget {
// Initialization
$this->addClasses( array( 'oo-ui-checkboxInputWidget' ) );
+ // Required for pretty styling in MediaWiki theme
+ $this->appendContent( new Tag( 'span' ) );
$this->setSelected( isset( $config['selected'] ) ? $config['selected'] : false );
}
diff --git a/vendor/oojs/oojs-ui/php/widgets/DropdownInputWidget.php b/vendor/oojs/oojs-ui/php/widgets/DropdownInputWidget.php
index ae541a66..f8ea48a3 100644
--- a/vendor/oojs/oojs-ui/php/widgets/DropdownInputWidget.php
+++ b/vendor/oojs/oojs-ui/php/widgets/DropdownInputWidget.php
@@ -23,6 +23,10 @@ class DropdownInputWidget extends InputWidget {
// Parent constructor
parent::__construct( $config );
+ // Mixins
+ $this->mixin( new TitledElement( $this,
+ array_merge( $config, array( 'titled' => $this->input ) ) ) );
+
// Initialization
$this->setOptions( isset( $config['options'] ) ? $config['options'] : array() );
$this->addClasses( array( 'oo-ui-dropdownInputWidget' ) );
@@ -60,11 +64,12 @@ class DropdownInputWidget extends InputWidget {
// Rebuild the dropdown menu
$this->input->clearContent();
foreach ( $options as $opt ) {
+ $optValue = $this->cleanUpValue( $opt['data'] );
$option = new Tag( 'option' );
- $option->setAttributes( array( 'value' => $opt['data'] ) );
- $option->appendContent( isset( $opt['label'] ) ? $opt['label'] : $opt['data'] );
+ $option->setAttributes( array( 'value' => $optValue ) );
+ $option->appendContent( isset( $opt['label'] ) ? $opt['label'] : $optValue );
- if ( $value === $opt['data'] ) {
+ if ( $value === $optValue ) {
$isValueAvailable = true;
}
diff --git a/vendor/oojs/oojs-ui/php/widgets/IconWidget.php b/vendor/oojs/oojs-ui/php/widgets/IconWidget.php
index f8273f37..d752ddc8 100644
--- a/vendor/oojs/oojs-ui/php/widgets/IconWidget.php
+++ b/vendor/oojs/oojs-ui/php/widgets/IconWidget.php
@@ -9,7 +9,7 @@ namespace OOUI;
*/
class IconWidget extends Widget {
- /* Static properties */
+ /* Static Properties */
public static $tagName = 'span';
diff --git a/vendor/oojs/oojs-ui/php/widgets/IndicatorWidget.php b/vendor/oojs/oojs-ui/php/widgets/IndicatorWidget.php
index 01f2055d..b933a309 100644
--- a/vendor/oojs/oojs-ui/php/widgets/IndicatorWidget.php
+++ b/vendor/oojs/oojs-ui/php/widgets/IndicatorWidget.php
@@ -9,7 +9,7 @@ namespace OOUI;
*/
class IndicatorWidget extends Widget {
- /* Static properties */
+ /* Static Properties */
public static $tagName = 'span';
diff --git a/vendor/oojs/oojs-ui/php/widgets/InputWidget.php b/vendor/oojs/oojs-ui/php/widgets/InputWidget.php
index 234d3145..24f5a51c 100644
--- a/vendor/oojs/oojs-ui/php/widgets/InputWidget.php
+++ b/vendor/oojs/oojs-ui/php/widgets/InputWidget.php
@@ -9,6 +9,10 @@ namespace OOUI;
*/
class InputWidget extends Widget {
+ /* Static Properties */
+
+ public static $supportsSimpleLabel = true;
+
/* Properties */
/**
@@ -42,6 +46,10 @@ class InputWidget extends Widget {
array_merge( $config, array( 'flagged' => $this ) ) ) );
$this->mixin( new TabIndexedElement( $this,
array_merge( $config, array( 'tabIndexed' => $this->input ) ) ) );
+ $this->mixin( new TitledElement( $this,
+ array_merge( $config, array( 'titled' => $this->input ) ) ) );
+ $this->mixin( new AccessKeyedElement( $this,
+ array_merge( $config, array( 'accessKeyed' => $this->input ) ) ) );
// Initialization
if ( isset( $config['name'] ) ) {
@@ -53,7 +61,7 @@ class InputWidget extends Widget {
$this
->addClasses( array( 'oo-ui-inputWidget' ) )
->appendContent( $this->input );
- $this->appendContent( new Tag( 'span' ) );
+ $this->input->addClasses( array( 'oo-ui-inputWidget-input' ) );
$this->setValue( isset( $config['value'] ) ? $config['value'] : null );
}
diff --git a/vendor/oojs/oojs-ui/php/widgets/LabelWidget.php b/vendor/oojs/oojs-ui/php/widgets/LabelWidget.php
index b59a5f25..8945b15f 100644
--- a/vendor/oojs/oojs-ui/php/widgets/LabelWidget.php
+++ b/vendor/oojs/oojs-ui/php/widgets/LabelWidget.php
@@ -7,7 +7,7 @@ namespace OOUI;
*/
class LabelWidget extends Widget {
- /* Static properties */
+ /* Static Properties */
public static $tagName = 'span';
diff --git a/vendor/oojs/oojs-ui/php/widgets/RadioInputWidget.php b/vendor/oojs/oojs-ui/php/widgets/RadioInputWidget.php
index 26da29d0..69fd0a8e 100644
--- a/vendor/oojs/oojs-ui/php/widgets/RadioInputWidget.php
+++ b/vendor/oojs/oojs-ui/php/widgets/RadioInputWidget.php
@@ -18,6 +18,8 @@ class RadioInputWidget extends InputWidget {
// Initialization
$this->addClasses( array( 'oo-ui-radioInputWidget' ) );
+ // Required for pretty styling in MediaWiki theme
+ $this->appendContent( new Tag( 'span' ) );
$this->setSelected( isset( $config['selected'] ) ? $config['selected'] : false );
}
diff --git a/vendor/oojs/oojs-ui/php/widgets/RadioSelectInputWidget.php b/vendor/oojs/oojs-ui/php/widgets/RadioSelectInputWidget.php
new file mode 100644
index 00000000..912c6917
--- /dev/null
+++ b/vendor/oojs/oojs-ui/php/widgets/RadioSelectInputWidget.php
@@ -0,0 +1,127 @@
+<?php
+
+namespace OOUI;
+
+/**
+ * Multiple radio buttons input widget. Intended to be used within a OO.ui.FormLayout.
+ */
+class RadioSelectInputWidget extends InputWidget {
+
+ /* Static Properties */
+
+ public static $supportsSimpleLabel = false;
+
+ /* Properties */
+
+ /**
+ * @var string|null
+ */
+ protected $name = null;
+
+ /**
+ * @var FieldLayout[]
+ */
+ protected $fields = array();
+
+ /**
+ * @param array $config Configuration options
+ * @param array[] $config['options'] Array of menu options in the format
+ * `array( 'data' => …, 'label' => … )`
+ */
+ public function __construct( array $config = array() ) {
+ // Parent constructor
+ parent::__construct( $config );
+
+ if ( isset( $config['name'] ) ) {
+ $this->name = $config['name'];
+ }
+
+ // Initialization
+ $this->setOptions( isset( $config['options'] ) ? $config['options'] : array() );
+ $this->addClasses( array( 'oo-ui-radioSelectInputWidget' ) );
+ }
+
+ protected function getInputElement( $config ) {
+ // Actually unused
+ return new Tag( 'div' );
+ }
+
+ public function setValue( $value ) {
+ $this->value = $this->cleanUpValue( $value );
+ foreach ( $this->fields as &$field ) {
+ $field->getField()->setSelected( $field->getField()->getValue() === $this->value );
+ }
+ return $this;
+ }
+
+ /**
+ * Set the options available for this input.
+ *
+ * @param array[] $options Array of menu options in the format
+ * `array( 'data' => …, 'label' => … )`
+ * @chainable
+ */
+ public function setOptions( $options ) {
+ $value = $this->getValue();
+ $isValueAvailable = false;
+ $this->fields = array();
+
+ // Rebuild the radio buttons
+ $this->clearContent();
+ // Need a unique name, otherwise more than one radio will be selectable
+ $name = $this->name ?: 'oo-ui-radioSelectInputWidget' . mt_rand();
+ foreach ( $options as $opt ) {
+ $optValue = $this->cleanUpValue( $opt['data'] );
+ $field = new FieldLayout(
+ new RadioInputWidget( array(
+ 'name' => $name,
+ 'value' => $optValue,
+ 'disabled' => $this->isDisabled(),
+ ) ),
+ array(
+ 'label' => isset( $opt['label'] ) ? $opt['label'] : $optValue,
+ 'align' => 'inline',
+ )
+ );
+
+ if ( $value === $optValue ) {
+ $isValueAvailable = true;
+ }
+
+ $this->fields[] = $field;
+ $this->appendContent( $field );
+ }
+
+ // Restore the previous value, or reset to something sensible
+ if ( $isValueAvailable ) {
+ // Previous value is still available
+ $this->setValue( $value );
+ } else {
+ // No longer valid, reset
+ if ( count( $options ) ) {
+ $this->setValue( $options[0]['data'] );
+ }
+ }
+
+ return $this;
+ }
+
+ public function setDisabled( $state ) {
+ parent::setDisabled( $state );
+ foreach ( $this->fields as $field ) {
+ $field->getField()->setDisabled( $this->isDisabled() );
+ }
+ return $this;
+ }
+
+ public function getConfig( &$config ) {
+ $o = array();
+ foreach ( $this->fields as $field ) {
+ $label = $field->getLabel();
+ $data = $field->getField()->getValue();
+ $o[] = array( 'data' => $data, 'label' => $label );
+ }
+ $config['options'] = $o;
+ return parent::getConfig( $config );
+ }
+}
diff --git a/vendor/oojs/oojs-ui/php/widgets/TextInputWidget.php b/vendor/oojs/oojs-ui/php/widgets/TextInputWidget.php
index a5f31f74..210729fd 100644
--- a/vendor/oojs/oojs-ui/php/widgets/TextInputWidget.php
+++ b/vendor/oojs/oojs-ui/php/widgets/TextInputWidget.php
@@ -10,6 +10,13 @@ class TextInputWidget extends InputWidget {
/* Properties */
/**
+ * Input field type.
+ *
+ * @var string
+ */
+ protected $type = null;
+
+ /**
* Prevent changes.
*
* @var boolean
@@ -25,27 +32,49 @@ class TextInputWidget extends InputWidget {
/**
* @param array $config Configuration options
- * @param string $config['type'] HTML tag `type` attribute (default: 'text')
+ * @param string $config['type'] HTML tag `type` attribute: 'text', 'password', 'search', 'email'
+ * or 'url'. Ignored if `multiline` is true. (default: 'text')
+ *
+ * Some values of `type` result in additional behaviors:
+ * - `search`: implies `icon: 'search'` and `indicator: 'clear'`; when clicked, the indicator
+ * empties the text field
* @param string $config['placeholder'] Placeholder text
* @param boolean $config['autofocus'] Ask the browser to focus this widget, using the 'autofocus'
* HTML attribute (default: false)
* @param boolean $config['readOnly'] Prevent changes (default: false)
* @param number $config['maxLength'] Maximum allowed number of characters to input
* @param boolean $config['multiline'] Allow multiple lines of text (default: false)
- * @param boolean $config['required'] Mark the field as required (default: false)
+ * @param int $config['rows'] If multiline, number of visible lines in textarea
+ * @param boolean $config['required'] Mark the field as required.
+ * Implies `indicator: 'required'`. (default: false)
+ * @param boolean $config['autocomplete'] If the field should support autocomplete
+ * or not (default: true)
*/
public function __construct( array $config = array() ) {
// Config initialization
$config = array_merge( array(
+ 'type' => 'text',
'readOnly' => false,
'autofocus' => false,
'required' => false,
+ 'autocomplete' => true,
), $config );
+ if ( $config['type'] === 'search' ) {
+ if ( !array_key_exists( 'icon', $config ) ) {
+ $config['icon'] = 'search';
+ }
+ }
+ if ( $config['required'] ) {
+ if ( !array_key_exists( 'indicator', $config ) ) {
+ $config['indicator'] = 'required';
+ }
+ }
// Parent constructor
parent::__construct( $config );
// Properties
+ $this->type = $this->getSaneType( $config );
$this->multiline = isset( $config['multiline'] ) ? (bool)$config['multiline'] : false;
// Mixins
@@ -54,7 +83,7 @@ class TextInputWidget extends InputWidget {
// Initialization
$this
- ->addClasses( array( 'oo-ui-textInputWidget' ) )
+ ->addClasses( array( 'oo-ui-textInputWidget', 'oo-ui-textInputWidget-type-' . $this->type ) )
->appendContent( $this->icon, $this->indicator );
$this->setReadOnly( $config['readOnly'] );
if ( isset( $config['placeholder'] ) ) {
@@ -69,6 +98,12 @@ class TextInputWidget extends InputWidget {
if ( $config['required'] ) {
$this->input->setAttributes( array( 'required' => 'required', 'aria-required' => 'true' ) );
}
+ if ( !$config['autocomplete'] ) {
+ $this->input->setAttributes( array( 'autocomplete' => 'off' ) );
+ }
+ if ( $this->multiline && isset( $config['rows'] ) ) {
+ $this->input->setAttributes( array( 'rows' => $config['rows'] ) );
+ }
}
/**
@@ -101,13 +136,23 @@ class TextInputWidget extends InputWidget {
if ( isset( $config['multiline'] ) && $config['multiline'] ) {
return new Tag( 'textarea' );
} else {
- $type = isset( $config['type'] ) ? $config['type'] : 'text';
$input = new Tag( 'input' );
- $input->setAttributes( array( 'type' => $type ) );
+ $input->setAttributes( array( 'type' => $this->getSaneType( $config ) ) );
return $input;
}
}
+ private function getSaneType( $config ) {
+ if ( isset( $config['multiline'] ) && $config['multiline'] ) {
+ return 'multiline';
+ } else {
+ $type = in_array( $config['type'], array( 'text', 'password', 'search', 'email', 'url' ) ) ?
+ $config['type'] :
+ 'text';
+ return $type;
+ }
+ }
+
/**
* Check if input supports multiple lines.
*
@@ -120,6 +165,10 @@ class TextInputWidget extends InputWidget {
public function getConfig( &$config ) {
if ( $this->isMultiline() ) {
$config['multiline'] = true;
+ $rows = $this->input->getAttribute( 'rows' );
+ if ( $rows !== null ) {
+ $config['rows'] = $rows;
+ }
} else {
$type = $this->input->getAttribute( 'type' );
if ( $type !== 'text' ) {
@@ -146,6 +195,10 @@ class TextInputWidget extends InputWidget {
if ( ( $required !== null ) || ( $ariarequired !== null ) ) {
$config['required'] = true;
}
+ $autocomplete = $this->input->getAttribute( 'autocomplete' );
+ if ( $autocomplete !== null ) {
+ $config['autocomplete'] = false;
+ }
return parent::getConfig( $config );
}
}