You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
179 lines
4.3 KiB
179 lines
4.3 KiB
<?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])));
|
|
}
|
|
|
|
}
|
|
|