Created
March 14, 2012 14:52
-
-
Save jaikdean/2037007 to your computer and use it in GitHub Desktop.
PHP_CodeSniffer sniff for CSS to find box model styles which can be optimised using shorthand
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Shorthand box model value sniffer | |
* | |
* @package SkylabCodeSniffer | |
* @author Jaik Dean | |
**/ | |
/** | |
* Shorthand box model value sniffer | |
* | |
* @author Jaik Dean | |
**/ | |
class Skylab_Sniffs_CSS_ShorthandBoxModelSniff implements PHP_CodeSniffer_Sniff | |
{ | |
/** | |
* A list of tokenizers this sniff supports. | |
* | |
* @var array | |
**/ | |
public $supportedTokenizers = array('CSS'); | |
/** | |
* A list of styles this rule applies to | |
* | |
* @var array | |
**/ | |
protected $applicableStyles = array( | |
'margin', | |
'padding', | |
'border-width', | |
'border-color', | |
'border-style', | |
); | |
/** | |
* Returns the token types that this sniff is interested in. | |
* | |
* @return array(int) | |
**/ | |
public function register() | |
{ | |
return array(T_STYLE); | |
} | |
/** | |
* Processes the tokens that this sniff is interested in. | |
* | |
* @param PHP_CodeSniffer_File $phpcsFile The file where the token was found. | |
* @param int $stackPtr The position in the stack where | |
* the token was found. | |
* | |
* @return void | |
**/ | |
public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) | |
{ | |
$tokens = $phpcsFile->getTokens(); | |
// only apply to margin, padding and borders | |
if (!in_array($tokens[$stackPtr]['content'], $this->applicableStyles)) { | |
return; | |
} | |
// find the start and end of the value | |
$valueStart = $phpcsFile->findNext(array(T_COLON, T_WHITESPACE), ($stackPtr + 1), null, true); | |
$valueEnd = $phpcsFile->findNext(array(T_SEMICOLON), ($valueStart + 1)); | |
// concatenate the value into a string | |
$value = ''; | |
for ($i = $valueStart; $i < $valueEnd; $i++) { | |
$value .= $tokens[$i]['content']; | |
} | |
$value = trim($value); | |
// exit if we don't have any whitespace to avoid expensive preg_match()ing | |
if (!preg_match('/\\s/', $value)) { | |
return; | |
} | |
// check if we aren't using the most compact shorthand | |
$errorData = false; | |
if (preg_match('/^([^\\s]+)(?:\\s+\\1){1,3}$/', $value, $matches)) { | |
// one unique value | |
$errorData = array( | |
$matches[1], | |
$value, | |
$tokens[$stackPtr]['content'], | |
); | |
} elseif (preg_match('/^([^\\s]+)\\s+([^\\s]+)\\s+\\1(?:\\s+\\2)?$/', $value, $matches)) { | |
// two unique values | |
$errorData = array( | |
$matches[1] . ' ' . $matches[2], | |
$value, | |
$tokens[$stackPtr]['content'], | |
); | |
} elseif (preg_match('/^([^\\s]+)\\s+([^\\s]+)\\s+([^\\s]+)\\s+\\2$/', $value, $matches)) { | |
// three unique values | |
$errorData = array( | |
$matches[1] . ' ' . $matches[2] . ' ' . $matches[3], | |
$value, | |
$tokens[$stackPtr]['content'], | |
); | |
} | |
if ($errorData !== false) { | |
$phpcsFile->addError('Box model styles must be shorthand; expected "%s" but found "%s" (%s)', $i, 'Found', $errorData); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment