166 lines
4.1 KiB
PHP
166 lines
4.1 KiB
PHP
|
<?php
|
||
|
|
||
|
/**
|
||
|
* Selector
|
||
|
*
|
||
|
* @package Less
|
||
|
* @subpackage tree
|
||
|
*/
|
||
|
class Less_Tree_Selector extends Less_Tree {
|
||
|
|
||
|
public $elements;
|
||
|
public $condition;
|
||
|
public $extendList = array();
|
||
|
public $_css;
|
||
|
public $index;
|
||
|
public $evaldCondition = false;
|
||
|
public $type = 'Selector';
|
||
|
public $currentFileInfo = array();
|
||
|
public $isReferenced;
|
||
|
public $mediaEmpty;
|
||
|
|
||
|
public $elements_len = 0;
|
||
|
|
||
|
public $_oelements;
|
||
|
public $_oelements_assoc;
|
||
|
public $_oelements_len;
|
||
|
public $cacheable = true;
|
||
|
|
||
|
/**
|
||
|
* @param boolean $isReferenced
|
||
|
*/
|
||
|
public function __construct( $elements, $extendList = array(), $condition = null, $index = null, $currentFileInfo = null, $isReferenced = null ) {
|
||
|
$this->elements = $elements;
|
||
|
$this->elements_len = count( $elements );
|
||
|
$this->extendList = $extendList;
|
||
|
$this->condition = $condition;
|
||
|
if ( $currentFileInfo ) {
|
||
|
$this->currentFileInfo = $currentFileInfo;
|
||
|
}
|
||
|
$this->isReferenced = $isReferenced;
|
||
|
if ( !$condition ) {
|
||
|
$this->evaldCondition = true;
|
||
|
}
|
||
|
|
||
|
$this->CacheElements();
|
||
|
}
|
||
|
|
||
|
public function accept( $visitor ) {
|
||
|
$this->elements = $visitor->visitArray( $this->elements );
|
||
|
$this->extendList = $visitor->visitArray( $this->extendList );
|
||
|
if ( $this->condition ) {
|
||
|
$this->condition = $visitor->visitObj( $this->condition );
|
||
|
}
|
||
|
|
||
|
if ( $visitor instanceof Less_Visitor_extendFinder ) {
|
||
|
$this->CacheElements();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public function createDerived( $elements, $extendList = null, $evaldCondition = null ) {
|
||
|
$newSelector = new Less_Tree_Selector( $elements, ( $extendList ? $extendList : $this->extendList ), null, $this->index, $this->currentFileInfo, $this->isReferenced );
|
||
|
$newSelector->evaldCondition = $evaldCondition ? $evaldCondition : $this->evaldCondition;
|
||
|
return $newSelector;
|
||
|
}
|
||
|
|
||
|
public function match( $other ) {
|
||
|
if ( !$other->_oelements || ( $this->elements_len < $other->_oelements_len ) ) {
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
for ( $i = 0; $i < $other->_oelements_len; $i++ ) {
|
||
|
if ( $this->elements[$i]->value !== $other->_oelements[$i] ) {
|
||
|
return 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return $other->_oelements_len; // return number of matched elements
|
||
|
}
|
||
|
|
||
|
public function CacheElements() {
|
||
|
$this->_oelements = array();
|
||
|
$this->_oelements_assoc = array();
|
||
|
|
||
|
$css = '';
|
||
|
|
||
|
foreach ( $this->elements as $v ) {
|
||
|
|
||
|
$css .= $v->combinator;
|
||
|
if ( !$v->value_is_object ) {
|
||
|
$css .= $v->value;
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
if ( !property_exists( $v->value, 'value' ) || !is_string( $v->value->value ) ) {
|
||
|
$this->cacheable = false;
|
||
|
return;
|
||
|
}
|
||
|
$css .= $v->value->value;
|
||
|
}
|
||
|
|
||
|
$this->_oelements_len = preg_match_all( '/[,&#\.\w-](?:[\w-]|(?:\\\\.))*/', $css, $matches );
|
||
|
if ( $this->_oelements_len ) {
|
||
|
$this->_oelements = $matches[0];
|
||
|
|
||
|
if ( $this->_oelements[0] === '&' ) {
|
||
|
array_shift( $this->_oelements );
|
||
|
$this->_oelements_len--;
|
||
|
}
|
||
|
|
||
|
$this->_oelements_assoc = array_fill_keys( $this->_oelements, true );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public function isJustParentSelector() {
|
||
|
return !$this->mediaEmpty &&
|
||
|
count( $this->elements ) === 1 &&
|
||
|
$this->elements[0]->value === '&' &&
|
||
|
( $this->elements[0]->combinator === ' ' || $this->elements[0]->combinator === '' );
|
||
|
}
|
||
|
|
||
|
public function compile( $env ) {
|
||
|
$elements = array();
|
||
|
foreach ( $this->elements as $el ) {
|
||
|
$elements[] = $el->compile( $env );
|
||
|
}
|
||
|
|
||
|
$extendList = array();
|
||
|
foreach ( $this->extendList as $el ) {
|
||
|
$extendList[] = $el->compile( $el );
|
||
|
}
|
||
|
|
||
|
$evaldCondition = false;
|
||
|
if ( $this->condition ) {
|
||
|
$evaldCondition = $this->condition->compile( $env );
|
||
|
}
|
||
|
|
||
|
return $this->createDerived( $elements, $extendList, $evaldCondition );
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @see Less_Tree::genCSS
|
||
|
*/
|
||
|
public function genCSS( $output, $firstSelector = true ) {
|
||
|
if ( !$firstSelector && $this->elements[0]->combinator === "" ) {
|
||
|
$output->add( ' ', $this->currentFileInfo, $this->index );
|
||
|
}
|
||
|
|
||
|
foreach ( $this->elements as $element ) {
|
||
|
$element->genCSS( $output );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public function markReferenced() {
|
||
|
$this->isReferenced = true;
|
||
|
}
|
||
|
|
||
|
public function getIsReferenced() {
|
||
|
return !isset( $this->currentFileInfo['reference'] ) || !$this->currentFileInfo['reference'] || $this->isReferenced;
|
||
|
}
|
||
|
|
||
|
public function getIsOutput() {
|
||
|
return $this->evaldCondition;
|
||
|
}
|
||
|
|
||
|
}
|