/** * Vyhození chyby * * @param string * @param int * @return void */ protected function throwError($message, $line) { $exception = new CompileException($message); $exception->setLine($line); throw $exception; }
/** * Redukce stromu * * @param Block * @param array * @param array * @return void */ protected function reduceBlock(Block $block, array $selectors = array(), array $variables = array()) { //inicializace nové vrstvy proměnných if (!$block instanceof Main) { $this->variables[] = array(); foreach ($variables as $variable) { try { $this->saveVariable($variable[0], $this->reduceValue($variable[1]), $block instanceof Mixin); } catch (CompileException $e) { throw $e->setLine(end($variable)); } } } if ($block instanceof NestedRule) { $group = array_shift($selectors); $selectors = $this->combineSelectors($this->replaceVariables($block->prefixes), $selectors); $selectors = $this->combineSelectors($selectors, $this->replaceVariables($block->selectors), $group); array_unshift($selectors, count($block->selectors)); } $reduced = $this->getReduced($block, $selectors); foreach ($block->properties as $property) { if (is_array($property)) { try { if ($property[0] == Compiler::$prefixes['variable']) { if (count($property) == 5) { //zápis do pole $this->saveToMap($property[1], $this->valueToIndex($property[4]), $this->reduceValue($property[2])); } else { $this->saveVariable($property[1], $this->reduceValue($property[2])); } } elseif ($property[0] == Compiler::$prefixes['mixin']) { $this->callMixin($property[1], $this->reduceValue($property[2]), $selectors); } elseif ($property[0] == Compiler::$prefixes['none'] || $property[0] == Compiler::$prefixes['important'] || $property[0] == Compiler::$prefixes['raw']) { if ($reduced instanceof Main || $reduced instanceof Media || $reduced instanceof Rule && $this->emptySelectors($selectors)) { throw new CompileException("Vlastnost nemůže být v globálním bloku ani v @media bloku"); } $reduced->properties[] = array($property[0], $property[1], $this->reduceValue($property[2])); } elseif ($property[0] == Compiler::$prefixes['special'] && $property[1] == 'include') { if ($this->inMedia || $reduced instanceof Rule && !$this->emptySelectors($selectors)) { throw new CompileException("Include může být jen v globálním bloku"); } $this->callInclude($property); } elseif ($property[0] == Compiler::$prefixes['special'] && $property[1] == 'import') { if ($this->inMedia || $reduced instanceof Rule && !$this->emptySelectors($selectors)) { throw new CompileException("Import může být jen v globálním bloku"); } $path = $this->reduceValue($property[2]); if ($path[0] !== 'string') { throw new CompileException("Název vkládaného souboru musí být řetězec"); } $media = $this->convertMedia($this->reduceValue($property[3])); $context =& $this->getReducedContext(); $context[] = array('import', $path, $media); } elseif ($property[0] == Compiler::$prefixes['special'] && $property[1] == 'charset') { if (!$reduced instanceof Main) { throw new CompileException("Charset může být jen v globálním bloku"); } $value = $this->reduceValue($property[2]); if ($value[0] !== 'string') { throw new CompileException("Název kódování musí být řetězec"); } $context =& $this->getReducedContext(); $context[] = array('charset', $value); } else { throw new \Exception("Neimplementováno"); } } catch (CompileException $e) { throw $e->setLine(end($property)); } } elseif ($property instanceof NestedRule) { if ($reduced instanceof AtRule && !$reduced instanceof Media) { throw new CompileException("S výjimkou @media at-rules nesmí obsahovat pravidlo"); } $this->callBlock($property, $selectors); } elseif ($property instanceof Mixin) { if ($reduced instanceof AtRule) { throw new CompileException("At-rules nesmí obsahovat mixin"); } if (array_key_exists($property->name, $this->mixins)) { $e = new CompileException("Mixin '{$property->name}' již existuje"); throw $e->setLine($property->line); } $property->file = $this->getFile(); $this->mixins[$property->name] = $property; } elseif ($property instanceof Media) { try { $property->media = $this->convertMedia($this->reduceValue($property->media)); } catch (CompileException $e) { throw $e->setLine($property->line); } $this->reduceBlock($property); } elseif ($property instanceof FontFace) { $this->reduceBlock($property); } else { throw new \Exception("Neimplementováno"); } } if ($block instanceof Media) { $this->inMedia = FALSE; } //zrušení nejvyšší vrstvy proměnných if (!$block instanceof Main) { array_pop($this->variables); } }