Trevor Parscal has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/160996

Change subject: [WIP] PHP Implementation of OOjs UI
......................................................................

[WIP] PHP Implementation of OOjs UI

The PHP implmentation will include only a subset of elements, widgets and 
layouts, based on what makes sense for static content. Future work will be done 
to support progressive enhancement on the client for certain widgets, such as 
turning a TextInputWidget into an MwTitleInputWidget.

Working so far:

* ButtonElement
* FlaggedElement
* IconElement
* IndicatorElement
* LabelElement
* ButtonWidget

In progress:
* FormLayout
* FieldsetLayout
* FieldLayout

Todo:
* A few other things

Change-Id: Ifcc9b859c76e9c3f1d6ca2012a21d4198caa8240
---
A demos/widgets.php
A php/OoUiElement.php
A php/OoUiElementMixin.php
A php/OoUiLayout.php
A php/OoUiTag.php
A php/OoUiWidget.php
A php/elements/OoUiButtonElement.php
A php/elements/OoUiFlaggedElement.php
A php/elements/OoUiIconElement.php
A php/elements/OoUiIndicatorElement.php
A php/elements/OoUiLabelElement.php
A php/layouts/OoUiFieldLayout.php
A php/layouts/OoUiFieldsetLayout.php
A php/layouts/OoUiFormLayout.php
A php/widgets/OoUiButtonWidget.php
M src/themes/apex/elements.less
16 files changed, 861 insertions(+), 0 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/oojs/ui refs/changes/96/160996/1

diff --git a/demos/widgets.php b/demos/widgets.php
new file mode 100644
index 0000000..fe5e95b
--- /dev/null
+++ b/demos/widgets.php
@@ -0,0 +1,97 @@
+<!DOCTYPE html>
+<html lang="en" dir="ltr">
+<head>
+       <meta charset="UTF-8">
+       <title>OOjs UI Widget Demo</title>
+       <link rel="stylesheet" href="../dist/oojs-ui.css">
+       <link rel="stylesheet" href="../dist/oojs-ui-apex.css">
+       <link rel="stylesheet" href="demo.css">
+</head>
+<body>
+       <div class="oo-ui-demo">
+               <div class="oo-ui-demo-container">
+                       <?php
+                               require_once '../php/OoUiTag.php';
+                               require_once '../php/OoUiElement.php';
+                               require_once '../php/OoUiElementMixin.php';
+                               require_once '../php/OoUiWidget.php';
+                               require_once '../php/OoUiLayout.php';
+                               require_once 
'../php/elements/OoUiButtonElement.php';
+                               require_once 
'../php/elements/OoUiLabelElement.php';
+                               require_once 
'../php/elements/OoUiIconElement.php';
+                               require_once 
'../php/elements/OoUiIndicatorElement.php';
+                               require_once 
'../php/elements/OoUiFlaggedElement.php';
+                               require_once 
'../php/widgets/OoUiButtonWidget.php';
+                       ?>
+
+                       <table>
+                               <tbody>
+                                       <?php
+                                               $styles = array(
+                                                       array(
+                                                               'flags' => 
array(),
+                                                       ),
+                                                       array(
+                                                               'flags' => 
array( 'primary' ),
+                                                       ),
+                                                       array(
+                                                               'flags' => 
array( 'constructive' ),
+                                                       ),
+                                                       array(
+                                                               'flags' => 
array( 'destructive' ),
+                                                       ),
+                                               );
+                                               $states = array(
+                                                       array(
+                                                               'label' => 
'Button',
+                                                       ),
+                                                       array(
+                                                               'label' => 
'Button',
+                                                               'icon' => 
'picture',
+                                                       ),
+                                                       array(
+                                                               'label' => 
'Button',
+                                                               'icon' => 
'picture',
+                                                               'indicator' => 
'down',
+                                                       ),
+                                                       array(
+                                                               'icon' => 
'picture',
+                                                       ),
+                                                       array(
+                                                               'indicator' => 
'down',
+                                                       ),
+                                                       array(
+                                                               'icon' => 
'picture',
+                                                               'indicator' => 
'down',
+                                                       ),
+                                                       array(
+                                                               'label' => 
'Button',
+                                                               'disabled' => 
true,
+                                                       ),
+                                                       array(
+                                                               'icon' => 
'picture',
+                                                               'disabled' => 
true,
+                                                       ),
+                                                       array(
+                                                               'indicator' => 
'down',
+                                                               'disabled' => 
true,
+                                                       ),
+                                               );
+                                               foreach ( $styles as $style ) {
+                                                       echo '<tr>';
+                                                       foreach ( $states as 
$state ) {
+                                                               echo '<td>';
+                                                               echo new 
OoUiButtonWidget(
+                                                                       
array_merge( $style, $state )
+                                                               );
+                                                               echo '</td>';
+                                                       }
+                                                       echo '</tr>';
+                                               }
+                                       ?>
+                               </tbody>
+                       </table>
+               </div>
+       </div>
+</body>
+</html>
diff --git a/php/OoUiElement.php b/php/OoUiElement.php
new file mode 100644
index 0000000..f11bf58
--- /dev/null
+++ b/php/OoUiElement.php
@@ -0,0 +1,66 @@
+<?php
+
+class OoUiElement extends OoUiTag {
+
+       /* Members */
+
+       /**
+        * Mixins.
+        *
+        * @var array List mixed in objects.
+        */
+       protected $mixins = array();
+
+       /* Methods */
+
+       /**
+        * Create element.
+        *
+        * @param array $config Configuration options
+        * @param array $config['classes'] CSS class names to add
+        * @param array $config['content'] Content to append, text or 
OoUiElement objects
+        */
+       public function __construct ( array $config ) {
+               // Parent constructor
+               parent::__construct( 'div' );
+
+               // Initialization
+               if ( isset( $config['classes'] ) && is_array( 
$config['classes'] ) ) {
+                       $this->addClasses( $config['classes'] );
+               }
+               if ( isset( $config['content'] ) ) {
+                       $this->appendContent( $config['content'] );
+               }
+       }
+
+       /**
+        * Call a mixed-in method.
+        *
+        * @param [string] $name Method name
+        * @param [array] $arguments Method arguments
+        * @return [mixed] Result of method call
+        * @throws  Error If method doesn't exist
+        */
+       public function __call( $name, $arguments ) {
+               // Search mixins for methods
+               foreach ( $this->mixins as $mixin ) {
+                       if ( method_exists( $mixin, $name ) ) {
+                               return call_user_func_array( array( $mixin, 
$name ), $arguments );
+                       }
+               }
+               // Fail normally
+               trigger_error(
+                       'Call to undefined method ' . __CLASS__ . '::' . $name 
. '()',
+                       E_USER_ERROR
+               );
+       }
+
+       /**
+        * Mixin a class.
+        *
+        * @param [OoUiElementMixin] $mixin Mixin object
+        */
+       public function mixin ( OoUiElementMixin $mixin ) {
+               $this->mixins[] = $mixin;
+       }
+}
diff --git a/php/OoUiElementMixin.php b/php/OoUiElementMixin.php
new file mode 100644
index 0000000..6baa6a1
--- /dev/null
+++ b/php/OoUiElementMixin.php
@@ -0,0 +1,34 @@
+<?php
+
+class OoUiElementMixin {
+
+       /* Properties */
+
+       /**
+        * Tag being targeted.
+        *
+        * @var OoUiTag
+        */
+       protected $target = null;
+
+       /**
+        * Element being mixed into.
+        *
+        * @var OoUiElement
+        */
+       protected $element = null;
+
+       /* Methods */
+
+       /**
+        * Create element.
+        *
+        * @param OoUiElement $element Element being mixed into
+        * @param OoUiTag $target Tag being targeted
+        * @param array $config Configuration options
+        */
+       public function __construct ( OoUiElement $element, OoUiTag $target, 
array $config ) {
+               $this->element = $element;
+               $this->target = $target;
+       }
+}
diff --git a/php/OoUiLayout.php b/php/OoUiLayout.php
new file mode 100644
index 0000000..202d33f
--- /dev/null
+++ b/php/OoUiLayout.php
@@ -0,0 +1,13 @@
+<?php
+
+class OoUiLayout extends OoUiElement {
+       /**
+        * Create widget.
+        *
+        * @param array $config Configuration options
+        */
+       public function __construct ( array $config ) {
+               // Parent constructor
+               parent::__construct( $config );
+       }
+}
diff --git a/php/OoUiTag.php b/php/OoUiTag.php
new file mode 100644
index 0000000..cc57ecb
--- /dev/null
+++ b/php/OoUiTag.php
@@ -0,0 +1,197 @@
+<?php
+
+class OoUiTag {
+
+       /* Members */
+
+       /**
+        * Tag name.
+        *
+        * @var string HTML tag name
+        */
+       protected $tagName = '';
+
+       /**
+        * Attributes.
+        *
+        * @var array HTML attributes
+        */
+       protected $attributes = array();
+
+       /**
+        * Classes.
+        *
+        * @var array CSS classes
+        */
+       protected $classes = array();
+
+       /**
+        * Content.
+        *
+        * @var array Content text and elements
+        */
+       protected $content = array();
+
+       /* Methods */
+
+       /**
+        * Create element.
+        *
+        * @param string $tagName HTML tag name
+        */
+       public function __construct ( $tagName = 'div' ) {
+               $this->tagName = $tagName;
+       }
+
+       /**
+        * Check for CSS class.
+        *
+        * @param string $name CSS class name
+        * @return boolean
+        */
+       public function hasClass ( $class ) {
+               return in_array( $class, $this->classes );
+       }
+
+       /**
+        * Add CSS classes.
+        *
+        * @param array $classes List of classes to add
+        * @chainable
+        */
+       public function addClasses ( array $classes ) {
+               $this->classes = array_merge( $this->classes, $classes );
+               return $this;
+       }
+
+       /**
+        * Remove CSS classes.
+        *
+        * @param array $classes List of classes to remove
+        * @chainable
+        */
+       public function removeClasses ( array $classes ) {
+               $this->classes = array_diff( $this->classes, $classes );
+               return $this;
+       }
+
+       /**
+        * Toggle CSS classes.
+        *
+        * @param array $classes List of classes to add
+        * @param boolean $toggle Add classes
+        * @chainable
+        */
+       public function toggleClasses ( array $classes, $toggle = null ) {
+               if ( $toggle === null ) {
+                       $this->classes = array_diff(
+                               array_merge( $this->classes, $classes ),
+                               array_intersect( $this->classes, $class )
+                       );
+               } else if ( $toggle ) {
+                       $this->classes = array_merge( $this->classes, $classes 
);
+               } else {
+                       $this->classes = array_diff( $this->classes, $classes );
+               }
+               return $this;
+       }
+
+       /**
+        * Get HTML attribute value.
+        *
+        * @param string $key HTML attribute name
+        * @return string|null
+        */
+       public function getAttribute ( $key ) {
+               return isset( $this->attributes[$key] ) ? 
$this->attributes[$key] : null;
+       }
+
+       /**
+        * Add HTML attributes.
+        *
+        * @param array $attributes List of attribute key/value pairs to add
+        * @chainable
+        */
+       public function setAttributes ( array $attributes ) {
+               foreach ( $attributes as $key => $value ) {
+                       $this->attributes[$key] = $value;
+               }
+               return $this;
+       }
+
+       /**
+        * Remove HTML attributes.
+        *
+        * @param array $keys List of attribute keys to remove
+        * @chainable
+        */
+       public function removeAttributes ( array $keys ) {
+               foreach ( $keys as $key ) {
+                       unset( $this->attributes[$key] );
+               }
+               return $this;
+       }
+
+       /**
+        * Add content to the end.
+        *
+        * @param string|array|Serializable One or more strings or serializable 
elements to append
+        * @chainable
+        */
+       public function appendContent ( $content ) {
+               array_push( $this->content, $content );
+               return $this;
+       }
+
+       /**
+        * Add content to the beginning.
+        *
+        * @param string|array|Serializable One or more strings or serializable 
elements to prepend
+        * @chainable
+        */
+       public function prependContent ( $content ) {
+               array_unshift( $this->content, $content );
+               return $this;
+       }
+
+       /**
+        * Remove all content.
+        *
+        * @chainable
+        */
+       public function clearContent () {
+               $this->content = array();
+               return $this;
+       }
+
+       /**
+        * Render element into HTML.
+        *
+        * @return string HTML serialization
+        */
+       public function __toString () {
+               // Attributes
+               $attributes = '';
+               foreach (
+                       array_merge(
+                               $this->attributes,
+                               array( 'class' => implode( ' ', array_unique( 
$this->classes ) ) )
+                       ) as
+                       $key => $value
+               ) {
+                       // TODO: Escaping
+                       $attributes .= ' ' . $key . '="' . $value . '"'; 
+               }
+
+               // Content
+               $content = '';
+               foreach ( $this->content as $part ) {
+                       if ( is_string( $part ) || $part instanceof OoUiTag ) {
+                               $content .= (string)$part;
+                       }
+               }
+
+               // Tag
+               return '<' . $this->tagName . $attributes . '>' . $content . 
'</' . $this->tagName . '>';
+       }
+}
diff --git a/php/OoUiWidget.php b/php/OoUiWidget.php
new file mode 100644
index 0000000..0c7d1b1
--- /dev/null
+++ b/php/OoUiWidget.php
@@ -0,0 +1,53 @@
+<?php
+
+class OoUiWidget extends OoUiElement {
+
+       /* Properties */
+
+       /**
+        * Disabled.
+        *
+        * @var boolean Widget is disabled
+        */
+       protected $disabled = false;
+
+       /* Methods */
+
+       /**
+        * Create widget.
+        *
+        * @param array $config Configuration options
+        */
+       public function __construct ( array $config ) {
+               // Parent constructor
+               parent::__construct( $config );
+
+               // Initialization
+               $this->setDisabled( $config['disabled'] );
+       }
+
+       /**
+        * Check if the widget is disabled.
+        *
+        * @param boolean Button is disabled
+        */
+       public function isDisabled () {
+               return $this->disabled;
+       }
+
+       /**
+        * Set the disabled state of the widget.
+        *
+        * This should probably change the widgets' appearance and prevent it 
from being used.
+        *
+        * @param boolean disabled Disable widget
+        * @chainable
+        */
+       public function setDisabled ( $disabled ) {
+               $this->disabled = !!$disabled;
+               $this->toggleClasses( array( 'oo-ui-widget-disabled' ), 
$this->disabled );
+               $this->toggleClasses( array( 'oo-ui-widget-enabled' ), 
!$this->disabled );
+
+               return $this;
+       }
+}
diff --git a/php/elements/OoUiButtonElement.php 
b/php/elements/OoUiButtonElement.php
new file mode 100644
index 0000000..193dbfe
--- /dev/null
+++ b/php/elements/OoUiButtonElement.php
@@ -0,0 +1,88 @@
+<?php
+
+class OoUiButtonElement extends OoUiElementMixin {
+       /**
+        * Button is framed.
+        *
+        * @var boolean
+        */
+       protected $framed = false;
+
+       /**
+        * Mixin button element.
+        *
+        * @param OoUiElement $element Element being mixed into
+        * @param OoUiTag $target Button tag
+        * @param array $config Configuration options
+        * @param {boolean} $config['framed'] Render button with a frame
+        * @param {number} $config['tabIndex'] Button's tab index, use -1 to 
prevent tab focusing
+        */
+       public function __construct ( OoUiElement $element, OoUiTag $target, 
array $config ) {
+               // Parent constructor
+               parent::__construct( $element, $target, $config );
+
+               // Initialization
+               $this->element->addClasses( array( 'oo-ui-buttonElement' ) );
+               $this->target->addClasses( array( 'oo-ui-buttonElement-button' 
) );
+               $this->toggleFramed( isset( $config['framed'] ) ? 
$config['framed'] : true );
+               $this->target->setAttributes( array(
+                       'role' => 'button',
+                       'tabIndex' => isset( $config['tabIndex'] ) &&
+                               is_numeric( $config['tabIndex'] ) ? 
$config['tabIndex'] : 0
+               ) );
+       }
+
+       /**
+        * Toggle frame.
+        *
+        * @param boolean [framed] Make button framed, omit to toggle
+        * @chainable
+        */
+       public function toggleFramed ( $framed = null ) {
+               $this->framed = $framed !== null ? !!$framed : !$this->framed;
+               $this->element->toggleClasses( array( 
'oo-ui-buttonElement-framed' ), $this->framed );
+               $this->element->toggleClasses( array( 
'oo-ui-buttonElement-frameless' ), !$this->framed );
+       }
+
+       /**
+        * Set tab index.
+        *
+        * @param number|null $tabIndex Button's tab index, use null to remove
+        * @chainable
+        */
+       public function setTabIndex ( $tabIndex ) {
+               $tabIndex = is_numeric( $tabIndex ) && $tabIndex >= 0 ? 
$tabIndex : null;
+
+               if ( $this->tabIndex !== $tabIndex ) {
+                       if ( $tabIndex !== null ) {
+                               $this->target->setAttributes( array( 'tabindex' 
=> $tabIndex ) );
+                       } else {
+                               $this->target->removeAttributes( array( 
'tabindex' ) );
+                       }
+                       $this->tabIndex = $tabIndex;
+               }
+
+               return $this;
+       }
+
+       /**
+        * 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;
+       }
+}
diff --git a/php/elements/OoUiFlaggedElement.php 
b/php/elements/OoUiFlaggedElement.php
new file mode 100644
index 0000000..5b435b6
--- /dev/null
+++ b/php/elements/OoUiFlaggedElement.php
@@ -0,0 +1,115 @@
+<?php
+
+class OoUiFlaggedElement extends OoUiElementMixin {
+       /**
+        * Flags.
+        *
+        * @var string
+        */
+       protected $flags = array();
+
+       /**
+        * Mixin flagged element.
+        *
+        * @param OoUiElement $element Element being mixed into
+        * @param OoUiTag $target Flaged tag
+        * @param array $config Configuration options
+        * @param string $config['flags'] Flags
+        */
+       public function __construct ( OoUiElement $element, OoUiTag $target, 
array $config ) {
+               // Parent constructor
+               parent::__construct( $element, $target, $config );
+
+               // Initialization]
+               $this->setFlags( $config['flags'] );
+       }
+
+       /**
+        * Check if a flag is set.
+        *
+        * @param string flag Name of flag
+        * @return boolean Has flag
+        */
+       public function hasFlag ( $flag ) {
+               return isset( $this->flags[$flag] );
+       }
+
+       /**
+        * Get the names of all flags set.
+        *
+        * @return array flags Flag names
+        */
+       public function getFlags () {
+               return array_keys( $this->flags );
+       }
+
+       /**
+        * Clear all flags.
+        *
+        * @chainable
+        */
+       public function clearFlags () {
+               $remove = [];
+               $classPrefix = 'oo-ui-flaggedElement-';
+
+               foreach ( $this->flags as $flag ) {
+                       $remove[] = $classPrefix . $flag;
+               }
+
+               $this->target->removeClasses( $remove );
+               $this->flags = array();
+
+               return $this;
+       }
+
+       /**
+        * Add one or more flags.
+        *
+        * @param string|array flags One or more flags to add, or an array 
keyed by flag name
+        *   containing boolean set/remove instructions.
+        * @chainable
+        */
+       public function setFlags ( $flags ) {
+               $add = array();
+               $remove = array();
+               $classPrefix = 'oo-ui-flaggedElement-';
+
+               if ( is_string( $flags ) ) {
+                       // Set
+                       if ( !$this->flags[$flags] ) {
+                               $this->flags[$flags] = true;
+                               $add[] = $classPrefix . $flags;
+                       }
+               } else if ( is_array( $flags ) ) {
+                       foreach ( $flags as $key => $value ) {
+                               if ( is_numeric( $key ) ) {
+                                       // Set
+                                       if ( !isset( $this->flags[$value] ) ) {
+                                               $this->flags[$value] = true;
+                                               $add[] = $classPrefix . $value;
+                                       }
+                               } else {
+                                       if ( $value ) {
+                                               // Set
+                                               if ( !isset( $this->flags[$key] 
) ) {
+                                                       $this->flags[$key] = 
true;
+                                                       $add[] = $classPrefix . 
$key;
+                                               }
+                                       } else {
+                                               // Remove
+                                               if ( isset( $this->flags[$key] 
) ) {
+                                                       unset( 
$this->flags[$key] );
+                                                       $remove[] = 
$classPrefix . $key;
+                                               }
+                                       }
+                               }
+                       }
+               }
+
+               $this->target
+                       ->addClasses( $add )
+                       ->removeClasses( $remove );
+
+               return $this;
+       }
+}
diff --git a/php/elements/OoUiIconElement.php b/php/elements/OoUiIconElement.php
new file mode 100644
index 0000000..699c246
--- /dev/null
+++ b/php/elements/OoUiIconElement.php
@@ -0,0 +1,49 @@
+<?php
+
+class OoUiIconElement extends OoUiElementMixin {
+       /**
+        * Icon value.
+        *
+        * @var string
+        */
+       protected $icon = null;
+
+       /**
+        * Mixin icon element.
+        *
+        * @param OoUiElement $element Element being mixed into
+        * @param OoUiTag $target Icon tag
+        * @param array $config Configuration options
+        * @param string $config['icon'] Icon value
+        */
+       public function __construct ( OoUiElement $element, OoUiTag $target, 
array $config ) {
+               // Parent constructor
+               parent::__construct( $element, $target, $config );
+
+               // Initialization
+               $this->target->addClasses( array( 'oo-ui-iconElement-icon' ) );
+               $this->setIcon( $config['icon'] );
+       }
+
+       /**
+        * Set icon value.
+        *
+        * @param string $icon Icon value
+        * @chainable
+        */
+       public function setIcon ( $icon = null ) {
+               $this->icon = is_string( $icon ) ? $icon : null;
+               $this->element->toggleClasses( array( 'oo-ui-iconElement' ), 
!!$this->icon );
+               $this->target->addClasses( array( 'oo-ui-icon-' . $this->icon ) 
);
+               return $this;
+       }
+
+       /**
+        * Get icon value.
+        *
+        * @return string Icon value
+        */
+       public function getIcon () {
+               return $this->icon;
+       }
+}
diff --git a/php/elements/OoUiIndicatorElement.php 
b/php/elements/OoUiIndicatorElement.php
new file mode 100644
index 0000000..186c123
--- /dev/null
+++ b/php/elements/OoUiIndicatorElement.php
@@ -0,0 +1,49 @@
+<?php
+
+class OoUiIndicatorElement extends OoUiElementMixin {
+       /**
+        * Indicator value.
+        *
+        * @var string
+        */
+       protected $indicator = null;
+
+       /**
+        * Mixin indicator element.
+        *
+        * @param OoUiElement $element Element being mixed into
+        * @param OoUiTag $target Indicator tag
+        * @param array $config Configuration options
+        * @param string $config['indicator'] Indicator value
+        */
+       public function __construct ( OoUiElement $element, OoUiTag $target, 
array $config ) {
+               // Parent constructor
+               parent::__construct( $element, $target, $config );
+
+               // Initialization
+               $this->target->addClasses( array( 
'oo-ui-indicatorElement-indicator' ) );
+               $this->setIndicator( $config['indicator'] );
+       }
+
+       /**
+        * Set indicator value.
+        *
+        * @param string $indicator Indicator value
+        * @chainable
+        */
+       public function setIndicator ( $indicator = null ) {
+               $this->indicator = is_string( $indicator ) ? $indicator : null;
+               $this->element->toggleClasses( array( 'oo-ui-indicatorElement' 
), !!$this->indicator );
+               $this->target->addClasses( array( 'oo-ui-indicator-' . 
$this->indicator ) );
+               return $this;
+       }
+
+       /**
+        * Get indicator value.
+        *
+        * @return string Indicator value
+        */
+       public function getIndicator () {
+               return $this->indicator;
+       }
+}
diff --git a/php/elements/OoUiLabelElement.php 
b/php/elements/OoUiLabelElement.php
new file mode 100644
index 0000000..5aec422
--- /dev/null
+++ b/php/elements/OoUiLabelElement.php
@@ -0,0 +1,52 @@
+<?php
+
+class OoUiLabelElement extends OoUiElementMixin {
+       /**
+        * Label value.
+        *
+        * @var string
+        */
+       protected $label;
+
+       /**
+        * Mixin label element.
+        *
+        * @param OoUiElement $element Element being mixed into
+        * @param OoUiTag $target Label tag
+        * @param array $config Configuration options
+        * @param string $config['label'] Label value
+        */
+       public function __construct ( OoUiElement $element, OoUiTag $target, 
array $config ) {
+               // Parent constructor
+               parent::__construct( $element, $target, $config );
+
+               // Initialization
+               $this->target->addClasses( array( 'oo-ui-labelElement-label' ) 
);
+               $this->setLabel( isset( $config['label'] ) ? $config['label'] : 
null );
+       }
+
+       /**
+        * Set label value.
+        *
+        * @param string $label Label value
+        * @chainable
+        */
+       public function setLabel ( $label ) {
+               $this->label = is_string( $label ) ? $label : null;
+               $this->element->toggleClasses( array( 'oo-ui-labelElement' ), 
!!$this->label );
+               $this->target->clearContent();
+               if ( $this->label ) {
+                       $this->target->appendContent( $label );
+               }
+               return $this;
+       }
+
+       /**
+        * Get label value.
+        *
+        * @return string Label value
+        */
+       public function getLabel () {
+               return $this->label;
+       }
+}
diff --git a/php/layouts/OoUiFieldLayout.php b/php/layouts/OoUiFieldLayout.php
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/php/layouts/OoUiFieldLayout.php
diff --git a/php/layouts/OoUiFieldsetLayout.php 
b/php/layouts/OoUiFieldsetLayout.php
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/php/layouts/OoUiFieldsetLayout.php
diff --git a/php/layouts/OoUiFormLayout.php b/php/layouts/OoUiFormLayout.php
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/php/layouts/OoUiFormLayout.php
diff --git a/php/widgets/OoUiButtonWidget.php b/php/widgets/OoUiButtonWidget.php
new file mode 100644
index 0000000..4144aa5
--- /dev/null
+++ b/php/widgets/OoUiButtonWidget.php
@@ -0,0 +1,35 @@
+<?php
+
+class OoUiButtonWidget extends OoUiWidget {
+       /**
+        * Create button widget.
+        *
+        * @param array $config Configuration options
+        * @param array $config['classes'] CSS class names to add
+        */
+       public function __construct ( array $config ) {
+               // Parent constructor
+               parent::__construct( $config );
+
+               // Properties
+               $this->button = new OoUiTag( 'a' );
+               $this->label = new OoUiTag( 'span' );
+               $this->icon = new OoUiTag( 'span' );
+               $this->indicator = new OoUiTag( 'span' );
+
+               // Mixins
+               $this->mixin( new OoUiButtonElement( $this, $this->button, 
$config ) );
+               $this->mixin( new OoUiLabelElement( $this, $this->label, 
$config ) );
+               $this->mixin( new OoUiIconElement( $this, $this->icon, $config 
) );
+               $this->mixin( new OoUiIndicatorElement( $this, 
$this->indicator, $config ) );
+               $this->mixin( new OoUiFlaggedElement( $this, $this, $config ) );
+
+               // Initialization
+               $this->addClasses( array( 'oo-ui-buttonWidget' ) );
+               $this->appendContent( $this->button );
+               $this->button
+                       ->appendContent( $this->icon )
+                       ->appendContent( $this->label )
+                       ->appendContent( $this->indicator );
+       }
+}
diff --git a/src/themes/apex/elements.less b/src/themes/apex/elements.less
index 4151669..f105903 100644
--- a/src/themes/apex/elements.less
+++ b/src/themes/apex/elements.less
@@ -10,7 +10,13 @@
 
                > .oo-ui-indicatorElement-indicator {
                        margin-right: -0.75em;
+                       margin-left: -0.75em;
                }
+       }
+
+       &.oo-ui-labelElement > .oo-ui-buttonElement-button > 
.oo-ui-indicatorElement-indicator,
+       &.oo-ui-iconElement > .oo-ui-buttonElement-button > 
.oo-ui-indicatorElement-indicator {
+               margin-left: 0;
        }
 
        &.oo-ui-indicatorElement > .oo-ui-buttonElement-button > 
.oo-ui-indicatorElement-indicator,
@@ -29,6 +35,8 @@
 
                        &:hover,
                        &:focus {
+                               outline: none;
+
                                > .oo-ui-iconElement-icon {
                                        opacity: 1;
                                }
@@ -80,6 +88,7 @@
                        &:hover,
                        &:focus {
                                border-color: #aaa;
+                               outline: none;
                        }
 
                        > .oo-ui-labelElement-label {
@@ -87,6 +96,7 @@
                        }
                }
 
+               &.oo-ui-widget-enabled > .oo-ui-buttonElement-button:active,
                &.oo-ui-buttonElement-active > .oo-ui-buttonElement-button,
                &.oo-ui-buttonElement-pressed > .oo-ui-buttonElement-button {
                        box-shadow: inset 0 1px 4px 0 rgba(0, 0, 0, 0.07);
@@ -119,6 +129,7 @@
                                        }
                                }
 
+                               &.oo-ui-widget-enabled > 
.oo-ui-buttonElement-button:active,
                                &.oo-ui-buttonElement-active > 
.oo-ui-buttonElement-button,
                                &.oo-ui-buttonElement-pressed > 
.oo-ui-buttonElement-button {
                                        border: solid 1px #a6cee1;
@@ -136,6 +147,8 @@
                                                border-color: #adcb89;
                                        }
                                }
+
+                               &.oo-ui-widget-enabled > 
.oo-ui-buttonElement-button:active,
                                &.oo-ui-buttonElement-active > 
.oo-ui-buttonElement-button,
                                &.oo-ui-buttonElement-pressed > 
.oo-ui-buttonElement-button {
                                        border: solid 1px #b8d892;

-- 
To view, visit https://gerrit.wikimedia.org/r/160996
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ifcc9b859c76e9c3f1d6ca2012a21d4198caa8240
Gerrit-PatchSet: 1
Gerrit-Project: oojs/ui
Gerrit-Branch: master
Gerrit-Owner: Trevor Parscal <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to