public function hattr($attributes)
{
// http://www.w3.org/html/wg/drafts/html/master/infrastructure.html#boolean-attributes
// We implement only a subset for now that is used in Bolt.
$booleans = ['checked', 'disabled', 'multiple', 'readonly', 'required', 'selected'];
$return = '';
$add = function ($name, $value = null) use(&$return) {
$return .= ' ' . $name . ($value === null ? '' : '="' . htmlspecialchars($value) . '"');
};
foreach ($attributes as $name => $value) {
// Force outputting of empty non booleans.
$force = substr($name, -1) === '!';
$name = rtrim($name, '!');
// Check for being a boolean attribute.
$isBoolean = in_array($name, $booleans);
// Assume integer 0, float 0.0 and string "0" as not empty on non booleans.
$set = !empty($value) || !$isBoolean && (string) $value === '0';
if ($set || !$isBoolean && $force) {
if ($isBoolean) {
$add($name);
} elseif ($name === 'name+id') {
$add('name', $value);
$add('id', $value);
} elseif ($name === 'class') {
$add($name, $this->hclass($value, true));
} elseif (is_array($value)) {
$add($name, json_encode($value));
} else {
$add($name, $value);
}
}
}
return $return;
}