true, 'add_filter' => true, ]; /** * CSS properties this sniff is looking for. * * @since WPCS 0.11.0 * * @var array */ protected $target_css_properties = [ 'visibility' => [ 'type' => '!=', 'value' => 'hidden', ], 'display' => [ 'type' => '!=', 'value' => 'none', ], 'opacity' => [ 'type' => '>', 'value' => 0.3, ], ]; /** * CSS selectors this sniff is looking for. * * @since WPCS 0.11.0 * * @var array */ protected $target_css_selectors = [ '.show-admin-bar', '#wpadminbar', ]; /** * Regex template for use with the CSS selectors in combination with PHP text strings. * * @since WPCS 0.11.0 * * @var string */ private $target_css_selectors_regex = '`(?:%s).*?\{(.*)$`'; /** * Property to keep track of whether a ' ) ) { // Make sure we check any content on this line before the closing style tag. $this->in_style[ $file_name ] = false; $content = trim( substr( $content, 0, strpos( $content, '' ) ) ); } } elseif ( false !== strpos( $content, ' open tag. if ( false === strpos( $content, '' ) ) { // Make sure we check any content on this line after the opening style tag. $this->in_style[ $file_name ] = true; $content = trim( substr( $content, ( strpos( $content, '' ); $content = trim( substr( $content, $start, ( $end - $start ) ) ); unset( $start, $end ); } } else { return; } // Are we in one of the target selectors ? if ( true === $this->in_target_selector[ $file_name ] ) { if ( false !== strpos( $content, '}' ) ) { // Make sure we check any content on this line before the selector closing brace. $this->in_target_selector[ $file_name ] = false; $content = trim( substr( $content, 0, strpos( $content, '}' ) ) ); } } elseif ( preg_match( $this->target_css_selectors_regex, $content, $matches ) > 0 ) { // Ok, found a new target selector. $content = ''; if ( isset( $matches[1] ) && '' !== $matches[1] ) { if ( false === strpos( $matches[1], '}' ) ) { // Make sure we check any content on this line before the closing brace. $this->in_target_selector[ $file_name ] = true; $content = trim( $matches[1] ); } else { // Ok, we have the selector open and close brace on the same line. $content = trim( substr( $matches[1], 0, strpos( $matches[1], '}' ) ) ); } } else { $this->in_target_selector[ $file_name ] = true; } } else { return; } unset( $matches ); // Now let's do the check for the CSS properties. if ( ! empty( $content ) ) { foreach ( $this->target_css_properties as $property => $requirements ) { if ( false !== strpos( $content, $property ) ) { $error = true; if ( true === $this->remove_only ) { // Check the value of the CSS property. if ( preg_match( '`' . preg_quote( $property, '`' ) . '\s*:\s*(.+?)\s*(?:!important)?;`', $content, $matches ) > 0 ) { $value = trim( $matches[1] ); $valid = $this->validate_css_property_value( $value, $requirements['type'], $requirements['value'] ); if ( true === $valid ) { $error = false; } } } if ( true === $error ) { $this->phpcsFile->addError( 'Hiding of the admin bar is not allowed.', $stackPtr, 'HidingDetected' ); } } } } } /** * Processes this test for T_STYLE tokens in CSS files. * * @since WPCS 0.11.0 * * @param int $stackPtr The position of the current token in the stack passed in $tokens. * * @return void */ protected function process_css_style( $stackPtr ) { if ( ! isset( $this->target_css_properties[ $this->tokens[ $stackPtr ]['content'] ] ) ) { // Not one of the CSS properties we're interested in. return; } $css_property = $this->target_css_properties[ $this->tokens[ $stackPtr ]['content'] ]; // Check if the CSS selector matches. $opener = $this->phpcsFile->findPrevious( \T_OPEN_CURLY_BRACKET, $stackPtr ); if ( false !== $opener ) { for ( $i = ( $opener - 1 ); $i >= 0; $i-- ) { if ( isset( Tokens::$commentTokens[ $this->tokens[ $i ]['code'] ] ) || \T_CLOSE_CURLY_BRACKET === $this->tokens[ $i ]['code'] ) { break; } } $start = ( $i + 1 ); $selector = trim( $this->phpcsFile->getTokensAsString( $start, ( $opener - $start ) ) ); unset( $i ); foreach ( $this->target_css_selectors as $target_selector ) { if ( false !== strpos( $selector, $target_selector ) ) { $error = true; if ( true === $this->remove_only ) { // Check the value of the CSS property. $valuePtr = $this->phpcsFile->findNext( [ \T_COLON, \T_WHITESPACE ], ( $stackPtr + 1 ), null, true ); $value = $this->tokens[ $valuePtr ]['content']; $valid = $this->validate_css_property_value( $value, $css_property['type'], $css_property['value'] ); if ( true === $valid ) { $error = false; } } if ( true === $error ) { $this->phpcsFile->addError( 'Hiding of the admin bar is not allowed.', $stackPtr, 'HidingDetected' ); } } } } } /** * Verify if a CSS property value complies with an expected value. * * {@internal This is a method stub, doing only what is needed for this sniff. * If at some point in the future other sniff would need similar functionality, * this method should be moved to the WordPress_Sniff class and expanded to cover * all types of comparisons.}} * * @since WPCS 0.11.0 * * @param mixed $value The value of CSS property. * @param string $compare_type The type of comparison to use for the validation. * @param string $compare_value The value to compare against. * * @return bool True if the property value complies, false otherwise. */ protected function validate_css_property_value( $value, $compare_type, $compare_value ) { switch ( $compare_type ) { case '!=': return $value !== $compare_value; case '>': return $value > $compare_value; default: return false; } } }