aboutsummaryrefslogtreecommitdiff
path: root/lib/less.php/Visitor
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--lib/less.php/Visitor.php49
-rw-r--r--lib/less.php/Visitor/extendFinder.php114
-rw-r--r--lib/less.php/Visitor/import.php139
-rw-r--r--lib/less.php/Visitor/joinSelector.php70
-rw-r--r--lib/less.php/Visitor/processExtends.php469
-rw-r--r--lib/less.php/Visitor/toCSS.php292
-rw-r--r--lib/less.php/VisitorReplacing.php75
7 files changed, 0 insertions, 1208 deletions
diff --git a/lib/less.php/Visitor.php b/lib/less.php/Visitor.php
deleted file mode 100644
index d85f1d9..0000000
--- a/lib/less.php/Visitor.php
+++ /dev/null
@@ -1,49 +0,0 @@
-<?php
-
-/**
- * Visitor
- *
- * @package Less
- * @subpackage visitor
- */
-class Less_Visitor{
-
- protected $methods = array();
- protected $_visitFnCache = array();
-
- public function __construct(){
- $this->_visitFnCache = get_class_methods(get_class($this));
- $this->_visitFnCache = array_flip($this->_visitFnCache);
- }
-
- public function visitObj( $node ){
-
- $funcName = 'visit'.$node->type;
- if( isset($this->_visitFnCache[$funcName]) ){
-
- $visitDeeper = true;
- $this->$funcName( $node, $visitDeeper );
-
- if( $visitDeeper ){
- $node->accept($this);
- }
-
- $funcName = $funcName . "Out";
- if( isset($this->_visitFnCache[$funcName]) ){
- $this->$funcName( $node );
- }
-
- }else{
- $node->accept($this);
- }
-
- return $node;
- }
-
- public function visitArray( $nodes ){
-
- array_map( array($this,'visitObj'), $nodes);
- return $nodes;
- }
-}
-
diff --git a/lib/less.php/Visitor/extendFinder.php b/lib/less.php/Visitor/extendFinder.php
deleted file mode 100644
index 22b3aac..0000000
--- a/lib/less.php/Visitor/extendFinder.php
+++ /dev/null
@@ -1,114 +0,0 @@
-<?php
-
-/**
- * Extend Finder Visitor
- *
- * @package Less
- * @subpackage visitor
- */
-class Less_Visitor_extendFinder extends Less_Visitor{
-
- public $contexts = array();
- public $allExtendsStack;
- public $foundExtends;
-
- public function __construct(){
- $this->contexts = array();
- $this->allExtendsStack = array(array());
- parent::__construct();
- }
-
- /**
- * @param Less_Tree_Ruleset $root
- */
- public function run($root){
- $root = $this->visitObj($root);
- $root->allExtends =& $this->allExtendsStack[0];
- return $root;
- }
-
- public function visitRule($ruleNode, &$visitDeeper ){
- $visitDeeper = false;
- }
-
- public function visitMixinDefinition( $mixinDefinitionNode, &$visitDeeper ){
- $visitDeeper = false;
- }
-
- public function visitRuleset($rulesetNode){
-
- if( $rulesetNode->root ){
- return;
- }
-
- $allSelectorsExtendList = array();
-
- // get &:extend(.a); rules which apply to all selectors in this ruleset
- if( $rulesetNode->rules ){
- foreach($rulesetNode->rules as $rule){
- if( $rule instanceof Less_Tree_Extend ){
- $allSelectorsExtendList[] = $rule;
- $rulesetNode->extendOnEveryPath = true;
- }
- }
- }
-
-
- // now find every selector and apply the extends that apply to all extends
- // and the ones which apply to an individual extend
- foreach($rulesetNode->paths as $selectorPath){
- $selector = end($selectorPath); //$selectorPath[ count($selectorPath)-1];
-
- $j = 0;
- foreach($selector->extendList as $extend){
- $this->allExtendsStackPush($rulesetNode, $selectorPath, $extend, $j);
- }
- foreach($allSelectorsExtendList as $extend){
- $this->allExtendsStackPush($rulesetNode, $selectorPath, $extend, $j);
- }
- }
-
- $this->contexts[] = $rulesetNode->selectors;
- }
-
- public function allExtendsStackPush($rulesetNode, $selectorPath, $extend, &$j){
- $this->foundExtends = true;
- $extend = clone $extend;
- $extend->findSelfSelectors( $selectorPath );
- $extend->ruleset = $rulesetNode;
- if( $j === 0 ){
- $extend->firstExtendOnThisSelectorPath = true;
- }
-
- $end_key = count($this->allExtendsStack)-1;
- $this->allExtendsStack[$end_key][] = $extend;
- $j++;
- }
-
-
- public function visitRulesetOut( $rulesetNode ){
- if( !is_object($rulesetNode) || !$rulesetNode->root ){
- array_pop($this->contexts);
- }
- }
-
- public function visitMedia( $mediaNode ){
- $mediaNode->allExtends = array();
- $this->allExtendsStack[] =& $mediaNode->allExtends;
- }
-
- public function visitMediaOut(){
- array_pop($this->allExtendsStack);
- }
-
- public function visitDirective( $directiveNode ){
- $directiveNode->allExtends = array();
- $this->allExtendsStack[] =& $directiveNode->allExtends;
- }
-
- public function visitDirectiveOut(){
- array_pop($this->allExtendsStack);
- }
-}
-
-
diff --git a/lib/less.php/Visitor/import.php b/lib/less.php/Visitor/import.php
deleted file mode 100644
index f79a36d..0000000
--- a/lib/less.php/Visitor/import.php
+++ /dev/null
@@ -1,139 +0,0 @@
-<?php
-
-/*
-class Less_Visitor_import extends Less_VisitorReplacing{
-
- public $_visitor;
- public $_importer;
- public $importCount;
-
- function __construct( $evalEnv ){
- $this->env = $evalEnv;
- $this->importCount = 0;
- parent::__construct();
- }
-
-
- function run( $root ){
- $root = $this->visitObj($root);
- $this->isFinished = true;
-
- //if( $this->importCount === 0) {
- // $this->_finish();
- //}
- }
-
- function visitImport($importNode, &$visitDeeper ){
- $importVisitor = $this;
- $inlineCSS = $importNode->options['inline'];
-
- if( !$importNode->css || $inlineCSS ){
- $evaldImportNode = $importNode->compileForImport($this->env);
-
- if( $evaldImportNode && (!$evaldImportNode->css || $inlineCSS) ){
- $importNode = $evaldImportNode;
- $this->importCount++;
- $env = clone $this->env;
-
- if( (isset($importNode->options['multiple']) && $importNode->options['multiple']) ){
- $env->importMultiple = true;
- }
-
- //get path & uri
- $path_and_uri = null;
- if( is_callable(Less_Parser::$options['import_callback']) ){
- $path_and_uri = call_user_func(Less_Parser::$options['import_callback'],$importNode);
- }
-
- if( !$path_and_uri ){
- $path_and_uri = $importNode->PathAndUri();
- }
-
- if( $path_and_uri ){
- list($full_path, $uri) = $path_and_uri;
- }else{
- $full_path = $uri = $importNode->getPath();
- }
-
-
- //import once
- if( $importNode->skip( $full_path, $env) ){
- return array();
- }
-
- if( $importNode->options['inline'] ){
- //todo needs to reference css file not import
- //$contents = new Less_Tree_Anonymous($importNode->root, 0, array('filename'=>$importNode->importedFilename), true );
-
- Less_Parser::AddParsedFile($full_path);
- $contents = new Less_Tree_Anonymous( file_get_contents($full_path), 0, array(), true );
-
- if( $importNode->features ){
- return new Less_Tree_Media( array($contents), $importNode->features->value );
- }
-
- return array( $contents );
- }
-
-
- // css ?
- if( $importNode->css ){
- $features = ( $importNode->features ? $importNode->features->compile($env) : null );
- return new Less_Tree_Import( $importNode->compilePath( $env), $features, $importNode->options, $this->index);
- }
-
- return $importNode->ParseImport( $full_path, $uri, $env );
- }
-
- }
-
- $visitDeeper = false;
- return $importNode;
- }
-
-
- function visitRule( $ruleNode, &$visitDeeper ){
- $visitDeeper = false;
- return $ruleNode;
- }
-
- function visitDirective($directiveNode, $visitArgs){
- array_unshift($this->env->frames,$directiveNode);
- return $directiveNode;
- }
-
- function visitDirectiveOut($directiveNode) {
- array_shift($this->env->frames);
- }
-
- function visitMixinDefinition($mixinDefinitionNode, $visitArgs) {
- array_unshift($this->env->frames,$mixinDefinitionNode);
- return $mixinDefinitionNode;
- }
-
- function visitMixinDefinitionOut($mixinDefinitionNode) {
- array_shift($this->env->frames);
- }
-
- function visitRuleset($rulesetNode, $visitArgs) {
- array_unshift($this->env->frames,$rulesetNode);
- return $rulesetNode;
- }
-
- function visitRulesetOut($rulesetNode) {
- array_shift($this->env->frames);
- }
-
- function visitMedia($mediaNode, $visitArgs) {
- array_unshift($this->env->frames, $mediaNode->ruleset);
- return $mediaNode;
- }
-
- function visitMediaOut($mediaNode) {
- array_shift($this->env->frames);
- }
-
-}
-*/
-
-
diff --git a/lib/less.php/Visitor/joinSelector.php b/lib/less.php/Visitor/joinSelector.php
deleted file mode 100644
index f62af1a..0000000
--- a/lib/less.php/Visitor/joinSelector.php
+++ /dev/null
@@ -1,70 +0,0 @@
-<?php
-
-/**
- * Join Selector Visitor
- *
- * @package Less
- * @subpackage visitor
- */
-class Less_Visitor_joinSelector extends Less_Visitor{
-
- public $contexts = array( array() );
-
- /**
- * @param Less_Tree_Ruleset $root
- */
- public function run( $root ){
- return $this->visitObj($root);
- }
-
- public function visitRule( $ruleNode, &$visitDeeper ){
- $visitDeeper = false;
- }
-
- public function visitMixinDefinition( $mixinDefinitionNode, &$visitDeeper ){
- $visitDeeper = false;
- }
-
- public function visitRuleset( $rulesetNode ){
-
- $paths = array();
-
- if( !$rulesetNode->root ){
- $selectors = array();
-
- if( $rulesetNode->selectors && $rulesetNode->selectors ){
- foreach($rulesetNode->selectors as $selector){
- if( $selector->getIsOutput() ){
- $selectors[] = $selector;
- }
- }
- }
-
- if( !$selectors ){
- $rulesetNode->selectors = null;
- $rulesetNode->rules = null;
- }else{
- $context = end($this->contexts); //$context = $this->contexts[ count($this->contexts) - 1];
- $paths = $rulesetNode->joinSelectors( $context, $selectors);
- }
-
- $rulesetNode->paths = $paths;
- }
-
- $this->contexts[] = $paths; //different from less.js. Placed after joinSelectors() so that $this->contexts will get correct $paths
- }
-
- public function visitRulesetOut(){
- array_pop($this->contexts);
- }
-
- public function visitMedia($mediaNode) {
- $context = end($this->contexts); //$context = $this->contexts[ count($this->contexts) - 1];
-
- if( !count($context) || (is_object($context[0]) && $context[0]->multiMedia) ){
- $mediaNode->rules[0]->root = true;
- }
- }
-
-}
-
diff --git a/lib/less.php/Visitor/processExtends.php b/lib/less.php/Visitor/processExtends.php
deleted file mode 100644
index bb5f082..0000000
--- a/lib/less.php/Visitor/processExtends.php
+++ /dev/null
@@ -1,469 +0,0 @@
-<?php
-
-/**
- * Process Extends Visitor
- *
- * @package Less
- * @subpackage visitor
- */
-class Less_Visitor_processExtends extends Less_Visitor{
-
- public $allExtendsStack;
-
- /**
- * @param Less_Tree_Ruleset $root
- */
- public function run( $root ){
- $extendFinder = new Less_Visitor_extendFinder();
- $extendFinder->run( $root );
- if( !$extendFinder->foundExtends){
- return $root;
- }
-
- $root->allExtends = $this->doExtendChaining( $root->allExtends, $root->allExtends);
-
- $this->allExtendsStack = array();
- $this->allExtendsStack[] = &$root->allExtends;
-
- return $this->visitObj( $root );
- }
-
- private function doExtendChaining( $extendsList, $extendsListTarget, $iterationCount = 0){
- //
- // chaining is different from normal extension.. if we extend an extend then we are not just copying, altering and pasting
- // the selector we would do normally, but we are also adding an extend with the same target selector
- // this means this new extend can then go and alter other extends
- //
- // this method deals with all the chaining work - without it, extend is flat and doesn't work on other extend selectors
- // this is also the most expensive.. and a match on one selector can cause an extension of a selector we had already processed if
- // we look at each selector at a time, as is done in visitRuleset
-
- $extendsToAdd = array();
-
-
- //loop through comparing every extend with every target extend.
- // a target extend is the one on the ruleset we are looking at copy/edit/pasting in place
- // e.g. .a:extend(.b) {} and .b:extend(.c) {} then the first extend extends the second one
- // and the second is the target.
- // the separation into two lists allows us to process a subset of chains with a bigger set, as is the
- // case when processing media queries
- for( $extendIndex = 0, $extendsList_len = count($extendsList); $extendIndex < $extendsList_len; $extendIndex++ ){
- for( $targetExtendIndex = 0; $targetExtendIndex < count($extendsListTarget); $targetExtendIndex++ ){
-
- $extend = $extendsList[$extendIndex];
- $targetExtend = $extendsListTarget[$targetExtendIndex];
-
- // look for circular references
- if( in_array($targetExtend->object_id, $extend->parent_ids,true) ){
- continue;
- }
-
- // find a match in the target extends self selector (the bit before :extend)
- $selectorPath = array( $targetExtend->selfSelectors[0] );
- $matches = $this->findMatch( $extend, $selectorPath);
-
-
- if( $matches ){
-
- // we found a match, so for each self selector..
- foreach($extend->selfSelectors as $selfSelector ){
-
-
- // process the extend as usual
- $newSelector = $this->extendSelector( $matches, $selectorPath, $selfSelector);
-
- // but now we create a new extend from it
- $newExtend = new Less_Tree_Extend( $targetExtend->selector, $targetExtend->option, 0);
- $newExtend->selfSelectors = $newSelector;
-
- // add the extend onto the list of extends for that selector
- end($newSelector)->extendList = array($newExtend);
- //$newSelector[ count($newSelector)-1]->extendList = array($newExtend);
-
- // record that we need to add it.
- $extendsToAdd[] = $newExtend;
- $newExtend->ruleset = $targetExtend->ruleset;
-
- //remember its parents for circular references
- $newExtend->parent_ids = array_merge($newExtend->parent_ids,$targetExtend->parent_ids,$extend->parent_ids);
-
- // only process the selector once.. if we have :extend(.a,.b) then multiple
- // extends will look at the same selector path, so when extending
- // we know that any others will be duplicates in terms of what is added to the css
- if( $targetExtend->firstExtendOnThisSelectorPath ){
- $newExtend->firstExtendOnThisSelectorPath = true;
- $targetExtend->ruleset->paths[] = $newSelector;
- }
- }
- }
- }
- }
-
- if( $extendsToAdd ){
- // try to detect circular references to stop a stack overflow.
- // may no longer be needed. $this->extendChainCount++;
- if( $iterationCount > 100) {
-
- try{
- $selectorOne = $extendsToAdd[0]->selfSelectors[0]->toCSS();
- $selectorTwo = $extendsToAdd[0]->selector->toCSS();
- }catch(Exception $e){
- $selectorOne = "{unable to calculate}";
- $selectorTwo = "{unable to calculate}";
- }
-
- throw new Less_Exception_Parser("extend circular reference detected. One of the circular extends is currently:" . $selectorOne . ":extend(" . $selectorTwo . ")");
- }
-
- // now process the new extends on the existing rules so that we can handle a extending b extending c ectending d extending e...
- $extendsToAdd = $this->doExtendChaining( $extendsToAdd, $extendsListTarget, $iterationCount+1);
- }
-
- return array_merge($extendsList, $extendsToAdd);
- }
-
-
- protected function visitRule( $ruleNode, &$visitDeeper ){
- $visitDeeper = false;
- }
-
- protected function visitMixinDefinition( $mixinDefinitionNode, &$visitDeeper ){
- $visitDeeper = false;
- }
-
- protected function visitSelector( $selectorNode, &$visitDeeper ){
- $visitDeeper = false;
- }
-
- protected function visitRuleset($rulesetNode){
-
-
- if( $rulesetNode->root ){
- return;
- }
-
- $allExtends = end($this->allExtendsStack);
- $paths_len = count($rulesetNode->paths);
-
- // look at each selector path in the ruleset, find any extend matches and then copy, find and replace
- foreach($allExtends as $allExtend){
- for($pathIndex = 0; $pathIndex < $paths_len; $pathIndex++ ){
-
- // extending extends happens initially, before the main pass
- if( isset($rulesetNode->extendOnEveryPath) && $rulesetNode->extendOnEveryPath ){
- continue;
- }
-
- $selectorPath = $rulesetNode->paths[$pathIndex];
-
- if( end($selectorPath)->extendList ){
- continue;
- }
-
- $this->ExtendMatch( $rulesetNode, $allExtend, $selectorPath);
-
- }
- }
- }
-
-
- private function ExtendMatch( $rulesetNode, $extend, $selectorPath ){
- $matches = $this->findMatch($extend, $selectorPath);
-
- if( $matches ){
- foreach($extend->selfSelectors as $selfSelector ){
- $rulesetNode->paths[] = $this->extendSelector($matches, $selectorPath, $selfSelector);
- }
- }
- }
-
-
-
- private function findMatch($extend, $haystackSelectorPath ){
-
-
- if( !$this->HasMatches($extend, $haystackSelectorPath) ){
- return false;
- }
-
-
- //
- // look through the haystack selector path to try and find the needle - extend.selector
- // returns an array of selector matches that can then be replaced
- //
- $needleElements = $extend->selector->elements;
- $potentialMatches = array();
- $potentialMatches_len = 0;
- $potentialMatch = null;
- $matches = array();
-
-
-
- // loop through the haystack elements
- $haystack_path_len = count($haystackSelectorPath);
- for($haystackSelectorIndex = 0; $haystackSelectorIndex < $haystack_path_len; $haystackSelectorIndex++ ){
- $hackstackSelector = $haystackSelectorPath[$haystackSelectorIndex];
-
- $haystack_elements_len = count($hackstackSelector->elements);
- for($hackstackElementIndex = 0; $hackstackElementIndex < $haystack_elements_len; $hackstackElementIndex++ ){
-
- $haystackElement = $hackstackSelector->elements[$hackstackElementIndex];
-
- // if we allow elements before our match we can add a potential match every time. otherwise only at the first element.
- if( $extend->allowBefore || ($haystackSelectorIndex === 0 && $hackstackElementIndex === 0) ){
- $potentialMatches[] = array('pathIndex'=> $haystackSelectorIndex, 'index'=> $hackstackElementIndex, 'matched'=> 0, 'initialCombinator'=> $haystackElement->combinator);
- $potentialMatches_len++;
- }
-
- for($i = 0; $i < $potentialMatches_len; $i++ ){
-
- $potentialMatch = &$potentialMatches[$i];
- $potentialMatch = $this->PotentialMatch( $potentialMatch, $needleElements, $haystackElement, $hackstackElementIndex );
-
-
- // if we are still valid and have finished, test whether we have elements after and whether these are allowed
- if( $potentialMatch && $potentialMatch['matched'] === $extend->selector->elements_len ){
- $potentialMatch['finished'] = true;
-
- if( !$extend->allowAfter && ($hackstackElementIndex+1 < $haystack_elements_len || $haystackSelectorIndex+1 < $haystack_path_len) ){
- $potentialMatch = null;
- }
- }
-
- // if null we remove, if not, we are still valid, so either push as a valid match or continue
- if( $potentialMatch ){
- if( $potentialMatch['finished'] ){
- $potentialMatch['length'] = $extend->selector->elements_len;
- $potentialMatch['endPathIndex'] = $haystackSelectorIndex;
- $potentialMatch['endPathElementIndex'] = $hackstackElementIndex + 1; // index after end of match
- $potentialMatches = array(); // we don't allow matches to overlap, so start matching again
- $potentialMatches_len = 0;
- $matches[] = $potentialMatch;
- }
- continue;
- }
-
- array_splice($potentialMatches, $i, 1);
- $potentialMatches_len--;
- $i--;
- }
- }
- }
-
- return $matches;
- }
-
-
- // Before going through all the nested loops, lets check to see if a match is possible
- // Reduces Bootstrap 3.1 compile time from ~6.5s to ~5.6s
- private function HasMatches($extend, $haystackSelectorPath){
-
- if( !$extend->selector->cacheable ){
- return true;
- }
-
- $first_el = $extend->selector->_oelements[0];
-
- foreach($haystackSelectorPath as $hackstackSelector){
- if( !$hackstackSelector->cacheable ){
- return true;
- }
-
- if( in_array($first_el, $hackstackSelector->_oelements) ){
- return true;
- }
- }
-
- return false;
- }
-
-
- /**
- * @param integer $hackstackElementIndex
- */
- private function PotentialMatch( $potentialMatch, $needleElements, $haystackElement, $hackstackElementIndex ){
-
-
- if( $potentialMatch['matched'] > 0 ){
-
- // selectors add " " onto the first element. When we use & it joins the selectors together, but if we don't
- // then each selector in haystackSelectorPath has a space before it added in the toCSS phase. so we need to work out
- // what the resulting combinator will be
- $targetCombinator = $haystackElement->combinator;
- if( $targetCombinator === '' && $hackstackElementIndex === 0 ){
- $targetCombinator = ' ';
- }
-
- if( $needleElements[ $potentialMatch['matched'] ]->combinator !== $targetCombinator ){
- return null;
- }
- }
-
- // if we don't match, null our match to indicate failure
- if( !$this->isElementValuesEqual( $needleElements[$potentialMatch['matched'] ]->value, $haystackElement->value) ){
- return null;
- }
-
- $potentialMatch['finished'] = false;
- $potentialMatch['matched']++;
-
- return $potentialMatch;
- }
-
-
- private function isElementValuesEqual( $elementValue1, $elementValue2 ){
-
- if( $elementValue1 === $elementValue2 ){
- return true;
- }
-
- if( is_string($elementValue1) || is_string($elementValue2) ) {
- return false;
- }
-
- if( $elementValue1 instanceof Less_Tree_Attribute ){
- return $this->isAttributeValuesEqual( $elementValue1, $elementValue2 );
- }
-
- $elementValue1 = $elementValue1->value;
- if( $elementValue1 instanceof Less_Tree_Selector ){
- return $this->isSelectorValuesEqual( $elementValue1, $elementValue2 );
- }
-
- return false;
- }
-
-
- /**
- * @param Less_Tree_Selector $elementValue1
- */
- private function isSelectorValuesEqual( $elementValue1, $elementValue2 ){
-
- $elementValue2 = $elementValue2->value;
- if( !($elementValue2 instanceof Less_Tree_Selector) || $elementValue1->elements_len !== $elementValue2->elements_len ){
- return false;
- }
-
- for( $i = 0; $i < $elementValue1->elements_len; $i++ ){
-
- if( $elementValue1->elements[$i]->combinator !== $elementValue2->elements[$i]->combinator ){
- if( $i !== 0 || ($elementValue1->elements[$i]->combinator || ' ') !== ($elementValue2->elements[$i]->combinator || ' ') ){
- return false;
- }
- }
-
- if( !$this->isElementValuesEqual($elementValue1->elements[$i]->value, $elementValue2->elements[$i]->value) ){
- return false;
- }
- }
-
- return true;
- }
-
-
- /**
- * @param Less_Tree_Attribute $elementValue1
- */
- private function isAttributeValuesEqual( $elementValue1, $elementValue2 ){
-
- if( $elementValue1->op !== $elementValue2->op || $elementValue1->key !== $elementValue2->key ){
- return false;
- }
-
- if( !$elementValue1->value || !$elementValue2->value ){
- if( $elementValue1->value || $elementValue2->value ) {
- return false;
- }
- return true;
- }
-
- $elementValue1 = ($elementValue1->value->value ? $elementValue1->value->value : $elementValue1->value );
- $elementValue2 = ($elementValue2->value->value ? $elementValue2->value->value : $elementValue2->value );
-
- return $elementValue1 === $elementValue2;
- }
-
-
- private function extendSelector($matches, $selectorPath, $replacementSelector){
-
- //for a set of matches, replace each match with the replacement selector
-
- $currentSelectorPathIndex = 0;
- $currentSelectorPathElementIndex = 0;
- $path = array();
- $selectorPath_len = count($selectorPath);
-
- for($matchIndex = 0, $matches_len = count($matches); $matchIndex < $matches_len; $matchIndex++ ){
-
-
- $match = $matches[$matchIndex];
- $selector = $selectorPath[ $match['pathIndex'] ];
-
- $firstElement = new Less_Tree_Element(
- $match['initialCombinator'],
- $replacementSelector->elements[0]->value,
- $replacementSelector->elements[0]->index,
- $replacementSelector->elements[0]->currentFileInfo
- );
-
- if( $match['pathIndex'] > $currentSelectorPathIndex && $currentSelectorPathElementIndex > 0 ){
- $last_path = end($path);
- $last_path->elements = array_merge( $last_path->elements, array_slice( $selectorPath[$currentSelectorPathIndex]->elements, $currentSelectorPathElementIndex));
- $currentSelectorPathElementIndex = 0;
- $currentSelectorPathIndex++;
- }
-
- $newElements = array_merge(
- array_slice($selector->elements, $currentSelectorPathElementIndex, ($match['index'] - $currentSelectorPathElementIndex) ) // last parameter of array_slice is different than the last parameter of javascript's slice
- , array($firstElement)
- , array_slice($replacementSelector->elements,1)
- );
-
- if( $currentSelectorPathIndex === $match['pathIndex'] && $matchIndex > 0 ){
- $last_key = count($path)-1;
- $path[$last_key]->elements = array_merge($path[$last_key]->elements,$newElements);
- }else{
- $path = array_merge( $path, array_slice( $selectorPath, $currentSelectorPathIndex, $match['pathIndex'] ));
- $path[] = new Less_Tree_Selector( $newElements );
- }
-
- $currentSelectorPathIndex = $match['endPathIndex'];
- $currentSelectorPathElementIndex = $match['endPathElementIndex'];
- if( $currentSelectorPathElementIndex >= count($selectorPath[$currentSelectorPathIndex]->elements) ){
- $currentSelectorPathElementIndex = 0;
- $currentSelectorPathIndex++;
- }
- }
-
- if( $currentSelectorPathIndex < $selectorPath_len && $currentSelectorPathElementIndex > 0 ){
- $last_path = end($path);
- $last_path->elements = array_merge( $last_path->elements, array_slice($selectorPath[$currentSelectorPathIndex]->elements, $currentSelectorPathElementIndex));
- $currentSelectorPathIndex++;
- }
-
- $slice_len = $selectorPath_len - $currentSelectorPathIndex;
- $path = array_merge($path, array_slice($selectorPath, $currentSelectorPathIndex, $slice_len));
-
- return $path;
- }
-
-
- protected function visitMedia( $mediaNode ){
- $newAllExtends = array_merge( $mediaNode->allExtends, end($this->allExtendsStack) );
- $this->allExtendsStack[] = $this->doExtendChaining($newAllExtends, $mediaNode->allExtends);
- }
-
- protected function visitMediaOut(){
- array_pop( $this->allExtendsStack );
- }
-
- protected function visitDirective( $directiveNode ){
- $newAllExtends = array_merge( $directiveNode->allExtends, end($this->allExtendsStack) );
- $this->allExtendsStack[] = $this->doExtendChaining($newAllExtends, $directiveNode->allExtends);
- }
-
- protected function visitDirectiveOut(){
- array_pop($this->allExtendsStack);
- }
-
-} \ No newline at end of file
diff --git a/lib/less.php/Visitor/toCSS.php b/lib/less.php/Visitor/toCSS.php
deleted file mode 100644
index 8aaca96..0000000
--- a/lib/less.php/Visitor/toCSS.php
+++ /dev/null
@@ -1,292 +0,0 @@
-<?php
-
-/**
- * toCSS Visitor
- *
- * @package Less
- * @subpackage visitor
- */
-class Less_Visitor_toCSS extends Less_VisitorReplacing{
-
- private $charset;
-
- public function __construct(){
- parent::__construct();
- }
-
- /**
- * @param Less_Tree_Ruleset $root
- */
- public function run( $root ){
- return $this->visitObj($root);
- }
-
- public function visitRule( $ruleNode ){
- if( $ruleNode->variable ){
- return array();
- }
- return $ruleNode;
- }
-
- public function visitMixinDefinition($mixinNode){
- // mixin definitions do not get eval'd - this means they keep state
- // so we have to clear that state here so it isn't used if toCSS is called twice
- $mixinNode->frames = array();
- return array();
- }
-
- public function visitExtend(){
- return array();
- }
-
- public function visitComment( $commentNode ){
- if( $commentNode->isSilent() ){
- return array();
- }
- return $commentNode;
- }
-
- public function visitMedia( $mediaNode, &$visitDeeper ){
- $mediaNode->accept($this);
- $visitDeeper = false;
-
- if( !$mediaNode->rules ){
- return array();
- }
- return $mediaNode;
- }
-
- public function visitDirective( $directiveNode ){
- if( isset($directiveNode->currentFileInfo['reference']) && (!property_exists($directiveNode,'isReferenced') || !$directiveNode->isReferenced) ){
- return array();
- }
- if( $directiveNode->name === '@charset' ){
- // Only output the debug info together with subsequent @charset definitions
- // a comment (or @media statement) before the actual @charset directive would
- // be considered illegal css as it has to be on the first line
- if( isset($this->charset) && $this->charset ){
-
- //if( $directiveNode->debugInfo ){
- // $comment = new Less_Tree_Comment('/* ' . str_replace("\n",'',$directiveNode->toCSS())." */\n");
- // $comment->debugInfo = $directiveNode->debugInfo;
- // return $this->visit($comment);
- //}
-
-
- return array();
- }
- $this->charset = true;
- }
- return $directiveNode;
- }
-
- public function checkPropertiesInRoot( $rulesetNode ){
-
- if( !$rulesetNode->firstRoot ){
- return;
- }
-
- foreach($rulesetNode->rules as $ruleNode){
- if( $ruleNode instanceof Less_Tree_Rule && !$ruleNode->variable ){
- $msg = "properties must be inside selector blocks, they cannot be in the root. Index ".$ruleNode->index.($ruleNode->currentFileInfo ? (' Filename: '.$ruleNode->currentFileInfo['filename']) : null);
- throw new Less_Exception_Compiler($msg);
- }
- }
- }
-
-
- public function visitRuleset( $rulesetNode, &$visitDeeper ){
-
- $visitDeeper = false;
-
- $this->checkPropertiesInRoot( $rulesetNode );
-
- if( $rulesetNode->root ){
- return $this->visitRulesetRoot( $rulesetNode );
- }
-
- $rulesets = array();
- $rulesetNode->paths = $this->visitRulesetPaths($rulesetNode);
-
-
- // Compile rules and rulesets
- $nodeRuleCnt = $rulesetNode->rules?count($rulesetNode->rules):0;
- for( $i = 0; $i < $nodeRuleCnt; ){
- $rule = $rulesetNode->rules[$i];
-
- if( property_exists($rule,'rules') ){
- // visit because we are moving them out from being a child
- $rulesets[] = $this->visitObj($rule);
- array_splice($rulesetNode->rules,$i,1);
- $nodeRuleCnt--;
- continue;
- }
- $i++;
- }
-
-
- // accept the visitor to remove rules and refactor itself
- // then we can decide now whether we want it or not
- if( $nodeRuleCnt > 0 ){
- $rulesetNode->accept($this);
-
- if( $rulesetNode->rules ){
-
- if( count($rulesetNode->rules) > 1 ){
- $this->_mergeRules( $rulesetNode->rules );
- $this->_removeDuplicateRules( $rulesetNode->rules );
- }
-
- // now decide whether we keep the ruleset
- if( $rulesetNode->paths ){
- //array_unshift($rulesets, $rulesetNode);
- array_splice($rulesets,0,0,array($rulesetNode));
- }
- }
-
- }
-
-
- if( count($rulesets) === 1 ){
- return $rulesets[0];
- }
- return $rulesets;
- }
-
-
- /**
- * Helper function for visitiRuleset
- *
- * return array|Less_Tree_Ruleset
- */
- private function visitRulesetRoot( $rulesetNode ){
- $rulesetNode->accept( $this );
- if( $rulesetNode->firstRoot || $rulesetNode->rules ){
- return $rulesetNode;
- }
- return array();
- }
-
-
- /**
- * Helper function for visitRuleset()
- *
- * @return array
- */
- private function visitRulesetPaths($rulesetNode){
-
- $paths = array();
- foreach($rulesetNode->paths as $p){
- if( $p[0]->elements[0]->combinator === ' ' ){
- $p[0]->elements[0]->combinator = '';
- }
-
- foreach($p as $pi){
- if( $pi->getIsReferenced() && $pi->getIsOutput() ){
- $paths[] = $p;
- break;
- }
- }
- }
-
- return $paths;
- }
-
- protected function _removeDuplicateRules( &$rules ){
- // remove duplicates
- $ruleCache = array();
- for( $i = count($rules)-1; $i >= 0 ; $i-- ){
- $rule = $rules[$i];
- if( $rule instanceof Less_Tree_Rule || $rule instanceof Less_Tree_NameValue ){
-
- if( !isset($ruleCache[$rule->name]) ){
- $ruleCache[$rule->name] = $rule;
- }else{
- $ruleList =& $ruleCache[$rule->name];
-
- if( $ruleList instanceof Less_Tree_Rule || $ruleList instanceof Less_Tree_NameValue ){
- $ruleList = $ruleCache[$rule->name] = array( $ruleCache[$rule->name]->toCSS() );
- }
-
- $ruleCSS = $rule->toCSS();
- if( array_search($ruleCSS,$ruleList) !== false ){
- array_splice($rules,$i,1);
- }else{
- $ruleList[] = $ruleCSS;
- }
- }
- }
- }
- }
-
- protected function _mergeRules( &$rules ){
- $groups = array();
-
- //obj($rules);
-
- $rules_len = count($rules);
- for( $i = 0; $i < $rules_len; $i++ ){
- $rule = $rules[$i];
-
- if( ($rule instanceof Less_Tree_Rule) && $rule->merge ){
-
- $key = $rule->name;
- if( $rule->important ){
- $key .= ',!';
- }
-
- if( !isset($groups[$key]) ){
- $groups[$key] = array();
- }else{
- array_splice($rules, $i--, 1);
- $rules_len--;
- }
-
- $groups[$key][] = $rule;
- }
- }
-
-
- foreach($groups as $parts){
-
- if( count($parts) > 1 ){
- $rule = $parts[0];
- $spacedGroups = array();
- $lastSpacedGroup = array();
- $parts_mapped = array();
- foreach($parts as $p){
- if( $p->merge === '+' ){
- if( $lastSpacedGroup ){
- $spacedGroups[] = self::toExpression($lastSpacedGroup);
- }
- $lastSpacedGroup = array();
- }
- $lastSpacedGroup[] = $p;
- }
-
- $spacedGroups[] = self::toExpression($lastSpacedGroup);
- $rule->value = self::toValue($spacedGroups);
- }
- }
-
- }
-
- public static function toExpression($values){
- $mapped = array();
- foreach($values as $p){
- $mapped[] = $p->value;
- }
- return new Less_Tree_Expression( $mapped );
- }
-
- public static function toValue($values){
- //return new Less_Tree_Value($values); ??
-
- $mapped = array();
- foreach($values as $p){
- $mapped[] = $p;
- }
- return new Less_Tree_Value($mapped);
- }
-}
-
diff --git a/lib/less.php/VisitorReplacing.php b/lib/less.php/VisitorReplacing.php
deleted file mode 100644
index 5923170..0000000
--- a/lib/less.php/VisitorReplacing.php
+++ /dev/null
@@ -1,75 +0,0 @@
-<?php
-
-/**
- * Replacing Visitor
- *
- * @package Less
- * @subpackage visitor
- */
-class Less_VisitorReplacing extends Less_Visitor{
-
- public function visitObj( $node ){
-
- $funcName = 'visit'.$node->type;
- if( isset($this->_visitFnCache[$funcName]) ){
-
- $visitDeeper = true;
- $node = $this->$funcName( $node, $visitDeeper );
-
- if( $node ){
- if( $visitDeeper && is_object($node) ){
- $node->accept($this);
- }
-
- $funcName = $funcName . "Out";
- if( isset($this->_visitFnCache[$funcName]) ){
- $this->$funcName( $node );
- }
- }
-
- }else{
- $node->accept($this);
- }
-
- return $node;
- }
-
- public function visitArray( $nodes ){
-
- $newNodes = array();
- foreach($nodes as $node){
- $evald = $this->visitObj($node);
- if( $evald ){
- if( is_array($evald) ){
- self::flatten($evald,$newNodes);
- }else{
- $newNodes[] = $evald;
- }
- }
- }
- return $newNodes;
- }
-
- public function flatten( $arr, &$out ){
-
- foreach($arr as $item){
- if( !is_array($item) ){
- $out[] = $item;
- continue;
- }
-
- foreach($item as $nestedItem){
- if( is_array($nestedItem) ){
- self::flatten( $nestedItem, $out);
- }else{
- $out[] = $nestedItem;
- }
- }
- }
-
- return $out;
- }
-
-}
-
-