PageRenderTime 37ms CodeModel.GetById 9ms RepoModel.GetById 0ms app.codeStats 1ms

/sass/20140320-22659dc78b/tree/SassNode.php

https://github.com/vivid-planet/library
PHP | 392 lines | 197 code | 37 blank | 158 comment | 8 complexity | 218a90269cb7f32ff47f94dee2af8b59 MD5 | raw file
  1. <?php
  2. /* SVN FILE: $Id$ */
  3. /**
  4. * SassNode class file.
  5. * @author Chris Yates <chris.l.yates@gmail.com>
  6. * @copyright Copyright (c) 2010 PBM Web Development
  7. * @license http://phamlp.googlecode.com/files/license.txt
  8. * @package PHamlP
  9. * @subpackage Sass.tree
  10. */
  11. require_once 'SassContext.php';
  12. require_once 'SassCommentNode.php';
  13. require_once 'SassDebugNode.php';
  14. require_once 'SassDirectiveNode.php';
  15. require_once 'SassImportNode.php';
  16. require_once 'SassMixinNode.php';
  17. require_once 'SassMixinDefinitionNode.php';
  18. require_once 'SassPropertyNode.php';
  19. require_once 'SassRootNode.php';
  20. require_once 'SassRuleNode.php';
  21. require_once 'SassVariableNode.php';
  22. require_once 'SassExtendNode.php';
  23. require_once 'SassEachNode.php';
  24. require_once 'SassForNode.php';
  25. require_once 'SassIfNode.php';
  26. require_once 'SassElseNode.php';
  27. require_once 'SassWhileNode.php';
  28. require_once 'SassNodeExceptions.php';
  29. require_once 'SassFunctionDefinitionNode.php';
  30. require_once 'SassReturnNode.php';
  31. require_once 'SassContentNode.php';
  32. require_once 'SassWarnNode.php';
  33. require_once 'SassMediaNode.php';
  34. /**
  35. * SassNode class.
  36. * Base class for all Sass nodes.
  37. * @package PHamlP
  38. * @subpackage Sass.tree
  39. */
  40. class SassNode
  41. {
  42. /**
  43. * @var SassNode parent of this node
  44. */
  45. public $parent;
  46. /**
  47. * @var SassNode root node
  48. */
  49. public $root;
  50. /**
  51. * @var array children of this node
  52. */
  53. public $children = array();
  54. /**
  55. * @var object source token
  56. */
  57. public $token;
  58. /**
  59. * Constructor.
  60. * @param object source token
  61. * @return SassNode
  62. */
  63. public function __construct($token)
  64. {
  65. $this->token = $token;
  66. }
  67. /**
  68. * Getter.
  69. * @param string name of property to get
  70. * @return mixed return value of getter function
  71. */
  72. public function __get($name)
  73. {
  74. $getter = 'get' . ucfirst($name);
  75. if (method_exists($this, $getter)) {
  76. return $this->$getter();
  77. }
  78. throw new SassNodeException('No getter function for ' . $name, $this);
  79. }
  80. /**
  81. * Setter.
  82. * @param string name of property to set
  83. * @return mixed value of property
  84. * @return SassNode this node
  85. */
  86. public function __set($name, $value)
  87. {
  88. $setter = 'set' . ucfirst($name);
  89. if (method_exists($this, $setter)) {
  90. $this->$setter($value);
  91. return $this;
  92. }
  93. throw new SassNodeException('No setter function for ' . $name, $this);
  94. }
  95. /**
  96. * Resets children when cloned
  97. * @see parse
  98. */
  99. public function __clone()
  100. {
  101. $this->children = array();
  102. }
  103. /**
  104. * Return a value indicating if this node has a parent
  105. * @return array the node's parent
  106. */
  107. public function hasParent()
  108. {
  109. return !empty($this->parent);
  110. }
  111. /**
  112. * Returns the node's parent
  113. * @return array the node's parent
  114. */
  115. public function getParent()
  116. {
  117. return $this->parent;
  118. }
  119. /**
  120. * Adds a child to this node.
  121. * @return SassNode the child to add
  122. */
  123. public function addChild($child)
  124. {
  125. if ($child instanceof SassElseNode) {
  126. if (!$this->lastChild instanceof SassIfNode) {
  127. throw new SassException('@else(if) directive must come after @(else)if', $child);
  128. }
  129. $this->lastChild->addElse($child);
  130. } else {
  131. $this->children[] = $child;
  132. $child->parent = $this;
  133. $child->root = $this->root;
  134. }
  135. // The child will have children if a debug node has been added
  136. foreach ($child->children as $grandchild) {
  137. $grandchild->root = $this->root;
  138. }
  139. }
  140. /**
  141. * Returns a value indicating if this node has children
  142. * @return boolean true if the node has children, false if not
  143. */
  144. public function hasChildren()
  145. {
  146. return !empty($this->children);
  147. }
  148. /**
  149. * Returns the node's children
  150. * @return array the node's children
  151. */
  152. public function getChildren()
  153. {
  154. return $this->children;
  155. }
  156. /**
  157. * Returns a value indicating if this node is a child of the passed node.
  158. * This just checks the levels of the nodes. If this node is at a greater
  159. * level than the passed node if is a child of it.
  160. * @return boolean true if the node is a child of the passed node, false if not
  161. */
  162. public function isChildOf($node)
  163. {
  164. return $this->level > $node->level;
  165. }
  166. /**
  167. * Returns the last child node of this node.
  168. * @return SassNode the last child node of this node
  169. */
  170. public function getLastChild()
  171. {
  172. return $this->children[count($this->children) - 1];
  173. }
  174. /**
  175. * Returns the level of this node.
  176. * @return integer the level of this node
  177. */
  178. public function getLevel()
  179. {
  180. return $this->token->level;
  181. }
  182. /**
  183. * Returns the source for this node
  184. * @return string the source for this node
  185. */
  186. public function getSource()
  187. {
  188. return $this->token->source;
  189. }
  190. /**
  191. * Returns the debug_info option setting for this node
  192. * @return boolean the debug_info option setting for this node
  193. */
  194. public function getDebug_info()
  195. {
  196. return $this->parser->debug_info;
  197. }
  198. /**
  199. * Returns the line number for this node
  200. * @return string the line number for this node
  201. */
  202. public function getLine()
  203. {
  204. return $this->token->line;
  205. }
  206. /**
  207. * Returns the line_numbers option setting for this node
  208. * @return boolean the line_numbers option setting for this node
  209. */
  210. public function getLine_numbers()
  211. {
  212. return $this->parser->line_numbers;
  213. }
  214. /**
  215. * Returns the filename for this node
  216. * @return string the filename for this node
  217. */
  218. public function getFilename()
  219. {
  220. return $this->token->filename;
  221. }
  222. /**
  223. * Returns the Sass parser.
  224. * @return SassParser the Sass parser
  225. */
  226. public function getParser()
  227. {
  228. return $this->root->parser;
  229. }
  230. /**
  231. * Returns the property syntax being used.
  232. * @return string the property syntax being used
  233. */
  234. public function getPropertySyntax()
  235. {
  236. return $this->root->parser->propertySyntax;
  237. }
  238. /**
  239. * Returns the SassScript parser.
  240. * @return SassScriptParser the SassScript parser
  241. */
  242. public function getScript()
  243. {
  244. return $this->root->script;
  245. }
  246. /**
  247. * Returns the renderer.
  248. * @return SassRenderer the renderer
  249. */
  250. public function getRenderer()
  251. {
  252. return $this->root->renderer;
  253. }
  254. /**
  255. * Returns the render style of the document tree.
  256. * @return string the render style of the document tree
  257. */
  258. public function getStyle()
  259. {
  260. return $this->root->parser->style;
  261. }
  262. /**
  263. * Returns a value indicating whether this node is in a directive
  264. * @param boolean true if the node is in a directive, false if not
  265. */
  266. public function inDirective()
  267. {
  268. return $this->parent instanceof SassDirectiveNode ||
  269. $this->parent instanceof SassDirectiveNode;
  270. }
  271. /**
  272. * Returns a value indicating whether this node is in a SassScript directive
  273. * @param boolean true if this node is in a SassScript directive, false if not
  274. */
  275. public function inSassScriptDirective()
  276. {
  277. return $this->parent instanceof SassEachNode ||
  278. $this->parent->parent instanceof SassEachNode ||
  279. $this->parent instanceof SassForNode ||
  280. $this->parent->parent instanceof SassForNode ||
  281. $this->parent instanceof SassIfNode ||
  282. $this->parent->parent instanceof SassIfNode ||
  283. $this->parent instanceof SassWhileNode ||
  284. $this->parent->parent instanceof SassWhileNode;
  285. }
  286. /**
  287. * Evaluates a SassScript expression.
  288. * @param string expression to evaluate
  289. * @param SassContext the context in which the expression is evaluated
  290. * @return SassLiteral value of parsed expression
  291. */
  292. public function evaluate($expression, $context, $x=null)
  293. {
  294. $context->node = $this;
  295. return $this->script->evaluate($expression, $context, $x);
  296. }
  297. /**
  298. * Replace interpolated SassScript contained in '#{}' with the parsed value.
  299. * @param string the text to interpolate
  300. * @param SassContext the context in which the string is interpolated
  301. * @return string the interpolated text
  302. */
  303. public function interpolate($expression, $context)
  304. {
  305. $context->node = $this;
  306. return $this->script->interpolate($expression, $context);
  307. }
  308. /**
  309. * Adds a warning to the node.
  310. * @param string warning message
  311. * @param array line
  312. */
  313. public function addWarning($message)
  314. {
  315. $warning = new SassDebugNode($this->token, $message);
  316. $this->addChild($warning);
  317. }
  318. /**
  319. * Parse the children of the node.
  320. * @param SassContext the context in which the children are parsed
  321. * @return array the parsed child nodes
  322. */
  323. public function parseChildren($context)
  324. {
  325. $children = array();
  326. foreach ($this->children as $child) {
  327. # child could be a SassLiteral /or/ SassNode
  328. if (method_exists($child, 'parse')) {
  329. $kid = $child->parse($context);
  330. } else {
  331. $kid = array($child);
  332. }
  333. $children = array_merge($children, $kid);
  334. }
  335. return $children;
  336. }
  337. /**
  338. * Returns a value indicating if the token represents this type of node.
  339. * @param object token
  340. * @return boolean true if the token represents this type of node, false if not
  341. */
  342. public static function isa($token)
  343. {
  344. throw new SassNodeException('Child classes must override this method');
  345. }
  346. public function printDebugTree($i = 0)
  347. {
  348. echo str_repeat(' ', $i*2).get_class($this)." ".$this->getSource()."\n";
  349. $p = $this->getParent();
  350. if ($p) echo str_repeat(' ', $i*2)." parent: ".get_class($p)."\n";
  351. foreach ($this->getChildren() as $c) {
  352. $c->printDebugTree($i+1);
  353. }
  354. }
  355. }