mirror of
				https://github.com/Icinga/icinga-php-thirdparty.git
				synced 2025-10-31 03:03:55 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			184 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			184 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| /**
 | |
|  * @private
 | |
|  */
 | |
| class Less_Tree_Media extends Less_Tree {
 | |
| 
 | |
| 	public $features;
 | |
| 	public $rules;
 | |
| 	public $index;
 | |
| 	public $currentFileInfo;
 | |
| 	public $isReferenced;
 | |
| 	public $type = 'Media';
 | |
| 
 | |
| 	public function __construct( $value = [], $features = [], $index = null, $currentFileInfo = null ) {
 | |
| 		$this->index = $index;
 | |
| 		$this->currentFileInfo = $currentFileInfo;
 | |
| 
 | |
| 		$selectors = $this->emptySelectors();
 | |
| 
 | |
| 		$this->features = new Less_Tree_Value( $features );
 | |
| 
 | |
| 		$this->rules = [ 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 );
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * @param Less_Environment $env
 | |
| 	 * @return Less_Tree_Media|Less_Tree_Ruleset
 | |
| 	 * @see less-2.5.3.js#Media.prototype.eval
 | |
| 	 */
 | |
| 	public function compile( $env ) {
 | |
| 		$media = new Less_Tree_Media( [], [], $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 = [ $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 = [ new Less_Tree_Selector( [ $el ], [], 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 = [];
 | |
| 		$env->mediaPath = [];
 | |
| 
 | |
| 		return $result;
 | |
| 	}
 | |
| 
 | |
| 	/**
 | |
| 	 * @param Less_Environment $env
 | |
| 	 * @return Less_Tree_Ruleset
 | |
| 	 */
 | |
| 	public function compileNested( $env ) {
 | |
| 		$path = array_merge( $env->mediaPath, [ $this ] );
 | |
| 		'@phan-var array<Less_Tree_Media> $path';
 | |
| 
 | |
| 		// 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 : [ $value ];
 | |
| 		}
 | |
| 		'@phan-var array<array<Less_Tree>> $path';
 | |
| 
 | |
| 		// 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 = [];
 | |
| 		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, [ 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( [], [] );
 | |
| 	}
 | |
| 
 | |
| 	public function permute( $arr ) {
 | |
| 		if ( !$arr ) {
 | |
| 			return [];
 | |
| 		}
 | |
| 
 | |
| 		if ( count( $arr ) == 1 ) {
 | |
| 			return $arr[0];
 | |
| 		}
 | |
| 
 | |
| 		$result = [];
 | |
| 		$rest = $this->permute( array_slice( $arr, 1 ) );
 | |
| 		foreach ( $rest as $r ) {
 | |
| 			foreach ( $arr[0] as $a ) {
 | |
| 				$result[] = array_merge(
 | |
| 					is_array( $a ) ? $a : [ $a ],
 | |
| 					is_array( $r ) ? $r : [ $r ]
 | |
| 				);
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		return $result;
 | |
| 	}
 | |
| 
 | |
| 	public function bubbleSelectors( $selectors ) {
 | |
| 		if ( !$selectors ) {
 | |
| 			return;
 | |
| 		}
 | |
| 
 | |
| 		$this->rules = [ new Less_Tree_Ruleset( $selectors, [ $this->rules[0] ] ) ];
 | |
| 	}
 | |
| 
 | |
| }
 |