PHP_CodeSniffer
[ class tree: PHP_CodeSniffer ] [ index: PHP_CodeSniffer ] [ all elements ]

Source for file ShorthandSizeSniff.php

Documentation is available at ShorthandSizeSniff.php

  1. <?php
  2. /**
  3.  * Ensure sizes are defined using shorthand notation where possible.
  4.  *
  5.  * @author    Greg Sherwood <gsherwood@squiz.net>
  6.  * @copyright 2006-2015 Squiz Pty Ltd (ABN 77 084 670 600)
  7.  * @license   https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
  8.  */
  9.  
  10. namespace PHP_CodeSniffer\Standards\Squiz\Sniffs\CSS;
  11.  
  12. use PHP_CodeSniffer\Sniffs\Sniff;
  13. use PHP_CodeSniffer\Files\File;
  14.  
  15. class ShorthandSizeSniff implements Sniff
  16. {
  17.  
  18.     /**
  19.      * A list of tokenizers this sniff supports.
  20.      *
  21.      * @var array 
  22.      */
  23.     public $supportedTokenizers = array('CSS');
  24.  
  25.     /**
  26.      * A list of styles that we shouldn't check.
  27.      *
  28.      * These have values that looks like sizes, but are not.
  29.      *
  30.      * @var array 
  31.      */
  32.     protected $excludeStyles = array(
  33.                                 'background-position'      => 'background-position',
  34.                                 'box-shadow'               => 'box-shadow',
  35.                                 'transform-origin'         => 'transform-origin',
  36.                                 '-webkit-transform-origin' => '-webkit-transform-origin',
  37.                                 '-ms-transform-origin'     => '-ms-transform-origin',
  38.                                );
  39.  
  40.  
  41.     /**
  42.      * Returns the token types that this sniff is interested in.
  43.      *
  44.      * @return int[] 
  45.      */
  46.     public function register()
  47.     {
  48.         return array(T_STYLE);
  49.  
  50.     }//end register()
  51.  
  52.  
  53.     /**
  54.      * Processes the tokens that this sniff is interested in.
  55.      *
  56.      * @param \PHP_CodeSniffer\Files\File $phpcsFile The file where the token was found.
  57.      * @param int                         $stackPtr  The position in the stack where
  58.      *                                                the token was found.
  59.      *
  60.      * @return void 
  61.      */
  62.     public function process(File $phpcsFile$stackPtr)
  63.     {
  64.         $tokens $phpcsFile->getTokens();
  65.  
  66.         // Some styles look like shorthand but are not actually a set of 4 sizes.
  67.         $style strtolower($tokens[$stackPtr]['content']);
  68.         if (isset($this->excludeStyles[$style]=== true{
  69.             return;
  70.         }
  71.  
  72.         // Get the whole style content.
  73.         $end         $phpcsFile->findNext(T_SEMICOLON($stackPtr + 1));
  74.         $origContent $phpcsFile->getTokensAsString(($stackPtr + 1)($end $stackPtr - 1));
  75.         $origContent trim($origContent': ');
  76.  
  77.         // Account for a !important annotation.
  78.         $content $origContent;
  79.         if (substr($content-10=== '!important'{
  80.             $content substr($content0-10);
  81.             $content trim($content);
  82.         }
  83.  
  84.         // Check if this style value is a set of numbers with optional prefixes.
  85.         $content preg_replace('/\s+/'' '$content);
  86.         $values  = array();
  87.         $num     preg_match_all(
  88.             '/([0-9]+)([a-zA-Z]{2}\s+|%\s+|\s+)/',
  89.             $content.' ',
  90.             $values,
  91.             PREG_SET_ORDER
  92.         );
  93.  
  94.         // Only interested in styles that have multiple sizes defined.
  95.         if ($num < 2{
  96.             return;
  97.         }
  98.  
  99.         // Rebuild the content we matched to ensure we got everything.
  100.         $matched '';
  101.         foreach ($values as $value{
  102.             $matched .= $value[0];
  103.         }
  104.  
  105.         if ($content !== trim($matched)) {
  106.             return;
  107.         }
  108.  
  109.         if ($num === 3{
  110.             $expected trim($content.' '.$values[1][1].$values[1][2]);
  111.             $error    'Shorthand syntax not allowed here; use %s instead';
  112.             $data     = array($expected);
  113.             $fix      $phpcsFile->addFixableError($error$stackPtr'NotAllowed'$data);
  114.  
  115.             if ($fix === true{
  116.                 $phpcsFile->fixer->beginChangeset();
  117.                 if (substr($origContent-10=== '!important'{
  118.                     $expected .= ' !important';
  119.                 }
  120.  
  121.                 $next $phpcsFile->findNext(T_WHITESPACE($stackPtr + 2)nulltrue);
  122.                 $phpcsFile->fixer->replaceToken($next$expected);
  123.                 for ($next++; $next $end$next++{
  124.                     $phpcsFile->fixer->replaceToken($next'');
  125.                 }
  126.  
  127.                 $phpcsFile->fixer->endChangeset();
  128.             }
  129.  
  130.             return;
  131.         }//end if
  132.  
  133.         if ($num === 2{
  134.             if ($values[0][0!== $values[1][0]{
  135.                 // Both values are different, so it is already shorthand.
  136.                 return;
  137.             }
  138.         else if ($values[0][0!== $values[2][0|| $values[1][0!== $values[3][0]{
  139.             // Can't shorthand this.
  140.             return;
  141.         }
  142.  
  143.         if ($values[0][0=== $values[1][0]{
  144.             // All values are the same.
  145.             $expected $values[0][0];
  146.         else {
  147.             $expected $values[0][0].' '.$values[1][0];
  148.         }
  149.  
  150.         $expected preg_replace('/\s+/'' 'trim($expected));
  151.  
  152.         $error 'Size definitions must use shorthand if available; expected "%s" but found "%s"';
  153.         $data  = array(
  154.                   $expected,
  155.                   $content,
  156.                  );
  157.  
  158.         $fix $phpcsFile->addFixableError($error$stackPtr'NotUsed'$data);
  159.         if ($fix === true{
  160.             $phpcsFile->fixer->beginChangeset();
  161.             if (substr($origContent-10=== '!important'{
  162.                 $expected .= ' !important';
  163.             }
  164.  
  165.             $next $phpcsFile->findNext(T_WHITESPACE($stackPtr + 2)nulltrue);
  166.             $phpcsFile->fixer->replaceToken($next$expected);
  167.             for ($next++; $next $end$next++{
  168.                 $phpcsFile->fixer->replaceToken($next'');
  169.             }
  170.  
  171.             $phpcsFile->fixer->endChangeset();
  172.         }
  173.  
  174.     }//end process()
  175.  
  176.  
  177. }//end class

Documentation generated on Mon, 11 Mar 2019 15:27:46 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.