PluginProbe
TablePress – Tables in WordPress made easy / 3.4
TablePress – Tables in WordPress made easy v3.4
3.4 3.3.4 3.3.3 3.3.2 3.3.1 trunk 1.12 1.14 1.9.2 2.0.4 2.1.7 2.1.8 2.2 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.3 2.3.1 2.3.2 2.4 2.4.1 2.4.2 2.4.3 All 45 releases
← All changes | libraries/csstidy/class.csstidy_optimise.php +181 -292 1.12 → 3.4 View file →
@@ -7,108 +7,71 @@
7 7 * @author Florian Schmitz, Brett Zamir, Nikolay Matsievsky, Cedric Morin, Christopher Finke, Mark Scherer, Tobias Bäthge
8 8 * @since 1.0.0
9 9 */
10 10
11 +declare(strict_types=1);
12 +
11 13 // Prohibit direct script loading.
12 14 defined( 'ABSPATH' ) || die( 'No direct script access allowed!' );
13 15
14 16 /**
15 - * CSSTidy - CSS Parser and Optimiser
16 - *
17 17 * CSS Optimising Class
18 - * This class optimises CSS data generated by CSSTidy.
19 18 *
20 - * Copyright 2005, 2006, 2007 Florian Schmitz
21 - *
22 - * This file is part of CSSTidy.
23 - *
24 - * CSSTidy is free software; you can redistribute it and/or modify
25 - * it under the terms of the GNU Lesser General Public License as published by
26 - * the Free Software Foundation; either version 2.1 of the License, or
27 - * (at your option) any later version.
28 - *
29 - * CSSTidy is distributed in the hope that it will be useful,
30 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
31 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32 - * GNU Lesser General Public License for more details.
33 - *
34 - * You should have received a copy of the GNU Lesser General Public License
35 - * along with this program. If not, see <https://www.gnu.org/licenses/>.
36 - *
37 - * @license https://opensource.org/licenses/lgpl-license.php GNU Lesser General Public License
38 - * @package CSSTidy
39 - * @author Florian Schmitz (floele at gmail dot com) 2005-2007
40 - * @author Brett Zamir (brettz9 at yahoo dot com) 2007
41 - * @author Nikolay Matsievsky (speed at webo dot name) 2009-2010
42 - * @author Cedric Morin (cedric at yterium dot com) 2010-2012
43 - */
44 -
45 -/**
46 - * CSS Optimising Class
47 - *
48 19 * This class optimises CSS data generated by CSSTidy.
49 20 *
50 21 * @package CSSTidy
51 - * @author Florian Schmitz (floele at gmail dot com) 2005-2006
52 22 * @version 1.0
53 23 */
54 -class TablePress_CSSTidy_optimise {
24 +class TablePress_CSSTidy_Optimise {
55 25
56 26 /**
57 - * CSSTidy instance.
27 + * TablePress_CSSTidy instance.
58 28 *
59 29 * @since 1.0.0
60 - * @var CSSTidy
61 30 */
62 - public $parser;
31 + public \TablePress_CSSTidy $parser;
63 32
64 33 /**
65 34 * The parsed CSS.
66 35 *
67 36 * @since 1.0.0
68 - * @var array
69 37 */
70 - public $css = array();
38 + public array $css = array();
71 39
72 40 /**
73 41 * The current sub-value.
74 42 *
75 43 * @since 1.0.0
76 - * @var string
77 44 */
78 - public $sub_value = '';
45 + public string $sub_value = '';
79 46
80 47 /**
81 48 * The current at rule (@media).
82 49 *
83 50 * @since 1.0.0
84 - * @var string
85 51 */
86 - public $at = '';
52 + public string $at = '';
87 53
88 54 /**
89 55 * The current selector.
90 56 *
91 57 * @since 1.0.0
92 - * @var string
93 58 */
94 - public $selector = '';
59 + public string $selector = '';
95 60
96 61 /**
97 62 * The current property.
98 63 *
99 64 * @since 1.0.0
100 - * @var string
101 65 */
102 - public $property = '';
66 + public string $property = '';
103 67
104 68 /**
105 69 * The current value.
106 70 *
107 71 * @since 1.0.0
108 - * @var string
109 72 */
110 - public $value = '';
73 + public string $value = '';
111 74
112 75 /**
113 76 * Constructor.
114 77 *
@@ -113,18 +76,18 @@
113 76 * Constructor.
114 77 *
115 78 * @since 1.0.0
116 79 *
117 - * @param CSSTidy $css Instance of the CSSTidy class.
80 + * @param TablePress_CSSTidy $csstidy Instance of the TablePress_CSSTidy class.
118 81 */
119 - public function __construct( $css ) {
120 - $this->parser = $css;
121 - $this->css = &$css->css;
122 - $this->sub_value = &$css->sub_value;
123 - $this->at = &$css->at;
124 - $this->selector = &$css->selector;
125 - $this->property = &$css->property;
126 - $this->value = &$css->value;
82 + public function __construct( TablePress_CSSTidy $csstidy ) {
83 + $this->parser = $csstidy;
84 + $this->css = &$csstidy->css;
85 + $this->sub_value = &$csstidy->sub_value;
86 + $this->at = &$csstidy->at;
87 + $this->selector = &$csstidy->selector;
88 + $this->property = &$csstidy->property;
89 + $this->value = &$csstidy->value;
127 90 }
128 91
129 92 /**
130 93 * Optimises $css after parsing.
@@ -130,9 +93,9 @@
130 93 * Optimises $css after parsing.
131 94 *
132 95 * @since 1.0.0
133 96 */
134 - public function postparse() {
97 + public function postparse(): void {
135 98 if ( $this->parser->get_cfg( 'preserve_css' ) ) {
136 99 return;
137 100 }
138 101
@@ -182,14 +145,14 @@
182 145 * Optimises values
183 146 *
184 147 * @since 1.0.0
185 148 */
186 - public function value() {
149 + public function value(): void {
187 150 $shorthands = &$this->parser->data['csstidy']['shorthands'];
188 151
189 152 // Optimise shorthand properties.
190 153 if ( isset( $shorthands[ $this->property ] ) && $this->parser->get_cfg( 'optimise_shorthands' ) > 0 ) {
191 - $temp = $this->shorthand( $this->value ); // FIXME - move
154 + $temp = $this->shorthand( $this->value ); // FIXME - move.
192 155 if ( $temp !== $this->value ) {
193 156 $this->parser->log( 'Optimised shorthand notation (' . $this->property . '): Changed "' . $this->value . '" to "' . $temp . '"', 'Information' );
194 157 }
195 158 $this->value = $temp;
@@ -194,9 +157,9 @@
194 157 }
195 158 $this->value = $temp;
196 159 }
197 160
198 - // Remove whitespace at !important
161 + // Remove whitespace at !important.
199 162 if ( $this->value !== $this->compress_important( $this->value ) ) {
200 163 $this->parser->log( 'Optimised !important', 'Information' );
201 164 }
202 165 }
@@ -205,9 +168,9 @@
205 168 * Optimises shorthands.
206 169 *
207 170 * @since 1.0.0
208 171 */
209 - public function shorthands() {
172 + public function shorthands(): void {
210 173 $shorthands = &$this->parser->data['csstidy']['shorthands'];
211 174
212 175 if ( ! $this->parser->get_cfg( 'optimise_shorthands' ) || $this->parser->get_cfg( 'preserve_css' ) ) {
213 176 return;
@@ -233,13 +196,13 @@
233 196 * Optimises a sub-value.
234 197 *
235 198 * @since 1.0.0
236 199 */
237 - public function subvalue() {
200 + public function subvalue(): void {
238 201 $replace_colors = &$this->parser->data['csstidy']['replace_colors'];
239 202
240 203 $this->sub_value = trim( $this->sub_value );
241 - if ( '' === $this->sub_value ) { // caution : '0'
204 + if ( '' === $this->sub_value ) { // caution : '0'.
242 205 return;
243 206 }
244 207
245 208 $important = '';
@@ -291,9 +254,9 @@
291 254 *
292 255 * @param string $value Shorthand value.
293 256 * @return string Compressed value.
294 257 */
295 - public function shorthand( $value ) {
258 + public function shorthand( string $value ): string {
296 259 $important = '';
297 260 if ( $this->parser->is_important( $value ) ) {
298 261 $values = $this->parser->gvw_important( $value );
299 262 $important = ' !important';
@@ -333,16 +296,16 @@
333 296 * Removes unnecessary whitespace in ! important.
334 297 *
335 298 * @since 1.0.0
336 299 *
337 - * @param string $string String.
300 + * @param string $a_string String.
338 301 * @return string Cleaned string.
339 302 */
340 - public function compress_important( &$string ) {
341 - if ( $this->parser->is_important( $string ) ) {
342 - $string = $this->parser->gvw_important( $string ) . ' !important';
303 + public function compress_important( string &$a_string ): string {
304 + if ( $this->parser->is_important( $a_string ) ) {
305 + $a_string = $this->parser->gvw_important( $a_string ) . ' !important';
343 306 }
344 - return $string;
307 + return $a_string;
345 308 }
346 309
347 310 /**
348 311 * Color compression function. Converts all rgb() values to #-values and uses the short-form if possible. Also replaces 4 color names by #-values.
@@ -351,23 +314,23 @@
351 314 *
352 315 * @param string $color Color value.
353 316 * @return string Compressed color.
354 317 */
355 - public function cut_color( $color ) {
318 + public function cut_color( string $color ): string {
356 319 $replace_colors = &$this->parser->data['csstidy']['replace_colors'];
357 320
358 - // If it's a string, don't touch!
359 - if ( 0 === strncmp( $color, "'", 1 ) || 0 === strncmp( $color, '"', 1 ) ) {
321 + // If it's a string, don't touch it!
322 + if ( str_starts_with( $color, "'" ) || str_starts_with( $color, '"' ) ) {
360 323 return $color;
361 324 }
362 325
363 - // Complex gradient expressions
364 - if ( false !== strpos( $color, '(' ) && 0 !== strncmp( $color, 'rgb(', 4 ) ) {
365 - // Don't touch properties within MSIE filters, those are to sensitive.
326 + // Complex gradient expressions.
327 + if ( str_contains( $color, '(' ) && 0 !== strncasecmp( $color, 'rgb(', 4 ) && 0 !== strncasecmp( $color, 'rgba(', 5 ) ) {
328 + // Don't touch properties within MSIE filters, those are too sensitive.
366 329 if ( false !== stripos( $color, 'progid:' ) ) {
367 330 return $color;
368 331 }
369 - preg_match_all( ',rgb\([^)]+\),i', $color, $matches, PREG_SET_ORDER );
332 + preg_match_all( ',rgba?\([^)]+\),i', $color, $matches, PREG_SET_ORDER );
370 333 if ( count( $matches ) ) {
371 334 foreach ( $matches as $m ) {
372 335 $color = str_replace( $m[0], $this->cut_color( $m[0] ), $color );
373 336 }
@@ -380,27 +343,50 @@
380 343 }
381 344 return $color;
382 345 }
383 346
384 - // rgb(0,0,0) -> #000000 (or #000 in this case later)
385 - if ( 0 === strncasecmp( $color, 'rgb(', 4 ) ) {
386 - $color_tmp = substr( $color, 4, strlen( $color ) - 5 );
387 - $color_tmp = explode( ',', $color_tmp );
388 - for ( $i = 0; $i < count( $color_tmp ); $i++ ) {
389 - $color_tmp[ $i ] = trim( $color_tmp[ $i ] );
390 - if ( '%' === substr( $color_tmp[ $i ], -1 ) ) {
391 - $color_tmp[ $i ] = round( ( 255 * $color_tmp[ $i ] ) / 100 );
347 + // rgb(0,0,0) -> #000000 (or #000 in this case later).
348 + if (
349 + // Be sure to not corrupt a rgb with calc() value.
350 + ( 0 === strncasecmp( $color, 'rgb(', 4 ) && false === strpos( $color, '(', 4 ) ) || ( 0 === strncasecmp( $color, 'rgba(', 5 ) && false === strpos( $color, '(', 5 ) )
351 + ) {
352 + $color_tmp = explode( '(', $color, 2 );
353 + $color_tmp = rtrim( end( $color_tmp ), ')' );
354 + if ( str_contains( $color_tmp, '/' ) ) {
355 + $color_tmp = explode( '/', $color_tmp, 2 );
356 + $color_parts = explode( ' ', trim( reset( $color_tmp ) ), 3 );
357 + while ( count( $color_parts ) < 3 ) { // phpcs:ignore Squiz.PHP.DisallowSizeFunctionsInLoops.Found
358 + $color_parts[] = 0;
392 359 }
393 - if ( $color_tmp[ $i ] > 255 ) {
394 - $color_tmp[ $i ] = 255;
360 + $color_parts[] = end( $color_tmp );
361 + } else {
362 + $color_parts = explode( ',', $color_tmp, 4 );
363 + }
364 + $color_parts_count = count( $color_parts );
365 + for ( $i = 0; $i < $color_parts_count; $i++ ) {
366 + $color_parts[ $i ] = trim( $color_parts[ $i ] );
367 + if ( str_ends_with( $color_parts[ $i ], '%' ) ) {
368 + $color_parts[ $i ] = round( ( 255 * intval( $color_parts[ $i ] ) ) / 100 );
369 + } elseif ( $i > 2 ) {
370 + // 4th argument is alpha layer between 0 and 1 (if not %).
371 + $color_parts[ $i ] = round( 255 * floatval( $color_parts[ $i ] ) );
395 372 }
373 + $color_parts[ $i ] = intval( $color_parts[ $i ] );
374 + if ( $color_parts[ $i ] > 255 ) {
375 + $color_parts[ $i ] = 255;
376 + }
396 377 }
397 378 $color = '#';
398 - for ( $i = 0; $i < 3; $i++ ) {
399 - if ( $color_tmp[ $i ] < 16 ) {
400 - $color .= '0' . dechex( $color_tmp[ $i ] );
379 + // 3 or 4 parts depending on alpha layer.
380 + $nb = min( max( count( $color_parts ), 3 ), 4 );
381 + for ( $i = 0; $i < $nb; $i++ ) {
382 + if ( ! isset( $color_parts[ $i ] ) ) {
383 + $color_parts[ $i ] = 0;
384 + }
385 + if ( $color_parts[ $i ] < 16 ) {
386 + $color .= '0' . dechex( $color_parts[ $i ] );
401 387 } else {
402 - $color .= dechex( $color_tmp[ $i ] );
388 + $color .= dechex( $color_parts[ $i ] );
403 389 }
404 390 }
405 391 }
406 392
@@ -408,14 +394,20 @@
408 394 if ( isset( $replace_colors[ strtolower( $color ) ] ) ) {
409 395 $color = $replace_colors[ strtolower( $color ) ];
410 396 }
411 397
412 - // #aabbcc -> #abc
413 398 if ( 7 === strlen( $color ) ) {
399 + // #aabbcc -> #abc
414 400 $color_temp = strtolower( $color );
415 401 if ( '#' === $color_temp[0] && $color_temp[1] === $color_temp[2] && $color_temp[3] === $color_temp[4] && $color_temp[5] === $color_temp[6] ) {
416 402 $color = '#' . $color[1] . $color[3] . $color[5];
417 403 }
404 + } elseif ( 9 === strlen( $color ) ) {
405 + // #aabbccdd -> #abcd
406 + $color_temp = strtolower( $color );
407 + if ( '#' === $color_temp[0] && $color_temp[1] === $color_temp[2] && $color_temp[3] === $color_temp[4] && $color_temp[5] === $color_temp[6] && $color_temp[7] === $color_temp[8] ) {
408 + $color = '#' . $color[1] . $color[3] . $color[5] . $color[7];
409 + }
418 410 }
419 411
420 412 switch ( strtolower( $color ) ) {
421 413 /* color name -> hex code */
@@ -461,13 +453,13 @@
461 453 *
462 454 * @param string $subvalue Value.
463 455 * @return string Compressed value.
464 456 */
465 - public function compress_numbers( $subvalue ) {
457 + public function compress_numbers( string $subvalue ): string {
466 458 $unit_values = &$this->parser->data['csstidy']['unit_values'];
467 459 $color_values = &$this->parser->data['csstidy']['color_values'];
468 460
469 - // for font:1em/1em sans-serif...;
461 + // for font:1em/1em sans-serif...;.
470 462 if ( 'font' === $this->property ) {
471 463 $temp = explode( '/', $subvalue );
472 464 } else {
473 465 $temp = array( $subvalue );
@@ -472,17 +464,18 @@
472 464 } else {
473 465 $temp = array( $subvalue );
474 466 }
475 467
476 - for ( $l = 0; $l < count( $temp ); $l++ ) {
468 + $temp_count = count( $temp );
469 + for ( $l = 0; $l < $temp_count; $l++ ) {
477 470 // If we are not dealing with a number at this point, do not optimize anything.
478 - $number = $this->AnalyseCssNumber( $temp[ $l ] );
471 + $number = $this->analyse_css_number( $temp[ $l ] );
479 472 if ( false === $number ) {
480 473 return $subvalue;
481 474 }
482 475
483 476 // Fix bad colors.
484 - if ( in_array( $this->property, $color_values ) ) {
477 + if ( in_array( $this->property, $color_values, true ) ) {
485 478 if ( 3 === strlen( $temp[ $l ] ) || 6 === strlen( $temp[ $l ] ) ) {
486 479 $temp[ $l ] = '#' . $temp[ $l ];
487 480 } else {
488 481 $temp[ $l ] = '0';
@@ -508,14 +501,14 @@
508 501 * Checks if a given string is a CSS valid number. If it is, an array containing the value and unit is returned.
509 502 *
510 503 * @since 1.0.0
511 504 *
512 - * @param string $string String.
513 - * @return array ('unit' if unit is found or '' if no unit exists, number value) or false if no number.
505 + * @param string $a_string String.
506 + * @return array{int|string, string}|false ('unit' if unit is found or '' if no unit exists, number value) or false if no number.
514 507 */
515 - public function analyseCssNumber( $string ) {
516 - // most simple checks first
517 - if ( 0 === strlen( $string ) || ctype_alpha( $string[0] ) ) {
508 + public function analyse_css_number( string $a_string ) /* : array|false */ {
509 + // Most simple checks first.
510 + if ( 0 === strlen( $a_string ) || ctype_alpha( $a_string[0] ) ) {
518 511 return false;
519 512 }
520 513
521 514 $units = &$this->parser->data['csstidy']['units'];
@@ -520,31 +513,31 @@
520 513
521 514 $units = &$this->parser->data['csstidy']['units'];
522 515 $return = array( 0, '' );
523 516
524 - $return[0] = floatval( $string );
517 + $return[0] = (float) $a_string;
525 518 if ( abs( $return[0] ) > 0 && abs( $return[0] ) < 1 ) {
526 519 if ( $return[0] < 0 ) {
527 - $return[0] = '-' . ltrim( substr( $return[0], 1 ), '0' );
520 + $return[0] = '-' . ltrim( substr( (string) $return[0], 1 ), '0' );
528 521 } else {
529 - $return[0] = ltrim( $return[0], '0' );
522 + $return[0] = ltrim( (string) $return[0], '0' );
530 523 }
531 524 }
532 525
533 - // Look for unit and split from value if exists
526 + // Look for unit and split from value if exists.
534 527 foreach ( $units as $unit ) {
535 - $expectUnitAt = strlen( $string ) - strlen( $unit );
536 - if ( ! ( $unitInString = stristr( $string, $unit ) ) ) { // mb_strpos() fails with "false"
528 + $expect_unit_at = strlen( $a_string ) - strlen( $unit );
529 + if ( ! ( $unit_in_string = stristr( $a_string, $unit ) ) ) { // phpcs:ignore Generic.CodeAnalysis.AssignmentInCondition.Found,Squiz.PHP.DisallowMultipleAssignments.FoundInControlStructure
537 530 continue;
538 531 }
539 - $actualPosition = strpos( $string, $unitInString );
540 - if ( $expectUnitAt === $actualPosition ) {
532 + $actual_position = strpos( $a_string, $unit_in_string );
533 + if ( $expect_unit_at === $actual_position ) {
541 534 $return[1] = $unit;
542 - $string = substr( $string, 0, - strlen( $unit ) );
535 + $a_string = substr( $a_string, 0, - strlen( $unit ) );
543 536 break;
544 537 }
545 538 }
546 - if ( ! is_numeric( $string ) ) {
539 + if ( ! is_numeric( $a_string ) ) {
547 540 return false;
548 541 }
549 542 return $return;
550 543 }
@@ -554,13 +547,12 @@
554 547 * Very basic and has at least one bug. Hopefully there is a replacement soon.
555 548 *
556 549 * @since 1.0.0
557 550 *
558 - * @param array $array
559 - * @return array
551 + * @param array<string, mixed> $an_array List of selectors. This parameter is modified by reference.
560 552 */
561 - public function merge_selectors( array &$array ) {
562 - $css = $array;
553 + public function merge_selectors( array &$an_array ): void {
554 + $css = $an_array;
563 555 foreach ( $css as $key => $value ) {
564 556 if ( ! isset( $css[ $key ] ) ) {
565 557 continue;
566 558 }
@@ -566,9 +558,9 @@
566 558 }
567 559
568 560 // Check if properties also exist in another selector.
569 561 $keys = array();
570 - // PHP bug (?) without $css = $array; here
562 + // PHP bug (?) without $css = $an_array; here.
571 563 foreach ( $css as $selector => $vali ) {
572 564 if ( $selector === $key ) {
573 565 continue;
574 566 }
@@ -587,9 +579,9 @@
587 579 }
588 580 $css[ $newsel ] = $value;
589 581 }
590 582 }
591 - $array = $css;
583 + $an_array = $css;
592 584 }
593 585
594 586 /**
595 587 * Removes invalid selectors and their corresponding rule-sets as
@@ -598,12 +590,12 @@
598 590 * regular expression.
599 591 *
600 592 * @since 1.0.0
601 593 *
602 - * @param [type] $array [description]
594 + * @param array<string, mixed> $an_array [description].
603 595 */
604 - public function discard_invalid_selectors( &$array ) {
605 - foreach ( $array as $selector => $decls ) {
596 + public function discard_invalid_selectors( array &$an_array ): void {
597 + foreach ( $an_array as $selector => $decls ) {
606 598 $ok = true;
607 599 $selectors = array_map( 'trim', explode( ',', $selector ) );
608 600 foreach ( $selectors as $s ) {
609 601 $simple_selectors = preg_split( '/\s*[+>~\s]\s*/', $s );
@@ -610,14 +602,13 @@
610 602 foreach ( $simple_selectors as $ss ) {
611 603 if ( '' === $ss ) {
612 604 $ok = false;
613 605 }
614 - // could also check $ss for internal structure,
615 - // but that probably would be too slow
606 + // Could also check $ss for internal structure, but that probably would be too slow.
616 607 }
617 608 }
618 609 if ( ! $ok ) {
619 - unset( $array[ $selector ] );
610 + unset( $an_array[ $selector ] );
620 611 }
621 612 }
622 613 }
623 614
@@ -625,14 +616,13 @@
625 616 * Dissolves properties like padding:10px 10px 10px to padding-top:10px;padding-bottom:10px;...
626 617 *
627 618 * @since 1.0.0
628 619 *
629 - * @param string $property [description]
630 - * @param string $value [description]
631 - *
632 - * @return [type] [description]
620 + * @param string $property [description].
621 + * @param string $value [description].
622 + * @return array [description]
633 623 */
634 - public function dissolve_4value_shorthands( $property, $value ) {
624 + public function dissolve_4value_shorthands( string $property, string $value ): array {
635 625 $return = array();
636 626
637 627 $shorthands = &$this->parser->data['csstidy']['shorthands'];
638 628 if ( ! is_array( $shorthands[ $property ] ) ) {
@@ -673,37 +663,37 @@
673 663 * Explodes a string as explode() does, however, not if $sep is escaped or within a string.
674 664 *
675 665 * @since 1.0.0
676 666 *
677 - * @param string $sep Separator.
678 - * @param string $string String.
679 - * @return array
667 + * @param string $sep Separator.
668 + * @param string $a_string String.
669 + * @return array [description]
680 670 */
681 - public function explode_ws( $sep, $string ) {
671 + public function explode_ws( string $sep, string $a_string ): array {
682 672 $status = 'st';
683 673 $to = '';
684 674
685 675 $output = array();
686 676 $num = 0;
687 - for ( $i = 0, $len = strlen( $string ); $i < $len; $i++ ) {
677 + for ( $i = 0, $len = strlen( $a_string ); $i < $len; $i++ ) {
688 678 switch ( $status ) {
689 679 case 'st':
690 - if ( $string[ $i ] === $sep && ! $this->parser->escaped( $string, $i ) ) {
680 + if ( $a_string[ $i ] === $sep && ! $this->parser->escaped( $a_string, $i ) ) {
691 681 ++$num;
692 - } elseif ( '"' === $string[ $i ] || "'" === $string[ $i ] || '(' === $string[ $i ] && ! $this->parser->escaped( $string, $i ) ) {
682 + } elseif ( '"' === $a_string[ $i ] || "'" === $a_string[ $i ] || ( '(' === $a_string[ $i ] && ! $this->parser->escaped( $a_string, $i ) ) ) {
693 683 $status = 'str';
694 - $to = ( '(' === $string[ $i ] ) ? ')' : $string[ $i ];
695 - ( isset( $output[ $num ] ) ) ? $output[ $num ] .= $string[ $i ] : $output[ $num ] = $string[ $i ];
684 + $to = ( '(' === $a_string[ $i ] ) ? ')' : $a_string[ $i ];
685 + ( isset( $output[ $num ] ) ) ? $output[ $num ] .= $a_string[ $i ] : $output[ $num ] = $a_string[ $i ];
696 686 } else {
697 - ( isset( $output[ $num ] ) ) ? $output[ $num ] .= $string[ $i ] : $output[ $num ] = $string[ $i ];
687 + ( isset( $output[ $num ] ) ) ? $output[ $num ] .= $a_string[ $i ] : $output[ $num ] = $a_string[ $i ];
698 688 }
699 689 break;
700 690
701 691 case 'str':
702 - if ( $string[ $i ] === $to && ! $this->parser->escaped( $string, $i ) ) {
692 + if ( $a_string[ $i ] === $to && ! $this->parser->escaped( $a_string, $i ) ) {
703 693 $status = 'st';
704 694 }
705 - ( isset( $output[ $num ] ) ) ? $output[ $num ] .= $string[ $i ] : $output[ $num ] = $string[ $i ];
695 + ( isset( $output[ $num ] ) ) ? $output[ $num ] .= $a_string[ $i ] : $output[ $num ] = $a_string[ $i ];
706 696 break;
707 697 }
708 698 }
709 699
@@ -718,23 +708,22 @@
718 708 * Merges Shorthand properties again, the opposite of dissolve_4value_shorthands().
719 709 *
720 710 * @since 1.0.0
721 711 *
722 - * @param [type] $array [description]
723 - * @return [type] [description]
712 + * @param array<string, mixed> $an_array [description].
713 + * @return array<string, mixed> [description]
724 714 */
725 - public function merge_4value_shorthands( $array ) {
726 - $return = $array;
715 + public function merge_4value_shorthands( array $an_array ): array {
716 + $return = $an_array;
727 717 $shorthands = &$this->parser->data['csstidy']['shorthands'];
728 718
729 719 foreach ( $shorthands as $key => $value ) {
730 - if ( isset( $array[ $value[0] ] ) && isset( $array[ $value[1] ] )
731 - && isset( $array[ $value[2] ] ) && isset( $array[ $value[3] ] ) && 0 !== $value ) {
720 + if ( 0 !== $value && isset( $an_array[ $value[0] ], $an_array[ $value[1] ], $an_array[ $value[2] ], $an_array[ $value[3] ] ) ) {
732 721 $return[ $key ] = '';
733 722
734 723 $important = '';
735 724 for ( $i = 0; $i < 4; $i++ ) {
736 - $val = $array[ $value[ $i ] ];
725 + $val = $an_array[ $value[ $i ] ];
737 726 if ( $this->parser->is_important( $val ) ) {
738 727 $important = ' !important';
739 728 $return[ $key ] .= $this->parser->gvw_important( $val ) . ' ';
740 729 } else {
@@ -750,17 +739,17 @@
750 739
751 740 /**
752 741 * Dissolve background property.
753 742 *
754 - * @TODO Full CSS3 compliance.
743 + * @todo Full CSS3 compliance.
755 744 *
756 745 * @since 1.0.0
757 746 *
758 747 * @param string $str_value String value.
759 - * @return array Array.
748 + * @return array<string, string|null> Array.
760 749 */
761 - public function dissolve_short_bg( $str_value ) {
762 - // Don't try to explose background gradient!
750 + public function dissolve_short_bg( string $str_value ): array {
751 + // Don't try to explode background gradient!
763 752 if ( false !== stripos( $str_value, 'gradient(' ) ) {
764 753 return array( 'background' => $str_value );
765 754 }
766 755
@@ -788,9 +777,10 @@
788 777 }
789 778
790 779 $have = array();
791 780 $str_value = $this->explode_ws( ',', $str_value );
792 - for ( $i = 0; $i < count( $str_value ); $i++ ) {
781 + $str_value_count = count( $str_value );
782 + for ( $i = 0; $i < $str_value_count; $i++ ) {
793 783 $have['clip'] = false;
794 784 $have['pos'] = false;
795 785 $have['color'] = false;
796 786 $have['bg'] = false;
@@ -799,10 +789,11 @@
799 789 $str_value[ $i ] = $str_value[ $i ][0];
800 790 }
801 791 $str_value[ $i ] = $this->explode_ws( ' ', trim( $str_value[ $i ] ) );
802 792
803 - for ( $j = 0; $j < count( $str_value[ $i ] ); $j++ ) {
804 - if ( false === $have['bg'] && ( 'url(' === substr( $str_value[ $i ][ $j ], 0, 4 ) || 'none' === $str_value[ $i ][ $j ] ) ) {
793 + $str_value_i_count = count( $str_value[ $i ] );
794 + for ( $j = 0; $j < $str_value_i_count; $j++ ) {
795 + if ( false === $have['bg'] && ( str_starts_with( $str_value[ $i ][ $j ], 'url(' ) || 'none' === $str_value[ $i ][ $j ] ) ) {
805 796 $return['background-image'] .= $str_value[ $i ][ $j ] . ',';
806 797 $have['bg'] = true;
807 798 } elseif ( in_array( $str_value[ $i ][ $j ], $repeat, true ) ) {
808 799 $return['background-repeat'] .= $str_value[ $i ][ $j ] . ',';
@@ -814,9 +805,9 @@
814 805 } elseif ( in_array( $str_value[ $i ][ $j ], $origin, true ) ) {
815 806 $return['background-origin'] .= $str_value[ $i ][ $j ] . ',';
816 807 } elseif ( '(' === $str_value[ $i ][ $j ][0] ) {
817 808 $return['background-size'] .= substr( $str_value[ $i ][ $j ], 1, -1 ) . ',';
818 - } elseif ( in_array( $str_value[ $i ][ $j ], $pos, true ) || is_numeric( $str_value[ $i ][ $j ][0] ) || null === $str_value[ $i ][ $j ][0] || '-' === $str_value[ $i ][ $j ][0] || '.' === $str_value[ $i ][ $j ][0] ) {
809 + } elseif ( in_array( $str_value[ $i ][ $j ], $pos, true ) || is_numeric( $str_value[ $i ][ $j ][0] ) || is_null( $str_value[ $i ][ $j ][0] ) || '-' === $str_value[ $i ][ $j ][0] || '.' === $str_value[ $i ][ $j ][0] ) {
819 810 $return['background-position'] .= $str_value[ $i ][ $j ];
820 811 if ( ! $have['pos'] ) {
821 812 $return['background-position'] .= ' ';
822 813 } else {
@@ -842,21 +833,21 @@
842 833
843 834 /**
844 835 * Merges all background properties.
845 836 *
846 - * @TODO Full CSS3 compliance.
837 + * @todo Full CSS3 compliance.
847 838 *
848 839 * @since 1.0.0
849 840 *
850 - * @param array $input_css CSS.
851 - * @return array Array.
841 + * @param array<string, mixed> $input_css CSS.
842 + * @return array<string, mixed> Array.
852 843 */
853 - public function merge_bg( array $input_css ) {
844 + public function merge_bg( array $input_css ): array {
854 845 $background_prop_default = &$this->parser->data['csstidy']['background_prop_default'];
855 846 // Max number of background images. CSS3 not yet fully implemented.
856 - $number_of_values = @max( count( $this->explode_ws( ',', $input_css['background-image'] ) ), count( $this->explode_ws( ',', $input_css['background-color'] ) ), 1 );
847 + $number_of_values = @max( count( $this->explode_ws( ',', $input_css['background-image'] ) ), count( $this->explode_ws( ',', $input_css['background-color'] ) ), 1 ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
857 848 // Array with background images to check if BG image exists.
858 - $bg_img_array = @$this->explode_ws( ',', $this->parser->gvw_important( $input_css['background-image'] ) );
849 + $bg_img_array = @$this->explode_ws( ',', $this->parser->gvw_important( $input_css['background-image'] ) ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
859 850 $new_bg_value = '';
860 851 $important = '';
861 852
862 853 // If background properties is here and not empty, don't try anything.
@@ -930,12 +921,12 @@
930 921 * Dissolve font property.
931 922 *
932 923 * @since 1.0.0
933 924 *
934 - * @param [type] $str_value [description]
935 - * @return [type] [description]
925 + * @param string $str_value [description].
926 + * @return array<string, string|null> [description]
936 927 */
937 - public function dissolve_short_font( $str_value ) {
928 + public function dissolve_short_font( string $str_value ): array {
938 929 $font_prop_default = &$this->parser->data['csstidy']['font_prop_default'];
939 930 $font_weight = array( 'normal', 'bold', 'bolder', 'lighter', 100, 200, 300, 400, 500, 600, 700, 800, 900 );
940 931 $font_variant = array( 'normal', 'small-caps' );
941 932 $font_style = array( 'normal', 'italic', 'oblique' );
@@ -966,19 +957,20 @@
966 957 $str_value = $this->explode_ws( ',', trim( $str_value ) );
967 958
968 959 $str_value[0] = $this->explode_ws( ' ', trim( $str_value[0] ) );
969 960
970 - for ( $j = 0; $j < count( $str_value[0] ); $j++ ) {
971 - if ( false === $have['weight'] && in_array( $str_value[0][ $j ], $font_weight ) ) {
961 + $str_value_0_count = count( $str_value[0] );
962 + for ( $j = 0; $j < $str_value_0_count; $j++ ) {
963 + if ( false === $have['weight'] && in_array( $str_value[0][ $j ], $font_weight, false ) ) { // phpcs:ignore WordPress.PHP.StrictInArray.FoundNonStrictFalse
972 964 $return['font-weight'] = $str_value[0][ $j ];
973 965 $have['weight'] = true;
974 - } elseif ( false === $have['variant'] && in_array( $str_value[0][ $j ], $font_variant ) ) {
966 + } elseif ( false === $have['variant'] && in_array( $str_value[0][ $j ], $font_variant, true ) ) {
975 967 $return['font-variant'] = $str_value[0][ $j ];
976 968 $have['variant'] = true;
977 - } elseif ( false === $have['style'] && in_array( $str_value[0][ $j ], $font_style ) ) {
969 + } elseif ( false === $have['style'] && in_array( $str_value[0][ $j ], $font_style, true ) ) {
978 970 $return['font-style'] = $str_value[0][ $j ];
979 971 $have['style'] = true;
980 - } elseif ( false === $have['size'] && ( is_numeric( $str_value[0][ $j ][0] ) || null === $str_value[0][ $j ][0] || '.' === $str_value[0][ $j ][0] ) ) {
972 + } elseif ( false === $have['size'] && ( is_numeric( $str_value[0][ $j ][0] ) || is_null( $str_value[0][ $j ][0] ) || '.' === $str_value[0][ $j ][0] ) ) {
981 973 $size = $this->explode_ws( '/', trim( $str_value[0][ $j ] ) );
982 974 $return['font-size'] = $size[0];
983 975 if ( isset( $size[1] ) ) {
984 976 $return['line-height'] = $size[1];
@@ -985,9 +977,9 @@
985 977 } else {
986 978 $return['line-height'] = ''; // Don't add 'normal'!
987 979 }
988 980 $have['size'] = true;
989 - } else {
981 + } else { // phpcs:ignore Universal.ControlStructures.DisallowLonelyIf.Found
990 982 if ( isset( $return['font-family'] ) ) {
991 983 $return['font-family'] .= ' ' . $str_value[0][ $j ];
992 984 $multiwords = true;
993 985 } else {
@@ -995,15 +987,15 @@
995 987 }
996 988 }
997 989 }
998 990 // Add quotes if we have several words in font-family.
999 - if ( false !== $multiwords ) {
991 + if ( $multiwords ) {
1000 992 $return['font-family'] = '"' . $return['font-family'] . '"';
1001 993 }
1002 994 $i = 1;
1003 995 while ( isset( $str_value[ $i ] ) ) {
1004 996 $return['font-family'] .= ',' . trim( $str_value[ $i ] );
1005 - $i++;
997 + ++$i;
1006 998 }
1007 999
1008 1000 // Fix for font-size 100 and higher.
1009 1001 if ( false === $have['size'] && isset( $return['font-weight'] ) && is_numeric( $return['font-weight'][0] ) ) {
@@ -1025,33 +1017,31 @@
1025 1017 * Merges all fonts properties.
1026 1018 *
1027 1019 * @since 1.0.0
1028 1020 *
1029 - * @param [type] $input_css [description]
1030 - * @return [type] [description]
1021 + * @param array<string, string> $input_css [description].
1022 + * @return array<string, string> [description]
1031 1023 */
1032 - public function merge_font( $input_css ) {
1024 + public function merge_font( array $input_css ): array {
1033 1025 $font_prop_default = &$this->parser->data['csstidy']['font_prop_default'];
1034 1026 $new_font_value = '';
1035 1027 $important = '';
1036 1028 // Skip if no font-family and font-size set.
1037 - if ( isset( $input_css['font-family'] ) && isset( $input_css['font-size'] ) && 'inherit' !== $input_css['font-family'] ) {
1029 + if ( isset( $input_css['font-family'], $input_css['font-size'] ) && 'inherit' !== $input_css['font-family'] ) {
1038 1030 // Fix several words in font-family - add quotes.
1039 - if ( isset( $input_css['font-family'] ) ) {
1040 - $families = explode( ',', $input_css['font-family'] );
1041 - $result_families = array();
1042 - foreach ( $families as $family ) {
1043 - $family = trim( $family );
1044 - $len = strlen( $family );
1045 - if ( strpos( $family, ' ' ) &&
1046 - ! ( ( '"' === $family[0] && '"' === $family[ $len - 1 ] ) ||
1047 - ( "'" === $family[0] && "'" === $family[ $len - 1 ] ) ) ) {
1048 - $family = '"' . $family . '"';
1049 - }
1050 - $result_families[] = $family;
1031 + $families = explode( ',', $input_css['font-family'] );
1032 + $result_families = array();
1033 + foreach ( $families as $family ) {
1034 + $family = trim( $family );
1035 + $len = strlen( $family );
1036 + if ( str_contains( $family, ' ' ) &&
1037 + ! ( ( '"' === $family[0] && '"' === $family[ $len - 1 ] ) ||
1038 + ( "'" === $family[0] && "'" === $family[ $len - 1 ] ) ) ) {
1039 + $family = '"' . $family . '"';
1051 1040 }
1052 - $input_css['font-family'] = implode( ',', $result_families );
1041 + $result_families[] = $family;
1053 1042 }
1043 + $input_css['font-family'] = implode( ',', $result_families );
1054 1044 foreach ( $font_prop_default as $font_property => $default_value ) {
1055 1045 // Skip if property does not exist.
1056 1046 if ( ! isset( $input_css[ $font_property ] ) ) {
1057 1047 continue;
@@ -1092,106 +1082,5 @@
1092 1082
1093 1083 return $input_css;
1094 1084 }
1095 1085
1096 -} // class TablePress_CSSTidy_optimise
1097 -
1098 -/**
1099 - * Sanitization class
1100 - */
1101 -class TablePress_CSSTidy_custom_sanitize extends TablePress_CSSTidy_optimise {
1102 -
1103 - /**
1104 - * [$props_w_urls description]
1105 - *
1106 - * @since 1.0.0
1107 - * @var array
1108 - */
1109 - protected $props_w_urls = array( 'background', 'background-image', 'list-style', 'list-style-image' );
1110 -
1111 - /**
1112 - * [$allowed_protocols description]
1113 - *
1114 - * @since 1.0.0
1115 - * @var array
1116 - */
1117 - protected $allowed_protocols = array( 'http', 'https' );
1118 -
1119 - /**
1120 - * [__construct description]
1121 - *
1122 - * @since 1.0.0
1123 - *
1124 - * @param [type] $css [description]
1125 - */
1126 - public function __construct( $css ) {
1127 - return parent::__construct( $css );
1128 - }
1129 -
1130 - /**
1131 - * [postparse description]
1132 - *
1133 - * @since 1.0.0
1134 - *
1135 - * @return [type] [description]
1136 - */
1137 - public function postparse() {
1138 - if ( ! empty( $this->parser->import ) ) {
1139 - $this->parser->import = array();
1140 - }
1141 - if ( ! empty( $this->parser->charset ) ) {
1142 - $this->parser->charset = array();
1143 - }
1144 -
1145 - return parent::postparse();
1146 - }
1147 -
1148 - /**
1149 - * [subvalue description]
1150 - *
1151 - * @since 1.0.0
1152 - *
1153 - * @return [type] [description]
1154 - */
1155 - public function subvalue() {
1156 - $this->sub_value = trim( $this->sub_value );
1157 -
1158 - // Send any urls through our filter
1159 - if ( preg_match( '!^\\s*url\\s*(?:\\(|\\\\0028)(.*)(?:\\)|\\\\0029).*$!Dis', $this->sub_value, $matches ) ) {
1160 - $this->sub_value = $this->clean_url( $matches[1] );
1161 - }
1162 -
1163 - // Strip any expressions
1164 - if ( preg_match( '!^\\s*expression!Dis', $this->sub_value ) ) {
1165 - $this->sub_value = '';
1166 - }
1167 -
1168 - return parent::subvalue();
1169 - }
1170 -
1171 - /**
1172 - * [clean_url description]
1173 - *
1174 - * @since 1.0.0
1175 - *
1176 - * @param [type] $url [description]
1177 - * @return [type] [description]
1178 - */
1179 - protected function clean_url( $url ) {
1180 - // Clean up the string.
1181 - $url = trim( $url, "'\"\r\n " );
1182 -
1183 - // Check against whitelist for properties allowed to have URL values.
1184 - if ( ! in_array( $this->property, $this->props_w_urls ) ) {
1185 - return '';
1186 - }
1187 -
1188 - $url = wp_kses_bad_protocol_once( $url, $this->allowed_protocols );
1189 -
1190 - if ( empty( $url ) ) {
1191 - return '';
1192 - }
1193 -
1194 - return "url('$url')";
1195 - }
1196 -
1197 -} // class TablePress_CSSTidy_custom_sanitize
1086 +} // class TablePress_CSSTidy_Optimise