summaryrefslogtreecommitdiff
path: root/vendor/oojs/oojs-ui/php/mixins
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/oojs/oojs-ui/php/mixins')
-rw-r--r--vendor/oojs/oojs-ui/php/mixins/AccessKeyedElement.php76
-rw-r--r--vendor/oojs/oojs-ui/php/mixins/ButtonElement.php69
-rw-r--r--vendor/oojs/oojs-ui/php/mixins/FlaggedElement.php133
-rw-r--r--vendor/oojs/oojs-ui/php/mixins/GroupElement.php129
-rw-r--r--vendor/oojs/oojs-ui/php/mixins/IconElement.php76
-rw-r--r--vendor/oojs/oojs-ui/php/mixins/IndicatorElement.php78
-rw-r--r--vendor/oojs/oojs-ui/php/mixins/LabelElement.php77
-rw-r--r--vendor/oojs/oojs-ui/php/mixins/TabIndexedElement.php88
-rw-r--r--vendor/oojs/oojs-ui/php/mixins/TitledElement.php74
9 files changed, 800 insertions, 0 deletions
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/mixins/ButtonElement.php b/vendor/oojs/oojs-ui/php/mixins/ButtonElement.php
new file mode 100644
index 00000000..b09c7941
--- /dev/null
+++ b/vendor/oojs/oojs-ui/php/mixins/ButtonElement.php
@@ -0,0 +1,69 @@
+<?php
+
+namespace OOUI;
+
+/**
+ * Element with a button.
+ *
+ * Buttons are used for controls which can be clicked. They can be configured to use tab indexing
+ * and access keys for accessibility purposes.
+ *
+ * @abstract
+ */
+class ButtonElement extends ElementMixin {
+ /**
+ * Button is framed.
+ *
+ * @var boolean
+ */
+ protected $framed = false;
+
+ 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)
+ */
+ public function __construct( Element $element, array $config = array() ) {
+ // Parent constructor
+ $target = isset( $config['button'] ) ? $config['button'] : new Tag( 'a' );
+ 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',
+ ) );
+ }
+
+ /**
+ * 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 );
+ }
+
+ /**
+ * Check if button has a frame.
+ *
+ * @return boolean Button is framed
+ */
+ public function isFramed() {
+ return $this->framed;
+ }
+
+ public function getConfig( &$config ) {
+ if ( $this->framed !== true ) {
+ $config['framed'] = $this->framed;
+ }
+ return parent::getConfig( $config );
+ }
+}
diff --git a/vendor/oojs/oojs-ui/php/mixins/FlaggedElement.php b/vendor/oojs/oojs-ui/php/mixins/FlaggedElement.php
new file mode 100644
index 00000000..bd5dc80d
--- /dev/null
+++ b/vendor/oojs/oojs-ui/php/mixins/FlaggedElement.php
@@ -0,0 +1,133 @@
+<?php
+
+namespace OOUI;
+
+/**
+ * Element with named flags that can be added, removed, listed and checked.
+ *
+ * A flag, when set, adds a CSS class on the `$element` by combining `oo-ui-flaggedElement-` with
+ * the flag name. Flags are primarily useful for styling.
+ *
+ * @abstract
+ */
+class FlaggedElement extends ElementMixin {
+ /**
+ * Flags.
+ *
+ * @var string
+ */
+ protected $flags = array();
+
+ public static $targetPropertyName = 'flagged';
+
+ /**
+ * @param Element $element Element being mixed into
+ * @param array $config Configuration options
+ * @param string|string[] $config['flags'] Flags describing importance and functionality, e.g.
+ * 'primary', 'safe', 'progressive', 'destructive' or 'constructive'
+ */
+ public function __construct( Element $element, array $config = array() ) {
+ // Parent constructor
+ $target = isset( $config['flagged'] ) ? $config['flagged'] : $element;
+ parent::__construct( $element, $target, $config );
+
+ // Initialization
+ $this->setFlags( isset( $config['flags'] ) ? $config['flags'] : null );
+ }
+
+ /**
+ * 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 string[] Flag names
+ */
+ public function getFlags() {
+ return array_keys( $this->flags );
+ }
+
+ /**
+ * Clear all flags.
+ *
+ * @chainable
+ */
+ public function clearFlags() {
+ $remove = array();
+ $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 ( !isset( $this->flags[$flags] ) ) {
+ $this->flags[$flags] = true;
+ $add[] = $classPrefix . $flags;
+ }
+ } elseif ( 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;
+ }
+
+ public function getConfig( &$config ) {
+ if ( !empty( $this->flags ) ) {
+ $config['flags'] = $this->getFlags();
+ }
+ return parent::getConfig( $config );
+ }
+}
diff --git a/vendor/oojs/oojs-ui/php/mixins/GroupElement.php b/vendor/oojs/oojs-ui/php/mixins/GroupElement.php
new file mode 100644
index 00000000..93d3c7a1
--- /dev/null
+++ b/vendor/oojs/oojs-ui/php/mixins/GroupElement.php
@@ -0,0 +1,129 @@
+<?php
+
+namespace OOUI;
+
+/**
+ * Element containing a sequence of child elements.
+ *
+ * @abstract
+ */
+class GroupElement extends ElementMixin {
+ /**
+ * List of items in the group.
+ *
+ * @var Element[]
+ */
+ protected $items = array();
+
+ public static $targetPropertyName = 'group';
+
+ /**
+ * @param Element $element Element being mixed into
+ * @param array $config Configuration options
+ */
+ public function __construct( Element $element, array $config = array() ) {
+ // Parent constructor
+ $target = isset( $config['group'] ) ? $config['group'] : new Tag( 'div' );
+ parent::__construct( $element, $target, $config );
+ }
+
+ /**
+ * Check if there are no items.
+ *
+ * @return boolean Group is empty
+ */
+ public function isEmpty() {
+ return !count( $this->items );
+ }
+
+ /**
+ * Get items.
+ *
+ * @return Element[] Items
+ */
+ public function getItems() {
+ return $this->items;
+ }
+
+ /**
+ * Add items.
+ *
+ * Adding an existing item will move it.
+ *
+ * @param Element[] $items Items
+ * @param number $index Index to insert items at
+ * @chainable
+ */
+ public function addItems( array $items, $index = null ) {
+ foreach ( $items as $item ) {
+ // Check if item exists then remove it first, effectively "moving" it
+ $currentIndex = array_search( $item, $this->items );
+ if ( $currentIndex !== false ) {
+ $this->removeItems( array( $item ) );
+ // Adjust index to compensate for removal
+ if ( $currentIndex < $index ) {
+ $index--;
+ }
+ }
+ // Add the item
+ $item->setElementGroup( $this );
+ }
+
+ if ( $index === null || $index < 0 || $index >= count( $this->items ) ) {
+ $this->items = array_merge( $this->items, $items );
+ } else {
+ array_splice( $this->items, $index, 0, $items );
+ }
+
+ // Update actual target element contents to reflect our list
+ $this->target->clearContent();
+ call_user_func_array( array( $this->target, 'appendContent' ), $this->items );
+
+ return $this;
+ }
+
+ /**
+ * Remove items.
+ *
+ * @param Element[] $items Items to remove
+ * @chainable
+ */
+ public function removeItems( $items ) {
+ foreach ( $items as $item ) {
+ $index = array_search( $item, $this->items );
+ if ( $index !== false ) {
+ $item->setElementGroup( null );
+ array_splice( $this->items, $index, 1 );
+ }
+ }
+
+ // Update actual target element contents to reflect our list
+ $this->target->clearContent();
+ call_user_func_array( array( $this->target, 'appendContent' ), $this->items );
+
+ return $this;
+ }
+
+ /**
+ * Clear all items.
+ *
+ * Items will be detached, not removed, so they can be used later.
+ *
+ * @chainable
+ */
+ public function clearItems() {
+ foreach ( $this->items as $item ) {
+ $item->setElementGroup( null );
+ }
+
+ $this->items = array();
+ $this->target->clearContent();
+
+ return $this;
+ }
+
+ public function getConfig( &$config ) {
+ $config['items'] = $this->items;
+ return parent::getConfig( $config );
+ }
+}
diff --git a/vendor/oojs/oojs-ui/php/mixins/IconElement.php b/vendor/oojs/oojs-ui/php/mixins/IconElement.php
new file mode 100644
index 00000000..b6d27376
--- /dev/null
+++ b/vendor/oojs/oojs-ui/php/mixins/IconElement.php
@@ -0,0 +1,76 @@
+<?php
+
+namespace OOUI;
+
+/**
+ * Element containing an icon.
+ *
+ * Icons are graphics, about the size of normal text. They can be used to aid the user in locating
+ * a control or convey information in a more space efficient way. Icons should rarely be used
+ * without labels; such as in a toolbar where space is at a premium or within a context where the
+ * meaning is very clear to the user.
+ *
+ * @abstract
+ */
+class IconElement extends ElementMixin {
+ /**
+ * Symbolic icon name.
+ *
+ * @var string
+ */
+ protected $icon = null;
+
+ public static $targetPropertyName = 'icon';
+
+ /**
+ * @param Element $element Element being mixed into
+ * @param array $config Configuration options
+ * @param string $config['icon'] Symbolic icon name
+ */
+ public function __construct( Element $element, array $config = array() ) {
+ // Parent constructor
+ // FIXME 'iconElement' is a very stupid way to call '$icon'
+ $target = isset( $config['iconElement'] ) ? $config['iconElement'] : new Tag( 'span' );
+ parent::__construct( $element, $target, $config );
+
+ // Initialization
+ $this->target->addClasses( array( 'oo-ui-iconElement-icon' ) );
+ $this->setIcon( isset( $config['icon'] ) ? $config['icon'] : null );
+ }
+
+ /**
+ * Set icon name.
+ *
+ * @param string|null $icon Symbolic icon name
+ * @chainable
+ */
+ public function setIcon( $icon = null ) {
+ if ( $this->icon !== null ) {
+ $this->target->removeClasses( array( 'oo-ui-icon-' . $this->icon ) );
+ }
+ if ( $icon !== null ) {
+ $this->target->addClasses( array( 'oo-ui-icon-' . $icon ) );
+ }
+
+ $this->icon = $icon;
+ $this->element->toggleClasses( array( 'oo-ui-iconElement' ), (bool)$this->icon );
+
+ return $this;
+ }
+
+ /**
+ * Get icon name.
+ *
+ * @return string Icon name
+ */
+ public function getIcon() {
+ return $this->icon;
+ }
+
+ public function getConfig( &$config ) {
+ if ( $this->icon !== null ) {
+ $config['icon'] = $this->icon;
+ }
+ return parent::getConfig( $config );
+ }
+}
diff --git a/vendor/oojs/oojs-ui/php/mixins/IndicatorElement.php b/vendor/oojs/oojs-ui/php/mixins/IndicatorElement.php
new file mode 100644
index 00000000..56238b6c
--- /dev/null
+++ b/vendor/oojs/oojs-ui/php/mixins/IndicatorElement.php
@@ -0,0 +1,78 @@
+<?php
+
+namespace OOUI;
+
+/**
+ * Element containing an indicator.
+ *
+ * Indicators are graphics, smaller than normal text. They can be used to describe unique status or
+ * behavior. Indicators should only be used in exceptional cases; such as a button that opens a menu
+ * instead of performing an action directly, or an item in a list which has errors that need to be
+ * resolved.
+ *
+ * @abstract
+ */
+class IndicatorElement extends ElementMixin {
+ /**
+ * Symbolic indicator name
+ *
+ * @var string|null
+ */
+ protected $indicator = null;
+
+ public static $targetPropertyName = 'indicator';
+
+ /**
+ * @param Element $element Element being mixed into
+ * @param array $config Configuration options
+ * @param string $config['indicator'] Symbolic indicator name
+ */
+ public function __construct( Element $element, array $config = array() ) {
+ // Parent constructor
+ // FIXME 'indicatorElement' is a very stupid way to call '$indicator'
+ $target = isset( $config['indicatorElement'] )
+ ? $config['indicatorElement']
+ : new Tag( 'span' );
+ parent::__construct( $element, $target, $config );
+
+ // Initialization
+ $this->target->addClasses( array( 'oo-ui-indicatorElement-indicator' ) );
+ $this->setIndicator( isset( $config['indicator'] ) ? $config['indicator'] : null );
+ }
+
+ /**
+ * Set indicator name.
+ *
+ * @param string|null $indicator Symbolic name of indicator to use or null for no indicator
+ * @chainable
+ */
+ public function setIndicator( $indicator = null ) {
+ if ( $this->indicator !== null ) {
+ $this->target->removeClasses( array( 'oo-ui-indicator-' . $this->indicator ) );
+ }
+ if ( $indicator !== null ) {
+ $this->target->addClasses( array( 'oo-ui-indicator-' . $indicator ) );
+ }
+
+ $this->indicator = $indicator;
+ $this->element->toggleClasses( array( 'oo-ui-indicatorElement' ), (bool)$this->indicator );
+
+ return $this;
+ }
+
+ /**
+ * Get indicator name.
+ *
+ * @return string Symbolic name of indicator
+ */
+ public function getIndicator() {
+ return $this->indicator;
+ }
+
+ public function getConfig( &$config ) {
+ if ( $this->indicator !== null ) {
+ $config['indicator'] = $this->indicator;
+ }
+ return parent::getConfig( $config );
+ }
+}
diff --git a/vendor/oojs/oojs-ui/php/mixins/LabelElement.php b/vendor/oojs/oojs-ui/php/mixins/LabelElement.php
new file mode 100644
index 00000000..d5cf7bee
--- /dev/null
+++ b/vendor/oojs/oojs-ui/php/mixins/LabelElement.php
@@ -0,0 +1,77 @@
+<?php
+
+namespace OOUI;
+
+/**
+ * Element containing a label.
+ *
+ * @abstract
+ */
+class LabelElement extends ElementMixin {
+ /**
+ * Label value.
+ *
+ * @var string|HtmlSnippet|null
+ */
+ protected $label = null;
+
+ public static $targetPropertyName = 'label';
+
+ /**
+ * @param Element $element Element being mixed into
+ * @param array $config Configuration options
+ * @param string|HtmlSnippet $config['label'] Label text
+ */
+ public function __construct( Element $element, array $config = array() ) {
+ // Parent constructor
+ // FIXME 'labelElement' is a very stupid way to call '$label'
+ $target = isset( $config['labelElement'] ) ? $config['labelElement'] : new Tag( 'span' );
+ parent::__construct( $element, $target, $config );
+
+ // Initialization
+ $this->target->addClasses( array( 'oo-ui-labelElement-label' ) );
+ $this->setLabel( isset( $config['label'] ) ? $config['label'] : null );
+ }
+
+ /**
+ * Set the label.
+ *
+ * An empty string will result in the label being hidden. A string containing only whitespace will
+ * be converted to a single `&nbsp;`.
+ *
+ * @param string|HtmlSnippet|null $label Label text
+ * @chainable
+ */
+ public function setLabel( $label ) {
+ $this->label = $label;
+
+ $this->target->clearContent();
+ if ( $this->label !== null ) {
+ if ( is_string( $this->label ) && $this->label !== '' && trim( $this->label ) === '' ) {
+ $this->target->appendContent( new HtmlSnippet( '&nbsp;' ) );
+ } else {
+ $this->target->appendContent( $label );
+ }
+ }
+
+ $this->element->toggleClasses( array( 'oo-ui-labelElement' ), !!$this->label );
+
+ return $this;
+ }
+
+ /**
+ * Get the label.
+ *
+ * @return string|HtmlSnippet|null Label text
+ */
+ public function getLabel() {
+ return $this->label;
+ }
+
+ public function getConfig( &$config ) {
+ if ( $this->label !== null ) {
+ $config['label'] = $this->label;
+ }
+ return parent::getConfig( $config );
+ }
+}
diff --git a/vendor/oojs/oojs-ui/php/mixins/TabIndexedElement.php b/vendor/oojs/oojs-ui/php/mixins/TabIndexedElement.php
new file mode 100644
index 00000000..223b5371
--- /dev/null
+++ b/vendor/oojs/oojs-ui/php/mixins/TabIndexedElement.php
@@ -0,0 +1,88 @@
+<?php
+
+namespace OOUI;
+
+/**
+ * Element supporting "sequential focus navigation" using the 'tabindex' attribute.
+ *
+ * @abstract
+ */
+class TabIndexedElement extends ElementMixin {
+ /**
+ * Tab index value.
+ *
+ * @var number|null
+ */
+ protected $tabIndex = null;
+
+ public static $targetPropertyName = 'tabIndexed';
+
+ /**
+ * @param Element $element Element being mixed into
+ * @param array $config Configuration options
+ * @param number|null $config['tabIndex'] Tab index value. Use 0 to use default ordering, use -1 to
+ * prevent tab focusing, use null to suppress the `tabindex` attribute. (default: 0)
+ */
+ public function __construct( Element $element, array $config = array() ) {
+ // Parent constructor
+ $target = isset( $config['tabIndexed'] ) ? $config['tabIndexed'] : $element;
+ parent::__construct( $element, $target, $config );
+
+ // Initialization
+ $this->setTabIndex( isset( $config['tabIndex'] ) ? $config['tabIndex'] : 0 );
+ }
+
+ /**
+ * Set tab index value.
+ *
+ * @param number|null $tabIndex Tab index value or null for no tab index
+ * @chainable
+ */
+ public function setTabIndex( $tabIndex ) {
+ $tabIndex = is_numeric( $tabIndex ) ? $tabIndex : null;
+
+ if ( $this->tabIndex !== $tabIndex ) {
+ $this->tabIndex = $tabIndex;
+ $this->updateTabIndex();
+ }
+
+ return $this;
+ }
+
+ /**
+ * Update the tabIndex attribute, in case of changes to tabIndex or disabled
+ * state.
+ *
+ * @chainable
+ */
+ public function updateTabIndex() {
+ $disabled = $this->element->isDisabled();
+ if ( $this->tabIndex !== null ) {
+ $this->target->setAttributes( array(
+ // Do not index over disabled elements
+ 'tabindex' => $disabled ? -1 : $this->tabIndex,
+ // ChromeVox and NVDA do not seem to inherit this from parent elements
+ 'aria-disabled' => ( $disabled ? 'true' : 'false' )
+ ) );
+ } else {
+ $this->target->removeAttributes( array( 'tabindex', 'aria-disabled' ) );
+ }
+ return $this;
+ }
+
+ /**
+ * Get tab index value.
+ *
+ * @return number|null Tab index value
+ */
+ public function getTabIndex() {
+ return $this->tabIndex;
+ }
+
+ public function getConfig( &$config ) {
+ if ( $this->tabIndex !== 0 ) {
+ $config['tabIndex'] = $this->tabIndex;
+ }
+ return parent::getConfig( $config );
+ }
+}
diff --git a/vendor/oojs/oojs-ui/php/mixins/TitledElement.php b/vendor/oojs/oojs-ui/php/mixins/TitledElement.php
new file mode 100644
index 00000000..5f1317c4
--- /dev/null
+++ b/vendor/oojs/oojs-ui/php/mixins/TitledElement.php
@@ -0,0 +1,74 @@
+<?php
+
+namespace OOUI;
+
+/**
+ * Element with a title.
+ *
+ * Titles are rendered by the browser and are made visible when hovering the element. Titles are
+ * not visible on touch devices.
+ *
+ * @abstract
+ */
+class TitledElement extends ElementMixin {
+ /**
+ * Title text.
+ *
+ * @var string
+ */
+ protected $title = null;
+
+ public static $targetPropertyName = 'titled';
+
+ /**
+ * @param Element $element Element being mixed into
+ * @param array $config Configuration options
+ * @param string $config['title'] Title. If not provided, the static property 'title' is used.
+ */
+ public function __construct( Element $element, array $config = array() ) {
+ // Parent constructor
+ $target = isset( $config['titled'] ) ? $config['titled'] : $element;
+ parent::__construct( $element, $target, $config );
+
+ // Initialization
+ $this->setTitle(
+ isset( $config['title'] ) ? $config['title'] :
+ ( isset( $element::$title ) ? $element::$title : null )
+ );
+ }
+
+ /**
+ * Set title.
+ *
+ * @param string|null $title Title text or null for no title
+ * @chainable
+ */
+ public function setTitle( $title ) {
+ if ( $this->title !== $title ) {
+ $this->title = $title;
+ if ( $title !== null ) {
+ $this->target->setAttributes( array( 'title' => $title ) );
+ } else {
+ $this->target->removeAttributes( array( 'title' ) );
+ }
+ }
+
+ return $this;
+ }
+
+ /**
+ * Get title.
+ *
+ * @return string Title string
+ */
+ public function getTitle() {
+ return $this->title;
+ }
+
+ public function getConfig( &$config ) {
+ if ( $this->title !== null ) {
+ $config['title'] = $this->title;
+ }
+ return parent::getConfig( $config );
+ }
+}