]> git.mxchange.org Git - friendica.git/blob - vendor/league/html-to-markdown/src/Element.php
Merge pull request #3301 from annando/issue-3300
[friendica.git] / vendor / league / html-to-markdown / src / Element.php
1 <?php
2
3 namespace League\HTMLToMarkdown;
4
5 class Element implements ElementInterface
6 {
7     /**
8      * @var \DOMNode
9      */
10     protected $node;
11
12     /**
13      * @var ElementInterface|null
14      */
15     private $nextCached;
16
17     public function __construct(\DOMNode $node)
18     {
19         $this->node = $node;
20     }
21
22     /**
23      * @return bool
24      */
25     public function isBlock()
26     {
27         switch ($this->getTagName()) {
28             case 'blockquote':
29             case 'body':
30             case 'code':
31             case 'div':
32             case 'h1':
33             case 'h2':
34             case 'h3':
35             case 'h4':
36             case 'h5':
37             case 'h6':
38             case 'hr':
39             case 'html':
40             case 'li':
41             case 'p':
42             case 'ol':
43             case 'ul':
44                 return true;
45             default:
46                 return false;
47         }
48     }
49
50     /**
51      * @return bool
52      */
53     public function isText()
54     {
55         return $this->getTagName() === '#text';
56     }
57
58     /**
59      * @return bool
60      */
61     public function isWhitespace()
62     {
63         return $this->getTagName() === '#text' && trim($this->getValue()) === '';
64     }
65
66     /**
67      * @return string
68      */
69     public function getTagName()
70     {
71         return $this->node->nodeName;
72     }
73
74     /**
75      * @return string
76      */
77     public function getValue()
78     {
79         return $this->node->nodeValue;
80     }
81
82     /**
83      * @return ElementInterface|null
84      */
85     public function getParent()
86     {
87         return new static($this->node->parentNode) ?: null;
88     }
89
90     /**
91      * @return bool
92      */
93     public function hasChildren()
94     {
95         return $this->node->hasChildNodes();
96     }
97
98     /**
99      * @return ElementInterface[]
100      */
101     public function getChildren()
102     {
103         $ret = array();
104         /** @var \DOMNode $node */
105         foreach ($this->node->childNodes as $node) {
106             $ret[] = new static($node);
107         }
108
109         return $ret;
110     }
111
112     /**
113      * @return ElementInterface|null
114      */
115     public function getNext()
116     {
117         if ($this->nextCached === null) {
118             $nextNode = $this->getNextNode($this->node);
119             if ($nextNode !== null) {
120                 $this->nextCached = new static($nextNode);
121             }
122         }
123
124         return $this->nextCached;
125     }
126
127     /**
128      * @param \DomNode $node
129      * @param bool $checkChildren
130      *
131      * @return \DomNode|null
132      */
133     private function getNextNode($node, $checkChildren = true)
134     {
135         if ($checkChildren && $node->firstChild) {
136             return $node->firstChild;
137         }
138
139         if ($node->nextSibling) {
140             return $node->nextSibling;
141         }
142
143         if ($node->parentNode) {
144             return $this->getNextNode($node->parentNode, false);
145         }
146     }
147
148     /**
149      * @param string[]|string $tagNames
150      *
151      * @return bool
152      */
153     public function isDescendantOf($tagNames)
154     {
155         if (!is_array($tagNames)) {
156             $tagNames = array($tagNames);
157         }
158
159         for ($p = $this->node->parentNode; $p !== false; $p = $p->parentNode) {
160             if (is_null($p)) {
161                 return false;
162             }
163
164             if (in_array($p->nodeName, $tagNames)) {
165                 return true;
166             }
167         }
168
169         return false;
170     }
171
172     /**
173      * @param string $markdown
174      */
175     public function setFinalMarkdown($markdown)
176     {
177         $markdown_node = $this->node->ownerDocument->createTextNode($markdown);
178         $this->node->parentNode->replaceChild($markdown_node, $this->node);
179     }
180
181     /**
182      * @return string
183      */
184     public function getChildrenAsString()
185     {
186         return $this->node->C14N();
187     }
188
189     /**
190      * @return int
191      */
192     public function getSiblingPosition()
193     {
194         $position = 0;
195
196         // Loop through all nodes and find the given $node
197         foreach ($this->getParent()->getChildren() as $current_node) {
198             if (!$current_node->isWhitespace()) {
199                 $position++;
200             }
201
202             // TODO: Need a less-buggy way of comparing these
203             // Perhaps we can somehow ensure that we always have the exact same object and use === instead?
204             if ($this->equals($current_node)) {
205                 break;
206             }
207         }
208
209         return $position;
210     }
211
212     /**
213      * @return int
214      */
215     public function getListItemLevel()
216     {
217         $level = 0;
218         $parent = $this->getParent();
219
220         while ($parent !== null && $parent->node->parentNode) {
221             if ($parent->getTagName() === 'li') {
222                 $level++;
223             }
224             $parent = $parent->getParent();
225         }
226
227         return $level;
228     }
229
230     /**
231      * @param string $name
232      *
233      * @return string
234      */
235     public function getAttribute($name)
236     {
237         if ($this->node instanceof \DOMElement) {
238             return $this->node->getAttribute($name);
239         }
240
241         return '';
242     }
243
244     /**
245      * @param ElementInterface $element
246      *
247      * @return bool
248      */
249     public function equals(ElementInterface $element)
250     {
251         if ($element instanceof self) {
252             return $element->node === $this->node;
253         }
254
255         return $element === $this;
256     }
257 }