Subversion-Projekte lars-tiefland.laravel_shop

Revision

Zur aktuellen Revision | Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
148 lars 1
<?php
2
 
3
declare(strict_types=1);
4
 
5
/*
6
 * This file is part of the league/commonmark package.
7
 *
8
 * (c) Colin O'Dell <colinodell@gmail.com>
9
 *
10
 * Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
11
 *  - (c) John MacFarlane
12
 *
13
 * For the full copyright and license information, please view the LICENSE
14
 * file that was distributed with this source code.
15
 */
16
 
17
namespace League\CommonMark\Util;
18
 
19
final class HtmlElement implements \Stringable
20
{
21
    /** @psalm-readonly */
22
    private string $tagName;
23
 
24
    /** @var array<string, string|bool> */
25
    private array $attributes = [];
26
 
27
    /** @var \Stringable|\Stringable[]|string */
28
    private $contents;
29
 
30
    /** @psalm-readonly */
31
    private bool $selfClosing;
32
 
33
    /**
34
     * @param string                                $tagName     Name of the HTML tag
35
     * @param array<string, string|string[]|bool>   $attributes  Array of attributes (values should be unescaped)
36
     * @param \Stringable|\Stringable[]|string|null $contents    Inner contents, pre-escaped if needed
37
     * @param bool                                  $selfClosing Whether the tag is self-closing
38
     */
39
    public function __construct(string $tagName, array $attributes = [], $contents = '', bool $selfClosing = false)
40
    {
41
        $this->tagName     = $tagName;
42
        $this->selfClosing = $selfClosing;
43
 
44
        foreach ($attributes as $name => $value) {
45
            $this->setAttribute($name, $value);
46
        }
47
 
48
        $this->setContents($contents ?? '');
49
    }
50
 
51
    /** @psalm-immutable */
52
    public function getTagName(): string
53
    {
54
        return $this->tagName;
55
    }
56
 
57
    /**
58
     * @return array<string, string|bool>
59
     *
60
     * @psalm-immutable
61
     */
62
    public function getAllAttributes(): array
63
    {
64
        return $this->attributes;
65
    }
66
 
67
    /**
68
     * @return string|bool|null
69
     *
70
     * @psalm-immutable
71
     */
72
    public function getAttribute(string $key)
73
    {
74
        return $this->attributes[$key] ?? null;
75
    }
76
 
77
    /**
78
     * @param string|string[]|bool $value
79
     */
80
    public function setAttribute(string $key, $value): self
81
    {
82
        if (\is_array($value)) {
83
            $this->attributes[$key] = \implode(' ', \array_unique($value));
84
        } else {
85
            $this->attributes[$key] = $value;
86
        }
87
 
88
        return $this;
89
    }
90
 
91
    /**
92
     * @return \Stringable|\Stringable[]|string
93
     *
94
     * @psalm-immutable
95
     */
96
    public function getContents(bool $asString = true)
97
    {
98
        if (! $asString) {
99
            return $this->contents;
100
        }
101
 
102
        return $this->getContentsAsString();
103
    }
104
 
105
    /**
106
     * Sets the inner contents of the tag (must be pre-escaped if needed)
107
     *
108
     * @param \Stringable|\Stringable[]|string $contents
109
     *
110
     * @return $this
111
     */
112
    public function setContents($contents): self
113
    {
114
        $this->contents = $contents ?? ''; // @phpstan-ignore-line
115
 
116
        return $this;
117
    }
118
 
119
    /** @psalm-immutable */
120
    public function __toString(): string
121
    {
122
        $result = '<' . $this->tagName;
123
 
124
        foreach ($this->attributes as $key => $value) {
125
            if ($value === true) {
126
                $result .= ' ' . $key;
127
            } elseif ($value === false) {
128
                continue;
129
            } else {
130
                $result .= ' ' . $key . '="' . Xml::escape($value) . '"';
131
            }
132
        }
133
 
134
        if ($this->contents !== '') {
135
            $result .= '>' . $this->getContentsAsString() . '</' . $this->tagName . '>';
136
        } elseif ($this->selfClosing && $this->tagName === 'input') {
137
            $result .= '>';
138
        } elseif ($this->selfClosing) {
139
            $result .= ' />';
140
        } else {
141
            $result .= '></' . $this->tagName . '>';
142
        }
143
 
144
        return $result;
145
    }
146
 
147
    /** @psalm-immutable */
148
    private function getContentsAsString(): string
149
    {
150
        if (\is_string($this->contents)) {
151
            return $this->contents;
152
        }
153
 
154
        if (\is_array($this->contents)) {
155
            return \implode('', $this->contents);
156
        }
157
 
158
        return (string) $this->contents;
159
    }
160
}