Some texta bold bitsome more text

// // If structures like these are required ten they can usually be achieved by wrapping the raw // text nodes in a . use function MRBS\escape_html; use function MRBS\is_assoc; class Element { private $tag; private $self_closing; private $attributes = array(); private $text = null; private $raw = false; private $text_at_start = false; private $elements = []; private $next = null; private $prev = null; public function __construct(string $tag, bool $self_closing=false) { $this->tag = $tag; $this->self_closing = $self_closing; } // If $raw is true then the text will not be put through escape_html(). Only to // be used for trusted text. public function setText(string $text, bool $text_at_start=false, bool $raw=false) : Element { if ($this->self_closing) { throw new \Exception("A self closing element cannot contain text."); } $this->text = $text; $this->text_at_start = $text_at_start; $this->raw = $raw; return $this; } public function getAttribute(string $name) { return (isset($this->attributes[$name])) ? $this->attributes[$name] : null; } // A value of true allows for the setting of boolean attributes such as // 'required' and 'disabled' public function setAttribute(string $name, $value=true) : Element { $this->attributes[$name] = $value; return $this; } public function setAttributes(array $attributes) : Element { foreach ($attributes as $name => $value) { $this->setAttribute($name, $value); } return $this; } public function removeAttribute(string $name) : Element { unset($this->attributes[$name]); return $this; } public function getElement(string $key) : Element { return $this->elements[$key]; } public function setElement(string $key, Element $element) : Element { $this->elements[$key] = $element; return $this; } public function getElements() : array { return $this->elements; } public function setElements(array $elements) : Element { $this->elements = $elements; return $this; } public function addElement(?Element $element=null, ?string $key=null) : Element { if (isset($element)) { if (isset($key)) { $this->elements[$key] = $element; } else { $this->elements[] = $element; } } return $this; } public function addElements(array $elements) : Element { foreach ($elements as $element) { $this->addElement($element); } return $this; } public function removeElement(string $key) : Element { unset($this->elements[$key]); return $this; } public function next(?Element $element=null) : ?Element { if (isset($element)) { $this->next = $element; return $this; } elseif (isset($this->next)) { return $this->next; } else { return null; } } public function prev(?Element $element=null): ?Element { if (isset($element)) { $this->prev = $element; return $this; } elseif (isset($this->prev)) { return $this->prev; } else { return null; } } public function addClass(string $class) : Element { $classes = $this->getAttribute('class'); $classes = (isset($classes)) ? explode(' ', $classes) : array(); if (!in_array($class, $classes)) { $classes[] = $class; $this->setAttribute('class', implode(' ', $classes)); } return $this; } // Add a set of select options to an element, eg to a element. // $selected The value(s) of the option(s) that are selected. Can be a single value // or an array of values. // $associative Whether to treat the options as a simple or an associative array. (This // parameter is necessary because if you index an array with strings that look // like integers then PHP casts the keys to integers and the array becomes a // simple array). Can take the following values: // true treat as an associative array // false treat as a simple array // null auto-detect // $for_datalist Whether the options are intended for use in a . public function addSelectOptions(array $options, $selected=null, ?bool $associative=null, bool $for_datalist=false) : Element { // Trivial case if (empty($options)) { return $this; } if (!isset($associative)) { $associative = is_assoc($options); } // It's possible to have multiple options selected if (!is_array($selected)) { $selected = array($selected); } // Test whether $options is a one-dimensional or two-dimensional array. // If two-dimensional then we need to use s. if (is_array(reset($options))) // cannot use $options[0] because $options may be associative { if ($for_datalist) { throw new \InvalidArgumentException("Datalists cannot have elements."); } foreach ($options as $group => $group_options) { $optgroup = new ElementOptgroup(); $optgroup->setAttribute('label', $group) ->addSelectOptions($group_options, $selected, $associative); $this->addElement($optgroup); } } else { foreach ($options as $key => $text) { $option = new ElementOption(); // We need to be careful about strings with multiple consecutive spaces in them. If we have a text where whitespace after the tag would // affect what the browser displays on the screen. public function toHTML(bool $no_whitespace=false): string { $html = ""; $prev = $this->prev(); if (isset($prev)) { $html .= $prev->toHTML(); } $terminator = ($no_whitespace) ? '' : "\n"; $html .= "<" . $this->tag; foreach ($this->attributes as $key => $value) { if (!isset($value) || ($value === false)) { // a boolean attribute, or else an empty attribute, that should be omitted. // We allow the empty string, '', because that can be used, for example, in // 'value=""' as an attribute for the