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.php +367 -464 1.9.2 → 3.4 View file →
@@ -7,109 +7,19 @@
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 - * CSS Parser class
18 - *
19 - * Copyright 2005, 2006, 2007 Florian Schmitz
20 - *
21 - * This file is part of CSSTidy.
22 - *
23 - * CSSTidy is free software; you can redistribute it and/or modify
24 - * it under the terms of the GNU Lesser General Public License as published by
25 - * the Free Software Foundation; either version 2.1 of the License, or
26 - * (at your option) any later version.
27 - *
28 - * CSSTidy is distributed in the hope that it will be useful,
29 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
30 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31 - * GNU Lesser General Public License for more details.
32 - *
33 - * You should have received a copy of the GNU Lesser General Public License
34 - * along with this program. If not, see <https://www.gnu.org/licenses/>.
35 - *
36 - * @license https://opensource.org/licenses/lgpl-license.php GNU Lesser General Public License
37 - * @package CSSTidy
38 - * @author Florian Schmitz (floele at gmail dot com) 2005-2007
39 - * @author Brett Zamir (brettz9 at yahoo dot com) 2007
40 - * @author Nikolay Matsievsky (speed at webo dot name) 2009-2010
41 - * @author Cedric Morin (cedric at yterium dot com) 2010-2012
42 - * @author Christopher Finke (cfinke at gmail.com) 2012
43 - * @author Mark Scherer (remove $GLOBALS once and for all + PHP5.4 comp) 2012
44 - */
45 -
46 -/**
47 - * Defines ctype functions if required.
48 - *
49 - * @TODO: Make these methods of CSSTidy.
50 - */
51 -if ( ! function_exists( 'ctype_space' ) ) {
52 - /**
53 - * Check for whitespace character(s).
54 - *
55 - * @since 1.0.0
56 - *
57 - * @param string $text Text to check.
58 - * @return bool Whether all characters in the string are whitespace characters.
59 - */
60 - function ctype_space( $text ) {
61 - return ( 1 === preg_match( "/^[ \r\n\t\f]+$/", $text ) );
62 - }
63 -}
64 -if ( ! function_exists( 'ctype_alpha' ) ) {
65 - /**
66 - * Check for alphabetic character(s).
67 - *
68 - * @since 1.0.0
69 - *
70 - * @param string $text Text to check.
71 - * @return bool Whether all characters in the string are alphabetic characters.
72 - */
73 - function ctype_alpha( $text ) {
74 - return ( 1 === preg_match( '/^[a-zA-Z]+$/', $text ) );
75 - }
76 -}
77 -if ( ! function_exists( 'ctype_xdigit' ) ) {
78 - /**
79 - * Check for character(s) representing a hexadecimal digit.
80 - *
81 - * @since 1.0.0
82 - *
83 - * @param string $text Text to check.
84 - * @return bool Whether $text is a hexadecimal number.
85 - */
86 - function ctype_xdigit( $text ) {
87 - return ( 1 === preg_match( '/^[a-fA-F0-9]+$/', $text ) );
88 - }
89 -}
90 -
91 -/**
92 - * Defines constants.
93 - *
94 - * @TODO: Make these class constants of CSSTidy.
95 - * @since 1.0.0
96 - */
97 -define( 'AT_START', 1 );
98 -define( 'AT_END', 2 );
99 -define( 'SEL_START', 3 );
100 -define( 'SEL_END', 4 );
101 -define( 'PROPERTY', 5 );
102 -define( 'VALUE', 6 );
103 -define( 'COMMENT', 7 );
104 -define( 'DEFAULT_AT', 41 );
105 -
106 -/**
107 17 * Load the class for printing CSS code.
108 18 *
109 19 * @since 1.0.0
110 20 */
111 -require dirname( __FILE__ ) . '/class.csstidy_print.php';
21 +require __DIR__ . '/class.csstidy_print.php';
112 22
113 23 /**
114 24 * Load the class for optimising CSS code.
115 25 *
@@ -114,9 +24,9 @@
114 24 * Load the class for optimising CSS code.
115 25 *
116 26 * @since 1.0.0
117 27 */
118 -require dirname( __FILE__ ) . '/class.csstidy_optimise.php';
28 +require __DIR__ . '/class.csstidy_optimise.php';
119 29
120 30 /**
121 31 * CSS Parser class
122 32 *
@@ -130,80 +40,79 @@
130 40 */
131 41 class TablePress_CSSTidy {
132 42
133 43 /**
44 + * Defines constants.
45 + *
46 + * @since 1.0.0
47 + */
48 + public const AT_START = 1;
49 + public const AT_END = 2;
50 + public const SEL_START = 3;
51 + public const SEL_END = 4;
52 + public const PROPERTY = 5;
53 + public const VALUE = 6;
54 + public const COMMENT = 7;
55 + public const IMPORTANT_COMMENT = 8;
56 + public const DEFAULT_AT = 41;
57 +
58 + /**
134 59 * The parsed CSS.
135 60 *
136 61 * This array is empty if preserve_css is on.
137 62 *
138 63 * @since 1.0.0
139 - * @var array
140 64 */
141 - public $css = array();
65 + public array $css = array();
142 66
143 67 /**
144 68 * The raw parsed CSS.
145 69 *
146 70 * @since 1.0.0
147 - * @var array
148 71 */
149 - public $tokens = array();
72 + public array $tokens = array();
150 73
151 74 /**
152 75 * Instance of the CSS Printer class.
153 76 *
154 77 * @since 1.0.0
155 - * @var TablePress_CSSTidy_print
156 78 */
157 - public $print;
79 + public \TablePress_CSSTidy_Print $print;
158 80
159 81 /**
160 82 * Instance of the CSS Optimiser class.
161 83 *
162 84 * @since 1.0.0
163 - * @var TablePress_CSSTidy_optimise
164 85 */
165 - public $optimise;
86 + public \TablePress_CSSTidy_Optimise $optimise;
166 87
167 88 /**
168 89 * The CSS charset.
169 90 *
170 91 * @since 1.0.0
171 - * @var string
172 92 */
173 - public $charset = '';
93 + public string $charset = '';
174 94
175 95 /**
176 96 * All @import URLs.
177 97 *
178 98 * @since 1.0.0
179 - * @var array
180 99 */
181 - public $import = array();
100 + public array $import = array();
182 101
183 102 /**
184 103 * The namespace.
185 104 *
186 105 * @since 1.0.0
187 - * @var string
188 106 */
189 - public $namespace = '';
107 + public string $namespace = '';
190 108
191 109 /**
192 - * The CSSTidy version.
193 - *
194 - * @since 1.0.0
195 - * @var string
196 - */
197 - public $version = '1.5.3';
198 -
199 - /**
200 110 * The settings.
201 111 *
202 112 * @since 1.0.0
203 - * @var array
204 113 */
205 - protected $settings = array();
114 + protected array $settings = array();
206 115
207 116 /**
208 117 * The parser-status.
209 118 *
@@ -215,25 +124,23 @@
215 124 * - ic = in comment (ignore everything)
216 125 * - at = in @-block
217 126 *
218 127 * @since 1.0.0
219 - * @var string
220 128 */
221 - protected $status = 'is';
129 + protected string $status = 'is';
222 130
223 131 /**
224 132 * The current at rule (@media).
225 133 *
226 134 * @since 1.0.0
227 - * @var string
228 135 */
229 - public $at = '';
136 + public string $at = '';
230 137
231 138 /**
232 139 * The at rule for next selector (during @font-face or other @).
233 140 *
234 141 * @since 1.0.0
235 - * @var string
142 + * @var string|int
236 143 */
237 144 protected $next_selector_at = '';
238 145
239 146 /**
@@ -239,35 +146,31 @@
239 146 /**
240 147 * The current selector.
241 148 *
242 149 * @since 1.0.0
243 - * @var string
244 150 */
245 - public $selector = '';
151 + public string $selector = '';
246 152
247 153 /**
248 154 * The current property.
249 155 *
250 156 * @since 1.0.0
251 - * @var string
252 157 */
253 - public $property = '';
158 + public string $property = '';
254 159
255 160 /**
256 161 * The position of , in selectors.
257 162 *
258 163 * @since 1.0.0
259 - * @var array
260 164 */
261 - protected $sel_separate = array();
165 + protected array $sel_separate = array();
262 166
263 167 /**
264 168 * The current value.
265 169 *
266 170 * @since 1.0.0
267 - * @var string
268 171 */
269 - public $value = '';
172 + public string $value = '';
270 173
271 174 /**
272 175 * The current sub-value.
273 176 *
@@ -276,107 +179,94 @@
276 179 * "url(foo.png)", "red", and "no-repeat" are sub-values,
277 180 * separated by whitespace.
278 181 *
279 182 * @since 1.0.0
280 - * @var string
281 183 */
282 - public $sub_value = '';
184 + public string $sub_value = '';
283 185
284 186 /**
285 187 * All sub-values for a property.
286 188 *
287 189 * @since 1.0.0
288 - * @var array
289 190 */
290 - protected $sub_value_arr = array();
191 + protected array $sub_value_arr = array();
291 192
292 193 /**
293 194 * The stack of characters that opened the current strings.
294 195 *
295 196 * @since 1.0.0
296 - * @var array
297 197 */
298 - public $str_char = array();
198 + public array $str_char = array();
299 199
300 200 /**
301 201 * [$cur_string description]
302 202 *
303 203 * @since 1.0.0
304 - * @var array
305 204 */
306 - public $cur_string = array();
205 + public array $cur_string = array();
307 206
308 207 /**
309 208 * Status from which the parser switched to ic or instr
310 209 *
311 210 * @since 1.0.0
312 - * @var array
313 211 */
314 - protected $from = array();
212 + protected array $from = array();
315 213
316 214 /**
317 215 * True if in invalid at-rule.
318 216 *
319 217 * @since 1.0.0
320 - * @var bool
321 218 */
322 - protected $invalid_at = false;
219 + protected bool $invalid_at = false;
323 220
324 221 /**
325 222 * True if something has been added to the current selector.
326 223 *
327 224 * @since 1.0.0
328 - * @var bool
329 225 */
330 - protected $added = false;
226 + protected bool $added = false;
331 227
332 228 /**
333 229 * The message log.
334 230 *
335 231 * @since 1.0.0
336 - * @var array
337 232 */
338 - public $log = array();
233 + public array $log = array();
339 234
340 235 /**
341 236 * The line number.
342 237 *
343 238 * @since 1.0.0
344 - * @var int
345 239 */
346 - protected $line = 1;
240 + protected int $line = 1;
347 241
348 242 /**
349 243 * Marks if we need to leave quotes for a string.
350 244 *
351 245 * @since 1.0.0
352 - * @var array
353 246 */
354 - protected $quoted_string = array();
247 + protected array $quoted_string = array();
355 248
356 249 /**
357 250 * List of tokens.
358 251 *
359 252 * @since 1.0.0
360 - * @var string
361 253 */
362 - protected $tokens_list = '';
254 + protected string $tokens_list = '';
363 255
364 256 /**
365 257 * Various CSS Data for CSSTidy.
366 258 *
367 259 * @since 1.0.0
368 - * @var array
369 260 */
370 - public $data = array();
261 + public array $data = array();
371 262
372 263 /**
373 264 * The output templates.
374 265 *
375 266 * @since 1.0.0
376 - * @var array
377 267 */
378 - public $template = array();
268 + public array $template = array();
379 269
380 270 /**
381 271 * Loads standard template and sets default settings.
382 272 *
@@ -382,15 +272,15 @@
382 272 *
383 273 * @since 1.0.0
384 274 */
385 275 public function __construct() {
386 - include dirname( __FILE__ ) . '/data.inc.php';
387 - $this->data = $data;
276 + $this->data = require __DIR__ . '/data.inc.php';
388 277
389 278 $this->settings['remove_bslash'] = true;
390 279 $this->settings['compress_colors'] = true;
391 280 $this->settings['compress_font-weight'] = true;
392 281 $this->settings['lowercase_s'] = false;
282 +
393 283 /*
394 284 * 1 common shorthands optimization
395 285 * 2 + font property optimization
396 286 * 3 + background property optimization
@@ -398,13 +288,15 @@
398 288 $this->settings['optimise_shorthands'] = 1;
399 289 $this->settings['remove_last_;'] = true;
400 290 // Rewrite all properties with lower case, better for later gzipping.
401 291 $this->settings['case_properties'] = 1;
292 +
402 293 /*
403 - * Sort properties in alpabetic order, better for later gzipping,
404 - * but can cause trouble in case of overiding same properties or using hacks.
294 + * Sort properties in alphabetic order, better for later gzipping,
295 + * but can cause trouble in case of overriding same properties or using hacks.
405 296 */
406 297 $this->settings['sort_properties'] = false;
298 +
407 299 /*
408 300 * 1, 3, 5, etc -- Enable sorting selectors inside @media: a{}b{}c{}.
409 301 * 2, 5, 8, etc -- Enable sorting selectors inside one CSS declaration: a,b,c{}.
410 302 * Preserve order by default cause it can break functionality.
@@ -420,23 +312,23 @@
420 312 $this->settings['timestamp'] = false;
421 313 $this->settings['template'] = ''; // say that property exists.
422 314 $this->set_cfg( 'template', 'default' ); // Call load_template.
423 315
424 - $this->print = new TablePress_CSSTidy_print( $this );
425 - $this->optimise = new TablePress_CSSTidy_optimise( $this );
316 + $this->print = new TablePress_CSSTidy_Print( $this );
317 + $this->optimise = new TablePress_CSSTidy_Optimise( $this );
426 318
427 319 $this->tokens_list = &$this->data['csstidy']['tokens'];
428 320 }
429 321
430 322 /**
431 - * Get the value of a setting.
323 + * Gets the value of a setting.
432 324 *
433 325 * @since 1.0.0
434 326 *
435 327 * @param string $setting Setting to get.
436 - * @return string|bool Value of the setting.
328 + * @return string|int|bool Value of the setting.
437 329 */
438 - public function get_cfg( $setting ) {
330 + public function get_cfg( string $setting ) /* : string|int|bool */ {
439 331 if ( isset( $this->settings[ $setting ] ) ) {
440 332 return $this->settings[ $setting ];
441 333 }
442 334 return false;
@@ -442,52 +334,21 @@
442 334 return false;
443 335 }
444 336
445 337 /**
446 - * Load a template.
338 + * Sets the value of a setting.
447 339 *
448 340 * @since 1.0.0
449 341 *
450 - * @param string $template Template used by set_cfg to load a template via a configuration setting.
342 + * @param string $setting Setting.
343 + * @param string|int|bool|null $value Optional. Value of the setting.
344 + * @return bool Whether the setting was set.
451 345 */
452 - protected function _load_template( $template ) {
453 - switch ( $template ) {
454 - case 'default':
455 - $this->load_template( 'default' );
456 - break;
457 - case 'highest':
458 - case 'high':
459 - case 'low':
460 - $this->load_template( $template . '_compression' );
461 - break;
462 - default:
463 - $this->load_template( $template );
464 - break;
465 - }
466 - }
467 -
468 - /**
469 - * Set the value of a setting.
470 - *
471 - * @since 1.0.0
472 - *
473 - * @param string $setting Setting.
474 - * @param mixed $value Optional. Value of the setting.
475 - * @return bool [return value]
476 - */
477 - public function set_cfg( $setting, $value = null ) {
478 - if ( is_array( $setting ) && is_null( $value ) ) {
479 - foreach ( $setting as $setprop => $setval ) {
480 - $this->settings[ $setprop ] = $setval;
481 - }
482 - if ( array_key_exists( 'template', $setting ) ) {
483 - $this->_load_template( $this->settings['template'] );
484 - }
485 - return true;
486 - } elseif ( isset( $this->settings[ $setting ] ) && '' !== $value ) {
346 + public function set_cfg( string $setting, $value = null ): bool {
347 + if ( isset( $this->settings[ $setting ] ) && '' !== $value ) {
487 348 $this->settings[ $setting ] = $value;
488 349 if ( 'template' === $setting ) {
489 - $this->_load_template( $this->settings['template'] );
350 + $this->load_template( $this->settings['template'] );
490 351 }
491 352 return true;
492 353 }
493 354 return false;
@@ -497,20 +358,29 @@
497 358 * Adds a token to $this->tokens.
498 359 *
499 360 * @since 1.0.0
500 361 *
501 - * @param mixed $type Type.
502 - * @param string $data Data.
503 - * @param bool $do Optional. Add a token even if preserve_css is off.
362 + * @param mixed $type Type.
363 + * @param string $data Data.
364 + * @param bool $force Optional. Add a token even if preserve_css is off.
504 365 */
505 - public function _add_token( $type, $data, $do = false ) {
506 - if ( $this->get_cfg( 'preserve_css' ) || $do ) {
507 - $this->tokens[] = array( $type, ( COMMENT === $type ) ? $data : trim( $data ) );
366 + public function _add_token( $type, string $data, bool $force = false ): void {
367 + if ( $this->get_cfg( 'preserve_css' ) || $force ) {
368 + // nested @...: if opening a new part we just closed, remove the previous closing instead of adding opening.
369 + if ( self::AT_START === $type
370 + && count( $this->tokens )
371 + && ( $last = end( $this->tokens ) ) // phpcs:ignore Generic.CodeAnalysis.AssignmentInCondition.Found,Squiz.PHP.DisallowMultipleAssignments.FoundInControlStructure
372 + && self::AT_END === $last[0]
373 + && trim( $data ) === $last[1] ) {
374 + array_pop( $this->tokens );
375 + } else {
376 + $this->tokens[] = array( $type, ( self::COMMENT === $type || self::IMPORTANT_COMMENT === $type ) ? $data : trim( $data ) );
377 + }
508 378 }
509 379 }
510 380
511 381 /**
512 - * Add a message to the message log.
382 + * Adds a message to the message log.
513 383 *
514 384 * @since 1.0.0
515 385 *
516 386 * @param string $message Message.
@@ -516,13 +386,13 @@
516 386 * @param string $message Message.
517 387 * @param string $type Type.
518 388 * @param int $line Optional. Line number. -1 will use the current line.
519 389 */
520 - public function log( $message, $type, $line = -1 ) {
390 + public function log( string $message, string $type, int $line = -1 ): void {
521 391 if ( -1 === $line ) {
522 392 $line = $this->line;
523 393 }
524 - $line = intval( $line );
394 + $line = (int) $line;
525 395 $add = array(
526 396 'm' => $message,
527 397 't' => $type,
528 398 );
@@ -531,30 +401,30 @@
531 401 }
532 402 }
533 403
534 404 /**
535 - * Parse Unicode notations and find a replacement character.
405 + * Parses Unicode notations and find a replacement character.
536 406 *
537 407 * @since 1.0.0
538 408 *
539 - * @param string $string String.
540 - * @param int $i i.
409 + * @param string $a_string String.
410 + * @param int $i i.
541 411 * @return string [return value]
542 412 */
543 - public function _unicode( &$string, &$i ) {
413 + public function _unicode( string &$a_string, int &$i ): string {
544 414 ++$i;
545 415 $add = '';
546 416 $replaced = false;
547 417
548 - while ( $i < strlen( $string ) && ( ctype_xdigit( $string[ $i ] ) || ctype_space( $string[ $i ] ) ) && strlen( $add ) < 6 ) {
549 - $add .= $string[ $i ];
550 - if ( ctype_space( $string[ $i ] ) ) {
418 + while ( $i < strlen( $a_string ) && ( ctype_xdigit( $a_string[ $i ] ) || ctype_space( $a_string[ $i ] ) ) && strlen( $add ) < 6 ) { // phpcs:ignore Squiz.PHP.DisallowSizeFunctionsInLoops.Found
419 + $add .= $a_string[ $i ];
420 + if ( ctype_space( $a_string[ $i ] ) ) {
551 421 break;
552 422 }
553 - $i++;
423 + ++$i;
554 424 }
555 425
556 - if ( hexdec( $add ) > 47 && hexdec( $add ) < 58 || hexdec( $add ) > 64 && hexdec( $add ) < 91 || hexdec( $add ) > 96 && hexdec( $add ) < 123 ) {
426 + if ( ( hexdec( $add ) > 47 && hexdec( $add ) < 58 ) || ( hexdec( $add ) > 64 && hexdec( $add ) < 91 ) || ( hexdec( $add ) > 96 && hexdec( $add ) < 123 ) ) {
557 427 $this->log( 'Replaced unicode notation: Changed \\' . $add . ' to ' . chr( hexdec( $add ) ), 'Information' );
558 428 $add = chr( hexdec( $add ) );
559 429 $replaced = true;
560 430 } else {
@@ -560,13 +430,13 @@
560 430 } else {
561 431 $add = trim( '\\' . $add );
562 432 }
563 433
564 - if ( @ctype_xdigit( $string[ $i + 1 ] ) && ctype_space( $string[ $i ] ) && ! $replaced || ! ctype_space( $string[ $i ] ) ) {
565 - $i--;
434 + if ( ( @ctype_xdigit( $a_string[ $i + 1 ] ) && ctype_space( $a_string[ $i ] ) && ! $replaced ) || ! ctype_space( $a_string[ $i ] ) ) { // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
435 + --$i;
566 436 }
567 437
568 - if ( '\\' !== $add || ! $this->get_cfg( 'remove_bslash' ) || false !== strpos( $this->tokens_list, $string[ $i + 1 ] ) ) {
438 + if ( '\\' !== $add || ! $this->get_cfg( 'remove_bslash' ) || str_contains( $this->tokens_list, $a_string[ $i + 1 ] ) ) {
569 439 return $add;
570 440 }
571 441
572 442 if ( '\\' === $add ) {
@@ -576,65 +446,20 @@
576 446 return '';
577 447 }
578 448
579 449 /**
580 - * Write formatted output to a file.
581 - *
582 - * @since 1.0.0
583 - *
584 - * @param string $filename File name.
585 - */
586 - public function write_page( $filename ) {
587 - $this->write( $filename, true );
588 - }
589 -
590 - /**
591 - * Write plain output to a file.
592 - *
593 - * @since 1.0.0
594 - *
595 - * @param string $filename File name.
596 - * @param bool $formatted Optional. Whether to print formatted or not.
597 - * @param string $doctype Optional. When printing formatted, is a shorthand for the document type.
598 - * @param bool $externalcss Optional. When printing formatted, indicates whether styles to be attached internally or as an external stylesheet.
599 - * @param string $title Optional. When printing formatted, is the title to be added in the head of the document.
600 - * @param string $lang Optional. When printing formatted, gives a two-letter language code to be added to the output.
601 - */
602 - public function write( $filename, $formatted = false, $doctype = 'xhtml1.1', $externalcss = true, $title = '', $lang = 'en' ) {
603 - $filename .= ( $formatted ) ? '.xhtml' : '.css';
604 -
605 - if ( ! is_dir( 'temp' ) ) {
606 - $madedir = mkdir( 'temp' );
607 - if ( ! $madedir ) {
608 - print 'Could not make directory "temp" in ' . dirname( __FILE__ );
609 - exit;
610 - }
611 - }
612 - $handle = fopen( 'temp/' . $filename, 'w' );
613 - if ( $handle ) {
614 - if ( ! $formatted ) {
615 - fwrite( $handle, $this->print->plain() );
616 - } else {
617 - fwrite( $handle, $this->print->formatted_page( $doctype, $externalcss, $title, $lang ) );
618 - }
619 - }
620 - fclose( $handle );
621 - }
622 -
623 - /**
624 450 * Loads a new template.
625 451 *
626 452 * @since 1.0.0
627 453 *
628 - * @link http://csstidy.sourceforge.net/templates.php
454 + * @link https://csstidy.sourceforge.net/templates.php
629 455 *
630 - * @param string $content Either file name (if $from_file is true), content of a template file, "high_compression", "highest_compression", "low_compression", or "default".
456 + * @param string $content Either file name (if $from_file is true), content of a template file, "default", "low", high", or "highest".
631 457 * @param bool $from_file Optional. Uses $content as filename if true.
632 458 */
633 - protected function load_template( $content, $from_file = true ) {
634 - $predefined_templates = &$this->data['csstidy']['predefined_templates'];
635 - if ( in_array( $content, array( 'default', 'low_compression', 'high_compression', 'highest_compression' ), true ) ) {
636 - $this->template = $predefined_templates[ $content ];
459 + protected function load_template( string $content, bool $from_file = true ): void {
460 + if ( in_array( $content, array( 'default', 'low', 'high', 'highest' ), true ) ) {
461 + $this->template = $this->data['csstidy']['predefined_templates'][ $content ];
637 462 return;
638 463 }
639 464
640 465 if ( $from_file ) {
@@ -639,15 +464,12 @@
639 464
640 465 if ( $from_file ) {
641 466 $content = strip_tags( file_get_contents( $content ), '<span>' );
642 467 }
468 +
643 469 // Unify newlines (because the output also only uses \n).
644 470 $content = str_replace( "\r\n", "\n", $content );
645 - $template = explode( '|', $content );
646 -
647 - for ( $i = 0; $i < count( $template ); $i++ ) {
648 - $this->template[ $i ] = $template[ $i ];
649 - }
471 + $this->template = explode( '|', $content );
650 472 }
651 473
652 474 /**
653 475 * Starts parsing from URL.
@@ -654,12 +476,16 @@
654 476 *
655 477 * @since 1.0.0
656 478 *
657 479 * @param string $url URL.
658 - * @return bool
480 + * @return bool Whether the CSS code could be parsed successfully.
659 481 */
660 - protected function parse_from_url( $url ) {
661 - return $this->parse( @file_get_contents( $url ) );
482 + protected function parse_from_url( string $url ): bool {
483 + $data = file_get_contents( $url );
484 + if ( false === $data ) {
485 + return false;
486 + }
487 + return $this->parse( $data );
662 488 }
663 489
664 490 /**
665 491 * Checks if there is a token at the current position.
@@ -665,14 +491,14 @@
665 491 * Checks if there is a token at the current position.
666 492 *
667 493 * @since 1.0.0
668 494 *
669 - * @param string $string String.
495 + * @param string $a_string String.
670 496 * @param int $i i.
671 497 * @return bool [return value]
672 498 */
673 - protected function is_token( &$string, $i ) {
674 - return ( false !== strpos( $this->tokens_list, $string[ $i ] ) && ! $this->escaped( $string, $i ) );
499 + protected function is_token( string &$a_string, int $i ): bool {
500 + return ( str_contains( $this->tokens_list, $a_string[ $i ] ) && ! $this->escaped( $a_string, $i ) );
675 501 }
676 502
677 503 /**
678 504 * Parses CSS in a string. The output is saved as an array in $this->css.
@@ -678,27 +504,27 @@
678 504 * Parses CSS in a string. The output is saved as an array in $this->css.
679 505 *
680 506 * @since 1.0.0
681 507 *
682 - * @param string $string The CSS code.
683 - * @return bool [return value]
508 + * @param string $a_string The CSS code.
509 + * @return bool Whether the CSS code could be parsed successfully.
684 510 */
685 - public function parse( $string ) {
511 + public function parse( string $a_string ): bool {
686 512 // Temporarily set locale to en_US in order to handle floats properly.
687 - $old = @setlocale( LC_ALL, 0 );
688 - @setlocale( LC_ALL, 'C' );
513 + $old = @setlocale( LC_ALL, '0' ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
514 + @setlocale( LC_ALL, 'C' ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
689 515
690 - $all_properties = &$this->data['csstidy']['all_properties'];
691 516 $at_rules = &$this->data['csstidy']['at_rules'];
692 517 $quoted_string_properties = &$this->data['csstidy']['quoted_string_properties'];
693 518
694 519 $this->css = array();
695 - $this->print->input_css = $string;
696 - $string = str_replace( "\r\n", "\n", $string ) . ' ';
520 + $this->print->input_css = $a_string;
521 + $a_string = str_replace( "\r\n", "\n", $a_string ) . ' ';
697 522 $cur_comment = '';
523 + $cur_at = '';
698 524
699 - for ( $i = 0, $size = strlen( $string ); $i < $size; $i++ ) {
700 - if ( "\n" === $string[ $i ] || "\r" === $string[ $i ] ) {
525 + for ( $i = 0, $size = strlen( $a_string ); $i < $size; $i++ ) {
526 + if ( "\n" === $a_string[ $i ] || "\r" === $a_string[ $i ] ) {
701 527 ++$this->line;
702 528 }
703 529
704 530 switch ( $this->status ) {
@@ -703,59 +529,59 @@
703 529
704 530 switch ( $this->status ) {
705 531 /* Case in at-block */
706 532 case 'at':
707 - if ( $this->is_token( $string, $i ) ) {
708 - if ( '/' === $string[ $i ] && '*' === @$string[ $i + 1 ] ) {
533 + if ( $this->is_token( $a_string, $i ) ) {
534 + if ( '/' === $a_string[ $i ] && '*' === @$a_string[ $i + 1 ] ) { // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
709 535 $this->status = 'ic';
710 536 ++$i;
711 537 $this->from[] = 'at';
712 - } elseif ( '{' === $string[ $i ] ) {
538 + } elseif ( '{' === $a_string[ $i ] ) {
713 539 $this->status = 'is';
714 - $this->at = $this->css_new_media_section( $this->at );
715 - $this->_add_token( AT_START, $this->at );
716 - } elseif ( ',' === $string[ $i ] ) {
717 - $this->at = trim( $this->at ) . ',';
718 - } elseif ( '\\' === $string[ $i ] ) {
719 - $this->at .= $this->_unicode( $string, $i );
540 + $this->at = $this->css_new_media_section( $this->at, $cur_at );
541 + $this->_add_token( self::AT_START, $this->at );
542 + } elseif ( ',' === $a_string[ $i ] ) {
543 + $cur_at = trim( $cur_at ) . ',';
544 + } elseif ( '\\' === $a_string[ $i ] ) {
545 + $cur_at .= $this->_unicode( $a_string, $i );
546 + } elseif ( in_array( $a_string[ $i ], array( '(', ')', ':', '.', '/' ), true ) ) {
547 + // Fix for complicated media, i.e @media screen and (-webkit-min-device-pixel-ratio:1.5).
548 + // '/' is included for ratios in Opera: (-o-min-device-pixel-ratio: 3/2).
549 + $cur_at .= $a_string[ $i ];
720 550 }
721 - // Fix for complicated media, i.e @media screen and (-webkit-min-device-pixel-ratio:1.5)
722 - // '/' is included for ratios in Opera: (-o-min-device-pixel-ratio: 3/2)
723 - elseif ( in_array( $string[ $i ], array( '(', ')', ':', '.', '/' ), true ) ) {
724 - $this->at .= $string[ $i ];
725 - }
726 551 } else {
727 - $lastpos = strlen( $this->at ) - 1;
728 - if ( ! ( ( ctype_space( $this->at[ $lastpos ] ) || $this->is_token( $this->at, $lastpos ) && ',' === $this->at[ $lastpos ] ) && ctype_space( $string[ $i ] ) ) ) {
729 - $this->at .= $string[ $i ];
552 + $lastpos = strlen( $cur_at ) - 1;
553 + if ( ! ( ( ctype_space( $cur_at[ $lastpos ] ) || ( $this->is_token( $cur_at, $lastpos ) && ',' === $cur_at[ $lastpos ] ) ) && ctype_space( $a_string[ $i ] ) ) ) {
554 + $cur_at .= $a_string[ $i ];
730 555 }
731 556 }
732 557 break;
733 558 /* Case in-selector */
734 559 case 'is':
735 - if ( $this->is_token( $string, $i ) ) {
736 - if ( '/' === $string[ $i ] && '*' === @$string[ $i + 1 ] && '' === trim( $this->selector ) ) {
560 + if ( $this->is_token( $a_string, $i ) ) {
561 + if ( '/' === $a_string[ $i ] && '*' === @$a_string[ $i + 1 ] && '' === trim( $this->selector ) ) { // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
737 562 $this->status = 'ic';
738 563 ++$i;
739 564 $this->from[] = 'is';
740 - } elseif ( '@' === $string[ $i ] && '' === trim( $this->selector ) ) {
565 + } elseif ( '@' === $a_string[ $i ] && '' === trim( $this->selector ) ) { // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
741 566 // Check for at-rule.
742 567 $this->invalid_at = true;
743 568 foreach ( $at_rules as $name => $type ) {
744 - if ( ! strcasecmp( substr( $string, $i + 1, strlen( $name ) ), $name ) ) {
569 + if ( ! strcasecmp( substr( $a_string, $i + 1, strlen( $name ) ), $name ) ) {
745 570 if ( 'at' === $type ) {
746 - $this->at = '@' . $name;
571 + $cur_at = '@' . $name;
747 572 } else {
748 573 $this->selector = '@' . $name;
749 574 }
750 575 if ( 'atis' === $type ) {
751 - $this->next_selector_at = ( $this->next_selector_at ? $this->next_selector_at : ( $this->at ? $this->at : DEFAULT_AT ) );
752 - $this->at = $this->css_new_media_section( ' ' );
576 + $this->next_selector_at = ( $this->next_selector_at ? $this->next_selector_at : ( $this->at ? $this->at : self::DEFAULT_AT ) );
577 + $this->at = $this->css_new_media_section( $this->at, ' ', true );
753 578 $type = 'is';
754 579 }
755 580 $this->status = $type;
756 581 $i += strlen( $name );
757 582 $this->invalid_at = false;
583 + break;
758 584 }
759 585 }
760 586
761 587 if ( $this->invalid_at ) {
@@ -761,118 +587,119 @@
761 587 if ( $this->invalid_at ) {
762 588 $this->selector = '@';
763 589 $invalid_at_name = '';
764 590 for ( $j = $i + 1; $j < $size; ++$j ) {
765 - if ( ! ctype_alpha( $string[ $j ] ) ) {
591 + if ( ! ctype_alpha( $a_string[ $j ] ) ) {
766 592 break;
767 593 }
768 - $invalid_at_name .= $string[ $j ];
594 + $invalid_at_name .= $a_string[ $j ];
769 595 }
770 596 $this->log( 'Invalid @-rule: ' . $invalid_at_name . ' (removed)', 'Warning' );
771 597 }
772 - } elseif ( ( '"' === $string[ $i ] || "'" === $string[ $i ] ) ) {
773 - $this->cur_string[] = $string[ $i ];
598 + } elseif ( ( '"' === $a_string[ $i ] || "'" === $a_string[ $i ] ) ) {
599 + $this->cur_string[] = $a_string[ $i ];
774 600 $this->status = 'instr';
775 - $this->str_char[] = $string[ $i ];
601 + $this->str_char[] = $a_string[ $i ];
776 602 $this->from[] = 'is';
777 603 /* Fixing CSS3 attribute selectors, i.e. a[href$=".mp3" */
778 - $this->quoted_string[] = ( '=' === $string[ $i - 1 ] );
779 - } elseif ( $this->invalid_at && ';' === $string[ $i ] ) {
604 + $this->quoted_string[] = ( '=' === $a_string[ $i - 1 ] );
605 + } elseif ( $this->invalid_at && ';' === $a_string[ $i ] ) {
780 606 $this->invalid_at = false;
781 607 $this->status = 'is';
782 608 if ( $this->next_selector_at ) {
783 - $this->at = $this->css_new_media_section( $this->next_selector_at );
609 + $this->at = $this->css_close_media_section( $this->at );
610 + $this->at = $this->css_new_media_section( $this->at, $this->next_selector_at );
784 611 $this->next_selector_at = '';
785 612 }
786 - } elseif ( '{' === $string[ $i ] ) {
613 + } elseif ( '{' === $a_string[ $i ] ) {
787 614 $this->status = 'ip';
788 615 if ( '' === $this->at ) {
789 - $this->at = $this->css_new_media_section( DEFAULT_AT );
616 + $this->at = $this->css_new_media_section( $this->at, (string) self::DEFAULT_AT );
790 617 }
791 618 $this->selector = $this->css_new_selector( $this->at, $this->selector );
792 - $this->_add_token( SEL_START, $this->selector );
619 + $this->_add_token( self::SEL_START, $this->selector );
793 620 $this->added = false;
794 - } elseif ( '}' === $string[ $i ] ) {
795 - $this->_add_token( AT_END, $this->at );
796 - $this->at = '';
621 + } elseif ( '}' === $a_string[ $i ] ) {
622 + $this->_add_token( self::AT_END, $this->at );
623 + $this->at = $this->css_close_media_section( $this->at );
797 624 $this->selector = '';
798 625 $this->sel_separate = array();
799 - } elseif ( ',' === $string[ $i ] ) {
626 + } elseif ( ',' === $a_string[ $i ] ) {
800 627 $this->selector = trim( $this->selector ) . ',';
801 628 $this->sel_separate[] = strlen( $this->selector );
802 - } elseif ( '\\' === $string[ $i ] ) {
803 - $this->selector .= $this->_unicode( $string, $i );
804 - } elseif ( '*' === $string[ $i ] && @in_array( $string[ $i + 1 ], array( '.', '#', '[', ':' ), true ) && ( 0 === $i || '/' !== $string[ $i - 1 ] ) ) {
629 + } elseif ( '\\' === $a_string[ $i ] ) {
630 + $this->selector .= $this->_unicode( $a_string, $i );
631 + } elseif ( '*' === $a_string[ $i ] && @in_array( $a_string[ $i + 1 ], array( '.', '#', '[', ':' ), true ) && ( 0 === $i || '/' !== $a_string[ $i - 1 ] ) ) { // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged,Generic.CodeAnalysis.EmptyStatement.DetectedElseif
805 632 // Remove unnecessary universal selector, FS#147, but not comment in selector.
806 633 } else {
807 - $this->selector .= $string[ $i ];
634 + $this->selector .= $a_string[ $i ];
808 635 }
809 636 } else {
810 637 $lastpos = strlen( $this->selector ) - 1;
811 - if ( -1 === $lastpos || ! ( ( ctype_space( $this->selector[ $lastpos ] ) || $this->is_token( $this->selector, $lastpos ) && ',' === $this->selector[ $lastpos ] ) && ctype_space( $string[ $i ] ) ) ) {
812 - $this->selector .= $string[ $i ];
638 + if ( -1 === $lastpos || ! ( ( ctype_space( $this->selector[ $lastpos ] ) || ( $this->is_token( $this->selector, $lastpos ) && ',' === $this->selector[ $lastpos ] ) ) && ctype_space( $a_string[ $i ] ) ) ) {
639 + $this->selector .= $a_string[ $i ];
813 640 }
814 641 }
815 642 break;
816 643 /* Case in-property */
817 644 case 'ip':
818 - if ( $this->is_token( $string, $i ) ) {
819 - if ( ( ':' === $string[ $i ] || '=' === $string[ $i ] ) && '' !== $this->property ) {
645 + if ( $this->is_token( $a_string, $i ) ) {
646 + if ( ( ':' === $a_string[ $i ] || '=' === $a_string[ $i ] ) && '' !== $this->property ) {
820 647 $this->status = 'iv';
821 648 if ( ! $this->get_cfg( 'discard_invalid_properties' ) || $this->property_is_valid( $this->property ) ) {
822 649 $this->property = $this->css_new_property( $this->at, $this->selector, $this->property );
823 650 $this->property = strtolower( $this->property );
824 - $this->_add_token( PROPERTY, $this->property );
651 + $this->_add_token( self::PROPERTY, $this->property );
825 652 }
826 - } elseif ( '/' === $string[ $i ] && '*' === @$string[ $i + 1 ] && '' === $this->property ) {
653 + } elseif ( '/' === $a_string[ $i ] && '*' === @$a_string[ $i + 1 ] && '' === $this->property ) { // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
827 654 $this->status = 'ic';
828 655 ++$i;
829 656 $this->from[] = 'ip';
830 - } elseif ( '}' === $string[ $i ] ) {
657 + } elseif ( '}' === $a_string[ $i ] ) {
831 658 $this->explode_selectors();
832 659 $this->status = 'is';
833 660 $this->invalid_at = false;
834 - $this->_add_token( SEL_END, $this->selector );
661 + $this->_add_token( self::SEL_END, $this->selector );
835 662 $this->selector = '';
836 663 $this->property = '';
837 664 if ( $this->next_selector_at ) {
838 - $this->at = $this->css_new_media_section( $this->next_selector_at );
665 + $this->at = $this->css_close_media_section( $this->at );
666 + $this->at = $this->css_new_media_section( $this->at, $this->next_selector_at );
839 667 $this->next_selector_at = '';
840 668 }
841 - } elseif ( ';' === $string[ $i ] ) {
669 + } elseif ( ';' === $a_string[ $i ] ) {
842 670 $this->property = '';
843 - } elseif ( '\\' === $string[ $i ] ) {
844 - $this->property .= $this->_unicode( $string, $i );
671 + } elseif ( '\\' === $a_string[ $i ] ) {
672 + $this->property .= $this->_unicode( $a_string, $i );
673 + } elseif ( ( '' === $this->property && ! ctype_space( $a_string[ $i ] ) ) || ( '/' === $this->property || '/' === $a_string[ $i ] ) ) {
674 + // else this is dumb IE a hack, keep it.
675 + // including /.
676 + $this->property .= $a_string[ $i ];
845 677 }
846 - // else this is dumb IE a hack, keep it
847 - // including /
848 - elseif ( ( '' === $this->property && ! ctype_space( $string[ $i ] ) ) || ( '/' === $this->property || '/' === $string[ $i ] ) ) {
849 - $this->property .= $string[ $i ];
850 - }
851 - } elseif ( ! ctype_space( $string[ $i ] ) ) {
852 - $this->property .= $string[ $i ];
678 + } elseif ( ! ctype_space( $a_string[ $i ] ) ) {
679 + $this->property .= $a_string[ $i ];
853 680 }
854 681 break;
855 682 /* Case in-value */
856 683 case 'iv':
857 - $pn = ( ( "\n" === $string[ $i ] || "\r" === $string[ $i ] ) && $this->property_is_next( $string, $i + 1 ) || ( strlen( $string ) - 1 ) === $i );
858 - if ( ( $this->is_token( $string, $i ) || $pn ) && ( ! ( ',' === $string[ $i ] && ! ctype_space( $string[ $i + 1 ] ) ) ) ) {
859 - if ( '/' === $string[ $i ] && '*' === @$string[ $i + 1 ] ) {
684 + $pn = ( ( ( "\n" === $a_string[ $i ] || "\r" === $a_string[ $i ] ) && $this->property_is_next( $a_string, $i + 1 ) ) || ( strlen( $a_string ) - 1 ) === $i );
685 + if ( ( $this->is_token( $a_string, $i ) || $pn ) && ( ! ( ',' === $a_string[ $i ] && ! ctype_space( $a_string[ $i + 1 ] ) ) ) ) {
686 + if ( '/' === $a_string[ $i ] && '*' === @$a_string[ $i + 1 ] ) { // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
860 687 $this->status = 'ic';
861 688 ++$i;
862 689 $this->from[] = 'iv';
863 - } elseif ( ( '"' === $string[ $i ] || "'" === $string[ $i ] || '(' === $string[ $i ] ) ) {
864 - $this->cur_string[] = $string[ $i ];
865 - $this->str_char[] = ( '(' === $string[ $i ] ) ? ')' : $string[ $i ];
690 + } elseif ( ( '"' === $a_string[ $i ] || "'" === $a_string[ $i ] || '(' === $a_string[ $i ] ) ) {
691 + $this->cur_string[] = $a_string[ $i ];
692 + $this->str_char[] = ( '(' === $a_string[ $i ] ) ? ')' : $a_string[ $i ];
866 693 $this->status = 'instr';
867 694 $this->from[] = 'iv';
868 695 $this->quoted_string[] = in_array( strtolower( $this->property ), $quoted_string_properties, true );
869 - } elseif ( ',' === $string[ $i ] ) {
696 + } elseif ( ',' === $a_string[ $i ] ) {
870 697 $this->sub_value = trim( $this->sub_value ) . ',';
871 - } elseif ( '\\' === $string[ $i ] ) {
872 - $this->sub_value .= $this->_unicode( $string, $i );
873 - } elseif ( ';' === $string[ $i ] || $pn ) {
874 - if ( '@' === $this->selector[0] && isset( $at_rules[ substr( $this->selector, 1 ) ] ) && 'iv' === $at_rules[ substr( $this->selector, 1 ) ] ) {
698 + } elseif ( '\\' === $a_string[ $i ] ) {
699 + $this->sub_value .= $this->_unicode( $a_string, $i );
700 + } elseif ( ';' === $a_string[ $i ] || $pn ) {
701 + if ( '' !== $this->selector && '@' === $this->selector[0] && isset( $at_rules[ substr( $this->selector, 1 ) ] ) && 'iv' === $at_rules[ substr( $this->selector, 1 ) ] ) {
875 702 $this->status = 'is';
876 703
877 704 switch ( $this->selector ) {
878 705 case '@charset':
@@ -889,10 +716,10 @@
889 716 $this->sub_value = trim( $this->sub_value );
890 717
891 718 if ( empty( $this->sub_value_arr ) ) {
892 719 // Quote URLs in imports only if they're not already inside url() and not already quoted.
893 - if ( 'url(' !== substr( $this->sub_value, 0, 4 ) ) {
894 - if ( ! ( substr( $this->sub_value, -1 ) === $this->sub_value[0] && in_array( $this->sub_value[0], array( "'", '"' ), true ) ) ) {
720 + if ( ! str_starts_with( $this->sub_value, 'url(' ) ) {
721 + if ( ! str_ends_with( $this->sub_value, $this->sub_value[0] ) && in_array( $this->sub_value[0], array( "'", '"' ), true ) ) {
895 722 $this->sub_value = '"' . $this->sub_value . '"';
896 723 }
897 724 }
898 725 }
@@ -908,14 +735,14 @@
908 735 $this->sel_separate = array();
909 736 } else {
910 737 $this->status = 'ip';
911 738 }
912 - } elseif ( '}' !== $string[ $i ] ) {
913 - $this->sub_value .= $string[ $i ];
739 + } elseif ( '}' !== $a_string[ $i ] ) {
740 + $this->sub_value .= $a_string[ $i ];
914 741 }
915 - if ( ( '}' === $string[ $i ] || ';' === $string[ $i ] || $pn ) && ! empty( $this->selector ) ) {
742 + if ( ( '}' === $a_string[ $i ] || ';' === $a_string[ $i ] || $pn ) && ! empty( $this->selector ) ) {
916 743 if ( '' === $this->at ) {
917 - $this->at = $this->css_new_media_section( DEFAULT_AT );
744 + $this->at = $this->css_new_media_section( $this->at, (string) self::DEFAULT_AT );
918 745 }
919 746
920 747 // Case settings.
921 748 if ( $this->get_cfg( 'lowercase_s' ) ) {
@@ -929,9 +756,9 @@
929 756 $this->sub_value = '';
930 757 }
931 758
932 759 $this->value = '';
933 - while ( count( $this->sub_value_arr ) ) {
760 + while ( count( $this->sub_value_arr ) ) { // phpcs:ignore Squiz.PHP.DisallowSizeFunctionsInLoops.Found
934 761 $sub = array_shift( $this->sub_value_arr );
935 762 if ( strstr( $this->selector, 'font-face' ) ) {
936 763 $sub = $this->quote_font_format( $sub );
937 764 }
@@ -936,9 +763,9 @@
936 763 $sub = $this->quote_font_format( $sub );
937 764 }
938 765
939 766 if ( '' !== $sub ) {
940 - if ( strlen( $this->value ) && ( ',' !== substr( $this->value, -1, 1 ) || $this->get_cfg( 'preserve_css' ) ) ) {
767 + if ( strlen( $this->value ) && ( ! str_ends_with( $this->value, ',' ) || $this->get_cfg( 'preserve_css' ) ) ) {
941 768 $this->value .= ' ';
942 769 }
943 770 $this->value .= $sub;
944 771 }
@@ -948,9 +775,9 @@
948 775
949 776 $valid = $this->property_is_valid( $this->property );
950 777 if ( ( ! $this->invalid_at || $this->get_cfg( 'preserve_css' ) ) && ( ! $this->get_cfg( 'discard_invalid_properties' ) || $valid ) ) {
951 778 $this->css_add_property( $this->at, $this->selector, $this->property, $this->value );
952 - $this->_add_token( VALUE, $this->value );
779 + $this->_add_token( self::VALUE, $this->value );
953 780 $this->optimise->shorthands();
954 781 }
955 782 if ( ! $valid ) {
956 783 if ( $this->get_cfg( 'discard_invalid_properties' ) ) {
@@ -963,23 +790,24 @@
963 790 $this->property = '';
964 791 $this->sub_value_arr = array();
965 792 $this->value = '';
966 793 }
967 - if ( '}' === $string[ $i ] ) {
794 + if ( '}' === $a_string[ $i ] ) {
968 795 $this->explode_selectors();
969 - $this->_add_token( SEL_END, $this->selector );
796 + $this->_add_token( self::SEL_END, $this->selector );
970 797 $this->status = 'is';
971 798 $this->invalid_at = false;
972 799 $this->selector = '';
973 800 if ( $this->next_selector_at ) {
974 - $this->at = $this->css_new_media_section( $this->next_selector_at );
801 + $this->at = $this->css_close_media_section( $this->at );
802 + $this->at = $this->css_new_media_section( $this->at, $this->next_selector_at );
975 803 $this->next_selector_at = '';
976 804 }
977 805 }
978 806 } elseif ( ! $pn ) {
979 - $this->sub_value .= $string[ $i ];
807 + $this->sub_value .= $a_string[ $i ];
980 808
981 - if ( ctype_space( $string[ $i ] ) || ',' === $string[ $i ] ) {
809 + if ( ctype_space( $a_string[ $i ] ) || ',' === $a_string[ $i ] ) {
982 810 $this->optimise->subvalue();
983 811 if ( '' !== $this->sub_value ) {
984 812 $this->sub_value_arr[] = $this->sub_value;
985 813 $this->sub_value = '';
@@ -991,21 +819,21 @@
991 819 case 'instr':
992 820 $_str_char = $this->str_char[ count( $this->str_char ) - 1 ];
993 821 $_cur_string = $this->cur_string[ count( $this->cur_string ) - 1 ];
994 822 $_quoted_string = $this->quoted_string[ count( $this->quoted_string ) - 1 ];
995 - $temp_add = $string[ $i ];
823 + $temp_add = $a_string[ $i ];
996 824
997 825 // Add another string to the stack. Strings can't be nested inside of quotes, only parentheses,
998 826 // but parentheticals can be nested more than once.
999 - if ( ')' === $_str_char && ( '(' === $string[ $i ] || '"' === $string[ $i ] || '\\' === $string[ $i ] ) && ! $this->escaped( $string, $i ) ) {
1000 - $this->cur_string[] = $string[ $i ];
1001 - $this->str_char[] = ( '(' === $string[ $i ] ) ? ')' : $string[ $i ];
827 + if ( ')' === $_str_char && ( '(' === $a_string[ $i ] || '"' === $a_string[ $i ] || '\\' === $a_string[ $i ] ) && ! $this->escaped( $a_string, $i ) ) {
828 + $this->cur_string[] = $a_string[ $i ];
829 + $this->str_char[] = ( '(' === $a_string[ $i ] ) ? ')' : $a_string[ $i ];
1002 830 $this->from[] = 'instr';
1003 - $this->quoted_string[] = ( ')' === $_str_char && '(' !== $string[ $i ] && '(' === trim( $_cur_string ) ) ? $_quoted_string : ( '(' !== $string[ $i ] );
831 + $this->quoted_string[] = ( ')' === $_str_char && '(' !== $a_string[ $i ] && '(' === trim( $_cur_string ) ) ? $_quoted_string : ( '(' !== $a_string[ $i ] );
1004 832 continue 2;
1005 833 }
1006 834
1007 - if ( ')' !== $_str_char && ( "\n" === $string[ $i ] || "\r" === $string[ $i ] ) && ! ( '\\' === $string[ $i - 1 ] && ! $this->escaped( $string, $i - 1 ) ) ) {
835 + if ( ')' !== $_str_char && ( "\n" === $a_string[ $i ] || "\r" === $a_string[ $i ] ) && ! ( '\\' === $a_string[ $i - 1 ] && ! $this->escaped( $a_string, $i - 1 ) ) ) {
1008 836 $temp_add = '\\A';
1009 837 $this->log( 'Fixed incorrect newline in string', 'Warning' );
1010 838 }
1011 839
@@ -1010,22 +838,24 @@
1010 838 }
1011 839
1012 840 $_cur_string .= $temp_add;
1013 841
1014 - if ( $string[ $i ] === $_str_char && ! $this->escaped( $string, $i ) ) {
842 + if ( $a_string[ $i ] === $_str_char && ! $this->escaped( $a_string, $i ) ) {
1015 843 $this->status = array_pop( $this->from );
1016 844
1017 845 if ( ! preg_match( '|[' . implode( '', $this->data['csstidy']['whitespace'] ) . ']|uis', $_cur_string ) && 'content' !== $this->property ) {
1018 846 if ( ! $_quoted_string ) {
1019 847 if ( ')' !== $_str_char ) {
1020 - // Convert properties like
1021 - // font-family: 'Arial';
1022 - // to
1023 - // font-family: Arial;
1024 - // or
1025 - // url("abc")
1026 - // to
1027 - // url(abc)
848 + /*
849 + * Convert properties like
850 + * font-family: 'Arial';
851 + * to
852 + * font-family: Arial;
853 + * or
854 + * url("abc")
855 + * to
856 + * url(abc)
857 + */
1028 858 $_cur_string = substr( $_cur_string, 1, -1 );
1029 859 }
1030 860 } else {
1031 861 $_quoted_string = false;
@@ -1041,14 +871,14 @@
1041 871 }
1042 872
1043 873 if ( 'iv' === $this->status ) {
1044 874 if ( ! $_quoted_string ) {
1045 - if ( false !== strpos( $_cur_string, ',' ) ) {
1046 - // We can on only remove space next to ','
875 + if ( str_contains( $_cur_string, ',' ) ) {
876 + // We can on only remove space next to ','.
1047 877 $_cur_string = implode( ',', array_map( 'trim', explode( ',', $_cur_string ) ) );
1048 878 }
1049 879 // and multiple spaces (too expensive).
1050 - if ( false !== strpos( $_cur_string, ' ' ) ) {
880 + if ( str_contains( $_cur_string, ' ' ) ) {
1051 881 $_cur_string = preg_replace( ',\s+,', ' ', $_cur_string );
1052 882 }
1053 883 }
1054 884 $this->sub_value .= $_cur_string;
@@ -1062,15 +892,20 @@
1062 892 }
1063 893 break;
1064 894 /* Case in-comment */
1065 895 case 'ic':
1066 - if ( '*' === $string[ $i ] && '/' === $string[ $i + 1 ] ) {
896 + if ( '*' === $a_string[ $i ] && '/' === $a_string[ $i + 1 ] ) {
1067 897 $this->status = array_pop( $this->from );
1068 - $i++;
1069 - $this->_add_token( COMMENT, $cur_comment );
898 + ++$i;
899 + if ( strlen( $cur_comment ) > 1 && str_starts_with( $cur_comment, '!' ) ) {
900 + $this->_add_token( self::IMPORTANT_COMMENT, $cur_comment );
901 + $this->css_add_important_comment( $cur_comment );
902 + } else {
903 + $this->_add_token( self::COMMENT, $cur_comment );
904 + }
1070 905 $cur_comment = '';
1071 906 } else {
1072 - $cur_comment .= $string[ $i ];
907 + $cur_comment .= $a_string[ $i ];
1073 908 }
1074 909 break;
1075 910 }
1076 911 }
@@ -1078,23 +913,23 @@
1078 913 $this->optimise->postparse();
1079 914 $this->print->_reset();
1080 915
1081 916 // Set locale back to original setting.
1082 - @setlocale( LC_ALL, $old );
917 + @setlocale( LC_ALL, $old ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
1083 918
1084 919 return ! ( empty( $this->css ) && empty( $this->import ) && empty( $this->charset ) && empty( $this->tokens ) && empty( $this->namespace ) );
1085 920 }
1086 921
1087 922 /**
1088 - * format() in font-face needs quoted values for somes browser (FF at least).
923 + * Quoting: format() in font-face needs quoted values for some browser (FF at least).
1089 924 *
1090 925 * @since 1.0.0
1091 926 *
1092 - * @param mixed $value Value.
927 + * @param string $value Value.
1093 928 * @return string String.
1094 929 */
1095 - protected function quote_font_format( $value ) {
1096 - if ( 0 === strncmp( $value, 'format', 6 ) ) {
930 + protected function quote_font_format( string $value ): string {
931 + if ( str_starts_with( $value, 'format' ) ) {
1097 932 $p = strpos( $value, ')', 7 );
1098 933 $end = substr( $value, $p );
1099 934 $format_strings = $this->parse_string_list( substr( $value, 7, $p - 7 ) );
1100 935 if ( ! $format_strings ) {
@@ -1114,9 +949,9 @@
1114 949 * Explodes selectors.
1115 950 *
1116 951 * @since 1.0.0
1117 952 */
1118 - protected function explode_selectors() {
953 + protected function explode_selectors(): void {
1119 954 // Explode multiple selectors.
1120 955 if ( 1 === $this->get_cfg( 'merge_selectors' ) ) {
1121 956 $new_sels = array();
1122 957 $lastpos = 0;
@@ -1122,9 +957,9 @@
1122 957 $lastpos = 0;
1123 958 $this->sel_separate[] = strlen( $this->selector );
1124 959 foreach ( $this->sel_separate as $num => $pos ) {
1125 960 if ( ( count( $this->sel_separate ) - 1 ) === $num ) {
1126 - $pos += 1;
961 + ++$pos;
1127 962 }
1128 963
1129 964 $new_sels[] = substr( $this->selector, $lastpos, $pos - $lastpos - 1 );
1130 965 $lastpos = $pos;
@@ -1142,21 +977,40 @@
1142 977 $this->sel_separate = array();
1143 978 }
1144 979
1145 980 /**
1146 - * Checks if a character is escaped (and returns true if it is).
981 + * Checks if a character is escaped.
1147 982 *
1148 983 * @since 1.0.0
1149 984 *
1150 - * @param string $string String.
985 + * @param string $a_string String.
1151 986 * @param int $pos Position.
1152 - * @return bool [return value]
987 + * @return bool Whether a character is escaped.
1153 988 */
1154 - public function escaped( &$string, $pos ) {
1155 - return $pos ? ! ( @( '\\' !== $string[ $pos - 1 ] ) || $this->escaped( $string, $pos - 1 ) ) : false;
989 + public function escaped( string &$a_string, int $pos ): bool {
990 + return $pos ? ! ( @( '\\' !== $a_string[ $pos - 1 ] ) || $this->escaped( $a_string, $pos - 1 ) ) : false; // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged
1156 991 }
1157 992
1158 993 /**
994 + * Adds an important comment to the CSS code (one we want to keep when minifying).
995 + *
996 + * @since 1.10.0
997 + *
998 + * @param string $comment CSS Comment.
999 + */
1000 + protected function css_add_important_comment( string $comment ): void {
1001 + if ( $this->get_cfg( 'preserve_css' ) || '' === trim( $comment ) ) {
1002 + return;
1003 + }
1004 + if ( ! isset( $this->css['!'] ) ) {
1005 + $this->css['!'] = '';
1006 + } else {
1007 + $this->css['!'] .= "\n";
1008 + }
1009 + $this->css['!'] .= $comment;
1010 + }
1011 +
1012 + /**
1159 1013 * Adds a property with value to the existing CSS code.
1160 1014 *
1161 1015 * @since 1.0.0
1162 1016 *
@@ -1164,9 +1018,9 @@
1164 1018 * @param string $selector Selector.
1165 1019 * @param string $property Property.
1166 1020 * @param string $new_val New value.
1167 1021 */
1168 - protected function css_add_property( $media, $selector, $property, $new_val ) {
1022 + protected function css_add_property( string $media, string $selector, string $property, string $new_val ): void {
1169 1023 if ( $this->get_cfg( 'preserve_css' ) || '' === trim( $new_val ) ) {
1170 1024 return;
1171 1025 }
1172 1026
@@ -1180,33 +1034,30 @@
1180 1034 }
1181 1035 }
1182 1036
1183 1037 /**
1184 - * Start a new media section.
1038 + * Checks if a current media section is the continuation of the last one.
1039 + * If not increase the name of the media section to avoid a merging.
1185 1040 *
1186 - * Check if the media is not already known, else rename it with extra spaces to avoid merging.
1041 + * @since 1.10.0
1187 1042 *
1188 - * @since 1.0.0
1189 - *
1190 - * @param string $media Media.
1191 - * @return string [return value]
1043 + * @param int|string $media Media.
1044 + * @return int|string [return value]
1192 1045 */
1193 - protected function css_new_media_section( $media ) {
1194 - if ( $this->get_cfg( 'preserve_css' ) ) {
1046 + protected function css_check_last_media_section_or_inc( $media ) /* : int|string */ {
1047 + // Are we starting?
1048 + if ( empty( $this->css ) || ! is_array( $this->css ) ) {
1195 1049 return $media;
1196 1050 }
1197 1051 // If the last @media is the same as this, keep it.
1198 - if ( ! $this->css || ! is_array( $this->css ) || empty( $this->css ) ) {
1199 - return $media;
1200 - }
1201 - end( $this->css );
1202 - $at = key( $this->css );
1052 + $at = array_key_last( $this->css );
1203 1053 if ( $at === $media ) {
1204 1054 return $media;
1205 1055 }
1056 + // Otherwise increase the section in the array.
1206 1057 while ( isset( $this->css[ $media ] ) ) {
1207 1058 if ( is_numeric( $media ) ) {
1208 - $media++;
1059 + ++$media;
1209 1060 } else {
1210 1061 $media .= ' ';
1211 1062 }
1212 1063 }
@@ -1213,10 +1064,61 @@
1213 1064 return $media;
1214 1065 }
1215 1066
1216 1067 /**
1217 - * Start a new selector.
1068 + * Starts a new media section.
1218 1069 *
1070 + * Check if the media is not already known, else rename it with extra spaces to avoid merging.
1071 + *
1072 + * @since 1.0.0
1073 + *
1074 + * @param string|int $current_media Media.
1075 + * @param string $new_media Media.
1076 + * @param bool $at_root Optional. Default false.
1077 + * @return int|string [return value]
1078 + */
1079 + protected function css_new_media_section( $current_media, string $new_media, bool $at_root = false ) /* : int|string */ {
1080 + if ( $this->get_cfg( 'preserve_css' ) ) {
1081 + return $new_media;
1082 + }
1083 + // If we already are in a media and CSS level is 3, manage nested medias.
1084 + if ( $current_media
1085 + && ! $at_root
1086 + // Numeric $current_media means self::DEFAULT_AT or inc.
1087 + && ! is_numeric( $current_media )
1088 + && str_starts_with( $this->get_cfg( 'css_level' ), 'CSS3' ) ) {
1089 + $new_media = rtrim( $current_media ) . '{' . rtrim( $new_media );
1090 + }
1091 + return $this->css_check_last_media_section_or_inc( $new_media );
1092 + }
1093 +
1094 + /**
1095 + * Closes a media section.
1096 + *
1097 + * Finds the parent media we were in before or the root.
1098 + *
1099 + * @since 1.10.0
1100 + *
1101 + * @param string $current_media Current Media.
1102 + * @return string [return value]
1103 + */
1104 + protected function css_close_media_section( string $current_media ): string {
1105 + if ( $this->get_cfg( 'preserve_css' ) ) {
1106 + return '';
1107 + }
1108 + if ( str_contains( $current_media, '{' ) ) {
1109 + $current_media = explode( '{', $current_media );
1110 + array_pop( $current_media );
1111 + $current_media = implode( '{', $current_media );
1112 + return $current_media;
1113 + }
1114 +
1115 + return '';
1116 + }
1117 +
1118 + /**
1119 + * Starts a new selector.
1120 + *
1219 1121 * If already referenced in this media section, rename it with extra space to avoid merging,
1220 1122 * except if merging is required, or last selector is the same (merge siblings).
1221 1123 * Never merge @font-face.
1222 1124 *
@@ -1225,25 +1127,24 @@
1225 1127 * @param string $media Media.
1226 1128 * @param string $selector Selector.
1227 1129 * @return string [return value]
1228 1130 */
1229 - protected function css_new_selector( $media, $selector ) {
1131 + protected function css_new_selector( string $media, string $selector ): string {
1230 1132 if ( $this->get_cfg( 'preserve_css' ) ) {
1231 1133 return $selector;
1232 1134 }
1233 1135 $selector = trim( $selector );
1234 - if ( 0 !== strncmp( $selector, '@font-face', 10 ) ) {
1136 + if ( ! str_starts_with( $selector, '@font-face' ) ) {
1235 1137 if ( false !== $this->settings['merge_selectors'] ) {
1236 1138 return $selector;
1237 1139 }
1238 1140
1239 - if ( ! $this->css || ! isset( $this->css[ $media ] ) || ! $this->css[ $media ] ) {
1141 + if ( empty( $this->css ) || ! isset( $this->css[ $media ] ) || ! $this->css[ $media ] ) {
1240 1142 return $selector;
1241 1143 }
1242 1144
1243 1145 // If last is the same, keep it.
1244 - end( $this->css[ $media ] );
1245 - $sel = key( $this->css[ $media ] );
1146 + $sel = array_key_last( $this->css[ $media ] );
1246 1147 if ( $sel === $selector ) {
1247 1148 return $selector;
1248 1149 }
1249 1150 }
@@ -1254,11 +1155,11 @@
1254 1155 return $selector;
1255 1156 }
1256 1157
1257 1158 /**
1258 - * Start a new property.
1159 + * Starts a new property.
1259 1160 *
1260 - * If already references in this selector, rename it with extra space to avoid override.
1161 + * If already referenced in this selector, rename it with extra space to avoid override.
1261 1162 *
1262 1163 * @since 1.0.0
1263 1164 *
1264 1165 * @param string $media Media.
@@ -1265,13 +1166,13 @@
1265 1166 * @param string $selector Selector.
1266 1167 * @param string $property Property.
1267 1168 * @return string [return value]
1268 1169 */
1269 - protected function css_new_property( $media, $selector, $property ) {
1170 + protected function css_new_property( string $media, string $selector, string $property ): string {
1270 1171 if ( $this->get_cfg( 'preserve_css' ) ) {
1271 1172 return $property;
1272 1173 }
1273 - if ( ! $this->css || ! isset( $this->css[ $media ][ $selector ] ) || ! $this->css[ $media ][ $selector ] ) {
1174 + if ( empty( $this->css ) || ! isset( $this->css[ $media ][ $selector ] ) || ! $this->css[ $media ][ $selector ] ) {
1274 1175 return $property;
1275 1176 }
1276 1177
1277 1178 while ( isset( $this->css[ $media ][ $selector ][ $property ] ) ) {
@@ -1285,13 +1186,13 @@
1285 1186 * Adds CSS to an existing media/selector.
1286 1187 *
1287 1188 * @since 1.0.0
1288 1189 *
1289 - * @param string $media Media.
1290 - * @param string $selector Selector.
1291 - * @param array $css_add Additional CSS.
1190 + * @param string $media Media.
1191 + * @param string $selector Selector.
1192 + * @param array<string, string> $css_add Additional CSS.
1292 1193 */
1293 - public function merge_css_blocks( $media, $selector, array $css_add ) {
1194 + public function merge_css_blocks( string $media, string $selector, array $css_add ): void {
1294 1195 foreach ( $css_add as $property => $value ) {
1295 1196 $this->css_add_property( $media, $selector, $property, $value );
1296 1197 }
1297 1198 }
@@ -1303,11 +1204,11 @@
1303 1204 *
1304 1205 * @param string $value Value.
1305 1206 * @return bool Whether the value has the !important keyword.
1306 1207 */
1307 - public function is_important( &$value ) {
1208 + public function is_important( string &$value ): bool {
1308 1209 return (
1309 - false !== strpos( $value, '!' ) // Quick test.
1210 + str_contains( $value, '!' ) // Quick test.
1310 1211 && ! strcasecmp( substr( str_replace( $this->data['csstidy']['whitespace'], '', $value ), -10, 10 ), '!important' ) );
1311 1212 }
1312 1213
1313 1214 /**
@@ -1317,9 +1218,9 @@
1317 1218 *
1318 1219 * @param string $value Value.
1319 1220 * @return string Value without the !important;
1320 1221 */
1321 - public function gvw_important( $value ) {
1222 + public function gvw_important( string $value ): string {
1322 1223 if ( $this->is_important( $value ) ) {
1323 1224 $value = trim( $value );
1324 1225 $value = substr( $value, 0, -9 );
1325 1226 $value = trim( $value );
@@ -1338,9 +1239,9 @@
1338 1239 * @param string $istring String.
1339 1240 * @param int $pos Position.
1340 1241 * @return bool [return value]
1341 1242 */
1342 - protected function property_is_next( $istring, $pos ) {
1243 + protected function property_is_next( string $istring, int $pos ): bool {
1343 1244 $all_properties = &$this->data['csstidy']['all_properties'];
1344 1245 $istring = substr( $istring, $pos, strlen( $istring ) - $pos );
1345 1246 $pos = strpos( $istring, ':' );
1346 1247 if ( false === $pos ) {
@@ -1361,15 +1262,17 @@
1361 1262 *
1362 1263 * @param string $property Property.
1363 1264 * @return bool Whether the property is valid.
1364 1265 */
1365 - public function property_is_valid( $property ) {
1266 + public function property_is_valid( string $property ): bool {
1366 1267 $property = strtolower( $property );
1367 - if ( in_array( trim( $property ), $this->data['csstidy']['multiple_properties'], true ) ) {
1268 + if ( str_starts_with( $property, '--' ) ) {
1269 + $property = '--custom'; // Replace custom properties with a temporary placeholder that is marked as valid in the list of properties.
1270 + } elseif ( in_array( trim( $property ), $this->data['csstidy']['multiple_properties'], true ) ) {
1368 1271 $property = trim( $property );
1369 1272 }
1370 1273 $all_properties = &$this->data['csstidy']['all_properties'];
1371 - return isset( $all_properties[ $property ] ) && false !== strpos( $all_properties[ $property ], strtoupper( $this->get_cfg( 'css_level' ) ) );
1274 + return isset( $all_properties[ $property ] ) && str_contains( $all_properties[ $property ], strtoupper( $this->get_cfg( 'css_level' ) ) );
1372 1275 }
1373 1276
1374 1277 /**
1375 1278 * Accepts a list of strings (e.g. the argument to format() in a @font-face src property)
@@ -1382,20 +1285,20 @@
1382 1285 * format("abc, def, ghi") => format("abc, def, ghi")
1383 1286 *
1384 1287 * @since 1.0.0
1385 1288 *
1386 - * @param [type] $value [description]
1387 - * @return [type] [description]
1289 + * @param string $value [description].
1290 + * @return string[] [description]
1388 1291 */
1389 - public function parse_string_list( $value ) {
1292 + public function parse_string_list( string $value ): array {
1390 1293 $value = trim( $value );
1391 1294
1392 - // Case: empty
1295 + // Case: empty.
1393 1296 if ( ! $value ) {
1394 1297 return array();
1395 1298 }
1396 1299
1397 - $strings = array();
1300 + $a_strings = array();
1398 1301
1399 1302 $in_str = false;
1400 1303 $current_string = '';
1401 1304
@@ -1401,13 +1304,13 @@
1401 1304
1402 1305 for ( $i = 0, $_len = strlen( $value ); $i < $_len; $i++ ) {
1403 1306 if ( ( ',' === $value[ $i ] || ' ' === $value[ $i ] ) && true === $in_str ) {
1404 1307 $in_str = false;
1405 - $strings[] = $current_string;
1308 + $a_strings[] = $current_string;
1406 1309 $current_string = '';
1407 1310 } elseif ( '"' === $value[ $i ] || "'" === $value[ $i ] ) {
1408 1311 if ( $in_str === $value[ $i ] ) {
1409 - $strings[] = $current_string;
1312 + $a_strings[] = $current_string;
1410 1313 $in_str = false;
1411 1314 $current_string = '';
1412 1315 continue;
1413 1316 } elseif ( ! $in_str ) {
@@ -1412,12 +1315,12 @@
1412 1315 continue;
1413 1316 } elseif ( ! $in_str ) {
1414 1317 $in_str = $value[ $i ];
1415 1318 }
1416 - } else {
1319 + } else { // phpcs:ignore Universal.ControlStructures.DisallowLonelyIf.Found
1417 1320 if ( $in_str ) {
1418 1321 $current_string .= $value[ $i ];
1419 - } else {
1322 + } else { // phpcs:ignore Universal.ControlStructures.DisallowLonelyIf.Found
1420 1323 if ( ! preg_match( '/[\s,]/', $value[ $i ] ) ) {
1421 1324 $in_str = true;
1422 1325 $current_string = $value[ $i ];
1423 1326 }
@@ -1425,11 +1328,11 @@
1425 1328 }
1426 1329 }
1427 1330
1428 1331 if ( $current_string ) {
1429 - $strings[] = $current_string;
1332 + $a_strings[] = $current_string;
1430 1333 }
1431 1334
1432 - return $strings;
1335 + return $a_strings;
1433 1336 }
1434 1337
1435 1338 } // class TablePress_CSSTidy