]> scripts.mit.edu Git - autoinstallsdev/mediawiki.git/blob - vendor/wikimedia/css-sanitizer/src/Util.php
MediaWiki 1.30.2
[autoinstallsdev/mediawiki.git] / vendor / wikimedia / css-sanitizer / src / Util.php
1 <?php
2 /**
3  * @file
4  * @license https://opensource.org/licenses/Apache-2.0 Apache-2.0
5  */
6
7 namespace Wikimedia\CSS;
8
9 use Wikimedia\CSS\Objects\ComponentValue;
10 use Wikimedia\CSS\Objects\ComponentValueList;
11 use Wikimedia\CSS\Objects\CSSObject;
12 use Wikimedia\CSS\Objects\Token;
13 use Wikimedia\CSS\Objects\TokenList;
14
15 /**
16  * Static utility functions
17  */
18 class Util {
19
20         /**
21          * Check that all elements in an array implement a particular class
22          * @param array $array
23          * @param string $class
24          * @param string $what Describe the array being checked
25          * @throws \InvalidArgumentException
26          */
27         public static function assertAllInstanceOf( array $array, $class, $what ) {
28                 foreach ( $array as $k => $v ) {
29                         if ( !$v instanceof $class ) {
30                                 $vtype = is_object( $v ) ? get_class( $v ) : gettype( $v );
31                                 throw new \InvalidArgumentException(
32                                         "$what may only contain instances of $class" .
33                                                 " (found $vtype at index $k)"
34                                 );
35                         }
36                 }
37         }
38
39         /**
40          * Check that a set of tokens are all of the same type
41          * @param Token[] $array
42          * @param string $type
43          * @param string $what Describe the array being checked
44          * @throws \InvalidArgumentException
45          */
46         public static function assertAllTokensOfType( array $array, $type, $what ) {
47                 foreach ( $array as $k => $v ) {
48                         if ( !$v instanceof Token ) {
49                                 $vtype = is_object( $v ) ? get_class( $v ) : gettype( $v );
50                                 throw new \InvalidArgumentException(
51                                         "$what may only contain instances of " . Token::class .
52                                                 " (found $vtype at index $k)"
53                                 );
54                         }
55                         if ( $v->type() !== $type ) {
56                                 throw new \InvalidArgumentException(
57                                         "$what may only contain \"$type\" tokens" .
58                                                 " (found \"{$v->type()}\" at index $k)"
59                                 );
60                         }
61                 }
62         }
63
64         /**
65          * Find the first non-whitespace ComponentValue in a list
66          * @param TokenList|ComponentValueList $list
67          * @return ComponentValue|null
68          */
69         public static function findFirstNonWhitespace( $list ) {
70                 if ( !$list instanceof TokenList && !$list instanceof ComponentValueList ) {
71                         throw new \InvalidArgumentException( 'List must be TokenList or ComponentValueList' );
72                 }
73                 foreach ( $list as $v ) {
74                         if ( !$v instanceof Token || $v->type() !== Token::T_WHITESPACE ) {
75                                 return $v;
76                         }
77                 }
78                 return null;
79         }
80
81         /**
82          * Turn a CSSObject into a string
83          * @param CSSObject $object
84          * @param array $options Serialziation options:
85          *  - minify: (bool) Skip comments and insignificant tokens
86          * @return string
87          */
88         public static function stringify( CSSObject $object, $options = [] ) {
89                 $tokens = $object->toTokenArray();
90                 if ( !$tokens ) {
91                         return '';
92                 }
93
94                 if ( !empty( $options['minify'] ) ) {
95                         // Last second check for significant whitespace
96                         $e = count( $tokens ) - 1;
97                         for ( $i = 1; $i < $e; $i++ ) {
98                                 $t = $tokens[$i];
99                                 if ( $t->type() === Token::T_WHITESPACE && !$t->significant() &&
100                                         Token::separate( $tokens[$i-1], $tokens[$i+1] )
101                                 ) {
102                                         $tokens[$i] = $t->copyWithSignificance( true );
103                                 }
104                         }
105
106                         // Filter!
107                         $tokens = array_filter( $tokens, function ( $t ) {
108                                 return $t->significant();
109                         } );
110                 }
111
112                 $prev = reset( $tokens );
113                 $ret = (string)$prev;
114                 while ( ( $token = next( $tokens ) ) !== false ) {
115                         if ( Token::separate( $prev, $token ) ) {
116                                 // Per https://www.w3.org/TR/2014/CR-css-syntax-3-20140220/#serialization
117                                 $ret .= '/**/';
118                         }
119                         $ret .= (string)$token;
120                         $prev = $token;
121                 }
122                 return $ret;
123         }
124 }