includes/base_controls/QHtmlAttributeManagerBase.class.php
<?php
/**
* QHtmlAttributeManager class
*
* This class is designed to be used as a base class for controls and other classes that need to manage HTML attributes.
*
* @package Controls
*/
/**
* A base class for objects that manage html attributes. Uses array functions and defines a couple of arrays to manage
* the attributes. Values will be html escaped when printed.
*
* Includes:
* - helper functions to manage the class, style, and data-* attributes specially.
* - helper functions to manage 'name-*' classes that are found in css frameworks like
* Bootstrap and Foundation.
* - helpers for __get and __set functions, partially for backwards compatibility and also to make the setting
* of some attributes and styles easier (so you don't have to remember how to set them).
*
* Usage: Use the helper functions to setup your styles, classes, data-* and other attributes, then call
* renderHtmlAttributes() to render the attributes to insert them into a tag.
*
*
* @property string $AccessKey allows you to specify what Alt-Letter combination will automatically focus that control on the form
* @property string $BackColor sets the CSS background-color of the control
* @property string $BorderColor sets the CSS border-color of the control
* @property string $BorderWidth sets the CSS border-width of the control
* @property string $BorderStyle is used to set CSS border-style by {@link QBorderStyle}
* @property string $BorderCollapse defines the BorderCollapse css style for a table
* @property string $CssClass sets or returns the CSS class for this control. When setting, if you precede the class name
* with a plus sign (+), it will add the class(es) to the currently existing classes, rather than replace them. Can add or
* set more than one class at once by separating names with a space.
* @property string $Cursor is used to set CSS cursor property by {@link QCursor}
* @property boolean $Display shows or hides the control using the CSS display property. In either case, the control is
* still rendered on the page. See the Visible property if you wish to not render a control.
* @property string $DisplayStyle is used to set CSS display property by {@link QDisplayStyle}
* @property boolean $Enabled specifies whether or not this is enabled (it will grey out the control and make it
* inoperable if set to true)
* @property boolean $FontBold sets the font bold or normal
* @property boolean $FontItalic sets the Font italic or normal
* @property string $FontNames sets the name of used fonts
* @property boolean $FontOverline
* @property string $FontSize sets the font-size of the control
* @property boolean $FontStrikeout
* @property boolean $FontUnderline sets the font underlined
* @property string $ForeColor sets the CSS color property, which controls text color
* @property string $Height
* @property string $Left CSS left property
* @property integer $Opacity sets the opacity of the control (0-100)
* @property string $Overflow is used to set CSS overflow property by {@link QOverflow}
* @property string $Position is used to set CSS position property by {@link QPosition}
* @property integer $TabIndex specifies the index/tab order on a form
* @property string $ToolTip specifies the text to be displayed when the mouse is hovering over the control
* @property string $Top
* @property string $Width
* @property string $HorizontalAlign sets the CSS text-align property
* @property string $VerticalAlign sets the CSS vertical-align property
* @property-write mixed $Padding sets the CSS padding property. Will accepts a string, which is passed verbatim, or
* an array, either numerically indexed, in which case it is in top, right, bottom, left order, or keyed with the
* names 'top', 'right', 'bottom', 'left'.
* @property-write mixed $Margin sets the CSS margin property. Will accepts a string, which is passed verbatim, or
* an array, either numerically indexed, in which case it is in top, right, bottom, left order, or keyed with the
* names 'top', 'right', 'bottom', 'left'
* @property-write array $Data a key/value array of data-* items to set. Keys can be in camelCase notation, in which case they will be
* converted to dashed notation. Use GetDataAttribute() to retrieve the value of a data attribute.
* @property boolean $NoWrap sets the CSS white-space property to nowrap
* @property boolean $ReadOnly is the "readonly" html attribute (making a textbox "ReadOnly" is similar to setting the textbox to Enabled
* Readonly textboxes are selectedable, and their values get posted. Disabled textboxes are not selectable and values do not post.
* @property string $AltText text used for 'alt' attribute in images
* @property string $OrderedListType type for ordered lists. Expects a QOrderedListType.
* @property string $UnorderedListStyle style for unordered lists. Expects a QUnorderedListType.
*/
class QHtmlAttributeManagerBase extends QBaseClass {
/** @var array attributes stored in PHP native format so they can be retrieved. Escaping happens when they are drawn. */
protected $attributes = array();
protected $styles = array();
/**
* Sets the given html attribute to the given value.
* @param $strName
* @param $strValue
* @return boolean true if the attribute changed value
*/
public function SetHtmlAttribute ($strName, $strValue) {
if (!is_null($strValue)) {
if (!isset($this->attributes[$strName]) || $this->attributes[$strName] !== $strValue) {
// only make a change if it has actually changed value.
$this->attributes[$strName] = $strValue;
$this->MarkAsModified();
return true;
}
} else {
if (isset($this->attributes[$strName])) {
unset($this->attributes[$strName]);
$this->MarkAsModified();
return true;
}
}
return false;
}
/**
* Removes the given html attribute.
*
* @param $strName
*/
public function RemoveHtmlAttribute ($strName) {
$this->SetHtmlAttribute($strName, null);
}
/**
* Gets the Html Attribute, or return null if it does not exist.
*
* @param $strName
* @return null
*/
public function GetHtmlAttribute ($strName) {
if (isset ($this->attributes[$strName])) {
return $this->attributes[$strName];
}
else {
return null;
}
}
/**
* Returns an attribute array, with styles rendered.
* @param array|null $attributeOverrides
* @param array|null $styleOverrides
* @param array|null $selection an array of titles of attributes that you want the result to be limited to
* @return array
*/
public function GetHtmlAttributes($attributeOverrides = null, $styleOverrides = null, $selection = null) {
$attributes = $this->attributes;
if ($attributeOverrides) {
$attributes = array_merge ($attributes, $attributeOverrides);
}
$strStyles = $this->RenderCssStyles($styleOverrides);
if ($strStyles) {
$attributes['style'] = $strStyles;
}
if ($selection) {
$attributes = array_intersect_key($attributes, array_fill_keys($selection, 1));
}
return $attributes;
}
/**
* Returns true if the given attribute is set.
*
* @param string $strName
* @return bool
*/
public function HasHtmlAttribute ($strName) {
return (isset($this->attributes[$strName]));
}
/**
* Sets the given value as an html "data-*" attribute. The named value will be retrievable in jQuery by using
* '.data("$strName");'
*
* Note: Data name cases are handled specially in jQuery. Names are supposed to only be lower case. jQuery
* converts dashed notation to camelCase.
*
* For example, if your html looks like this:
*
* <div id='test1' data-test-case="my test"></div>
*
* You would get that value in jQuery by doing:
*
* $j('#test1').data('testCase');
*
* Conversion to special html data-* name formatting is handled here automatically. So if you SetDataAttribute('testCase') here,
* you can get it using .data('testCase') in jQuery
*
* @param $strName
* @param $strValue
*/
public function SetDataAttribute ($strName, $strValue) {
$strName = 'data-' . JavaScriptHelper::dataNameFromCamelCase($strName);
$this->SetHtmlAttribute($strName, $strValue);
}
/**
* Gets the data-* attribute value that was set previously in PHP.
*
* Does NOT call into javascript to return a value that was set on the browser side. You need to use another
* mechanism to retrieve that.
*
* @param $strName
* @return null
*/
public function GetDataAttribute ($strName) {
$strName = 'data-' . JavaScriptHelper::dataNameFromCamelCase($strName);
return $this->GetHtmlAttribute($strName);
}
/**
* Removes the given data attribute.
* @param $strName
*/
public function RemoveDataAttribute ($strName) {
$strName = 'data-' . JavaScriptHelper::dataNameFromCamelCase($strName);
$this->RemoveHtmlAttribute($strName);
}
/**
* Sets the Css named value to the given property.
*
* If blnIsLength is true, we assume the value is a unit length specifier, and so send it to the QHtml helper
* function, which has the ability to perform arithmetic operations on the old value.
*
* Will set the value of the parent classes blnModified value if something changes.
*
* @param string $strName
* @param string $strValue
* @param bool $blnIsLength true if this is a unit specifier e.g. 2px
* @return bool true if the style was actually changed (vs. it was already set that way)
*/
public function SetCssStyle ($strName, $strValue, $blnIsLength = false) {
$ret = false;
if (!is_null($strValue)) {
if ($blnIsLength) {
if (isset($this->styles[$strName])) {
$oldValue = $this->styles[$strName];
} else {
$oldValue = '';
}
if (QHtml::SetLength ($oldValue, $strValue)) {
$ret = true;
$this->MarkAsModified();
$this->styles[$strName] = $oldValue; // oldValue was updated
}
}
elseif (!isset($this->styles[$strName]) || $this->styles[$strName] !== $strValue) {
$this->styles[$strName] = $strValue;
$this->MarkAsModified();
$ret = true;
}
} else {
if (isset($this->styles[$strName])) {
unset($this->styles[$strName]);
$this->MarkAsModified();
$ret = true;
}
}
return $ret;
}
/**
* Removes the given CSS style property.
* @param $strName
* @return bool true if the style was removed, false if it wasn't there to begin with
*/
public function RemoveCssStyle ($strName) {
return $this->SetCssStyle ($strName, null);
}
/**
* Return true if the CSS style has been set.
* @param $strName
* @return bool
*/
public function HasCssStyle ($strName) {
return isset($this->styles[$strName]);
}
/**
* Retrieves the given CSS style property value.
* @param $strName
* @return string|null
*/
public function GetCssStyle ($strName) {
if (isset ($this->styles[$strName])) {
return $this->styles[$strName];
}
else {
return null;
}
}
/**
* Sets a box style, like margin or padding. Can accept:
* - string, which will pass the string verbatim to the shortcut prefix (e.g. margin: 0px 1px)
* - array, which can accept two styles:
* - [top, right, bottom, left], or
* - ['top'=>top, 'bottom'=>bottom, etc.]
*
* When passing an array, missing items or null items will be ignored. Also, you can use arithmetic operations
* to change the current value (provided you set a previous value).
*
* For example:
* $obj->setCssBoxStyle ('padding', ['right'=>3]);
* $obj->setCssBoxStyle ('padding', ['right'=>'*4']);
* Will set the padding-right to 12.
*
* @param string $strPrefix
* @param string|array $mixValue
*/
public function SetCssBoxValue($strPrefix, $mixValue) {
if (is_string($mixValue)) {
// shortcut
$this->SetCssStyle($strPrefix, $mixValue);
} elseif (is_array($mixValue)) {
if (array_key_exists(0, $mixValue)) {
// top right bottom left, numerically indexed
if (isset($mixValue[0])) $this->SetCssStyle($strPrefix. '-top', $mixValue[0], true);
if (isset($mixValue[1])) $this->SetCssStyle($strPrefix. '-right', $mixValue[1], true);
if (isset($mixValue[2])) $this->SetCssStyle($strPrefix. '-bottom', $mixValue[2], true);
if (isset($mixValue[3])) $this->SetCssStyle($strPrefix. '-left', $mixValue[3], true);
} else {
// assume key/value
if (isset($mixValue['top'])) $this->SetCssStyle($strPrefix. '-top', $mixValue['top'], true);
if (isset($mixValue['right'])) $this->SetCssStyle($strPrefix. '-right', $mixValue['right'], true);
if (isset($mixValue['bottom'])) $this->SetCssStyle($strPrefix. '-bottom', $mixValue['bottom'], true);
if (isset($mixValue['left'])) $this->SetCssStyle($strPrefix. '-left', $mixValue['left'], true);
}
}
}
/**
* Sets the CSS class to the given value(s). Multiple class names can be separated with a space. If you
* preceed the class names with a plus(+) they will be added to the current class. If a minus (-) they
* will be removed.
*
* @param $strNewClass
*/
public function SetCssClass($strNewClass) {
assert ('$strNewClass[0] != "+" || $strNewClass[1] == " "'); // If a plus sign, be sure to follow with a space. For consistency.
if (substr($strNewClass, 0, 2) == '+ ') {
$ret = $this->AddCssClass(substr($strNewClass, 2));
}
elseif (substr($strNewClass, 0, 2) == '- ') {
$ret = $this->RemoveCssClass(substr($strNewClass, 2));
}
else {
$ret = $this->SetHtmlAttribute('class', $strNewClass);
}
return $ret;
}
/**
* Adds a css class name to the 'class' property. Prevents duplication.
* @param string $strNewClass
* @return bool true if the class was not already attached.
*/
public function AddCssClass($strNewClass) {
$ret = false;
if (!$strNewClass) return false;
$strClasses = $this->GetHtmlAttribute('class');
if (is_null($strClasses)) {
$strClasses= '';
}
if (QHtml::AddClass($strClasses, $strNewClass)) {
$this->SetHtmlAttribute('class', $strClasses);
$ret = true;
}
return $ret;
}
/**
* This will remove a css class name from the 'class' property (if it exists).
* @param string $strCssClass
*/
public function RemoveCssClass($strCssClass) {
if (!$strCssClass) return;
$strClasses = $this->GetHtmlAttribute('class');
if ($strClasses && QHtml::RemoveClass($strClasses, $strCssClass)) {
$this->SetHtmlAttribute('class', $strClasses);
}
}
/**
* Many CSS frameworks use families of classes, which are built up from a base family name. For example,
* Bootstrap uses 'col-lg-6' to represent a column that is 6 units wide on large screens and Foundation
* uses 'large-6' to do the same thing. This utility removes classes that start with a particular prefix
* to remove whatever sizing class was specified.
*
* @param string $strPrefix
*/
public function RemoveCssClassesByPrefix($strPrefix) {
if (!$strPrefix) return;
$strClasses = $this->GetHtmlAttribute('class');
if ($strClasses && QHtml::RemoveClassesByPrefix($strClasses, $strPrefix)) {
$this->SetHtmlAttribute('class', $strClasses);
}
}
/**
* Return true if the given class is in the attribute list.
*
* @param $strClass
* @return bool
*/
public function HasCssClass($strClass) {
if (!isset($this->attributes['class'])) return false;
$strClasses = explode (' ', $this->attributes['class']);
return (in_array($strClass, $strClasses));
}
/**
* Permanently overrides the current styles with a new set of attributes and styles.
*
* @param QHtmlAttributeManager $objNewStyles
*/
protected function Override(QHtmlAttributeManager $objNewStyles) {
$this->attributes = array_merge($this->attributes, $objNewStyles->attributes);
$this->styles = array_merge($this->styles, $objNewStyles->styles);
}
/**
* Mark the parent class as modified. The host class must implement this if this functionality is desired.
*/
public function MarkAsModified() {}
/**
* Returns the html for the attributes. Allows the given arrays to override the attributes and styles before
* rendering.
* @param null|string $attributeOverrides
* @param null|string $styleOverrides
* @return string
*/
public function RenderHtmlAttributes($attributeOverrides = null, $styleOverrides = null) {
return QHtml::RenderHtmlAttributes($this->GetHtmlAttributes($attributeOverrides, $styleOverrides));
}
/**
* Returns the styles rendered as a css style string.
* @param null|string $styleOverrides
* @return string
*/
public function RenderCssStyles($styleOverrides = null) {
$styles = $this->styles;
if ($styleOverrides) {
$styles = array_merge($styles, $styleOverrides);
}
return QHtml::RenderStyles($styles);
}
/**
* Helper function to render the current attributes and styles in a tag. Overrides will be merged in with
* current values before creating the output, but they will not affect the current values.
*
* @param $strTag
* @param null|array $attributeOverrides key/value pairs of values for attribute overrides
* @param null|array $styleOverrides key/value pairs of values for style overrides
* @param null|string $strInnerHtml inner html to render. Will NOT be escaped.
* @param bool $blnIsVoidElement true if it should not have innerHtml or a closing tag.
* @return string HTML out. Attributes will be escaped as needed, but innerHtml will be raw, so be careful.
*/
protected function RenderTag($strTag, $attributeOverrides = null, $styleOverrides = null, $strInnerHtml = null, $blnIsVoidElement = false, $blnNoSpace = false) {
$strAttributes = $this->RenderHtmlAttributes($attributeOverrides, $styleOverrides);
return QHtml::RenderTag($strTag, $strAttributes, $strInnerHtml, $blnIsVoidElement, $blnNoSpace);
}
/**
* PHP magic method.
*
* The attributes include general attributes that span across most kinds of QControls. Attributes that are specific
* to a particular kind of tag might appear just in that control's definition.
*
* @param string $strName
* @return mixed
* @throws Exception|QCallerException
*/
public function __get($strName) {
switch ($strName) {
// Styles
case "BackColor": return $this->GetCssStyle('background-color');
case "BorderColor": return $this->GetCssStyle('border-color');
case "BorderStyle": return $this->GetCssStyle('border-style');
case "BorderWidth": return $this->GetCssStyle('border-width');
case "BorderCollapse": return $this->GetCssStyle('border-collapse');
case "Display": return !($this->GetCssStyle('display') === QDisplayStyle::None);
case "DisplayStyle": return $this->GetCssStyle('display');
case "FontBold": return $this->GetCssStyle('font-weight') == 'bold';
case "FontItalic": return $this->GetCssStyle('font-style') == 'italic';
case "FontNames": return $this->GetCssStyle('font-family');
case "FontOverline": return $this->GetCssStyle('text-decoration') == 'overline';
case "FontStrikeout": return $this->GetCssStyle('text-decoration') == 'line-through';
case "FontUnderline": return $this->GetCssStyle('text-decoration') == 'underline';
case "FontSize": return $this->GetCssStyle('font-size');
case "ForeColor": return $this->GetCssStyle('color');
case "Opacity": return $this->GetCssStyle('opacity');
case "Cursor": return $this->GetCssStyle('cursor');
case "Height": return $this->GetCssStyle('height');
case "Width": return $this->GetCssStyle('width');
case "Overflow": return $this->GetCssStyle('overflow');
case "Position": return $this->GetCssStyle('position');
case "Top": return $this->GetCssStyle('top');
case "Left": return $this->GetCssStyle('left');
case "HorizontalAlign": return $this->GetCssStyle('text-align');
case "VerticalAlign": return $this->GetCssStyle('vertical-align');
case "Wrap": throw new Exception ("Wrap is deprecated. Use NoWrap instead");
case "NoWrap": return $this->GetCssStyle('white-space') == 'nowrap';
case "UnorderedListStyle": return $this->GetCssStyle('list-style-type');
// Attributes
case "CssClass": return $this->GetHtmlAttribute('class');
case "AccessKey": return $this->GetHtmlAttribute('accesskey');
case "Enabled": return $this->GetHtmlAttribute('disabled') === null;
case "TabIndex": return $this->GetHtmlAttribute('tabindex');
case "ToolTip": return $this->GetHtmlAttribute('title');
case "ReadOnly": return $this->HasHtmlAttribute('readonly');
case "AltText": return $this->HasHtmlAttribute('alt');
case "OrderedListType": return $this->GetHtmlAttribute('type');
default:
try {
return parent::__get($strName);
} catch (QCallerException $objExc) {
$objExc->IncrementOffset();
throw $objExc;
}
}
}
/**
* PHP magic method
*
* @param string $strName
* @param string $mixValue
*
* @return mixed
* @throws Exception|QCallerException|QInvalidCastException
*/
public function __set($strName, $mixValue) {
switch ($strName) {
// Styles
case "BackColor":
try {
$this->SetCssStyle('background-color', QType::Cast($mixValue, QType::String));
break;
} catch (QInvalidCastException $objExc) {
$objExc->IncrementOffset();
throw $objExc;
}
case "BorderColor":
try {
$this->SetCssStyle('border-color', QType::Cast($mixValue, QType::String));
break;
} catch (QInvalidCastException $objExc) {
$objExc->IncrementOffset();
throw $objExc;
}
case "BorderStyle":
try {
$this->SetCssStyle('border-style', QType::Cast($mixValue, QType::String));
break;
} catch (QInvalidCastException $objExc) {
$objExc->IncrementOffset();
throw $objExc;
}
case "BorderWidth":
try {
$this->SetCssStyle('border-width', QType::Cast($mixValue, QType::String), true);
if (!$this->HasCssStyle ('border-style')) {
$this->SetCssStyle('border-style', 'solid');
}
break;
} catch (QInvalidCastException $objExc) {
$objExc->IncrementOffset();
throw $objExc;
}
case "BorderCollapse":
try {
$this->SetCssStyle('border-collapse', QType::Cast($mixValue, QType::String));
break;
} catch (QInvalidCastException $objExc) {
$objExc->IncrementOffset();
throw $objExc;
}
case "Display": // QControl changes the meaning of this to a boolean
case "DisplayStyle":
if (is_bool($mixValue)) {
if ($mixValue) {
$this->RemoveCssStyle('display'); // do the default
}
else {
$this->SetCssStyle('display', QDisplayStyle::None);
}
} else {
try {
$this->SetCssStyle('display', QType::Cast($mixValue, QType::String));
break;
} catch (QInvalidCastException $objExc) {
$objExc->IncrementOffset();
throw $objExc;
}
}
case "FontBold":
try {
$this->SetCssStyle('font-weight', QType::Cast($mixValue, QType::Boolean) ? 'bold' : null);
break;
} catch (QInvalidCastException $objExc) {
$objExc->IncrementOffset();
throw $objExc;
}
case "FontItalic":
try {
$this->SetCssStyle('font-style', QType::Cast($mixValue, QType::Boolean) ? 'italic' : null);
break;
} catch (QInvalidCastException $objExc) {
$objExc->IncrementOffset();
throw $objExc;
}
case "FontNames":
try {
$this->SetCssStyle('font-family', QType::Cast($mixValue, QType::String));
break;
} catch (QInvalidCastException $objExc) {
$objExc->IncrementOffset();
throw $objExc;
}
case "FontOverline":
try {
$this->SetCssStyle('text-decoration', QType::Cast($mixValue, QType::Boolean) ? 'overline' : null);
break;
} catch (QInvalidCastException $objExc) {
$objExc->IncrementOffset();
throw $objExc;
}
case "FontStrikeout":
try {
$this->SetCssStyle('text-decoration', QType::Cast($mixValue, QType::Boolean) ? 'line-through' : null);
break;
} catch (QInvalidCastException $objExc) {
$objExc->IncrementOffset();
throw $objExc;
}
case "FontUnderline":
try {
$this->SetCssStyle('text-decoration', QType::Cast($mixValue, QType::Boolean) ? 'underline' : null);
break;
} catch (QInvalidCastException $objExc) {
$objExc->IncrementOffset();
throw $objExc;
}
case "FontSize":
try {
$this->SetCssStyle('font-size', QType::Cast($mixValue, QType::String), true);
break;
} catch (QInvalidCastException $objExc) {
$objExc->IncrementOffset();
throw $objExc;
}
case "ForeColor":
try {
$this->SetCssStyle('color', QType::Cast($mixValue, QType::String));
break;
} catch (QInvalidCastException $objExc) {
$objExc->IncrementOffset();
throw $objExc;
}
case "Opacity":
try {
$mixValue = QType::Cast($mixValue, QType::Integer);
if (($mixValue < 0) || ($mixValue > 100)) {
throw new QCallerException('Opacity must be an integer value between 0 and 100');
}
$this->SetCssStyle('opacity', $mixValue);
break;
} catch (QInvalidCastException $objExc) {
$objExc->IncrementOffset();
throw $objExc;
}
case "Cursor":
try {
$this->SetCssStyle('cursor', QType::Cast($mixValue, QType::String));
break;
} catch (QInvalidCastException $objExc) {
$objExc->IncrementOffset();
throw $objExc;
}
case "Height":
try {
$this->SetCssStyle('height', QType::Cast($mixValue, QType::String), true);
break;
} catch (QInvalidCastException $objExc) {
$objExc->IncrementOffset();
throw $objExc;
}
case "Width":
try {
$this->SetCssStyle('width', QType::Cast($mixValue, QType::String), true);
break;
} catch (QInvalidCastException $objExc) {
$objExc->IncrementOffset();
throw $objExc;
}
case "Overflow":
try {
$this->SetCssStyle('overflow', QType::Cast($mixValue, QType::String));
break;
} catch (QInvalidCastException $objExc) {
$objExc->IncrementOffset();
throw $objExc;
}
case "Position":
try {
$this->SetCssStyle('position', QType::Cast($mixValue, QType::String));
break;
} catch (QInvalidCastException $objExc) {
$objExc->IncrementOffset();
throw $objExc;
}
case "Top":
try {
$this->SetCssStyle('top', QType::Cast($mixValue, QType::String), true);
break;
} catch (QInvalidCastException $objExc) {
$objExc->IncrementOffset();
throw $objExc;
}
case "Left":
try {
$this->SetCssStyle('left', QType::Cast($mixValue, QType::String), true);
break;
} catch (QInvalidCastException $objExc) {
$objExc->IncrementOffset();
throw $objExc;
}
case "HorizontalAlign":
try {
$this->SetCssStyle('text-align', QType::Cast($mixValue, QType::String));
break;
} catch (QInvalidCastException $objExc) {
$objExc->IncrementOffset();
throw $objExc;
}
case "VerticalAlign":
try {
$this->SetCssStyle('vertical-align', QType::Cast($mixValue, QType::String));
break;
} catch (QInvalidCastException $objExc) {
$objExc->IncrementOffset();
throw $objExc;
}
case "Wrap": // Wrap is now an actual attribute. Original developer used Wrap instead of NoWrap, not anticipating future change to HTML
throw new QCallerException ("Wrap is deprecated. Use NoWrap instead");
break;
case "NoWrap":
try {
$this->SetCssStyle('white-space', QType::Cast($mixValue, QType::Boolean) ? 'nowrap' : null);
break;
} catch (QInvalidCastException $objExc) {
$objExc->IncrementOffset();
throw $objExc;
}
case "Padding": // top right bottom left
$this->SetCssBoxValue('padding', $mixValue);
break;
case "Margin": // top right bottom left
$this->SetCssBoxValue('margin', $mixValue);
break;
case "UnorderedListStyle":
try {
$this->SetCssStyle('list-style-type', QType::Cast($mixValue, QType::String));
break;
} catch (QInvalidCastException $objExc) {
$objExc->IncrementOffset();
throw $objExc;
}
// Attributes
case "CssClass":
try {
$strCssClass = QType::Cast($mixValue, QType::String);
$this->SetCssClass($strCssClass);
break;
} catch (QInvalidCastException $objExc) {
$objExc->IncrementOffset();
throw $objExc;
}
case "AccessKey":
try {
$this->SetHtmlAttribute('accesskey', QType::Cast($mixValue, QType::String));
break;
} catch (QInvalidCastException $objExc) {
$objExc->IncrementOffset();
throw $objExc;
}
case "Enabled":
try {
$this->SetHtmlAttribute('disabled', QType::Cast($mixValue, QType::Boolean) ? null : 'disabled');
break;
} catch (QInvalidCastException $objExc) {
$objExc->IncrementOffset();
throw $objExc;
}
/* case "Required": Not supported consistently by browsers. We handle this inhouse */
case "TabIndex":
try {
$this->SetHtmlAttribute('tabindex', QType::Cast($mixValue, QType::String));
break;
} catch (QInvalidCastException $objExc) {
$objExc->IncrementOffset();
throw $objExc;
}
case "ToolTip":
try {
$this->SetHtmlAttribute('title', QType::Cast($mixValue, QType::String));
break;
} catch (QInvalidCastException $objExc) {
$objExc->IncrementOffset();
throw $objExc;
}
case "Data":
try {
$dataArray = QType::Cast($mixValue, QType::ArrayType);
foreach ($dataArray as $key=>$value) {
$this->SetDataAttribute($key, $value);
}
break;
} catch (QInvalidCastException $objExc) {
$objExc->IncrementOffset();
throw $objExc;
}
case "ReadOnly":
try {
$this->SetHtmlAttribute('readonly', QType::Cast($mixValue, QType::Boolean) ? 'readonly' : null);
break;
} catch (QInvalidCastException $objExc) {
$objExc->IncrementOffset();
throw $objExc;
}
case "AltText":
try {
$this->SetHtmlAttribute('alt', QType::Cast($mixValue, QType::String));
break;
} catch (QInvalidCastException $objExc) {
$objExc->IncrementOffset();
throw $objExc;
}
case "OrderedListType":
try {
$this->SetHtmlAttribute('type', QType::Cast($mixValue, QType::String));
break;
} catch (QInvalidCastException $objExc) {
$objExc->IncrementOffset();
throw $objExc;
}
default:
try {
return parent::__set($strName, $mixValue);
} catch (QCallerException $objExc) {
$objExc->IncrementOffset();
throw $objExc;
}
}
return true;
}
}