Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
100.00% |
47 / 47 |
|
100.00% |
35 / 35 |
CRAP | n/a |
0 / 0 |
|
| Epic64\Elem\_applyCommon | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
4 | |||
| Epic64\Elem\el | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| Epic64\Elem\a | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| Epic64\Elem\div | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| Epic64\Elem\span | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| Epic64\Elem\p | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| Epic64\Elem\h | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| Epic64\Elem\img | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| Epic64\Elem\button | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| Epic64\Elem\input | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| Epic64\Elem\form | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| Epic64\Elem\label | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| Epic64\Elem\ul | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| Epic64\Elem\ol | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| Epic64\Elem\li | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| Epic64\Elem\table | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| Epic64\Elem\tr | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| Epic64\Elem\td | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| Epic64\Elem\th | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| Epic64\Elem\textarea | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| Epic64\Elem\select | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| Epic64\Elem\html | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| Epic64\Elem\head | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| Epic64\Elem\body | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| Epic64\Elem\title | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| Epic64\Elem\meta | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| Epic64\Elem\style | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| Epic64\Elem\script | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| Epic64\Elem\link | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| Epic64\Elem\stylesheet | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| Epic64\Elem\icon | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
2 | |||
| Epic64\Elem\font | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
2 | |||
| Epic64\Elem\text | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| Epic64\Elem\raw | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
| Epic64\Elem\list_of | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
2 | |||
| 1 | <?php |
| 2 | |
| 3 | declare(strict_types=1); |
| 4 | |
| 5 | namespace Epic64\Elem; |
| 6 | |
| 7 | use Epic64\Elem\Elements\Anchor; |
| 8 | use Epic64\Elem\Elements\Body; |
| 9 | use Epic64\Elem\Elements\Button; |
| 10 | use Epic64\Elem\Elements\Div; |
| 11 | use Epic64\Elem\Elements\Form; |
| 12 | use Epic64\Elem\Elements\Head; |
| 13 | use Epic64\Elem\Elements\Heading; |
| 14 | use Epic64\Elem\Elements\Html; |
| 15 | use Epic64\Elem\Elements\Image; |
| 16 | use Epic64\Elem\Elements\Input; |
| 17 | use Epic64\Elem\Elements\Label; |
| 18 | use Epic64\Elem\Elements\Link; |
| 19 | use Epic64\Elem\Elements\ListItem; |
| 20 | use Epic64\Elem\Elements\Meta; |
| 21 | use Epic64\Elem\Elements\OrderedList; |
| 22 | use Epic64\Elem\Elements\Paragraph; |
| 23 | use Epic64\Elem\Elements\RawHtml; |
| 24 | use Epic64\Elem\Elements\Script; |
| 25 | use Epic64\Elem\Elements\Select; |
| 26 | use Epic64\Elem\Elements\Span; |
| 27 | use Epic64\Elem\Elements\Style; |
| 28 | use Epic64\Elem\Elements\Table; |
| 29 | use Epic64\Elem\Elements\TableCell; |
| 30 | use Epic64\Elem\Elements\TableHeader; |
| 31 | use Epic64\Elem\Elements\TableRow; |
| 32 | use Epic64\Elem\Elements\Text; |
| 33 | use Epic64\Elem\Elements\Textarea; |
| 34 | use Epic64\Elem\Elements\Title; |
| 35 | use Epic64\Elem\Elements\UnorderedList; |
| 36 | |
| 37 | /** |
| 38 | * Apply common attributes (id and class) to an element. |
| 39 | * @template T of Element |
| 40 | * @param T $element |
| 41 | * @return T |
| 42 | */ |
| 43 | function _applyCommon(Element $element, ?string $id, ?string $class): Element |
| 44 | { |
| 45 | if ($id !== null) { |
| 46 | $element->id($id); |
| 47 | } |
| 48 | if ($class !== null && $class !== '') { |
| 49 | $element->class(...explode(' ', $class)); |
| 50 | } |
| 51 | return $element; |
| 52 | } |
| 53 | |
| 54 | function el(string $tag, ?string $id = null, ?string $class = null, ?string $text = null): Element |
| 55 | { |
| 56 | return _applyCommon(new Element($tag, $text), $id, $class); |
| 57 | } |
| 58 | |
| 59 | function a(string $href, ?string $id = null, ?string $class = null, ?string $text = null): Anchor |
| 60 | { |
| 61 | /** @var Anchor */ |
| 62 | return _applyCommon(new Anchor($href, $text), $id, $class); |
| 63 | } |
| 64 | |
| 65 | function div(?string $id = null, ?string $class = null, ?string $text = null): Div |
| 66 | { |
| 67 | /** @var Div */ |
| 68 | return _applyCommon(new Div($text), $id, $class); |
| 69 | } |
| 70 | |
| 71 | function span(?string $id = null, ?string $class = null, ?string $text = null): Span |
| 72 | { |
| 73 | /** @var Span */ |
| 74 | return _applyCommon(new Span($text), $id, $class); |
| 75 | } |
| 76 | |
| 77 | function p(?string $id = null, ?string $class = null, ?string $text = null): Paragraph |
| 78 | { |
| 79 | /** @var Paragraph */ |
| 80 | return _applyCommon(new Paragraph($text), $id, $class); |
| 81 | } |
| 82 | |
| 83 | function h(int $level, ?string $id = null, ?string $class = null, ?string $text = null): Heading |
| 84 | { |
| 85 | /** @var Heading */ |
| 86 | return _applyCommon(new Heading($level, $text), $id, $class); |
| 87 | } |
| 88 | |
| 89 | function img(string $src, ?string $id = null, ?string $class = null, string $alt = ''): Image |
| 90 | { |
| 91 | /** @var Image */ |
| 92 | return _applyCommon(new Image($src, $alt), $id, $class); |
| 93 | } |
| 94 | |
| 95 | function button(?string $id = null, ?string $class = null, ?string $text = null, string $type = 'button'): Button |
| 96 | { |
| 97 | /** @var Button */ |
| 98 | return _applyCommon(new Button($text, $type), $id, $class); |
| 99 | } |
| 100 | |
| 101 | function input(string $type, ?string $id = null, ?string $class = null, ?string $name = null): Input |
| 102 | { |
| 103 | /** @var Input */ |
| 104 | return _applyCommon(new Input($type, $name), $id, $class); |
| 105 | } |
| 106 | |
| 107 | function form(?string $id = null, ?string $class = null, ?string $action = null, string $method = 'post'): Form |
| 108 | { |
| 109 | /** @var Form */ |
| 110 | return _applyCommon(new Form($action, $method), $id, $class); |
| 111 | } |
| 112 | |
| 113 | function label(?string $id = null, ?string $class = null, ?string $text = null, ?string $for = null): Label |
| 114 | { |
| 115 | /** @var Label */ |
| 116 | return _applyCommon(new Label($text, $for), $id, $class); |
| 117 | } |
| 118 | |
| 119 | function ul(?string $id = null, ?string $class = null): UnorderedList |
| 120 | { |
| 121 | /** @var UnorderedList */ |
| 122 | return _applyCommon(new UnorderedList(), $id, $class); |
| 123 | } |
| 124 | |
| 125 | function ol(?string $id = null, ?string $class = null): OrderedList |
| 126 | { |
| 127 | /** @var OrderedList */ |
| 128 | return _applyCommon(new OrderedList(), $id, $class); |
| 129 | } |
| 130 | |
| 131 | function li(?string $id = null, ?string $class = null, ?string $text = null): ListItem |
| 132 | { |
| 133 | /** @var ListItem */ |
| 134 | return _applyCommon(new ListItem($text), $id, $class); |
| 135 | } |
| 136 | |
| 137 | function table(?string $id = null, ?string $class = null): Table |
| 138 | { |
| 139 | /** @var Table */ |
| 140 | return _applyCommon(new Table(), $id, $class); |
| 141 | } |
| 142 | |
| 143 | function tr(?string $id = null, ?string $class = null): TableRow |
| 144 | { |
| 145 | /** @var TableRow */ |
| 146 | return _applyCommon(new TableRow(), $id, $class); |
| 147 | } |
| 148 | |
| 149 | function td(?string $id = null, ?string $class = null, ?string $text = null): TableCell |
| 150 | { |
| 151 | /** @var TableCell */ |
| 152 | return _applyCommon(new TableCell($text), $id, $class); |
| 153 | } |
| 154 | |
| 155 | function th(?string $id = null, ?string $class = null, ?string $text = null): TableHeader |
| 156 | { |
| 157 | /** @var TableHeader */ |
| 158 | return _applyCommon(new TableHeader($text), $id, $class); |
| 159 | } |
| 160 | |
| 161 | function textarea(?string $id = null, ?string $class = null, ?string $name = null, ?string $content = null): Textarea |
| 162 | { |
| 163 | /** @var Textarea */ |
| 164 | return _applyCommon(new Textarea($name, $content), $id, $class); |
| 165 | } |
| 166 | |
| 167 | function select(?string $id = null, ?string $class = null, ?string $name = null): Select |
| 168 | { |
| 169 | /** @var Select */ |
| 170 | return _applyCommon(new Select($name), $id, $class); |
| 171 | } |
| 172 | |
| 173 | function html(?string $lang = null): Html |
| 174 | { |
| 175 | return new Html($lang); |
| 176 | } |
| 177 | |
| 178 | function head(): Head |
| 179 | { |
| 180 | return new Head(); |
| 181 | } |
| 182 | |
| 183 | function body(?string $id = null, ?string $class = null): Body |
| 184 | { |
| 185 | /** @var Body */ |
| 186 | return _applyCommon(new Body(), $id, $class); |
| 187 | } |
| 188 | |
| 189 | function title(?string $text = null): Title |
| 190 | { |
| 191 | return new Title($text); |
| 192 | } |
| 193 | |
| 194 | function meta(?string $charset = null, ?string $name = null, ?string $content = null): Meta |
| 195 | { |
| 196 | return new Meta($charset, $name, $content); |
| 197 | } |
| 198 | |
| 199 | function style(?string $css = null): Style |
| 200 | { |
| 201 | return new Style($css); |
| 202 | } |
| 203 | |
| 204 | function script(?string $code = null, ?string $src = null): Script |
| 205 | { |
| 206 | return new Script($code, $src); |
| 207 | } |
| 208 | |
| 209 | /** |
| 210 | * Create a <link> element for external resources. |
| 211 | * |
| 212 | * Note: For stylesheets, you probably want to use the stylesheet() helper instead: |
| 213 | * stylesheet('/css/style.css') |
| 214 | */ |
| 215 | function link(?string $href = null, ?string $rel = null): Link |
| 216 | { |
| 217 | return new Link($href, $rel); |
| 218 | } |
| 219 | |
| 220 | function stylesheet(string $href): Link |
| 221 | { |
| 222 | return new Link($href, 'stylesheet'); |
| 223 | } |
| 224 | |
| 225 | function icon(string $href, ?string $type = null): Link |
| 226 | { |
| 227 | $link = new Link($href, 'icon'); |
| 228 | if ($type !== null) { |
| 229 | $link->type($type); |
| 230 | } |
| 231 | return $link; |
| 232 | } |
| 233 | |
| 234 | function font(string $href, ?string $type = null): Link |
| 235 | { |
| 236 | $link = new Link($href, 'preload'); |
| 237 | $link->attr('as', 'font'); |
| 238 | $link->attr('crossorigin', 'anonymous'); |
| 239 | if ($type !== null) { |
| 240 | $link->type($type); |
| 241 | } |
| 242 | return $link; |
| 243 | } |
| 244 | |
| 245 | /** |
| 246 | * Create a text node that will be safely escaped when rendered. |
| 247 | * |
| 248 | * This is useful when you want to explicitly create a text node as a sibling |
| 249 | * to other elements, rather than using the `text` parameter of an element. |
| 250 | * |
| 251 | * @example |
| 252 | * ```php |
| 253 | * div()( |
| 254 | * text('Hello, '), |
| 255 | * span(class: 'name', text: $username), |
| 256 | * text('!') |
| 257 | * ) |
| 258 | * ``` |
| 259 | */ |
| 260 | function text(string $content): Text |
| 261 | { |
| 262 | return new Text($content); |
| 263 | } |
| 264 | |
| 265 | /** |
| 266 | * Create a raw HTML fragment that will not be escaped. |
| 267 | * |
| 268 | * WARNING: Only use this with trusted content. Using raw HTML with |
| 269 | * user-provided input can lead to XSS vulnerabilities. |
| 270 | * |
| 271 | * @example |
| 272 | * ```php |
| 273 | * div()( |
| 274 | * raw('<strong>Bold text</strong>'), |
| 275 | * raw($trustedHtmlFromMarkdownParser) |
| 276 | * ) |
| 277 | * ``` |
| 278 | */ |
| 279 | function raw(string $html): RawHtml |
| 280 | { |
| 281 | return new RawHtml($html); |
| 282 | } |
| 283 | |
| 284 | /** |
| 285 | * Create a Collection from an iterable for fluent transformations. |
| 286 | * |
| 287 | * Example: |
| 288 | * list_of($users) |
| 289 | * ->filter(fn($u) => $u->isAdmin()) |
| 290 | * ->map(fn($u) => div(class: 'user', text: $u->name)) |
| 291 | * |
| 292 | * @template T |
| 293 | * @param iterable<T> $items |
| 294 | * @return ElementsList<T> |
| 295 | */ |
| 296 | function list_of(iterable $items): ElementsList |
| 297 | { |
| 298 | return new ElementsList(is_array($items) ? $items : iterator_to_array($items)); |
| 299 | } |