123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173 |
- <?php
- /**
- * Media
- *
- * @package Less
- * @subpackage tree
- */
- class Less_Tree_Media extends Less_Tree {
- public $features;
- public $rules;
- public $index;
- public $currentFileInfo;
- public $isReferenced;
- public $type = 'Media';
- public function __construct( $value = array(), $features = array(), $index = null, $currentFileInfo = null ) {
- $this->index = $index;
- $this->currentFileInfo = $currentFileInfo;
- $selectors = $this->emptySelectors();
- $this->features = new Less_Tree_Value( $features );
- $this->rules = array( new Less_Tree_Ruleset( $selectors, $value ) );
- $this->rules[0]->allowImports = true;
- }
- public function accept( $visitor ) {
- $this->features = $visitor->visitObj( $this->features );
- $this->rules = $visitor->visitArray( $this->rules );
- }
- /**
- * @see Less_Tree::genCSS
- */
- public function genCSS( $output ) {
- $output->add( '@media ', $this->currentFileInfo, $this->index );
- $this->features->genCSS( $output );
- Less_Tree::outputRuleset( $output, $this->rules );
- }
- public function compile( $env ) {
- $media = new Less_Tree_Media( array(), array(), $this->index, $this->currentFileInfo );
- $strictMathBypass = false;
- if ( Less_Parser::$options['strictMath'] === false ) {
- $strictMathBypass = true;
- Less_Parser::$options['strictMath'] = true;
- }
- $media->features = $this->features->compile( $env );
- if ( $strictMathBypass ) {
- Less_Parser::$options['strictMath'] = false;
- }
- $env->mediaPath[] = $media;
- $env->mediaBlocks[] = $media;
- array_unshift( $env->frames, $this->rules[0] );
- $media->rules = array( $this->rules[0]->compile( $env ) );
- array_shift( $env->frames );
- array_pop( $env->mediaPath );
- return !$env->mediaPath ? $media->compileTop( $env ) : $media->compileNested( $env );
- }
- public function variable( $name ) {
- return $this->rules[0]->variable( $name );
- }
- public function find( $selector ) {
- return $this->rules[0]->find( $selector, $this );
- }
- public function emptySelectors() {
- $el = new Less_Tree_Element( '', '&', $this->index, $this->currentFileInfo );
- $sels = array( new Less_Tree_Selector( array( $el ), array(), null, $this->index, $this->currentFileInfo ) );
- $sels[0]->mediaEmpty = true;
- return $sels;
- }
- public function markReferenced() {
- $this->rules[0]->markReferenced();
- $this->isReferenced = true;
- Less_Tree::ReferencedArray( $this->rules[0]->rules );
- }
- // evaltop
- public function compileTop( $env ) {
- $result = $this;
- if ( count( $env->mediaBlocks ) > 1 ) {
- $selectors = $this->emptySelectors();
- $result = new Less_Tree_Ruleset( $selectors, $env->mediaBlocks );
- $result->multiMedia = true;
- }
- $env->mediaBlocks = array();
- $env->mediaPath = array();
- return $result;
- }
- public function compileNested( $env ) {
- $path = array_merge( $env->mediaPath, array( $this ) );
- // Extract the media-query conditions separated with `,` (OR).
- foreach ( $path as $key => $p ) {
- $value = $p->features instanceof Less_Tree_Value ? $p->features->value : $p->features;
- $path[$key] = is_array( $value ) ? $value : array( $value );
- }
- // Trace all permutations to generate the resulting media-query.
- //
- // (a, b and c) with nested (d, e) ->
- // a and d
- // a and e
- // b and c and d
- // b and c and e
- $permuted = $this->permute( $path );
- $expressions = array();
- foreach ( $permuted as $path ) {
- for ( $i = 0, $len = count( $path ); $i < $len; $i++ ) {
- $path[$i] = Less_Parser::is_method( $path[$i], 'toCSS' ) ? $path[$i] : new Less_Tree_Anonymous( $path[$i] );
- }
- for ( $i = count( $path ) - 1; $i > 0; $i-- ) {
- array_splice( $path, $i, 0, array( new Less_Tree_Anonymous( 'and' ) ) );
- }
- $expressions[] = new Less_Tree_Expression( $path );
- }
- $this->features = new Less_Tree_Value( $expressions );
- // Fake a tree-node that doesn't output anything.
- return new Less_Tree_Ruleset( array(), array() );
- }
- public function permute( $arr ) {
- if ( !$arr )
- return array();
- if ( count( $arr ) == 1 )
- return $arr[0];
- $result = array();
- $rest = $this->permute( array_slice( $arr, 1 ) );
- foreach ( $rest as $r ) {
- foreach ( $arr[0] as $a ) {
- $result[] = array_merge(
- is_array( $a ) ? $a : array( $a ),
- is_array( $r ) ? $r : array( $r )
- );
- }
- }
- return $result;
- }
- public function bubbleSelectors( $selectors ) {
- if ( !$selectors ) return;
- $this->rules = array( new Less_Tree_Ruleset( $selectors, array( $this->rules[0] ) ) );
- }
- }
|