Selector.php 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. <?php
  2. /**
  3. * Selector
  4. *
  5. * @package Less
  6. * @subpackage tree
  7. */
  8. class Less_Tree_Selector extends Less_Tree{
  9. public $elements;
  10. public $condition;
  11. public $extendList = array();
  12. public $_css;
  13. public $index;
  14. public $evaldCondition = false;
  15. public $type = 'Selector';
  16. public $currentFileInfo = array();
  17. public $isReferenced;
  18. public $mediaEmpty;
  19. public $elements_len = 0;
  20. public $_oelements;
  21. public $_oelements_len;
  22. public $cacheable = true;
  23. /**
  24. * @param boolean $isReferenced
  25. */
  26. public function __construct( $elements, $extendList = array() , $condition = null, $index=null, $currentFileInfo=null, $isReferenced=null ){
  27. $this->elements = $elements;
  28. $this->elements_len = count($elements);
  29. $this->extendList = $extendList;
  30. $this->condition = $condition;
  31. if( $currentFileInfo ){
  32. $this->currentFileInfo = $currentFileInfo;
  33. }
  34. $this->isReferenced = $isReferenced;
  35. if( !$condition ){
  36. $this->evaldCondition = true;
  37. }
  38. $this->CacheElements();
  39. }
  40. public function accept($visitor) {
  41. $this->elements = $visitor->visitArray($this->elements);
  42. $this->extendList = $visitor->visitArray($this->extendList);
  43. if( $this->condition ){
  44. $this->condition = $visitor->visitObj($this->condition);
  45. }
  46. if( $visitor instanceof Less_Visitor_extendFinder ){
  47. $this->CacheElements();
  48. }
  49. }
  50. public function createDerived( $elements, $extendList = null, $evaldCondition = null ){
  51. $newSelector = new Less_Tree_Selector( $elements, ($extendList ? $extendList : $this->extendList), null, $this->index, $this->currentFileInfo, $this->isReferenced);
  52. $newSelector->evaldCondition = $evaldCondition ? $evaldCondition : $this->evaldCondition;
  53. return $newSelector;
  54. }
  55. public function match( $other ){
  56. if( !$other->_oelements || ($this->elements_len < $other->_oelements_len) ){
  57. return 0;
  58. }
  59. for( $i = 0; $i < $other->_oelements_len; $i++ ){
  60. if( $this->elements[$i]->value !== $other->_oelements[$i]) {
  61. return 0;
  62. }
  63. }
  64. return $other->_oelements_len; // return number of matched elements
  65. }
  66. public function CacheElements(){
  67. $this->_oelements = array();
  68. $css = '';
  69. foreach($this->elements as $v){
  70. $css .= $v->combinator;
  71. if( !$v->value_is_object ){
  72. $css .= $v->value;
  73. continue;
  74. }
  75. if( !property_exists($v->value,'value') || !is_string($v->value->value) ){
  76. $this->cacheable = false;
  77. return;
  78. }
  79. $css .= $v->value->value;
  80. }
  81. $this->_oelements_len = preg_match_all('/[,&#\.\w-](?:[\w-]|(?:\\\\.))*/', $css, $matches);
  82. if( $this->_oelements_len ){
  83. $this->_oelements = $matches[0];
  84. if( $this->_oelements[0] === '&' ){
  85. array_shift($this->_oelements);
  86. $this->_oelements_len--;
  87. }
  88. }
  89. }
  90. public function isJustParentSelector(){
  91. return !$this->mediaEmpty &&
  92. count($this->elements) === 1 &&
  93. $this->elements[0]->value === '&' &&
  94. ($this->elements[0]->combinator === ' ' || $this->elements[0]->combinator === '');
  95. }
  96. public function compile($env) {
  97. $elements = array();
  98. foreach($this->elements as $el){
  99. $elements[] = $el->compile($env);
  100. }
  101. $extendList = array();
  102. foreach($this->extendList as $el){
  103. $extendList[] = $el->compile($el);
  104. }
  105. $evaldCondition = false;
  106. if( $this->condition ){
  107. $evaldCondition = $this->condition->compile($env);
  108. }
  109. return $this->createDerived( $elements, $extendList, $evaldCondition );
  110. }
  111. /**
  112. * @see Less_Tree::genCSS
  113. */
  114. public function genCSS( $output, $firstSelector = true ){
  115. if( !$firstSelector && $this->elements[0]->combinator === "" ){
  116. $output->add(' ', $this->currentFileInfo, $this->index);
  117. }
  118. foreach($this->elements as $element){
  119. $element->genCSS( $output );
  120. }
  121. }
  122. public function markReferenced(){
  123. $this->isReferenced = true;
  124. }
  125. public function getIsReferenced(){
  126. return !isset($this->currentFileInfo['reference']) || !$this->currentFileInfo['reference'] || $this->isReferenced;
  127. }
  128. public function getIsOutput(){
  129. return $this->evaldCondition;
  130. }
  131. }