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 +169 -284 1.14 → 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 27 * TablePress_CSSTidy instance.
58 28 *
59 29 * @since 1.0.0
60 - * @var TablePress_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 TablePress_CSSTidy $css Instance of the TablePress_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,28 +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 - $color_tmp_count = count( $color_tmp );
389 - for ( $i = 0; $i < $color_tmp_count; $i++ ) {
390 - $color_tmp[ $i ] = trim( $color_tmp[ $i ] );
391 - if ( '%' === substr( $color_tmp[ $i ], -1 ) ) {
392 - $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;
393 359 }
394 - if ( $color_tmp[ $i ] > 255 ) {
395 - $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 ] ) );
396 372 }
373 + $color_parts[ $i ] = intval( $color_parts[ $i ] );
374 + if ( $color_parts[ $i ] > 255 ) {
375 + $color_parts[ $i ] = 255;
376 + }
397 377 }
398 378 $color = '#';
399 - for ( $i = 0; $i < 3; $i++ ) {
400 - if ( $color_tmp[ $i ] < 16 ) {
401 - $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 ] );
402 387 } else {
403 - $color .= dechex( $color_tmp[ $i ] );
388 + $color .= dechex( $color_parts[ $i ] );
404 389 }
405 390 }
406 391 }
407 392
@@ -409,14 +394,20 @@
409 394 if ( isset( $replace_colors[ strtolower( $color ) ] ) ) {
410 395 $color = $replace_colors[ strtolower( $color ) ];
411 396 }
412 397
413 - // #aabbcc -> #abc
414 398 if ( 7 === strlen( $color ) ) {
399 + // #aabbcc -> #abc
415 400 $color_temp = strtolower( $color );
416 401 if ( '#' === $color_temp[0] && $color_temp[1] === $color_temp[2] && $color_temp[3] === $color_temp[4] && $color_temp[5] === $color_temp[6] ) {
417 402 $color = '#' . $color[1] . $color[3] . $color[5];
418 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 + }
419 410 }
420 411
421 412 switch ( strtolower( $color ) ) {
422 413 /* color name -> hex code */
@@ -462,13 +453,13 @@
462 453 *
463 454 * @param string $subvalue Value.
464 455 * @return string Compressed value.
465 456 */
466 - public function compress_numbers( $subvalue ) {
457 + public function compress_numbers( string $subvalue ): string {
467 458 $unit_values = &$this->parser->data['csstidy']['unit_values'];
468 459 $color_values = &$this->parser->data['csstidy']['color_values'];
469 460
470 - // for font:1em/1em sans-serif...;
461 + // for font:1em/1em sans-serif...;.
471 462 if ( 'font' === $this->property ) {
472 463 $temp = explode( '/', $subvalue );
473 464 } else {
474 465 $temp = array( $subvalue );
@@ -476,15 +467,15 @@
476 467
477 468 $temp_count = count( $temp );
478 469 for ( $l = 0; $l < $temp_count; $l++ ) {
479 470 // If we are not dealing with a number at this point, do not optimize anything.
480 - $number = $this->AnalyseCssNumber( $temp[ $l ] );
471 + $number = $this->analyse_css_number( $temp[ $l ] );
481 472 if ( false === $number ) {
482 473 return $subvalue;
483 474 }
484 475
485 476 // Fix bad colors.
486 - if ( in_array( $this->property, $color_values ) ) {
477 + if ( in_array( $this->property, $color_values, true ) ) {
487 478 if ( 3 === strlen( $temp[ $l ] ) || 6 === strlen( $temp[ $l ] ) ) {
488 479 $temp[ $l ] = '#' . $temp[ $l ];
489 480 } else {
490 481 $temp[ $l ] = '0';
@@ -510,14 +501,14 @@
510 501 * Checks if a given string is a CSS valid number. If it is, an array containing the value and unit is returned.
511 502 *
512 503 * @since 1.0.0
513 504 *
514 - * @param string $string String.
515 - * @return array|false ('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.
516 507 */
517 - public function analyseCssNumber( $string ) {
518 - // most simple checks first
519 - 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] ) ) {
520 511 return false;
521 512 }
522 513
523 514 $units = &$this->parser->data['csstidy']['units'];
@@ -522,31 +513,31 @@
522 513
523 514 $units = &$this->parser->data['csstidy']['units'];
524 515 $return = array( 0, '' );
525 516
526 - $return[0] = (float) $string;
517 + $return[0] = (float) $a_string;
527 518 if ( abs( $return[0] ) > 0 && abs( $return[0] ) < 1 ) {
528 519 if ( $return[0] < 0 ) {
529 - $return[0] = '-' . ltrim( substr( $return[0], 1 ), '0' );
520 + $return[0] = '-' . ltrim( substr( (string) $return[0], 1 ), '0' );
530 521 } else {
531 - $return[0] = ltrim( $return[0], '0' );
522 + $return[0] = ltrim( (string) $return[0], '0' );
532 523 }
533 524 }
534 525
535 - // Look for unit and split from value if exists
526 + // Look for unit and split from value if exists.
536 527 foreach ( $units as $unit ) {
537 - $expectUnitAt = strlen( $string ) - strlen( $unit );
538 - 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
539 530 continue;
540 531 }
541 - $actualPosition = strpos( $string, $unitInString );
542 - if ( $expectUnitAt === $actualPosition ) {
532 + $actual_position = strpos( $a_string, $unit_in_string );
533 + if ( $expect_unit_at === $actual_position ) {
543 534 $return[1] = $unit;
544 - $string = substr( $string, 0, - strlen( $unit ) );
535 + $a_string = substr( $a_string, 0, - strlen( $unit ) );
545 536 break;
546 537 }
547 538 }
548 - if ( ! is_numeric( $string ) ) {
539 + if ( ! is_numeric( $a_string ) ) {
549 540 return false;
550 541 }
551 542 return $return;
552 543 }
@@ -556,13 +547,12 @@
556 547 * Very basic and has at least one bug. Hopefully there is a replacement soon.
557 548 *
558 549 * @since 1.0.0
559 550 *
560 - * @param array $array
561 - * @return array
551 + * @param array<string, mixed> $an_array List of selectors. This parameter is modified by reference.
562 552 */
563 - public function merge_selectors( array &$array ) {
564 - $css = $array;
553 + public function merge_selectors( array &$an_array ): void {
554 + $css = $an_array;
565 555 foreach ( $css as $key => $value ) {
566 556 if ( ! isset( $css[ $key ] ) ) {
567 557 continue;
568 558 }
@@ -568,9 +558,9 @@
568 558 }
569 559
570 560 // Check if properties also exist in another selector.
571 561 $keys = array();
572 - // PHP bug (?) without $css = $array; here
562 + // PHP bug (?) without $css = $an_array; here.
573 563 foreach ( $css as $selector => $vali ) {
574 564 if ( $selector === $key ) {
575 565 continue;
576 566 }
@@ -589,9 +579,9 @@
589 579 }
590 580 $css[ $newsel ] = $value;
591 581 }
592 582 }
593 - $array = $css;
583 + $an_array = $css;
594 584 }
595 585
596 586 /**
597 587 * Removes invalid selectors and their corresponding rule-sets as
@@ -600,12 +590,12 @@
600 590 * regular expression.
601 591 *
602 592 * @since 1.0.0
603 593 *
604 - * @param [type] $array [description]
594 + * @param array<string, mixed> $an_array [description].
605 595 */
606 - public function discard_invalid_selectors( &$array ) {
607 - foreach ( $array as $selector => $decls ) {
596 + public function discard_invalid_selectors( array &$an_array ): void {
597 + foreach ( $an_array as $selector => $decls ) {
608 598 $ok = true;
609 599 $selectors = array_map( 'trim', explode( ',', $selector ) );
610 600 foreach ( $selectors as $s ) {
611 601 $simple_selectors = preg_split( '/\s*[+>~\s]\s*/', $s );
@@ -612,14 +602,13 @@
612 602 foreach ( $simple_selectors as $ss ) {
613 603 if ( '' === $ss ) {
614 604 $ok = false;
615 605 }
616 - // could also check $ss for internal structure,
617 - // but that probably would be too slow
606 + // Could also check $ss for internal structure, but that probably would be too slow.
618 607 }
619 608 }
620 609 if ( ! $ok ) {
621 - unset( $array[ $selector ] );
610 + unset( $an_array[ $selector ] );
622 611 }
623 612 }
624 613 }
625 614
@@ -627,14 +616,13 @@
627 616 * Dissolves properties like padding:10px 10px 10px to padding-top:10px;padding-bottom:10px;...
628 617 *
629 618 * @since 1.0.0
630 619 *
631 - * @param string $property [description]
632 - * @param string $value [description]
633 - *
634 - * @return [type] [description]
620 + * @param string $property [description].
621 + * @param string $value [description].
622 + * @return array [description]
635 623 */
636 - public function dissolve_4value_shorthands( $property, $value ) {
624 + public function dissolve_4value_shorthands( string $property, string $value ): array {
637 625 $return = array();
638 626
639 627 $shorthands = &$this->parser->data['csstidy']['shorthands'];
640 628 if ( ! is_array( $shorthands[ $property ] ) ) {
@@ -675,37 +663,37 @@
675 663 * Explodes a string as explode() does, however, not if $sep is escaped or within a string.
676 664 *
677 665 * @since 1.0.0
678 666 *
679 - * @param string $sep Separator.
680 - * @param string $string String.
681 - * @return array
667 + * @param string $sep Separator.
668 + * @param string $a_string String.
669 + * @return array [description]
682 670 */
683 - public function explode_ws( $sep, $string ) {
671 + public function explode_ws( string $sep, string $a_string ): array {
684 672 $status = 'st';
685 673 $to = '';
686 674
687 675 $output = array();
688 676 $num = 0;
689 - for ( $i = 0, $len = strlen( $string ); $i < $len; $i++ ) {
677 + for ( $i = 0, $len = strlen( $a_string ); $i < $len; $i++ ) {
690 678 switch ( $status ) {
691 679 case 'st':
692 - if ( $string[ $i ] === $sep && ! $this->parser->escaped( $string, $i ) ) {
680 + if ( $a_string[ $i ] === $sep && ! $this->parser->escaped( $a_string, $i ) ) {
693 681 ++$num;
694 - } 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 ) ) ) {
695 683 $status = 'str';
696 - $to = ( '(' === $string[ $i ] ) ? ')' : $string[ $i ];
697 - ( 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 ];
698 686 } else {
699 - ( 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 ];
700 688 }
701 689 break;
702 690
703 691 case 'str':
704 - if ( $string[ $i ] === $to && ! $this->parser->escaped( $string, $i ) ) {
692 + if ( $a_string[ $i ] === $to && ! $this->parser->escaped( $a_string, $i ) ) {
705 693 $status = 'st';
706 694 }
707 - ( 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 ];
708 696 break;
709 697 }
710 698 }
711 699
@@ -720,22 +708,22 @@
720 708 * Merges Shorthand properties again, the opposite of dissolve_4value_shorthands().
721 709 *
722 710 * @since 1.0.0
723 711 *
724 - * @param [type] $array [description]
725 - * @return [type] [description]
712 + * @param array<string, mixed> $an_array [description].
713 + * @return array<string, mixed> [description]
726 714 */
727 - public function merge_4value_shorthands( $array ) {
728 - $return = $array;
715 + public function merge_4value_shorthands( array $an_array ): array {
716 + $return = $an_array;
729 717 $shorthands = &$this->parser->data['csstidy']['shorthands'];
730 718
731 719 foreach ( $shorthands as $key => $value ) {
732 - if ( 0 !== $value && isset( $array[ $value[0] ], $array[ $value[1] ], $array[ $value[2] ], $array[ $value[3] ] ) ) {
720 + if ( 0 !== $value && isset( $an_array[ $value[0] ], $an_array[ $value[1] ], $an_array[ $value[2] ], $an_array[ $value[3] ] ) ) {
733 721 $return[ $key ] = '';
734 722
735 723 $important = '';
736 724 for ( $i = 0; $i < 4; $i++ ) {
737 - $val = $array[ $value[ $i ] ];
725 + $val = $an_array[ $value[ $i ] ];
738 726 if ( $this->parser->is_important( $val ) ) {
739 727 $important = ' !important';
740 728 $return[ $key ] .= $this->parser->gvw_important( $val ) . ' ';
741 729 } else {
@@ -751,16 +739,16 @@
751 739
752 740 /**
753 741 * Dissolve background property.
754 742 *
755 - * @TODO Full CSS3 compliance.
743 + * @todo Full CSS3 compliance.
756 744 *
757 745 * @since 1.0.0
758 746 *
759 747 * @param string $str_value String value.
760 - * @return array Array.
748 + * @return array<string, string|null> Array.
761 749 */
762 - public function dissolve_short_bg( $str_value ) {
750 + public function dissolve_short_bg( string $str_value ): array {
763 751 // Don't try to explode background gradient!
764 752 if ( false !== stripos( $str_value, 'gradient(' ) ) {
765 753 return array( 'background' => $str_value );
766 754 }
@@ -803,9 +791,9 @@
803 791 $str_value[ $i ] = $this->explode_ws( ' ', trim( $str_value[ $i ] ) );
804 792
805 793 $str_value_i_count = count( $str_value[ $i ] );
806 794 for ( $j = 0; $j < $str_value_i_count; $j++ ) {
807 - if ( false === $have['bg'] && ( 'url(' === substr( $str_value[ $i ][ $j ], 0, 4 ) || 'none' === $str_value[ $i ][ $j ] ) ) {
795 + if ( false === $have['bg'] && ( str_starts_with( $str_value[ $i ][ $j ], 'url(' ) || 'none' === $str_value[ $i ][ $j ] ) ) {
808 796 $return['background-image'] .= $str_value[ $i ][ $j ] . ',';
809 797 $have['bg'] = true;
810 798 } elseif ( in_array( $str_value[ $i ][ $j ], $repeat, true ) ) {
811 799 $return['background-repeat'] .= $str_value[ $i ][ $j ] . ',';
@@ -817,9 +805,9 @@
817 805 } elseif ( in_array( $str_value[ $i ][ $j ], $origin, true ) ) {
818 806 $return['background-origin'] .= $str_value[ $i ][ $j ] . ',';
819 807 } elseif ( '(' === $str_value[ $i ][ $j ][0] ) {
820 808 $return['background-size'] .= substr( $str_value[ $i ][ $j ], 1, -1 ) . ',';
821 - } 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] ) {
822 810 $return['background-position'] .= $str_value[ $i ][ $j ];
823 811 if ( ! $have['pos'] ) {
824 812 $return['background-position'] .= ' ';
825 813 } else {
@@ -845,21 +833,21 @@
845 833
846 834 /**
847 835 * Merges all background properties.
848 836 *
849 - * @TODO Full CSS3 compliance.
837 + * @todo Full CSS3 compliance.
850 838 *
851 839 * @since 1.0.0
852 840 *
853 - * @param array $input_css CSS.
854 - * @return array Array.
841 + * @param array<string, mixed> $input_css CSS.
842 + * @return array<string, mixed> Array.
855 843 */
856 - public function merge_bg( array $input_css ) {
844 + public function merge_bg( array $input_css ): array {
857 845 $background_prop_default = &$this->parser->data['csstidy']['background_prop_default'];
858 846 // Max number of background images. CSS3 not yet fully implemented.
859 - $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
860 848 // Array with background images to check if BG image exists.
861 - $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
862 850 $new_bg_value = '';
863 851 $important = '';
864 852
865 853 // If background properties is here and not empty, don't try anything.
@@ -933,12 +921,12 @@
933 921 * Dissolve font property.
934 922 *
935 923 * @since 1.0.0
936 924 *
937 - * @param [type] $str_value [description]
938 - * @return [type] [description]
925 + * @param string $str_value [description].
926 + * @return array<string, string|null> [description]
939 927 */
940 - public function dissolve_short_font( $str_value ) {
928 + public function dissolve_short_font( string $str_value ): array {
941 929 $font_prop_default = &$this->parser->data['csstidy']['font_prop_default'];
942 930 $font_weight = array( 'normal', 'bold', 'bolder', 'lighter', 100, 200, 300, 400, 500, 600, 700, 800, 900 );
943 931 $font_variant = array( 'normal', 'small-caps' );
944 932 $font_style = array( 'normal', 'italic', 'oblique' );
@@ -971,18 +959,18 @@
971 959 $str_value[0] = $this->explode_ws( ' ', trim( $str_value[0] ) );
972 960
973 961 $str_value_0_count = count( $str_value[0] );
974 962 for ( $j = 0; $j < $str_value_0_count; $j++ ) {
975 - if ( false === $have['weight'] && in_array( $str_value[0][ $j ], $font_weight ) ) {
963 + if ( false === $have['weight'] && in_array( $str_value[0][ $j ], $font_weight, false ) ) { // phpcs:ignore WordPress.PHP.StrictInArray.FoundNonStrictFalse
976 964 $return['font-weight'] = $str_value[0][ $j ];
977 965 $have['weight'] = true;
978 - } 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 ) ) {
979 967 $return['font-variant'] = $str_value[0][ $j ];
980 968 $have['variant'] = true;
981 - } 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 ) ) {
982 970 $return['font-style'] = $str_value[0][ $j ];
983 971 $have['style'] = true;
984 - } 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] ) ) {
985 973 $size = $this->explode_ws( '/', trim( $str_value[0][ $j ] ) );
986 974 $return['font-size'] = $size[0];
987 975 if ( isset( $size[1] ) ) {
988 976 $return['line-height'] = $size[1];
@@ -989,9 +977,9 @@
989 977 } else {
990 978 $return['line-height'] = ''; // Don't add 'normal'!
991 979 }
992 980 $have['size'] = true;
993 - } else {
981 + } else { // phpcs:ignore Universal.ControlStructures.DisallowLonelyIf.Found
994 982 if ( isset( $return['font-family'] ) ) {
995 983 $return['font-family'] .= ' ' . $str_value[0][ $j ];
996 984 $multiwords = true;
997 985 } else {
@@ -1005,9 +993,9 @@
1005 993 }
1006 994 $i = 1;
1007 995 while ( isset( $str_value[ $i ] ) ) {
1008 996 $return['font-family'] .= ',' . trim( $str_value[ $i ] );
1009 - $i++;
997 + ++$i;
1010 998 }
1011 999
1012 1000 // Fix for font-size 100 and higher.
1013 1001 if ( false === $have['size'] && isset( $return['font-weight'] ) && is_numeric( $return['font-weight'][0] ) ) {
@@ -1029,12 +1017,12 @@
1029 1017 * Merges all fonts properties.
1030 1018 *
1031 1019 * @since 1.0.0
1032 1020 *
1033 - * @param [type] $input_css [description]
1034 - * @return [type] [description]
1021 + * @param array<string, string> $input_css [description].
1022 + * @return array<string, string> [description]
1035 1023 */
1036 - public function merge_font( $input_css ) {
1024 + public function merge_font( array $input_css ): array {
1037 1025 $font_prop_default = &$this->parser->data['csstidy']['font_prop_default'];
1038 1026 $new_font_value = '';
1039 1027 $important = '';
1040 1028 // Skip if no font-family and font-size set.
@@ -1039,23 +1027,21 @@
1039 1027 $important = '';
1040 1028 // Skip if no font-family and font-size set.
1041 1029 if ( isset( $input_css['font-family'], $input_css['font-size'] ) && 'inherit' !== $input_css['font-family'] ) {
1042 1030 // Fix several words in font-family - add quotes.
1043 - if ( isset( $input_css['font-family'] ) ) {
1044 - $families = explode( ',', $input_css['font-family'] );
1045 - $result_families = array();
1046 - foreach ( $families as $family ) {
1047 - $family = trim( $family );
1048 - $len = strlen( $family );
1049 - if ( strpos( $family, ' ' ) &&
1050 - ! ( ( '"' === $family[0] && '"' === $family[ $len - 1 ] ) ||
1051 - ( "'" === $family[0] && "'" === $family[ $len - 1 ] ) ) ) {
1052 - $family = '"' . $family . '"';
1053 - }
1054 - $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 . '"';
1055 1040 }
1056 - $input_css['font-family'] = implode( ',', $result_families );
1041 + $result_families[] = $family;
1057 1042 }
1043 + $input_css['font-family'] = implode( ',', $result_families );
1058 1044 foreach ( $font_prop_default as $font_property => $default_value ) {
1059 1045 // Skip if property does not exist.
1060 1046 if ( ! isset( $input_css[ $font_property ] ) ) {
1061 1047 continue;
@@ -1096,106 +1082,5 @@
1096 1082
1097 1083 return $input_css;
1098 1084 }
1099 1085
1100 -} // class TablePress_CSSTidy_optimise
1101 -
1102 -/**
1103 - * Sanitization class
1104 - */
1105 -class TablePress_CSSTidy_custom_sanitize extends TablePress_CSSTidy_optimise {
1106 -
1107 - /**
1108 - * [$props_w_urls description]
1109 - *
1110 - * @since 1.0.0
1111 - * @var array
1112 - */
1113 - protected $props_w_urls = array( 'background', 'background-image', 'list-style', 'list-style-image' );
1114 -
1115 - /**
1116 - * [$allowed_protocols description]
1117 - *
1118 - * @since 1.0.0
1119 - * @var array
1120 - */
1121 - protected $allowed_protocols = array( 'http', 'https' );
1122 -
1123 - /**
1124 - * [__construct description]
1125 - *
1126 - * @since 1.0.0
1127 - *
1128 - * @param [type] $css [description]
1129 - */
1130 - public function __construct( $css ) {
1131 - parent::__construct( $css );
1132 - }
1133 -
1134 - /**
1135 - * [postparse description]
1136 - *
1137 - * @since 1.0.0
1138 - *
1139 - * @return [type] [description]
1140 - */
1141 - public function postparse() {
1142 - if ( ! empty( $this->parser->import ) ) {
1143 - $this->parser->import = array();
1144 - }
1145 - if ( ! empty( $this->parser->charset ) ) {
1146 - $this->parser->charset = '';
1147 - }
1148 -
1149 - parent::postparse();
1150 - }
1151 -
1152 - /**
1153 - * [subvalue description]
1154 - *
1155 - * @since 1.0.0
1156 - *
1157 - * @return [type] [description]
1158 - */
1159 - public function subvalue() {
1160 - $this->sub_value = trim( $this->sub_value );
1161 -
1162 - // Send any urls through our filter
1163 - if ( preg_match( '!^\\s*url\\s*(?:\\(|\\\\0028)(.*)(?:\\)|\\\\0029).*$!Dis', $this->sub_value, $matches ) ) {
1164 - $this->sub_value = $this->clean_url( $matches[1] );
1165 - }
1166 -
1167 - // Strip any expressions
1168 - if ( preg_match( '!^\\s*expression!Dis', $this->sub_value ) ) {
1169 - $this->sub_value = '';
1170 - }
1171 -
1172 - parent::subvalue();
1173 - }
1174 -
1175 - /**
1176 - * [clean_url description]
1177 - *
1178 - * @since 1.0.0
1179 - *
1180 - * @param [type] $url [description]
1181 - * @return [type] [description]
1182 - */
1183 - protected function clean_url( $url ) {
1184 - // Clean up the string.
1185 - $url = trim( $url, "'\"\r\n " );
1186 -
1187 - // Check against whitelist for properties allowed to have URL values.
1188 - if ( ! in_array( $this->property, $this->props_w_urls ) ) {
1189 - return '';
1190 - }
1191 -
1192 - $url = wp_kses_bad_protocol_once( $url, $this->allowed_protocols );
1193 -
1194 - if ( empty( $url ) ) {
1195 - return '';
1196 - }
1197 -
1198 - return "url('$url')";
1199 - }
1200 -
1201 -} // class TablePress_CSSTidy_custom_sanitize
1086 +} // class TablePress_CSSTidy_Optimise