Complex classes like HtmlMin often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use HtmlMin, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
21 | class HtmlMin |
||
22 | { |
||
23 | /** |
||
24 | * @var string |
||
25 | */ |
||
26 | private static $regExSpace = "/[[:space:]]{2,}|[\r\n]+/u"; |
||
27 | |||
28 | /** |
||
29 | * @var array |
||
30 | */ |
||
31 | private static $optional_end_tags = [ |
||
32 | 'html', |
||
33 | 'head', |
||
34 | 'body', |
||
35 | ]; |
||
36 | |||
37 | private static $selfClosingTags = [ |
||
38 | 'area', |
||
39 | 'base', |
||
40 | 'basefont', |
||
41 | 'br', |
||
42 | 'col', |
||
43 | 'command', |
||
44 | 'embed', |
||
45 | 'frame', |
||
46 | 'hr', |
||
47 | 'img', |
||
48 | 'input', |
||
49 | 'isindex', |
||
50 | 'keygen', |
||
51 | 'link', |
||
52 | 'meta', |
||
53 | 'param', |
||
54 | 'source', |
||
55 | 'track', |
||
56 | 'wbr', |
||
57 | ]; |
||
58 | |||
59 | private static $trimWhitespaceFromTags = [ |
||
60 | 'article' => '', |
||
61 | 'br' => '', |
||
62 | 'div' => '', |
||
63 | 'footer' => '', |
||
64 | 'hr' => '', |
||
65 | 'nav' => '', |
||
66 | 'p' => '', |
||
67 | 'script' => '', |
||
68 | ]; |
||
69 | |||
70 | /** |
||
71 | * @var array |
||
72 | */ |
||
73 | private static $booleanAttributes = [ |
||
74 | 'allowfullscreen' => '', |
||
75 | 'async' => '', |
||
76 | 'autofocus' => '', |
||
77 | 'autoplay' => '', |
||
78 | 'checked' => '', |
||
79 | 'compact' => '', |
||
80 | 'controls' => '', |
||
81 | 'declare' => '', |
||
82 | 'default' => '', |
||
83 | 'defaultchecked' => '', |
||
84 | 'defaultmuted' => '', |
||
85 | 'defaultselected' => '', |
||
86 | 'defer' => '', |
||
87 | 'disabled' => '', |
||
88 | 'enabled' => '', |
||
89 | 'formnovalidate' => '', |
||
90 | 'hidden' => '', |
||
91 | 'indeterminate' => '', |
||
92 | 'inert' => '', |
||
93 | 'ismap' => '', |
||
94 | 'itemscope' => '', |
||
95 | 'loop' => '', |
||
96 | 'multiple' => '', |
||
97 | 'muted' => '', |
||
98 | 'nohref' => '', |
||
99 | 'noresize' => '', |
||
100 | 'noshade' => '', |
||
101 | 'novalidate' => '', |
||
102 | 'nowrap' => '', |
||
103 | 'open' => '', |
||
104 | 'pauseonexit' => '', |
||
105 | 'readonly' => '', |
||
106 | 'required' => '', |
||
107 | 'reversed' => '', |
||
108 | 'scoped' => '', |
||
109 | 'seamless' => '', |
||
110 | 'selected' => '', |
||
111 | 'sortable' => '', |
||
112 | 'truespeed' => '', |
||
113 | 'typemustmatch' => '', |
||
114 | 'visible' => '', |
||
115 | ]; |
||
116 | |||
117 | /** |
||
118 | * @var array |
||
119 | */ |
||
120 | private static $skipTagsForRemoveWhitespace = [ |
||
121 | 'code', |
||
122 | 'pre', |
||
123 | 'script', |
||
124 | 'style', |
||
125 | 'textarea', |
||
126 | ]; |
||
127 | |||
128 | /** |
||
129 | * @var array |
||
130 | */ |
||
131 | private $protectedChildNodes = []; |
||
132 | |||
133 | /** |
||
134 | * @var string |
||
135 | */ |
||
136 | private $protectedChildNodesHelper = 'html-min--voku--saved-content'; |
||
137 | |||
138 | /** |
||
139 | * @var bool |
||
140 | */ |
||
141 | private $doOptimizeViaHtmlDomParser = true; |
||
142 | |||
143 | /** |
||
144 | * @var bool |
||
145 | */ |
||
146 | private $doOptimizeAttributes = true; |
||
147 | |||
148 | /** |
||
149 | * @var bool |
||
150 | */ |
||
151 | private $doRemoveComments = true; |
||
152 | |||
153 | /** |
||
154 | * @var bool |
||
155 | */ |
||
156 | private $doRemoveWhitespaceAroundTags = false; |
||
157 | |||
158 | /** |
||
159 | * @var bool |
||
160 | */ |
||
161 | private $doRemoveOmittedQuotes = true; |
||
162 | |||
163 | /** |
||
164 | * @var bool |
||
165 | */ |
||
166 | private $doRemoveOmittedHtmlTags = true; |
||
167 | |||
168 | /** |
||
169 | * @var bool |
||
170 | */ |
||
171 | private $doRemoveHttpPrefixFromAttributes = false; |
||
172 | |||
173 | /** |
||
174 | * @var array |
||
175 | */ |
||
176 | private $domainsToRemoveHttpPrefixFromAttributes = [ |
||
177 | 'google.com', |
||
178 | 'google.de', |
||
179 | ]; |
||
180 | |||
181 | /** |
||
182 | * @var bool |
||
183 | */ |
||
184 | private $doSortCssClassNames = true; |
||
185 | |||
186 | /** |
||
187 | * @var bool |
||
188 | */ |
||
189 | private $doSortHtmlAttributes = true; |
||
190 | |||
191 | /** |
||
192 | * @var bool |
||
193 | */ |
||
194 | private $doRemoveDeprecatedScriptCharsetAttribute = true; |
||
195 | |||
196 | /** |
||
197 | * @var bool |
||
198 | */ |
||
199 | private $doRemoveDefaultAttributes = false; |
||
200 | |||
201 | /** |
||
202 | * @var bool |
||
203 | */ |
||
204 | private $doRemoveDeprecatedAnchorName = true; |
||
205 | |||
206 | /** |
||
207 | * @var bool |
||
208 | */ |
||
209 | private $doRemoveDeprecatedTypeFromStylesheetLink = true; |
||
210 | |||
211 | /** |
||
212 | * @var bool |
||
213 | */ |
||
214 | private $doRemoveDeprecatedTypeFromScriptTag = true; |
||
215 | |||
216 | /** |
||
217 | * @var bool |
||
218 | */ |
||
219 | private $doRemoveValueFromEmptyInput = true; |
||
220 | |||
221 | /** |
||
222 | * @var bool |
||
223 | */ |
||
224 | private $doRemoveEmptyAttributes = true; |
||
225 | |||
226 | /** |
||
227 | * @var bool |
||
228 | */ |
||
229 | private $doSumUpWhitespace = true; |
||
230 | |||
231 | /** |
||
232 | * @var bool |
||
233 | */ |
||
234 | private $doRemoveSpacesBetweenTags = false; |
||
235 | |||
236 | /** |
||
237 | * @var bool |
||
238 | */ |
||
239 | private $keepBrokenHtml = false; |
||
240 | |||
241 | /** |
||
242 | * @var bool |
||
243 | */ |
||
244 | private $withDocType = false; |
||
245 | |||
246 | /** |
||
247 | * @var \SplObjectStorage|HtmlMinDomObserverInterface[] |
||
248 | */ |
||
249 | private $domLoopObservers; |
||
250 | |||
251 | /** |
||
252 | * HtmlMin constructor. |
||
253 | */ |
||
254 | 45 | public function __construct() |
|
260 | |||
261 | /** |
||
262 | * @param HtmlMinDomObserverInterface $observer |
||
263 | * |
||
264 | * @return void |
||
265 | */ |
||
266 | 45 | public function attachObserverToTheDomLoop(HtmlMinDomObserverInterface $observer) |
|
270 | |||
271 | /** |
||
272 | * @param $domElement SimpleHtmlDom |
||
273 | * |
||
274 | * @return void |
||
275 | */ |
||
276 | 41 | private function notifyObserversAboutDomElementBeforeMinification(SimpleHtmlDom $domElement) |
|
282 | |||
283 | 41 | private function notifyObserversAboutDomElementAfterMinification(SimpleHtmlDom $domElement) |
|
289 | |||
290 | /** |
||
291 | * @param bool $doOptimizeAttributes |
||
292 | * |
||
293 | * @return $this |
||
294 | */ |
||
295 | 2 | public function doOptimizeAttributes(bool $doOptimizeAttributes = true): self |
|
301 | |||
302 | /** |
||
303 | * @param bool $doOptimizeViaHtmlDomParser |
||
304 | * |
||
305 | * @return $this |
||
306 | */ |
||
307 | 1 | public function doOptimizeViaHtmlDomParser(bool $doOptimizeViaHtmlDomParser = true): self |
|
313 | |||
314 | /** |
||
315 | * @param bool $doRemoveComments |
||
316 | * |
||
317 | * @return $this |
||
318 | */ |
||
319 | 3 | public function doRemoveComments(bool $doRemoveComments = true): self |
|
325 | |||
326 | /** |
||
327 | * @param bool $doRemoveDefaultAttributes |
||
328 | * |
||
329 | * @return $this |
||
330 | */ |
||
331 | 2 | public function doRemoveDefaultAttributes(bool $doRemoveDefaultAttributes = true): self |
|
337 | |||
338 | /** |
||
339 | * @param bool $doRemoveDeprecatedAnchorName |
||
340 | * |
||
341 | * @return $this |
||
342 | */ |
||
343 | 2 | public function doRemoveDeprecatedAnchorName(bool $doRemoveDeprecatedAnchorName = true): self |
|
349 | |||
350 | /** |
||
351 | * @param bool $doRemoveDeprecatedScriptCharsetAttribute |
||
352 | * |
||
353 | * @return $this |
||
354 | */ |
||
355 | 2 | public function doRemoveDeprecatedScriptCharsetAttribute(bool $doRemoveDeprecatedScriptCharsetAttribute = true): self |
|
361 | |||
362 | /** |
||
363 | * @param bool $doRemoveDeprecatedTypeFromScriptTag |
||
364 | * |
||
365 | * @return $this |
||
366 | */ |
||
367 | 2 | public function doRemoveDeprecatedTypeFromScriptTag(bool $doRemoveDeprecatedTypeFromScriptTag = true): self |
|
373 | |||
374 | /** |
||
375 | * @param bool $doRemoveDeprecatedTypeFromStylesheetLink |
||
376 | * |
||
377 | * @return $this |
||
378 | */ |
||
379 | 2 | public function doRemoveDeprecatedTypeFromStylesheetLink(bool $doRemoveDeprecatedTypeFromStylesheetLink = true): self |
|
385 | |||
386 | /** |
||
387 | * @param bool $doRemoveEmptyAttributes |
||
388 | * |
||
389 | * @return $this |
||
390 | */ |
||
391 | 2 | public function doRemoveEmptyAttributes(bool $doRemoveEmptyAttributes = true): self |
|
397 | |||
398 | /** |
||
399 | * @param bool $doRemoveHttpPrefixFromAttributes |
||
400 | * |
||
401 | * @return $this |
||
402 | */ |
||
403 | 4 | public function doRemoveHttpPrefixFromAttributes(bool $doRemoveHttpPrefixFromAttributes = true): self |
|
409 | |||
410 | /** |
||
411 | * @return bool |
||
412 | */ |
||
413 | 25 | public function isDoSortCssClassNames(): bool |
|
417 | |||
418 | /** |
||
419 | * @return bool |
||
420 | */ |
||
421 | 25 | public function isDoSortHtmlAttributes(): bool |
|
425 | |||
426 | /** |
||
427 | * @return bool |
||
428 | */ |
||
429 | 25 | public function isDoRemoveDeprecatedScriptCharsetAttribute(): bool |
|
433 | |||
434 | /** |
||
435 | * @return bool |
||
436 | */ |
||
437 | 25 | public function isDoRemoveDefaultAttributes(): bool |
|
441 | |||
442 | /** |
||
443 | * @return bool |
||
444 | */ |
||
445 | 25 | public function isDoRemoveDeprecatedAnchorName(): bool |
|
449 | |||
450 | /** |
||
451 | * @return bool |
||
452 | */ |
||
453 | 25 | public function isDoRemoveDeprecatedTypeFromStylesheetLink(): bool |
|
457 | |||
458 | /** |
||
459 | * @return bool |
||
460 | */ |
||
461 | 25 | public function isDoRemoveDeprecatedTypeFromScriptTag(): bool |
|
465 | |||
466 | /** |
||
467 | * @return bool |
||
468 | */ |
||
469 | 25 | public function isDoRemoveValueFromEmptyInput(): bool |
|
473 | |||
474 | /** |
||
475 | * @return bool |
||
476 | */ |
||
477 | 25 | public function isDoRemoveEmptyAttributes(): bool |
|
481 | |||
482 | /** |
||
483 | * @return bool |
||
484 | */ |
||
485 | public function isDoSumUpWhitespace(): bool |
||
489 | |||
490 | /** |
||
491 | * @return bool |
||
492 | */ |
||
493 | public function isDoRemoveSpacesBetweenTags(): bool |
||
497 | |||
498 | /** |
||
499 | * @return bool |
||
500 | */ |
||
501 | public function isDoOptimizeViaHtmlDomParser(): bool |
||
505 | |||
506 | /** |
||
507 | * @return bool |
||
508 | */ |
||
509 | public function isDoOptimizeAttributes(): bool |
||
513 | |||
514 | /** |
||
515 | * @return bool |
||
516 | */ |
||
517 | public function isDoRemoveComments(): bool |
||
521 | |||
522 | /** |
||
523 | * @return bool |
||
524 | */ |
||
525 | public function isDoRemoveWhitespaceAroundTags(): bool |
||
529 | |||
530 | /** |
||
531 | * @return bool |
||
532 | */ |
||
533 | public function isDoRemoveOmittedQuotes(): bool |
||
537 | |||
538 | /** |
||
539 | * @return bool |
||
540 | */ |
||
541 | public function isDoRemoveOmittedHtmlTags(): bool |
||
545 | |||
546 | /** |
||
547 | * @return bool |
||
548 | */ |
||
549 | 25 | public function isDoRemoveHttpPrefixFromAttributes(): bool |
|
553 | |||
554 | /** |
||
555 | * @return array |
||
556 | */ |
||
557 | public function getDomainsToRemoveHttpPrefixFromAttributes(): array |
||
561 | |||
562 | /** |
||
563 | * @param bool $doRemoveOmittedHtmlTags |
||
564 | * |
||
565 | * @return $this |
||
566 | */ |
||
567 | 1 | public function doRemoveOmittedHtmlTags(bool $doRemoveOmittedHtmlTags = true): self |
|
573 | |||
574 | /** |
||
575 | * @param bool $doRemoveOmittedQuotes |
||
576 | * |
||
577 | * @return $this |
||
578 | */ |
||
579 | 1 | public function doRemoveOmittedQuotes(bool $doRemoveOmittedQuotes = true): self |
|
585 | |||
586 | /** |
||
587 | * @param bool $doRemoveSpacesBetweenTags |
||
588 | * |
||
589 | * @return $this |
||
590 | */ |
||
591 | public function doRemoveSpacesBetweenTags(bool $doRemoveSpacesBetweenTags = true): self |
||
597 | |||
598 | /** |
||
599 | * @param bool $doRemoveValueFromEmptyInput |
||
600 | * |
||
601 | * @return $this |
||
602 | */ |
||
603 | 2 | public function doRemoveValueFromEmptyInput(bool $doRemoveValueFromEmptyInput = true): self |
|
609 | |||
610 | /** |
||
611 | * @param bool $doRemoveWhitespaceAroundTags |
||
612 | * |
||
613 | * @return $this |
||
614 | */ |
||
615 | 4 | public function doRemoveWhitespaceAroundTags(bool $doRemoveWhitespaceAroundTags = true): self |
|
621 | |||
622 | /** |
||
623 | * @param bool $doSortCssClassNames |
||
624 | * |
||
625 | * @return $this |
||
626 | */ |
||
627 | 2 | public function doSortCssClassNames(bool $doSortCssClassNames = true): self |
|
633 | |||
634 | /** |
||
635 | * @param bool $doSortHtmlAttributes |
||
636 | * |
||
637 | * @return $this |
||
638 | */ |
||
639 | 2 | public function doSortHtmlAttributes(bool $doSortHtmlAttributes = true): self |
|
645 | |||
646 | /** |
||
647 | * @param bool $doSumUpWhitespace |
||
648 | * |
||
649 | * @return $this |
||
650 | */ |
||
651 | 2 | public function doSumUpWhitespace(bool $doSumUpWhitespace = true): self |
|
657 | |||
658 | 41 | private function domNodeAttributesToString(\DOMNode $node): string |
|
715 | |||
716 | /** |
||
717 | * @param \DOMNode $node |
||
718 | * |
||
719 | * @return bool |
||
720 | */ |
||
721 | 40 | private function domNodeClosingTagOptional(\DOMNode $node): bool |
|
940 | |||
941 | 41 | protected function domNodeToString(\DOMNode $node): string |
|
1028 | |||
1029 | /** |
||
1030 | * @param \DOMNode $node |
||
1031 | * |
||
1032 | * @return \DOMNode|null |
||
1033 | */ |
||
1034 | 40 | protected function getNextSiblingOfTypeDOMElement(\DOMNode $node) |
|
1042 | |||
1043 | /** |
||
1044 | * Check if the current string is an conditional comment. |
||
1045 | * |
||
1046 | * INFO: since IE >= 10 conditional comment are not working anymore |
||
1047 | * |
||
1048 | * <!--[if expression]> HTML <![endif]--> |
||
1049 | * <![if expression]> HTML <![endif]> |
||
1050 | * |
||
1051 | * @param string $comment |
||
1052 | * |
||
1053 | * @return bool |
||
1054 | */ |
||
1055 | 4 | private function isConditionalComment($comment): bool |
|
1067 | |||
1068 | /** |
||
1069 | * @param string $html |
||
1070 | * @param bool $decodeUtf8Specials <p>Use this only in special cases, e.g. for PHP 5.3</p> |
||
1071 | * |
||
1072 | * @return string |
||
1073 | */ |
||
1074 | 45 | public function minify($html, $decodeUtf8Specials = false): string |
|
1075 | { |
||
1076 | 45 | $html = (string) $html; |
|
1077 | 45 | if (!isset($html[0])) { |
|
1078 | 1 | return ''; |
|
1079 | } |
||
1080 | |||
1081 | 45 | $html = \trim($html); |
|
1082 | 45 | if (!$html) { |
|
1083 | 3 | return ''; |
|
1084 | } |
||
1085 | |||
1086 | // init |
||
1087 | 42 | static $CACHE_SELF_CLOSING_TAGS = null; |
|
1088 | 42 | if ($CACHE_SELF_CLOSING_TAGS === null) { |
|
1089 | 1 | $CACHE_SELF_CLOSING_TAGS = \implode('|', self::$selfClosingTags); |
|
1090 | } |
||
1091 | |||
1092 | // reset |
||
1093 | 42 | $this->protectedChildNodes = []; |
|
1094 | |||
1095 | // save old content |
||
1096 | 42 | $origHtml = $html; |
|
1097 | 42 | $origHtmlLength = \strlen($html); |
|
1098 | |||
1099 | // ------------------------------------------------------------------------- |
||
1100 | // Minify the HTML via "HtmlDomParser" |
||
1101 | // ------------------------------------------------------------------------- |
||
1102 | |||
1103 | 42 | if ($this->doOptimizeViaHtmlDomParser) { |
|
1104 | 41 | $html = $this->minifyHtmlDom($html, $decodeUtf8Specials); |
|
1105 | } |
||
1106 | |||
1107 | // ------------------------------------------------------------------------- |
||
1108 | // Trim whitespace from html-string. [protected html is still protected] |
||
1109 | // ------------------------------------------------------------------------- |
||
1110 | |||
1111 | // Remove extra white-space(s) between HTML attribute(s) |
||
1112 | 42 | $html = (string) \preg_replace_callback( |
|
1113 | 42 | '#<([^/\s<>!]+)(?:\s+([^<>]*?)\s*|\s*)(/?)>#', |
|
1114 | 42 | function ($matches) { |
|
1115 | 42 | return '<' . $matches[1] . (string) \preg_replace('#([^\s=]+)(\=([\'"]?)(.*?)\3)?(\s+|$)#s', ' $1$2', $matches[2]) . $matches[3] . '>'; |
|
1116 | 42 | }, |
|
1117 | 42 | $html |
|
1118 | ); |
||
1119 | |||
1120 | 42 | if ($this->doRemoveSpacesBetweenTags) { |
|
1121 | // Remove spaces that are between > and < |
||
1122 | $html = (string) \preg_replace('/(>) (<)/', '>$2', $html); |
||
1123 | } |
||
1124 | |||
1125 | // ------------------------------------------------------------------------- |
||
1126 | // Restore protected HTML-code. |
||
1127 | // ------------------------------------------------------------------------- |
||
1128 | |||
1129 | 42 | $html = (string) \preg_replace_callback( |
|
1130 | 42 | '/<(?<element>' . $this->protectedChildNodesHelper . ')(?<attributes> [^>]*)?>(?<value>.*?)<\/' . $this->protectedChildNodesHelper . '>/', |
|
1131 | 42 | [$this, 'restoreProtectedHtml'], |
|
1132 | 42 | $html |
|
1133 | ); |
||
1134 | |||
1135 | // ------------------------------------------------------------------------- |
||
1136 | // Restore protected HTML-entities. |
||
1137 | // ------------------------------------------------------------------------- |
||
1138 | |||
1139 | 42 | if ($this->doOptimizeViaHtmlDomParser) { |
|
1140 | 41 | $html = HtmlDomParser::putReplacedBackToPreserveHtmlEntities($html); |
|
1141 | } |
||
1142 | |||
1143 | // ------------------------------------ |
||
1144 | // Final clean-up |
||
1145 | // ------------------------------------ |
||
1146 | |||
1147 | 42 | $html = \str_replace( |
|
1148 | [ |
||
1149 | 42 | 'html>' . "\n", |
|
1150 | "\n" . '<html', |
||
1151 | 'html/>' . "\n", |
||
1152 | "\n" . '</html', |
||
1153 | 'head>' . "\n", |
||
1154 | "\n" . '<head', |
||
1155 | 'head/>' . "\n", |
||
1156 | "\n" . '</head', |
||
1157 | ], |
||
1158 | [ |
||
1159 | 42 | 'html>', |
|
1160 | '<html', |
||
1161 | 'html/>', |
||
1162 | '</html', |
||
1163 | 'head>', |
||
1164 | '<head', |
||
1165 | 'head/>', |
||
1166 | '</head', |
||
1167 | ], |
||
1168 | 42 | $html |
|
1169 | ); |
||
1170 | |||
1171 | // self closing tags, don't need a trailing slash ... |
||
1172 | 42 | $replace = []; |
|
1173 | 42 | $replacement = []; |
|
1174 | 42 | foreach (self::$selfClosingTags as $selfClosingTag) { |
|
1175 | 42 | $replace[] = '<' . $selfClosingTag . '/>'; |
|
1176 | 42 | $replacement[] = '<' . $selfClosingTag . '>'; |
|
1177 | 42 | $replace[] = '<' . $selfClosingTag . ' />'; |
|
1178 | 42 | $replacement[] = '<' . $selfClosingTag . '>'; |
|
1179 | } |
||
1180 | 42 | $html = \str_replace( |
|
1181 | 42 | $replace, |
|
1182 | 42 | $replacement, |
|
1183 | 42 | $html |
|
1184 | ); |
||
1185 | |||
1186 | 42 | $html = (string) \preg_replace('#<\b(' . $CACHE_SELF_CLOSING_TAGS . ')([^>]*+)><\/\b\1>#', '<\\1\\2>', $html); |
|
1187 | |||
1188 | // ------------------------------------ |
||
1189 | // check if compression worked |
||
1190 | // ------------------------------------ |
||
1191 | |||
1192 | 42 | if ($origHtmlLength < \strlen($html)) { |
|
1193 | 3 | $html = $origHtml; |
|
1194 | } |
||
1195 | |||
1196 | 42 | return $html; |
|
1197 | } |
||
1198 | |||
1199 | /** |
||
1200 | * @param $html |
||
1201 | * @param $decodeUtf8Specials |
||
1202 | * |
||
1203 | * @return string |
||
1204 | */ |
||
1205 | 41 | private function minifyHtmlDom($html, $decodeUtf8Specials): string |
|
1269 | |||
1270 | /** |
||
1271 | * Prevent changes of inline "styles" and "scripts". |
||
1272 | * |
||
1273 | * @param HtmlDomParser $dom |
||
1274 | * |
||
1275 | * @return HtmlDomParser |
||
1276 | */ |
||
1277 | 41 | private function protectTags(HtmlDomParser $dom): HtmlDomParser |
|
1330 | |||
1331 | /** |
||
1332 | * Remove comments in the dom. |
||
1333 | * |
||
1334 | * @param HtmlDomParser $dom |
||
1335 | * |
||
1336 | * @return HtmlDomParser |
||
1337 | */ |
||
1338 | 39 | private function removeComments(HtmlDomParser $dom): HtmlDomParser |
|
1353 | |||
1354 | /** |
||
1355 | * Trim tags in the dom. |
||
1356 | * |
||
1357 | * @param SimpleHtmlDom $element |
||
1358 | * |
||
1359 | * @return void |
||
1360 | */ |
||
1361 | 3 | private function removeWhitespaceAroundTags(SimpleHtmlDom $element) |
|
1386 | |||
1387 | /** |
||
1388 | * Callback function for preg_replace_callback use. |
||
1389 | * |
||
1390 | * @param array $matches PREG matches |
||
1391 | * |
||
1392 | * @return string |
||
1393 | */ |
||
1394 | 6 | private function restoreProtectedHtml($matches): string |
|
1405 | |||
1406 | /** |
||
1407 | * @param array $domainsToRemoveHttpPrefixFromAttributes |
||
1408 | * |
||
1409 | * @return $this |
||
1410 | */ |
||
1411 | 2 | public function setDomainsToRemoveHttpPrefixFromAttributes($domainsToRemoveHttpPrefixFromAttributes): self |
|
1417 | |||
1418 | /** |
||
1419 | * Sum-up extra whitespace from dom-nodes. |
||
1420 | * |
||
1421 | * @param HtmlDomParser $dom |
||
1422 | * |
||
1423 | * @return HtmlDomParser |
||
1424 | */ |
||
1425 | 40 | private function sumUpWhitespace(HtmlDomParser $dom): HtmlDomParser |
|
1452 | |||
1453 | /** |
||
1454 | * WARNING: maybe bad for performance ... |
||
1455 | * |
||
1456 | * @param bool $keepBrokenHtml |
||
1457 | * |
||
1458 | * @return HtmlMin |
||
1459 | */ |
||
1460 | public function useKeepBrokenHtml(bool $keepBrokenHtml): self |
||
1466 | } |
||
1467 |
There are different options of fixing this problem.
If you want to be on the safe side, you can add an additional type-check:
If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:
Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.