Selector.php 4.1 KB

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