Sass - Version 1.2.0

Version Notes

switch to leafo/scssphp library

Download this release

Release Info

Developer Laurent Clouet
Extension Sass
Version 1.2.0
Comparing to
See all releases


Code changes from version 1.1.5 to 1.2.0

Files changed (404) hide show
  1. app/code/community/Laurent/Sass/Helper/Data.php +31 -24
  2. app/code/community/Laurent/Sass/Model/Config/Style.php +13 -11
  3. app/code/community/Laurent/Sass/etc/config.xml +3 -3
  4. lib/phpsass/.travis.yml +0 -12
  5. lib/phpsass/Extensions/Compass/Compass.php +0 -618
  6. lib/phpsass/Extensions/Compass/stylesheets/_compass.scss +0 -3
  7. lib/phpsass/Extensions/Compass/stylesheets/_lemonade.scss +0 -38
  8. lib/phpsass/Extensions/Compass/stylesheets/compass/_css3.scss +0 -20
  9. lib/phpsass/Extensions/Compass/stylesheets/compass/_layout.scss +0 -3
  10. lib/phpsass/Extensions/Compass/stylesheets/compass/_reset-legacy.scss +0 -3
  11. lib/phpsass/Extensions/Compass/stylesheets/compass/_reset.scss +0 -3
  12. lib/phpsass/Extensions/Compass/stylesheets/compass/_support.scss +0 -40
  13. lib/phpsass/Extensions/Compass/stylesheets/compass/_typography.scss +0 -4
  14. lib/phpsass/Extensions/Compass/stylesheets/compass/_utilities.scss +0 -9
  15. lib/phpsass/Extensions/Compass/stylesheets/compass/css3/_appearance.scss +0 -17
  16. lib/phpsass/Extensions/Compass/stylesheets/compass/css3/_background-clip.scss +0 -43
  17. lib/phpsass/Extensions/Compass/stylesheets/compass/css3/_background-origin.scss +0 -42
  18. lib/phpsass/Extensions/Compass/stylesheets/compass/css3/_background-size.scss +0 -26
  19. lib/phpsass/Extensions/Compass/stylesheets/compass/css3/_border-radius.scss +0 -130
  20. lib/phpsass/Extensions/Compass/stylesheets/compass/css3/_box-shadow.scss +0 -76
  21. lib/phpsass/Extensions/Compass/stylesheets/compass/css3/_box-sizing.scss +0 -13
  22. lib/phpsass/Extensions/Compass/stylesheets/compass/css3/_box.scss +0 -111
  23. lib/phpsass/Extensions/Compass/stylesheets/compass/css3/_columns.scss +0 -157
  24. lib/phpsass/Extensions/Compass/stylesheets/compass/css3/_filter.scss +0 -23
  25. lib/phpsass/Extensions/Compass/stylesheets/compass/css3/_font-face.scss +0 -48
  26. lib/phpsass/Extensions/Compass/stylesheets/compass/css3/_hyphenation.scss +0 -77
  27. lib/phpsass/Extensions/Compass/stylesheets/compass/css3/_images.scss +0 -132
  28. lib/phpsass/Extensions/Compass/stylesheets/compass/css3/_inline-block.scss +0 -22
  29. lib/phpsass/Extensions/Compass/stylesheets/compass/css3/_opacity.scss +0 -19
  30. lib/phpsass/Extensions/Compass/stylesheets/compass/css3/_pie.scss +0 -73
  31. lib/phpsass/Extensions/Compass/stylesheets/compass/css3/_regions.scss +0 -22
  32. lib/phpsass/Extensions/Compass/stylesheets/compass/css3/_shared.scss +0 -38
  33. lib/phpsass/Extensions/Compass/stylesheets/compass/css3/_text-shadow.scss +0 -87
  34. lib/phpsass/Extensions/Compass/stylesheets/compass/css3/_transform-legacy.scss +0 -87
  35. lib/phpsass/Extensions/Compass/stylesheets/compass/css3/_transform.scss +0 -598
  36. lib/phpsass/Extensions/Compass/stylesheets/compass/css3/_transition.scss +0 -221
  37. lib/phpsass/Extensions/Compass/stylesheets/compass/css3/_user-interface.scss +0 -17
  38. lib/phpsass/Extensions/Compass/stylesheets/compass/layout/_grid-background.scss +0 -178
  39. lib/phpsass/Extensions/Compass/stylesheets/compass/layout/_sticky-footer.scss +0 -23
  40. lib/phpsass/Extensions/Compass/stylesheets/compass/layout/_stretching.scss +0 -24
  41. lib/phpsass/Extensions/Compass/stylesheets/compass/reset/_utilities-legacy.scss +0 -135
  42. lib/phpsass/Extensions/Compass/stylesheets/compass/reset/_utilities.scss +0 -142
  43. lib/phpsass/Extensions/Compass/stylesheets/compass/typography/_links.scss +0 -3
  44. lib/phpsass/Extensions/Compass/stylesheets/compass/typography/_lists.scss +0 -4
  45. lib/phpsass/Extensions/Compass/stylesheets/compass/typography/_text.scss +0 -4
  46. lib/phpsass/Extensions/Compass/stylesheets/compass/typography/links/_hover-link.scss +0 -5
  47. lib/phpsass/Extensions/Compass/stylesheets/compass/typography/links/_link-colors.scss +0 -28
  48. lib/phpsass/Extensions/Compass/stylesheets/compass/typography/links/_unstyled-link.scss +0 -7
  49. lib/phpsass/Extensions/Compass/stylesheets/compass/typography/lists/_bullets.scss +0 -34
  50. lib/phpsass/Extensions/Compass/stylesheets/compass/typography/lists/_horizontal-list.scss +0 -61
  51. lib/phpsass/Extensions/Compass/stylesheets/compass/typography/lists/_inline-block-list.scss +0 -50
  52. lib/phpsass/Extensions/Compass/stylesheets/compass/typography/lists/_inline-list.scss +0 -44
  53. lib/phpsass/Extensions/Compass/stylesheets/compass/typography/text/_ellipsis.scss +0 -25
  54. lib/phpsass/Extensions/Compass/stylesheets/compass/typography/text/_force-wrap.scss +0 -12
  55. lib/phpsass/Extensions/Compass/stylesheets/compass/typography/text/_nowrap.scss +0 -2
  56. lib/phpsass/Extensions/Compass/stylesheets/compass/typography/text/_replacement.scss +0 -68
  57. lib/phpsass/Extensions/Compass/stylesheets/compass/utilities/_color.scss +0 -1
  58. lib/phpsass/Extensions/Compass/stylesheets/compass/utilities/_general.scss +0 -6
  59. lib/phpsass/Extensions/Compass/stylesheets/compass/utilities/_links.scss +0 -5
  60. lib/phpsass/Extensions/Compass/stylesheets/compass/utilities/_lists.scss +0 -6
  61. lib/phpsass/Extensions/Compass/stylesheets/compass/utilities/_print.scss +0 -17
  62. lib/phpsass/Extensions/Compass/stylesheets/compass/utilities/_sprites.scss +0 -2
  63. lib/phpsass/Extensions/Compass/stylesheets/compass/utilities/_tables.scss +0 -3
  64. lib/phpsass/Extensions/Compass/stylesheets/compass/utilities/_text.scss +0 -5
  65. lib/phpsass/Extensions/Compass/stylesheets/compass/utilities/color/_contrast.scss +0 -28
  66. lib/phpsass/Extensions/Compass/stylesheets/compass/utilities/general/_clearfix.scss +0 -44
  67. lib/phpsass/Extensions/Compass/stylesheets/compass/utilities/general/_float.scss +0 -30
  68. lib/phpsass/Extensions/Compass/stylesheets/compass/utilities/general/_hacks.scss +0 -46
  69. lib/phpsass/Extensions/Compass/stylesheets/compass/utilities/general/_min.scss +0 -16
  70. lib/phpsass/Extensions/Compass/stylesheets/compass/utilities/general/_reset.scss +0 -2
  71. lib/phpsass/Extensions/Compass/stylesheets/compass/utilities/general/_tabs.scss +0 -1
  72. lib/phpsass/Extensions/Compass/stylesheets/compass/utilities/general/_tag-cloud.scss +0 -18
  73. lib/phpsass/Extensions/Compass/stylesheets/compass/utilities/links/_hover-link.scss +0 -3
  74. lib/phpsass/Extensions/Compass/stylesheets/compass/utilities/links/_link-colors.scss +0 -3
  75. lib/phpsass/Extensions/Compass/stylesheets/compass/utilities/links/_unstyled-link.scss +0 -3
  76. lib/phpsass/Extensions/Compass/stylesheets/compass/utilities/lists/_bullets.scss +0 -3
  77. lib/phpsass/Extensions/Compass/stylesheets/compass/utilities/lists/_horizontal-list.scss +0 -3
  78. lib/phpsass/Extensions/Compass/stylesheets/compass/utilities/lists/_inline-block-list.scss +0 -3
  79. lib/phpsass/Extensions/Compass/stylesheets/compass/utilities/lists/_inline-list.scss +0 -3
  80. lib/phpsass/Extensions/Compass/stylesheets/compass/utilities/sprites/_base.scss +0 -66
  81. lib/phpsass/Extensions/Compass/stylesheets/compass/utilities/sprites/_sprite-img.scss +0 -79
  82. lib/phpsass/Extensions/Compass/stylesheets/compass/utilities/tables/_alternating-rows-and-columns.scss +0 -22
  83. lib/phpsass/Extensions/Compass/stylesheets/compass/utilities/tables/_borders.scss +0 -33
  84. lib/phpsass/Extensions/Compass/stylesheets/compass/utilities/tables/_scaffolding.scss +0 -9
  85. lib/phpsass/Extensions/Compass/stylesheets/compass/utilities/text/_ellipsis.scss +0 -3
  86. lib/phpsass/Extensions/Compass/stylesheets/compass/utilities/text/_nowrap.scss +0 -3
  87. lib/phpsass/Extensions/Compass/stylesheets/compass/utilities/text/_replacement.scss +0 -3
  88. lib/phpsass/Extensions/Compass/test.php +0 -62
  89. lib/phpsass/Extensions/ExtensionInterface.php +0 -7
  90. lib/phpsass/Extensions/Own/Own.php +0 -91
  91. lib/phpsass/Extensions/Own/css/test/test2/test.scss +0 -3
  92. lib/phpsass/Extensions/README.md +0 -10
  93. lib/phpsass/Extensions/Susy/Susy.php +0 -75
  94. lib/phpsass/Extensions/Susy/stylesheets/_susy.scss +0 -16
  95. lib/phpsass/Extensions/Susy/stylesheets/susy/_background.scss +0 -18
  96. lib/phpsass/Extensions/Susy/stylesheets/susy/_functions.scss +0 -376
  97. lib/phpsass/Extensions/Susy/stylesheets/susy/_grid.scss +0 -286
  98. lib/phpsass/Extensions/Susy/stylesheets/susy/_isolation.scss +0 -48
  99. lib/phpsass/Extensions/Susy/stylesheets/susy/_margin.scss +0 -93
  100. lib/phpsass/Extensions/Susy/stylesheets/susy/_media.scss +0 -112
  101. lib/phpsass/Extensions/Susy/stylesheets/susy/_padding.scss +0 -92
  102. lib/phpsass/Extensions/Susy/stylesheets/susy/_settings.scss +0 -56
  103. lib/phpsass/Extensions/Susy/stylesheets/susy/_support.scss +0 -198
  104. lib/phpsass/Extensions/Susy/stylesheets/susy/_units.scss +0 -159
  105. lib/phpsass/Extensions/example.php +0 -82
  106. lib/phpsass/Extensions/example.scss +0 -8
  107. lib/phpsass/Extensions/theme.scss +0 -1
  108. lib/phpsass/README.md +0 -28
  109. lib/phpsass/SassException.php +0 -29
  110. lib/phpsass/SassFile.php +0 -166
  111. lib/phpsass/SassParser.php +0 -890
  112. lib/phpsass/VERSION +0 -23
  113. lib/phpsass/compile-apache.php +0 -42
  114. lib/phpsass/composer.json +0 -38
  115. lib/phpsass/renderers/SassCompactRenderer.php +0 -144
  116. lib/phpsass/renderers/SassCompressedRenderer.php +0 -124
  117. lib/phpsass/renderers/SassExpandedRenderer.php +0 -69
  118. lib/phpsass/renderers/SassNestedRenderer.php +0 -75
  119. lib/phpsass/renderers/SassRenderer.php +0 -53
  120. lib/phpsass/script/SassScriptFunction.php +0 -317
  121. lib/phpsass/script/SassScriptFunctions.php +0 -1053
  122. lib/phpsass/script/SassScriptLexer.php +0 -129
  123. lib/phpsass/script/SassScriptOperation.php +0 -195
  124. lib/phpsass/script/SassScriptParser.php +0 -256
  125. lib/phpsass/script/SassScriptParserExceptions.php +0 -40
  126. lib/phpsass/script/SassScriptVariable.php +0 -61
  127. lib/phpsass/script/literals/SassBoolean.php +0 -84
  128. lib/phpsass/script/literals/SassColour.php +0 -956
  129. lib/phpsass/script/literals/SassList.php +0 -237
  130. lib/phpsass/script/literals/SassLiteral.php +0 -410
  131. lib/phpsass/script/literals/SassLiteralExceptions.php +0 -47
  132. lib/phpsass/script/literals/SassNumber.php +0 -597
  133. lib/phpsass/script/literals/SassString.php +0 -148
  134. lib/phpsass/test-extensions.php +0 -147
  135. lib/phpsass/test.css +0 -39
  136. lib/phpsass/test.php +0 -149
  137. lib/phpsass/tests/_imported_charset_ibm866.sass +0 -4
  138. lib/phpsass/tests/_imported_charset_utf8.sass +0 -4
  139. lib/phpsass/tests/_imported_content.sass +0 -3
  140. lib/phpsass/tests/_partial.sass +0 -2
  141. lib/phpsass/tests/alt.css +0 -16
  142. lib/phpsass/tests/alt.sass +0 -16
  143. lib/phpsass/tests/alt.scss +0 -21
  144. lib/phpsass/tests/basic.css +0 -21
  145. lib/phpsass/tests/basic.sass +0 -22
  146. lib/phpsass/tests/bork1.sass +0 -2
  147. lib/phpsass/tests/bork2.sass +0 -2
  148. lib/phpsass/tests/bork3.sass +0 -2
  149. lib/phpsass/tests/bork4.sass +0 -2
  150. lib/phpsass/tests/bork5.sass +0 -3
  151. lib/phpsass/tests/colour-nth.css +0 -2
  152. lib/phpsass/tests/colour-nth.scss +0 -3
  153. lib/phpsass/tests/comments.css +0 -20
  154. lib/phpsass/tests/comments.sass +0 -20
  155. lib/phpsass/tests/compact.css +0 -13
  156. lib/phpsass/tests/compact.sass +0 -15
  157. lib/phpsass/tests/complex.css +0 -290
  158. lib/phpsass/tests/complex.sass +0 -303
  159. lib/phpsass/tests/compressed.css +0 -12
  160. lib/phpsass/tests/compressed.sass +0 -15
  161. lib/phpsass/tests/content.css +0 -2
  162. lib/phpsass/tests/content.scss +0 -3
  163. lib/phpsass/tests/css3.css +0 -7
  164. lib/phpsass/tests/css3.scss +0 -8
  165. lib/phpsass/tests/default.css +0 -4
  166. lib/phpsass/tests/default.sass +0 -11
  167. lib/phpsass/tests/default_imported.sass +0 -2
  168. lib/phpsass/tests/each.css +0 -14
  169. lib/phpsass/tests/each.scss +0 -17
  170. lib/phpsass/tests/expanded.css +0 -17
  171. lib/phpsass/tests/expanded.sass +0 -17
  172. lib/phpsass/tests/extend.css +0 -13
  173. lib/phpsass/tests/extend.sass +0 -13
  174. lib/phpsass/tests/extend_included.scss +0 -4
  175. lib/phpsass/tests/extend_placeholders.css +0 -48
  176. lib/phpsass/tests/extend_placeholders.scss +0 -58
  177. lib/phpsass/tests/extensions/linear_gradient_compass.css +0 -5
  178. lib/phpsass/tests/extensions/linear_gradient_compass.scss +0 -7
  179. lib/phpsass/tests/filters.css +0 -6
  180. lib/phpsass/tests/filters.scss +0 -10
  181. lib/phpsass/tests/functions.css +0 -9
  182. lib/phpsass/tests/functions.scss +0 -16
  183. lib/phpsass/tests/holmes.css +0 -227
  184. lib/phpsass/tests/holmes.sass +0 -262
  185. lib/phpsass/tests/hsl-functions.css +0 -14
  186. lib/phpsass/tests/hsl-functions.scss +0 -15
  187. lib/phpsass/tests/if.css +0 -5
  188. lib/phpsass/tests/if.sass +0 -11
  189. lib/phpsass/tests/if_parentheses.css +0 -2
  190. lib/phpsass/tests/if_parentheses.scss +0 -6
  191. lib/phpsass/tests/import.css +0 -62
  192. lib/phpsass/tests/import.sass +0 -15
  193. lib/phpsass/tests/import_content.css +0 -2
  194. lib/phpsass/tests/import_content.sass +0 -4
  195. lib/phpsass/tests/importee.sass +0 -19
  196. lib/phpsass/tests/interpolation.css +0 -27
  197. lib/phpsass/tests/interpolation.scss +0 -54
  198. lib/phpsass/tests/introspection.css +0 -13
  199. lib/phpsass/tests/introspection.scss +0 -16
  200. lib/phpsass/tests/line_numbers.css +0 -37
  201. lib/phpsass/tests/line_numbers.sass +0 -13
  202. lib/phpsass/tests/list.css +0 -4
  203. lib/phpsass/tests/list.scss +0 -8
  204. lib/phpsass/tests/list_empty.css +0 -2
  205. lib/phpsass/tests/list_empty.scss +0 -5
  206. lib/phpsass/tests/list_variable.css +0 -2
  207. lib/phpsass/tests/list_variable.scss +0 -9
  208. lib/phpsass/tests/media.css +0 -7
  209. lib/phpsass/tests/media.scss +0 -15
  210. lib/phpsass/tests/media_in_for.css +0 -6
  211. lib/phpsass/tests/media_in_for.scss +0 -10
  212. lib/phpsass/tests/media_in_mixin.css +0 -3
  213. lib/phpsass/tests/media_in_mixin.scss +0 -9
  214. lib/phpsass/tests/media_in_mixin_in_mixin.css +0 -4
  215. lib/phpsass/tests/media_in_mixin_in_mixin.scss +0 -18
  216. lib/phpsass/tests/misc-functions.css +0 -6
  217. lib/phpsass/tests/misc-functions.scss +0 -11
  218. lib/phpsass/tests/misc.css +0 -85
  219. lib/phpsass/tests/misc.scss +0 -103
  220. lib/phpsass/tests/mixin-content.css +0 -5
  221. lib/phpsass/tests/mixin-content.sass +0 -10
  222. lib/phpsass/tests/mixin-content.scss +0 -14
  223. lib/phpsass/tests/mixin-ja1.css +0 -8
  224. lib/phpsass/tests/mixin-ja1.sass +0 -14
  225. lib/phpsass/tests/mixin-list-params.css +0 -7
  226. lib/phpsass/tests/mixin-list-params.scss +0 -17
  227. lib/phpsass/tests/mixin-params.css +0 -23
  228. lib/phpsass/tests/mixin-params.scss +0 -28
  229. lib/phpsass/tests/mixin-rgba-param.css +0 -2
  230. lib/phpsass/tests/mixin-rgba-param.scss +0 -7
  231. lib/phpsass/tests/mixin_bork.sass +0 -5
  232. lib/phpsass/tests/mixin_in_mixin.css +0 -2
  233. lib/phpsass/tests/mixin_in_mixin.scss +0 -15
  234. lib/phpsass/tests/mixin_setvar.css +0 -2
  235. lib/phpsass/tests/mixin_setvar.scss +0 -10
  236. lib/phpsass/tests/mixins.css +0 -87
  237. lib/phpsass/tests/mixins.sass +0 -84
  238. lib/phpsass/tests/multiline.css +0 -24
  239. lib/phpsass/tests/multiline.sass +0 -20
  240. lib/phpsass/tests/nested-media.css +0 -14
  241. lib/phpsass/tests/nested-media.scss +0 -22
  242. lib/phpsass/tests/nested.css +0 -24
  243. lib/phpsass/tests/nested.sass +0 -28
  244. lib/phpsass/tests/nested_bork1.sass +0 -2
  245. lib/phpsass/tests/nested_bork2.sass +0 -2
  246. lib/phpsass/tests/nested_bork3.sass +0 -2
  247. lib/phpsass/tests/nested_bork4.sass +0 -2
  248. lib/phpsass/tests/nested_bork5.sass +0 -2
  249. lib/phpsass/tests/nested_import.css +0 -18
  250. lib/phpsass/tests/nested_import.sass +0 -2
  251. lib/phpsass/tests/nested_media.css +0 -5
  252. lib/phpsass/tests/nested_media.scss +0 -10
  253. lib/phpsass/tests/nested_mixin_bork.sass +0 -6
  254. lib/phpsass/tests/nested_pseudo.css +0 -3
  255. lib/phpsass/tests/nested_pseudo.scss +0 -7
  256. lib/phpsass/tests/number.css +0 -9
  257. lib/phpsass/tests/number.scss +0 -10
  258. lib/phpsass/tests/opacity.css +0 -7
  259. lib/phpsass/tests/opacity.scss +0 -8
  260. lib/phpsass/tests/other-color.css +0 -5
  261. lib/phpsass/tests/other-color.scss +0 -5
  262. lib/phpsass/tests/parent_ref.css +0 -39
  263. lib/phpsass/tests/parent_ref.sass +0 -30
  264. lib/phpsass/tests/phpSassTest.php +0 -409
  265. lib/phpsass/tests/phpunit.xml.dist +0 -14
  266. lib/phpsass/tests/proprietary-selector.css +0 -4
  267. lib/phpsass/tests/proprietary-selector.scss +0 -8
  268. lib/phpsass/tests/rgb-functions.css +0 -8
  269. lib/phpsass/tests/rgb-functions.scss +0 -9
  270. lib/phpsass/tests/scss_import.css +0 -62
  271. lib/phpsass/tests/scss_import.scss +0 -15
  272. lib/phpsass/tests/scss_importee.css +0 -2
  273. lib/phpsass/tests/scss_importee.scss +0 -1
  274. lib/phpsass/tests/splats.css +0 -5
  275. lib/phpsass/tests/splats.scss +0 -19
  276. lib/phpsass/tests/string.css +0 -3
  277. lib/phpsass/tests/string.scss +0 -6
  278. lib/phpsass/tests/subdir/nested_subdir/_nested_partial.sass +0 -2
  279. lib/phpsass/tests/subdir/nested_subdir/nested_subdir.css +0 -1
  280. lib/phpsass/tests/subdir/nested_subdir/nested_subdir.sass +0 -3
  281. lib/phpsass/tests/subdir/subdir.css +0 -3
  282. lib/phpsass/tests/subdir/subdir.sass +0 -6
  283. lib/phpsass/tests/units.css +0 -12
  284. lib/phpsass/tests/units.sass +0 -12
  285. lib/phpsass/tests/warn.css +0 -1
  286. lib/phpsass/tests/warn.sass +0 -4
  287. lib/phpsass/tests/warn_imported.sass +0 -4
  288. lib/phpsass/tree/SassCommentNode.php +0 -70
  289. lib/phpsass/tree/SassContentNode.php +0 -75
  290. lib/phpsass/tree/SassContext.php +0 -213
  291. lib/phpsass/tree/SassDebugNode.php +0 -93
  292. lib/phpsass/tree/SassDirectiveNode.php +0 -124
  293. lib/phpsass/tree/SassEachNode.php +0 -79
  294. lib/phpsass/tree/SassElseNode.php +0 -30
  295. lib/phpsass/tree/SassExtendNode.php +0 -53
  296. lib/phpsass/tree/SassForNode.php +0 -103
  297. lib/phpsass/tree/SassFunctionDefinitionNode.php +0 -123
  298. lib/phpsass/tree/SassIfNode.php +0 -98
  299. lib/phpsass/tree/SassImportNode.php +0 -109
  300. lib/phpsass/tree/SassMediaNode.php +0 -99
  301. lib/phpsass/tree/SassMixinDefinitionNode.php +0 -85
  302. lib/phpsass/tree/SassMixinNode.php +0 -93
  303. lib/phpsass/tree/SassNode.php +0 -392
  304. lib/phpsass/tree/SassNodeExceptions.php +0 -131
  305. lib/phpsass/tree/SassPropertyNode.php +0 -276
  306. lib/phpsass/tree/SassReturnNode.php +0 -86
  307. lib/phpsass/tree/SassRootNode.php +0 -122
  308. lib/phpsass/tree/SassRuleNode.php +0 -392
  309. lib/phpsass/tree/SassVariableNode.php +0 -96
  310. lib/phpsass/tree/SassWarnNode.php +0 -83
  311. lib/phpsass/tree/SassWhileNode.php +0 -67
  312. lib/scssphp/.travis.yml +10 -0
  313. lib/scssphp/LICENSE.md +660 -0
  314. lib/scssphp/Makefile +2 -0
  315. lib/scssphp/README.md +34 -0
  316. lib/scssphp/bin/pscss +71 -0
  317. lib/scssphp/classmap.php +62 -0
  318. lib/scssphp/composer.json +32 -0
  319. lib/scssphp/package.sh +24 -0
  320. lib/scssphp/phpunit.xml.dist +29 -0
  321. lib/scssphp/scss.inc.php +11 -0
  322. lib/scssphp/site/composer.html +6 -0
  323. lib/scssphp/site/docs/index.md +325 -0
  324. lib/scssphp/site/index.md +233 -0
  325. lib/scssphp/site/site.moon +15 -0
  326. lib/scssphp/site/style.scss +303 -0
  327. lib/scssphp/site/templates/index.html +81 -0
  328. lib/scssphp/site/www/img/tile.png +0 -0
  329. lib/scssphp/site/www/style/normalize.css +500 -0
  330. lib/scssphp/src/Colors.php +179 -0
  331. lib/scssphp/src/Compiler.php +3006 -0
  332. lib/scssphp/src/Formatter.php +93 -0
  333. lib/scssphp/src/Formatter/Compressed.php +58 -0
  334. lib/scssphp/src/Formatter/Crunched.php +56 -0
  335. lib/scssphp/src/Formatter/Expanded.php +34 -0
  336. lib/scssphp/src/Formatter/Nested.php +133 -0
  337. lib/scssphp/src/Parser.php +1811 -0
  338. lib/scssphp/src/Server.php +316 -0
  339. lib/scssphp/tests/ApiTest.php +82 -0
  340. lib/scssphp/tests/ExceptionTest.php +93 -0
  341. lib/scssphp/tests/InputTest.php +98 -0
  342. lib/scssphp/tests/compare-scss.sh +25 -0
  343. lib/scssphp/tests/inputs/builtins.scss +171 -0
  344. lib/scssphp/tests/inputs/comments.scss +44 -0
  345. lib/{phpsass/Extensions/Compass/stylesheets/compass/typography/_vertical_rhythm.scss → scssphp/tests/inputs/compass_extract.scss} +28 -1
  346. lib/scssphp/tests/inputs/content.scss +61 -0
  347. lib/scssphp/tests/inputs/content_with_function.scss +17 -0
  348. lib/scssphp/tests/inputs/default_args.scss +15 -0
  349. lib/scssphp/tests/inputs/directives.scss +108 -0
  350. lib/scssphp/tests/inputs/extends.scss +184 -0
  351. lib/scssphp/tests/inputs/filter_effects.scss +48 -0
  352. lib/scssphp/tests/inputs/functions.scss +89 -0
  353. lib/scssphp/tests/inputs/ie7.scss +12 -0
  354. lib/scssphp/tests/inputs/if.scss +76 -0
  355. lib/scssphp/tests/inputs/if_on_null.scss +8 -0
  356. lib/scssphp/tests/inputs/import.scss +23 -0
  357. lib/scssphp/tests/inputs/imports/_partial.scss +10 -0
  358. lib/scssphp/tests/inputs/imports/simple.scss +4 -0
  359. lib/scssphp/tests/inputs/interpolation.scss +86 -0
  360. lib/scssphp/tests/inputs/keyword_args.scss +24 -0
  361. lib/scssphp/tests/inputs/list.scss +15 -0
  362. lib/scssphp/tests/inputs/looping.scss +51 -0
  363. lib/scssphp/tests/inputs/media.scss +208 -0
  364. lib/scssphp/tests/inputs/mixins.scss +183 -0
  365. lib/scssphp/tests/inputs/nesting.scss +45 -0
  366. lib/scssphp/tests/inputs/null.scss +41 -0
  367. lib/scssphp/tests/inputs/operators.scss +143 -0
  368. lib/scssphp/tests/inputs/parsing_comments.scss +59 -0
  369. lib/scssphp/tests/inputs/placeholder_selector.scss +18 -0
  370. lib/scssphp/tests/inputs/scss_css.scss +986 -0
  371. lib/scssphp/tests/inputs/selectors.scss +195 -0
  372. lib/scssphp/tests/inputs/values.scss +43 -0
  373. lib/scssphp/tests/inputs/variables.scss +56 -0
  374. lib/scssphp/tests/outputs/builtins.css +126 -0
  375. lib/scssphp/tests/outputs/comments.css +31 -0
  376. lib/scssphp/tests/outputs/compass_extract.css +28 -0
  377. lib/scssphp/tests/outputs/content.css +29 -0
  378. lib/scssphp/tests/outputs/content_with_function.css +2 -0
  379. lib/scssphp/tests/outputs/default_args.css +3 -0
  380. lib/scssphp/tests/outputs/directives.css +77 -0
  381. lib/scssphp/tests/outputs/extends.css +87 -0
  382. lib/scssphp/tests/outputs/filter_effects.css +20 -0
  383. lib/scssphp/tests/outputs/functions.css +25 -0
  384. lib/scssphp/tests/outputs/ie7.css +8 -0
  385. lib/scssphp/tests/outputs/if.css +21 -0
  386. lib/scssphp/tests/outputs/if_on_null.css +2 -0
  387. lib/scssphp/tests/outputs/import.css +27 -0
  388. lib/scssphp/tests/outputs/interpolation.css +54 -0
  389. lib/scssphp/tests/outputs/keyword_args.css +6 -0
  390. lib/scssphp/tests/outputs/list.css +7 -0
  391. lib/scssphp/tests/outputs/looping.css +45 -0
  392. lib/scssphp/tests/outputs/media.css +103 -0
  393. lib/scssphp/tests/outputs/mixins.css +93 -0
  394. lib/scssphp/tests/outputs/nesting.css +22 -0
  395. lib/scssphp/tests/outputs/null.css +21 -0
  396. lib/scssphp/tests/outputs/operators.css +105 -0
  397. lib/scssphp/tests/outputs/parsing_comments.css +50 -0
  398. lib/scssphp/tests/outputs/placeholder_selector.css +7 -0
  399. lib/scssphp/tests/outputs/scss_css.css +771 -0
  400. lib/scssphp/tests/outputs/selectors.css +341 -0
  401. lib/scssphp/tests/outputs/values.css +34 -0
  402. lib/scssphp/tests/outputs/variables.css +24 -0
  403. lib/scssphp/todo +47 -0
  404. package.xml +5 -6
app/code/community/Laurent/Sass/Helper/Data.php CHANGED
@@ -11,7 +11,7 @@
11
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
12
  */
13
 
14
- require_once 'phpsass/SassParser.php';
15
 
16
  class Laurent_Sass_Helper_Data extends Mage_Core_Helper_Abstract
17
  {
@@ -36,13 +36,13 @@ class Laurent_Sass_Helper_Data extends Mage_Core_Helper_Abstract
36
 
37
  /**
38
  * Create a new css file based on sass file
39
- * @param string $sourceFilename
40
- * @param string $targetFilename
41
  * @throws Exception
42
  */
43
- public function createNewCss($sourceFilename, $targetFilename){
44
  $config = $this->_getConfig();
45
- $targetDir = dirname($targetFilename);
46
  $this->_createDir($targetDir);
47
  $this->_createDir($config['cache_dir']);
48
 
@@ -51,28 +51,35 @@ class Laurent_Sass_Helper_Data extends Mage_Core_Helper_Abstract
51
  if($config['debug']){
52
  $options .= ' --debug-info --line-numbers';
53
  }
54
- $command = $config['sass_command'] . ' ' . $options . ' ' . $sourceFilename .':' . $targetFilename;
55
  $execResult = exec($command, $output);
56
  if($execResult != ''){
57
  throw new Exception("Error while processing sass file with command '$command':\n" . implode("\n", $output));
58
  }
59
- }
60
- else{
61
- //Using PhpSass
62
- $sassOptions = array(
63
- 'style' => $config['output_style'],
64
- 'syntax' => $this->getFileExtension($sourceFilename),
65
- 'debug' => $config['debug'],
66
- 'debug_info' => $config['debug'],
67
- 'line_numbers' => $config['debug'],
68
- 'callbacks' => array(
69
- 'warn' => array(__CLASS__, 'logWarning'),
70
- 'debug' => array(__CLASS__, 'logDebug'),
71
- ),
72
- );
73
- $sassParser = new SassParser($sassOptions);
74
- $cssContent = $sassParser->toCss($sourceFilename);
75
- file_put_contents($targetFilename, $cssContent);
 
 
 
 
 
 
 
76
  }
77
  }
78
 
@@ -114,7 +121,7 @@ class Laurent_Sass_Helper_Data extends Mage_Core_Helper_Abstract
114
  $configStyleModel = Mage::getModel('sass/config_style');
115
  $authorizedOutputStyles = $configStyleModel->authorizedValues();
116
  if(!in_array($outputStyle, $authorizedOutputStyles)){
117
- $outputStyle = SassRenderer::STYLE_NESTED;
118
  }
119
 
120
  return array(
11
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
12
  */
13
 
14
+ require_once 'scssphp/scss.inc.php';
15
 
16
  class Laurent_Sass_Helper_Data extends Mage_Core_Helper_Abstract
17
  {
36
 
37
  /**
38
  * Create a new css file based on sass file
39
+ * @param string $sourceFilePath
40
+ * @param string $targetFilenamePath
41
  * @throws Exception
42
  */
43
+ public function createNewCss($sourceFilePath, $targetFilenamePath){
44
  $config = $this->_getConfig();
45
+ $targetDir = dirname($targetFilenamePath);
46
  $this->_createDir($targetDir);
47
  $this->_createDir($config['cache_dir']);
48
 
51
  if($config['debug']){
52
  $options .= ' --debug-info --line-numbers';
53
  }
54
+ $command = $config['sass_command'] . ' ' . $options . ' ' . $sourceFilePath .':' . $targetFilenamePath;
55
  $execResult = exec($command, $output);
56
  if($execResult != ''){
57
  throw new Exception("Error while processing sass file with command '$command':\n" . implode("\n", $output));
58
  }
59
+ } else {
60
+ $compiler = new \Leafo\ScssPhp\Compiler();
61
+ switch ($config['output_style']) {
62
+ case Laurent_Sass_Model_Config_Style::STYLE_COMPACT:
63
+ default:
64
+ $formatter = 'scss_formatter_crunched';
65
+ break;
66
+ case Laurent_Sass_Model_Config_Style::STYLE_NESTED:
67
+ $formatter = 'scss_formatter_nested';
68
+ break;
69
+ case Laurent_Sass_Model_Config_Style::STYLE_COMPRESSED:
70
+ $formatter = 'scss_formatter_compressed';
71
+ break;
72
+ case Laurent_Sass_Model_Config_Style::STYLE_EXPANDED:
73
+ $formatter = 'scss_formatter';
74
+ break;
75
+ }
76
+ $compiler->setFormatter($formatter);
77
+ $compiler->setImportPaths(array (
78
+ dirname($sourceFilePath),
79
+ Mage::getBaseDir('lib') . '/scssphp/stylesheets',
80
+ ));
81
+
82
+ file_put_contents($targetFilenamePath, $compiler->compile(sprintf('@import "%s"', basename($sourceFilePath))));
83
  }
84
  }
85
 
121
  $configStyleModel = Mage::getModel('sass/config_style');
122
  $authorizedOutputStyles = $configStyleModel->authorizedValues();
123
  if(!in_array($outputStyle, $authorizedOutputStyles)){
124
+ $outputStyle = Laurent_Sass_Model_Config_Style::STYLE_NESTED;
125
  }
126
 
127
  return array(
app/code/community/Laurent/Sass/Model/Config/Style.php CHANGED
@@ -11,11 +11,13 @@
11
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
12
  */
13
 
14
- require_once 'phpsass/renderers/SassRenderer.php';
15
-
16
  class Laurent_Sass_Model_Config_Style
17
  {
18
-
 
 
 
 
19
  /**
20
  * Options getter
21
  * @return array
@@ -25,10 +27,10 @@ class Laurent_Sass_Model_Config_Style
25
  $sassHelper = Mage::helper('sass');
26
 
27
  return array(
28
- array('value' => SassRenderer::STYLE_NESTED, 'label' => $sassHelper->__('Nested')),
29
- array('value' => SassRenderer::STYLE_COMPACT, 'label' => $sassHelper->__('Compact')),
30
- array('value' => SassRenderer::STYLE_COMPRESSED, 'label' => $sassHelper->__('Compressed')),
31
- array('value' => SassRenderer::STYLE_EXPANDED, 'label' => $sassHelper->__('Expanded')),
32
  );
33
  }
34
 
@@ -38,10 +40,10 @@ class Laurent_Sass_Model_Config_Style
38
  */
39
  public function authorizedValues(){
40
  return array(
41
- SassRenderer::STYLE_NESTED,
42
- SassRenderer::STYLE_COMPACT,
43
- SassRenderer::STYLE_COMPRESSED,
44
- SassRenderer::STYLE_EXPANDED,
45
  );
46
  }
47
  }
11
  * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
12
  */
13
 
 
 
14
  class Laurent_Sass_Model_Config_Style
15
  {
16
+ const STYLE_NESTED = 'nested';
17
+ const STYLE_EXPANDED = 'expanded';
18
+ const STYLE_COMPACT = 'compact';
19
+ const STYLE_COMPRESSED = 'compressed';
20
+
21
  /**
22
  * Options getter
23
  * @return array
27
  $sassHelper = Mage::helper('sass');
28
 
29
  return array(
30
+ array('value' => self::STYLE_NESTED, 'label' => $sassHelper->__('Nested')),
31
+ array('value' => self::STYLE_EXPANDED, 'label' => $sassHelper->__('Expanded')),
32
+ array('value' => self::STYLE_COMPACT, 'label' => $sassHelper->__('Compact')),
33
+ array('value' => self::STYLE_COMPRESSED, 'label' => $sassHelper->__('Compressed')),
34
  );
35
  }
36
 
40
  */
41
  public function authorizedValues(){
42
  return array(
43
+ self::STYLE_NESTED,
44
+ self::STYLE_COMPACT,
45
+ self::STYLE_COMPRESSED,
46
+ self::STYLE_EXPANDED,
47
  );
48
  }
49
  }
app/code/community/Laurent/Sass/etc/config.xml CHANGED
@@ -14,7 +14,7 @@
14
  <config>
15
  <modules>
16
  <Laurent_Sass>
17
- <version>1.1.4</version>
18
  </Laurent_Sass>
19
  </modules>
20
  <global>
@@ -57,9 +57,9 @@
57
  <default>
58
  <dev>
59
  <sass>
60
- <output_style>nested</output_style>
61
  <ruby_sass_command>sass</ruby_sass_command>
62
  </sass>
63
  </dev>
64
  </default>
65
- </config>
14
  <config>
15
  <modules>
16
  <Laurent_Sass>
17
+ <version>1.2.0</version>
18
  </Laurent_Sass>
19
  </modules>
20
  <global>
57
  <default>
58
  <dev>
59
  <sass>
60
+ <output_style>compressed</output_style>
61
  <ruby_sass_command>sass</ruby_sass_command>
62
  </sass>
63
  </dev>
64
  </default>
65
+ </config>
lib/phpsass/.travis.yml DELETED
@@ -1,12 +0,0 @@
1
- # Configuration file for unit test runner.
2
- language: php
3
- php:
4
- - 5.3
5
- - 5.4
6
- env:
7
- - PHPUNIT_ARGS=--group=sass
8
- before_script:
9
- - cd tests
10
- script: phpunit $PHPUNIT_ARGS
11
- notifications:
12
- email: false
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/Compass/Compass.php DELETED
@@ -1,618 +0,0 @@
1
- <?php
2
- require_once dirname(__FILE__) . '/../ExtensionInterface.php';
3
- class Compass implements ExtensionInterface
4
- {
5
-
6
- public static $filesFolder = 'stylesheets';
7
- public static $filePaths = null;
8
-
9
- /**
10
- * List with alias functions in Compass
11
- * @var array
12
- */
13
- public static $functions = array(
14
- 'resolve-path',
15
- 'adjust-lightness',
16
- 'scale-lightness',
17
- 'adjust-saturation',
18
- 'scale-saturation',
19
- 'scale-color-value',
20
- 'is-position',
21
- 'is-position-list',
22
- 'opposite-position',
23
- '-webkit',
24
- '-moz',
25
- '-o',
26
- '-ms',
27
- '-svg',
28
- '-pie',
29
- '-css2',
30
- 'owg',
31
- 'prefixed',
32
- 'prefix',
33
- 'elements-of-type',
34
- 'enumerate',
35
- 'font-files',
36
- 'image-width',
37
- 'image-height',
38
- 'inline-image',
39
- 'inline-font-files',
40
- 'blank',
41
- 'compact',
42
- '-compass-nth',
43
- '-compass-list',
44
- '-compass-list',
45
- '-compass-space-list',
46
- '-compass-list-size',
47
- '-compass-slice',
48
- 'first-value-of',
49
- 'nest',
50
- 'append-selector',
51
- 'headers',
52
- 'pi',
53
- 'sin',
54
- 'cos',
55
- 'tan',
56
- 'comma-list',
57
- 'prefixed-for-transition',
58
- 'stylesheet-url',
59
- 'font-url',
60
- 'image-url'
61
- );
62
-
63
- public static function getFunctions($namespace)
64
- {
65
-
66
- $output = array();
67
- foreach (self::$functions as $function) {
68
- $originalFunction = $function;
69
- $function[0] = strtoupper($function[0]);
70
- $func = create_function('$c', 'return strtoupper($c[1]);');
71
- $function = preg_replace_callback('/-([a-z])/', $func, $function);
72
- $output[$originalFunction] = $namespace . strtolower(__CLASS__) . $function;
73
- }
74
-
75
- return $output;
76
- }
77
-
78
- /**
79
- * Returns an array with all files in $root path recursively and assign each array Key with clean alias
80
- * @param $root
81
- * @return array
82
- */
83
- public static function getFilesArray($root)
84
- {
85
-
86
- $alias = array();
87
- $directories = array();
88
- $last_letter = $root[strlen($root) - 1];
89
- $root = ($last_letter == '\\' || $last_letter == '/') ? $root : $root . DIRECTORY_SEPARATOR;
90
-
91
- $directories[] = $root;
92
-
93
- while (sizeof($directories)) {
94
- $dir = array_pop($directories);
95
- if ($handle = opendir($dir)) {
96
- while (false !== ($file = readdir($handle))) {
97
- if ($file == '.' || $file == '..' || substr($file,0,1)=='.') {
98
- continue;
99
- }
100
- $file = $dir . $file;
101
- if (is_dir($file)) {
102
- $directory_path = $file . DIRECTORY_SEPARATOR;
103
- array_push($directories, $directory_path);
104
- } elseif (is_file($file)) {
105
- $key = basename($file);
106
- $alias[substr($key, 1, strpos($key, '.') - 1)] = $file;
107
- }
108
- }
109
- closedir($handle);
110
- }
111
- }
112
-
113
- return $alias;
114
- }
115
-
116
- /**
117
- * Implementation of hook_resolve_path_NAMESPACE().
118
- */
119
- public static function resolveExtensionPath($callerImport, $parser, $syntax = 'scss')
120
- {
121
- $alias = str_replace('/_', '/', str_replace(array('.scss', '.sass'), '', $callerImport));
122
- if (strrpos($alias, '/') !== false) {
123
- $alias = substr($alias, strrpos($alias, '/') + 1);
124
- }
125
- if (self::$filePaths == null) {
126
- self::$filePaths = self::getFilesArray(dirname(__FILE__) . '/' . self::$filesFolder . '/');
127
- }
128
- if (isset(self::$filePaths[$alias])) {
129
- return self::$filePaths[$alias];
130
- }
131
- }
132
-
133
- /**
134
- * Resolves requires to the compass namespace (eg namespace/css3/border-radius)
135
- */
136
- public static function compassResolvePath($file)
137
- {
138
- if ($file{0} == '/') {
139
- return $file;
140
- }
141
- if (!$path = realpath($file)) {
142
- $path = SassScriptFunction::$context->node->token->filename;
143
- $path = substr($path, 0, strrpos($path, '/')) . '/';
144
- $path = $path . $file;
145
- $last = '';
146
- while ($path != $last) {
147
- $last = $path;
148
- $path = preg_replace('`(^|/)(?!\.\./)([^/]+)/\.\./`', '$1', $path);
149
- }
150
- $path = realpath($path);
151
- }
152
- if ($path) {
153
- return $path;
154
- }
155
-
156
- return false;
157
- }
158
-
159
- public static function compassImageWidth($file)
160
- {
161
- if ($info = self::compassImageInfo($file)) {
162
- return new SassNumber($info[0] . 'px');
163
- }
164
-
165
- return new SassNumber('0px');
166
- }
167
-
168
- public static function compassImageHeight($file)
169
- {
170
- if ($info = self::compassImageInfo($file)) {
171
- return new SassNumber($info[1] . 'px');
172
- }
173
-
174
- return new SassNumber('0px');
175
- }
176
-
177
- public static function compassImageInfo($file)
178
- {
179
- if ($path = self::compassResolvePath($file)) {
180
- if ($info = getimagesize($path)) {
181
- return $info;
182
- }
183
- }
184
-
185
- return false;
186
- }
187
-
188
- public static function compassInlineImage($file, $mime = null)
189
- {
190
- if ($path = self::compassUrl($file, true, false)) {
191
- $info = getimagesize($path);
192
- $mime = $info['mime'];
193
- $data = base64_encode(file_get_contents($path));
194
- # todo - do not return encoded if file size > 32kb
195
-
196
- return new SassString("url('data:$mime;base64,$data')");
197
- }
198
-
199
- return new SassString('');
200
- }
201
-
202
- public static function compassInlineFontFiles($file)
203
- {
204
- $args = func_get_args();
205
- $files = array();
206
- $mimes = array(
207
- 'otf' => 'font.opentype',
208
- 'ttf' => 'font.truetype',
209
- 'woff' => 'font.woff',
210
- 'off' => 'font.openfont',
211
- );
212
-
213
- while (count($args)) {
214
- $path = self::compassResolvePath(array_shift($args));
215
- $data = base64_encode(file_get_contents($path));
216
- $format = array_shift($args);
217
-
218
- $ext = array_pop(explode('.', $file));
219
- if (isset($mimes[$ext])) {
220
- $mime = $mimes[$ext];
221
- } else {
222
- continue;
223
- }
224
-
225
- $files[] = "url('data:$mime;base64,$data') format('$format')";
226
- }
227
-
228
- return new SassString(implode(', ', $files));
229
- }
230
-
231
- public static function compassBlank($object)
232
- {
233
- if (is_object($object)) {
234
- $object = $object->value;
235
- }
236
- $result = false;
237
- if (is_bool($object)) {
238
- $result = !$object;
239
- }
240
- if (is_string($object)) {
241
- $result = (strlen(trim($object, ' ,')) === 0);
242
- }
243
-
244
- return new SassBoolean($result);
245
- }
246
-
247
- public static function compassCompact()
248
- {
249
- $sep = ', ';
250
-
251
- $args = func_get_args();
252
- $list = array();
253
-
254
- // remove blank entries
255
- // append non-blank entries to list
256
- foreach ($args as $k => $v) {
257
- if (is_object($v)) {
258
- $string = (isset($v->value) ? $v->value : false);
259
- } else {
260
- $string = (string) $v;
261
- }
262
- if (empty($string) || $string == 'false') {
263
- unset($args[$k]);
264
- continue;
265
- }
266
- $list[] = $string;
267
- }
268
-
269
- return new SassString(implode($sep, $list));
270
- }
271
-
272
- public static function compassCompassNth()
273
- {
274
- $args = func_get_args();
275
- $place = array_pop($args);
276
- $list = array();
277
- foreach ($args as $arg) {
278
- $list = array_merge($list, self::compassList($arg));
279
- }
280
-
281
- if ($place == 'first') {
282
- $place = 0;
283
- }
284
- if ($place == 'last') {
285
- $place = count($list) - 1;
286
- }
287
-
288
- if (isset($list[$place])) {
289
- return current(SassScriptLexer::$instance->lex($list[$place], new SassContext()));
290
- }
291
-
292
- return new SassBoolean(false);
293
- }
294
-
295
- public static function compassCompassList()
296
- {
297
- $args = func_get_args();
298
- $list = array();
299
- foreach ($args as $arg) {
300
- $list = array_merge($list, self::compassList($arg));
301
- }
302
-
303
- return new SassString(implode(', ', $list));
304
- }
305
-
306
- public static function compassCompassSpaceList()
307
- {
308
- $args = func_get_args();
309
- $list = self::compassList($args, ',');
310
-
311
- return new SassString(implode(' ', $list));
312
- }
313
-
314
- public static function compassCompassListSize()
315
- {
316
- $args = func_get_args();
317
- $list = self::compassList($args, ',');
318
-
319
- return new SassNumber(count($list));
320
- }
321
-
322
- public static function compassCompassListSlice($list, $start, $end)
323
- {
324
- $args = func_get_args();
325
- $end = array_pop($args);
326
- $start = array_pop($args);
327
- $list = self::compassList($args, ',');
328
-
329
- return implode(',', array_slice($list, $start, $end));
330
- }
331
-
332
- public static function compassFirstValueOf()
333
- {
334
- $args = array();
335
- $args[] = 'first';
336
-
337
- return call_user_func_array('self::compassCompassNth', $args);
338
- }
339
-
340
- public static function compassList($list, $seperator = ',')
341
- {
342
- if (is_object($list)) {
343
- $list = $list->value;
344
- }
345
- if (is_array($list)) {
346
- $newlist = array();
347
- foreach ($list as $listlet) {
348
- $newlist = array_merge($newlist, self::compassList($listlet, $seperator));
349
- }
350
- $list = implode(', ', $newlist);
351
- }
352
-
353
- $out = array();
354
- $size = 0;
355
- $braces = 0;
356
- $stack = '';
357
- for ($i = 0; $i < strlen($list); $i++) {
358
- $char = substr($list, $i, 1);
359
- switch ($char) {
360
- case '(':
361
- $braces++;
362
- $stack .= $char;
363
- break;
364
- case ')':
365
- $braces--;
366
- $stack .= $char;
367
- break;
368
- case $seperator:
369
- if ($braces === 0) {
370
- $out[] = $stack;
371
- $stack = '';
372
- $size++;
373
- break;
374
- }
375
-
376
- default:
377
- $stack .= $char;
378
- }
379
- }
380
- $out[] = $stack;
381
-
382
- return $out;
383
- }
384
-
385
- // http://compass-style.org/reference/compass/helpers/selectors/#nest
386
- public static function compassNest()
387
- {
388
- $args = func_get_args();
389
- $output = explode(',', array_pop($args));
390
-
391
- for ($i = count($args) - 1; $i >= 0; $i--) {
392
- $current = explode(',', $args[$i]);
393
- $size = count($output);
394
- foreach ($current as $selector) {
395
- for ($j = 0; $j < $size; $j++) {
396
- $output[] = trim($selector) . " " . trim($output[$j]);
397
- }
398
- }
399
- $output = array_slice($output, $size);
400
- }
401
-
402
- return new SassString(implode(', ', $output));
403
- }
404
-
405
- public static function compassAppendSelector($initial, $new)
406
- {
407
- $list = explode(',', $initial);
408
- foreach ($list as $k => $selector) {
409
- $list[$k] = trim($selector) . $new;
410
- }
411
-
412
- return new SassString(implode(', ', $list));
413
- }
414
-
415
- public static function compassHeaders($from = false, $to = false)
416
- {
417
- if (is_object($from)) {
418
- $from = $from->value;
419
- }
420
- if (is_object($to)) {
421
- $to = $to->value;
422
- }
423
-
424
- if (!$from || !is_numeric($from)) {
425
- $from = 1;
426
- }
427
- if (!$to || !is_numeric($to)) {
428
- $to = 6;
429
- }
430
-
431
- $from = (int) $from;
432
- $to = (int) $to;
433
-
434
- $output = array();
435
- for ($i = $from; $i <= $to; $i++) {
436
- $output[] = 'h' . $i;
437
- }
438
-
439
- return new SassString(implode(', ', $output));
440
- }
441
-
442
- public static function compassCommaList()
443
- {
444
- print_r(func_get_args());
445
- die;
446
- }
447
-
448
- public static function compassPrefixed ($prefix, $list) {
449
- $list = static::compassList( $list );
450
- $prefix = trim ( preg_replace ( '/[^a-z]/', '', strtolower ( $prefix ) ) );
451
-
452
- $reqs = array (
453
- 'pie' => array (
454
- 'border-radius',
455
- 'box-shadow',
456
- 'border-image',
457
- 'background',
458
- 'linear-gradient'
459
- ),
460
- 'webkit' => array (
461
- 'background-clip',
462
- 'background-origin',
463
- 'border-radius',
464
- 'box-shadow',
465
- 'box-sizing',
466
- 'columns',
467
- 'gradient',
468
- 'linear-gradient',
469
- 'text-stroke'
470
- ),
471
- 'moz' => array (
472
- 'background-size',
473
- 'border-radius',
474
- 'box-shadow',
475
- 'box-sizing',
476
- 'columns',
477
- 'gradient',
478
- 'linear-gradient'
479
- ),
480
- 'o' => array (
481
- 'background-origin',
482
- 'text-overflow'
483
- )
484
- );
485
- foreach ( $list as $item ) {
486
- $aspect = trim ( current ( explode ( '(', $item ) ) );
487
- if (isset ( $reqs [$prefix] ) && in_array ( $aspect, $reqs [$prefix] )) {
488
- return new SassBoolean ( TRUE );
489
- }
490
- }
491
- return new SassBoolean ( FALSE );
492
- }
493
-
494
- public static function compassPrefix ($vendor, $input) {
495
- if (is_object($vendor)) {
496
- $vendor = $vendor->value;
497
- }
498
-
499
- $list = static::compassList($input, ',');
500
- $output = '';
501
- foreach($list as $key=>$value) {
502
- $list[$key] = '-' . $vendor . '-' . $value;
503
- }
504
- return new SassString(implode(', ', $list));
505
- }
506
-
507
- public static function compassWebkit ($input) {
508
- return static::compassPrefix('webkit', $input);
509
- }
510
-
511
- public static function compassMoz ($input) {
512
- return static::compassPrefix('moz', $input);
513
- }
514
-
515
- public static function compassO ($input) {
516
- return static::compassPrefix('o', $input);
517
- }
518
-
519
- public static function compassMs ($input) {
520
- return static::compassPrefix('ms', $input);
521
- }
522
-
523
- public static function compassSvg ($input) {
524
- return static::compassPrefix('svg', $input);
525
- }
526
-
527
- public static function compassPie ($input) {
528
- return static::compassPrefix('ms', $input);
529
- }
530
-
531
- public static function compassCss2 ($input) {
532
- return static::compassPrefix('ms', $input);
533
- }
534
-
535
- public static function compassOwg ($input) {
536
- return static::compassPrefix('ms', $input);
537
- }
538
-
539
- public static function compassPrefixedForTransition($prefix, $list)
540
- {
541
-
542
- }
543
-
544
- public static function compassPi()
545
- {
546
- return pi();
547
- }
548
-
549
- public static function compassSin($number)
550
- {
551
- return new SassNumber(sin($number));
552
- }
553
-
554
- public static function compassCos($number)
555
- {
556
- return new SassNumber(sin($number));
557
- }
558
-
559
- public static function compassTan($number)
560
- {
561
- return new SassNumber(sin($number));
562
- }
563
-
564
- # not sure what should happen with these
565
-
566
- public static function compassStylesheetUrl($path, $only_path = false)
567
- {
568
- return self::compassUrl($path, $only_path);
569
- }
570
-
571
- public static function compassFontUrl($path, $only_path = false)
572
- {
573
- return self::compassUrl($path, $only_path);
574
- }
575
-
576
- public static function compassImageUrl($path, $only_path = false)
577
- {
578
- return self::compassUrl($path, $only_path);
579
- }
580
-
581
- public static function compassUrl($path, $only_path = false, $web_path = true)
582
- {
583
- $opath = $path;
584
- if (!$path = SassFile::get_file($path, SassParser::$instance, false)) {
585
- throw new Exception('File not found: ' . $opath);
586
- }
587
-
588
- $path = $path[0];
589
- if ($web_path) {
590
- $webroot = realpath($_SERVER['DOCUMENT_ROOT']);
591
- $path = str_replace($webroot, '', $path);
592
- }
593
-
594
- if ($only_path) {
595
- return new SassString($path);
596
- }
597
-
598
- return new SassString("url('$path')");
599
- }
600
-
601
- public static function compassOppositePosition($from)
602
- {
603
- $ret = '';
604
- if ($from == 'top') {
605
- $ret = 'bottom';
606
- } elseif ($from == 'bottom') {
607
- $ret = 'top';
608
- } elseif ($from == 'left') {
609
- $ret = 'right';
610
- } elseif ($from == 'right') {
611
- $ret = 'left';
612
- } elseif ($from == 'center') {
613
- $ret = 'center';
614
- }
615
-
616
- return $ret;
617
- }
618
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/_compass.scss DELETED
@@ -1,3 +0,0 @@
1
- @import "compass/utilities";
2
- @import "compass/typography";
3
- @import "compass/css3";
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/_lemonade.scss DELETED
@@ -1,38 +0,0 @@
1
- @mixin image-dimensions($file) {
2
- height: image-height($file);
3
- width: image-width($file);
4
- }
5
-
6
- @mixin sprite-image($file) {
7
- background: sprite-image($file) $repeat;
8
- }
9
-
10
- @mixin sized-sprite-image($file) {
11
- background: sprite-image($file);
12
- @include image-dimensions($file);
13
- }
14
-
15
- @mixin sprite-folder($folder, $image-dimensions: false) {
16
- .#{$folder} {
17
- @if $image-dimensions {
18
- background: sprite-url($folder);
19
- }
20
- @else {
21
- background: sprite-url($folder) no-repeat;
22
- }
23
- }
24
- @for $i from 0 to sprite-files-in-folder($folder) {
25
- $file: sprite-file-from-folder($folder, $i);
26
- .#{$folder}-#{image-basename($file)} {
27
- @extend .#{$folder};
28
- background-position: sprite-position(sprite-file-from-folder($folder, $i));
29
- @if $image-dimensions {
30
- @include image-dimensions($file);
31
- }
32
- }
33
- }
34
- }
35
-
36
- @mixin sized-sprite-folder($folder) {
37
- @include sprite-folder($folder, true);
38
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/_css3.scss DELETED
@@ -1,20 +0,0 @@
1
- @import "css3/border-radius";
2
- @import "css3/inline-block";
3
- @import "css3/opacity";
4
- @import "css3/box-shadow";
5
- @import "css3/text-shadow";
6
- @import "css3/columns";
7
- @import "css3/box-sizing";
8
- @import "css3/box";
9
- @import "css3/images";
10
- @import "css3/background-clip";
11
- @import "css3/background-origin";
12
- @import "css3/background-size";
13
- @import "css3/font-face";
14
- @import "css3/transform";
15
- @import "css3/transition";
16
- @import "css3/appearance";
17
- @import "css3/regions";
18
- @import "css3/hyphenation";
19
- @import "css3/filter";
20
- @import "css3/user-interface";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/_layout.scss DELETED
@@ -1,3 +0,0 @@
1
- @import "layout/grid-background";
2
- @import "layout/sticky-footer";
3
- @import "layout/stretching";
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/_reset-legacy.scss DELETED
@@ -1,3 +0,0 @@
1
- @import "reset/utilities-legacy";
2
-
3
- @include global-reset;
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/_reset.scss DELETED
@@ -1,3 +0,0 @@
1
- @import "reset/utilities";
2
-
3
- @include global-reset;
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/_support.scss DELETED
@@ -1,40 +0,0 @@
1
- // Usually compass hacks apply to both ie6 & 7 -- set this to false to disable support for both.
2
- $legacy-support-for-ie: true !default;
3
-
4
- // Setting this to false will result in smaller output, but no support for ie6 hacks
5
- $legacy-support-for-ie6: $legacy-support-for-ie !default;
6
-
7
- // Setting this to false will result in smaller output, but no support for ie7 hacks
8
- $legacy-support-for-ie7: $legacy-support-for-ie !default;
9
-
10
- // Setting this to false will result in smaller output, but no support for legacy ie8 hacks
11
- $legacy-support-for-ie8: $legacy-support-for-ie !default;
12
-
13
- // @private
14
- // The user can simply set $legacy-support-for-ie and 6, 7, and 8 will be set accordingly,
15
- // But in case the user set each of those explicitly, we need to sync the value of
16
- // this combined variable.
17
- $legacy-support-for-ie: $legacy-support-for-ie6 or $legacy-support-for-ie7 or $legacy-support-for-ie8;
18
-
19
- // Whether to output legacy support for mozilla.
20
- // Usually this means hacks to support Firefox 3.6 or earlier.
21
- $legacy-support-for-mozilla: true;
22
-
23
- // Support for mozilla in experimental css3 properties (-moz).
24
- $experimental-support-for-mozilla : true !default;
25
- // Support for webkit in experimental css3 properties (-webkit).
26
- $experimental-support-for-webkit : true !default;
27
- // Support for webkit's original (non-standard) gradient syntax.
28
- $support-for-original-webkit-gradients : true !default;
29
- // Support for opera in experimental css3 properties (-o).
30
- $experimental-support-for-opera : true !default;
31
- // Support for microsoft in experimental css3 properties (-ms).
32
- $experimental-support-for-microsoft : true !default;
33
- // Support for khtml in experimental css3 properties (-khtml).
34
- $experimental-support-for-khtml : false !default;
35
- // Support for svg in experimental css3 properties.
36
- // Setting this to true might add significant size to your
37
- // generated stylesheets.
38
- $experimental-support-for-svg : false !default;
39
- // Support for CSS PIE in experimental css3 properties (-pie).
40
- $experimental-support-for-pie : false !default;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/_typography.scss DELETED
@@ -1,4 +0,0 @@
1
- @import "typography/links";
2
- @import "typography/lists";
3
- @import "typography/text";
4
- @import "typography/vertical_rhythm";
 
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/_utilities.scss DELETED
@@ -1,9 +0,0 @@
1
- @import "utilities/color";
2
- @import "utilities/general";
3
- @import "utilities/sprites";
4
- @import "utilities/tables";
5
-
6
- // deprecated
7
- @import "typography/links";
8
- @import "typography/lists";
9
- @import "typography/text";
 
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/css3/_appearance.scss DELETED
@@ -1,17 +0,0 @@
1
- @import "shared";
2
-
3
- // Change the appearance for Mozilla, Webkit and possibly the future.
4
- // The appearance property is currently not present in any newer CSS specification.
5
- //
6
- // There is no official list of accepted values, but you might check these source:
7
- //
8
- // * [Mozilla](https://developer.mozilla.org/en/CSS/-moz-appearance)
9
- // * [Webkit](http://code.google.com/p/webkit-mirror/source/browse/Source/WebCore/css/CSSValueKeywords.in?spec=svnf1aea559dcd025a8946aa7da6e4e8306f5c1b604&r=63c7d1af44430b314233fea342c3ddb2a052e365)
10
- // (search for 'appearance' within the page)
11
-
12
- @mixin appearance($ap) {
13
- $ap: unquote($ap);
14
- @include experimental(appearance, $ap,
15
- -moz, -webkit, not -o, not -ms, not -khtml, official
16
- );
17
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/css3/_background-clip.scss DELETED
@@ -1,43 +0,0 @@
1
- @import "shared";
2
-
3
- // The default value is `padding-box` -- the box model used by modern browsers.
4
- //
5
- // If you wish to do so, you can override the default constant with `border-box`
6
- //
7
- // To override to the default border-box model, use this code:
8
- // $default-background-clip: border-box
9
-
10
- $default-background-clip: padding-box !default;
11
-
12
- // Clip the background (image and color) at the edge of the padding or border.
13
- //
14
- // Legal Values:
15
- //
16
- // * padding-box
17
- // * border-box
18
- // * text
19
-
20
- @mixin background-clip($clip: $default-background-clip) {
21
- // webkit and mozilla use the deprecated short [border | padding]
22
- $clip: unquote($clip);
23
- $deprecated: $clip;
24
- @if $clip == padding-box { $deprecated: padding; }
25
- @if $clip == border-box { $deprecated: border; }
26
- // Support for webkit and mozilla's use of the deprecated short form
27
- @include experimental(background-clip, $deprecated,
28
- -moz,
29
- -webkit,
30
- not -o,
31
- not -ms,
32
- not -khtml,
33
- not official
34
- );
35
- @include experimental(background-clip, $clip,
36
- not -moz,
37
- not -webkit,
38
- not -o,
39
- not -ms,
40
- -khtml,
41
- official
42
- );
43
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/css3/_background-origin.scss DELETED
@@ -1,42 +0,0 @@
1
- // Override `$default-background-origin` to change the default.
2
-
3
- @import "shared";
4
-
5
- $default-background-origin: content-box !default;
6
-
7
- // Position the background off the edge of the padding, border or content
8
- //
9
- // * Possible values:
10
- // * `padding-box`
11
- // * `border-box`
12
- // * `content-box`
13
- // * browser defaults to `padding-box`
14
- // * mixin defaults to `content-box`
15
-
16
-
17
- @mixin background-origin($origin: $default-background-origin) {
18
- $origin: unquote($origin);
19
- // webkit and mozilla use the deprecated short [border | padding | content]
20
- $deprecated: $origin;
21
- @if $origin == padding-box { $deprecated: padding; }
22
- @if $origin == border-box { $deprecated: border; }
23
- @if $origin == content-box { $deprecated: content; }
24
-
25
- // Support for webkit and mozilla's use of the deprecated short form
26
- @include experimental(background-origin, $deprecated,
27
- -moz,
28
- -webkit,
29
- not -o,
30
- not -ms,
31
- not -khtml,
32
- not official
33
- );
34
- @include experimental(background-origin, $origin,
35
- not -moz,
36
- not -webkit,
37
- -o,
38
- -ms,
39
- -khtml,
40
- official
41
- );
42
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/css3/_background-size.scss DELETED
@@ -1,26 +0,0 @@
1
- @import "shared";
2
-
3
- // override to change the default
4
- $default-background-size: 100% auto !default;
5
-
6
- // Set the size of background images using px, width and height, or percentages.
7
- // Currently supported in: Opera, Gecko, Webkit.
8
- //
9
- // * percentages are relative to the background-origin (default = padding-box)
10
- // * mixin defaults to: `$default-background-size`
11
- @mixin background-size(
12
- $size-1: $default-background-size,
13
- $size-2: false,
14
- $size-3: false,
15
- $size-4: false,
16
- $size-5: false,
17
- $size-6: false,
18
- $size-7: false,
19
- $size-8: false,
20
- $size-9: false,
21
- $size-10: false
22
- ) {
23
- $size-1: if(type-of($size-1) == string, unquote($size-1), $size-1);
24
- $sizes: compact($size-1, $size-2, $size-3, $size-4, $size-5, $size-6, $size-7, $size-8, $size-9, $size-10);
25
- @include experimental(background-size, $sizes, -moz, -webkit, -o, not -ms, not -khtml);
26
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/css3/_border-radius.scss DELETED
@@ -1,130 +0,0 @@
1
- @import "shared";
2
-
3
- $default-border-radius: 5px !default;
4
-
5
- // Round all corners by a specific amount, defaults to value of `$default-border-radius`.
6
- //
7
- // When two values are passed, the first is the horizontal radius
8
- // and the second is the vertical radius.
9
- //
10
- // Note: webkit does not support shorthand syntax for several corners at once.
11
- // So in the case where you pass several values only the first will be passed to webkit.
12
- //
13
- // Examples:
14
- //
15
- // .simple { @include border-radius(4px, 4px); }
16
- // .compound { @include border-radius(2px 5px, 3px 6px); }
17
- // .crazy { @include border-radius(1px 3px 5px 7px, 2px 4px 6px 8px)}
18
- //
19
- // Which generates:
20
- //
21
- // .simple {
22
- // -webkit-border-radius: 4px 4px;
23
- // -moz-border-radius: 4px / 4px;
24
- // -khtml-border-radius: 4px / 4px;
25
- // border-radius: 4px / 4px; }
26
- //
27
- // .compound {
28
- // -webkit-border-radius: 2px 3px;
29
- // -moz-border-radius: 2px 5px / 3px 6px;
30
- // -khtml-border-radius: 2px 5px / 3px 6px;
31
- // border-radius: 2px 5px / 3px 6px; }
32
- //
33
- // .crazy {
34
- // -webkit-border-radius: 1px 2px;
35
- // -moz-border-radius: 1px 3px 5px 7px / 2px 4px 6px 8px;
36
- // -khtml-border-radius: 1px 3px 5px 7px / 2px 4px 6px 8px;
37
- // border-radius: 1px 3px 5px 7px / 2px 4px 6px 8px; }
38
-
39
- @mixin border-radius($radius: $default-border-radius, $vertical-radius: false) {
40
-
41
- @if $vertical-radius {
42
- // Webkit doesn't understand the official shorthand syntax for specifying
43
- // a vertical radius unless so in case there's several we only take the first.
44
- @include experimental(border-radius, first-value-of($radius) first-value-of($vertical-radius),
45
- not -moz,
46
- -webkit,
47
- not -o,
48
- not -ms,
49
- not -khtml,
50
- not official
51
- );
52
- @include experimental("border-radius", $radius unquote("/") $vertical-radius,
53
- -moz,
54
- not -webkit,
55
- not -o,
56
- not -ms,
57
- -khtml,
58
- official
59
- );
60
- }
61
- @else {
62
- @include experimental(border-radius, $radius);
63
- }
64
- }
65
-
66
- // Round radius at position by amount.
67
- //
68
- // * legal values for `$vert`: `top`, `bottom`
69
- // * legal values for `$horz`: `left`, `right`
70
-
71
- @mixin border-corner-radius($vert, $horz, $radius: $default-border-radius) {
72
- // Support for mozilla's syntax for specifying a corner
73
- @include experimental("border-radius-#{$vert}#{$horz}", $radius,
74
- -moz,
75
- not -webkit,
76
- not -o,
77
- not -ms,
78
- not -khtml,
79
- not official
80
- );
81
- @include experimental("border-#{$vert}-#{$horz}-radius", $radius,
82
- not -moz,
83
- -webkit,
84
- not -o,
85
- not -ms,
86
- -khtml,
87
- official
88
- );
89
-
90
- }
91
-
92
- // Round top-left corner only
93
-
94
- @mixin border-top-left-radius($radius: $default-border-radius) {
95
- @include border-corner-radius(top, left, $radius); }
96
-
97
- // Round top-right corner only
98
-
99
- @mixin border-top-right-radius($radius: $default-border-radius) {
100
- @include border-corner-radius(top, right, $radius); }
101
-
102
- // Round bottom-left corner only
103
-
104
- @mixin border-bottom-left-radius($radius: $default-border-radius) {
105
- @include border-corner-radius(bottom, left, $radius); }
106
-
107
- // Round bottom-right corner only
108
-
109
- @mixin border-bottom-right-radius($radius: $default-border-radius) {
110
- @include border-corner-radius(bottom, right, $radius); }
111
-
112
- // Round both top corners by amount
113
- @mixin border-top-radius($radius: $default-border-radius) {
114
- @include border-top-left-radius($radius);
115
- @include border-top-right-radius($radius); }
116
-
117
- // Round both right corners by amount
118
- @mixin border-right-radius($radius: $default-border-radius) {
119
- @include border-top-right-radius($radius);
120
- @include border-bottom-right-radius($radius); }
121
-
122
- // Round both bottom corners by amount
123
- @mixin border-bottom-radius($radius: $default-border-radius) {
124
- @include border-bottom-left-radius($radius);
125
- @include border-bottom-right-radius($radius); }
126
-
127
- // Round both left corners by amount
128
- @mixin border-left-radius($radius: $default-border-radius) {
129
- @include border-top-left-radius($radius);
130
- @include border-bottom-left-radius($radius); }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/css3/_box-shadow.scss DELETED
@@ -1,76 +0,0 @@
1
- // @doc off
2
- // These defaults make the arguments optional for this mixin
3
- // If you like, set different defaults before importing.
4
- // @doc on
5
-
6
- @import "shared";
7
-
8
-
9
- // The default color for box shadows
10
- $default-box-shadow-color: #333333 !default;
11
-
12
- // The default horizontal offset. Positive is to the right.
13
- $default-box-shadow-h-offset: 0px !default;
14
-
15
- // The default vertical offset. Positive is down.
16
- $default-box-shadow-v-offset: 0px !default;
17
-
18
- // The default blur length.
19
- $default-box-shadow-blur: 5px !default;
20
-
21
- // The default spread length.
22
- $default-box-shadow-spread : false !default;
23
-
24
- // The default shadow inset: inset or false (for standard shadow).
25
- $default-box-shadow-inset : false !default;
26
-
27
- // Provides cross-browser for Webkit, Gecko, and CSS3 box shadows when one or more box
28
- // shadows are needed.
29
- // Each shadow argument should adhere to the standard css3 syntax for the
30
- // box-shadow property.
31
- @mixin box-shadow(
32
- $shadow-1 : default,
33
- $shadow-2 : false,
34
- $shadow-3 : false,
35
- $shadow-4 : false,
36
- $shadow-5 : false,
37
- $shadow-6 : false,
38
- $shadow-7 : false,
39
- $shadow-8 : false,
40
- $shadow-9 : false,
41
- $shadow-10: false
42
- ) {
43
- @if $shadow-1 == default {
44
- $shadow-1 : -compass-space-list(compact(if($default-box-shadow-inset, inset, false), $default-box-shadow-h-offset, $default-box-shadow-v-offset, $default-box-shadow-blur, $default-box-shadow-spread, $default-box-shadow-color));
45
- }
46
- $shadow : compact($shadow-1, $shadow-2, $shadow-3, $shadow-4, $shadow-5, $shadow-6, $shadow-7, $shadow-8, $shadow-9, $shadow-10);
47
- @include experimental(box-shadow, $shadow,
48
- -moz, -webkit, not -o, not -ms, not -khtml, official
49
- );
50
- }
51
-
52
- // Provides a single cross-browser CSS box shadow for Webkit, Gecko, and CSS3.
53
- // Includes default arguments for color, horizontal offset, vertical offset, blur length, spread length, and inset.
54
- @mixin single-box-shadow(
55
- $color : $default-box-shadow-color,
56
- $hoff : $default-box-shadow-h-offset,
57
- $voff : $default-box-shadow-v-offset,
58
- $blur : $default-box-shadow-blur,
59
- $spread : $default-box-shadow-spread,
60
- $inset : $default-box-shadow-inset
61
- ) {
62
- @if not ($inset == true or $inset == false or $inset == inset) {
63
- @warn "$inset expected to be true or the inset keyword. Got #{$inset} instead. Using: inset";
64
- }
65
-
66
- @if $color == none {
67
- @include box-shadow(none);
68
- } @else {
69
- $full : $hoff $voff;
70
- @if $blur { $full: $full $blur; }
71
- @if $spread { $full: $full $spread; }
72
- @if $color { $full: $full $color; }
73
- @if $inset { $full: inset $full; }
74
- @include box-shadow($full);
75
- }
76
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/css3/_box-sizing.scss DELETED
@@ -1,13 +0,0 @@
1
- @import "shared";
2
-
3
- // Change the box model for Mozilla, Webkit, IE8 and the future
4
- //
5
- // @param $bs
6
- // [ content-box | border-box ]
7
-
8
- @mixin box-sizing($bs) {
9
- $bs: unquote($bs);
10
- @include experimental(box-sizing, $bs,
11
- -moz, -webkit, not -o, not -ms, not -khtml, official
12
- );
13
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/css3/_box.scss DELETED
@@ -1,111 +0,0 @@
1
- @import "shared";
2
-
3
- // display:box; must be used for any of the other flexbox mixins to work properly
4
- @mixin display-box {
5
- @include experimental-value(display, box,
6
- -moz, -webkit, not -o, -ms, not -khtml, official
7
- );
8
- }
9
-
10
- // Default box orientation, assuming that the user wants something less block-like
11
- $default-box-orient: horizontal !default;
12
-
13
- // Box orientation [ horizontal | vertical | inline-axis | block-axis | inherit ]
14
- @mixin box-orient(
15
- $orientation: $default-box-orient
16
- ) {
17
- $orientation : unquote($orientation);
18
- @include experimental(box-orient, $orientation,
19
- -moz, -webkit, not -o, -ms, not -khtml, official
20
- );
21
- }
22
-
23
- // Default box-align
24
- $default-box-align: stretch !default;
25
-
26
- // Box align [ start | end | center | baseline | stretch ]
27
- @mixin box-align(
28
- $alignment: $default-box-align
29
- ) {
30
- $alignment : unquote($alignment);
31
- @include experimental(box-align, $alignment,
32
- -moz, -webkit, not -o, -ms, not -khtml, official
33
- );
34
- }
35
-
36
- // Default box flex
37
- $default-box-flex: 0 !default;
38
-
39
- // mixin which takes an int argument for box flex. Apply this to the children inside the box.
40
- //
41
- // For example: "div.display-box > div.child-box" would get the box flex mixin.
42
- @mixin box-flex(
43
- $flex: $default-box-flex
44
- ) {
45
- @include experimental(box-flex, $flex,
46
- -moz, -webkit, not -o, -ms, not -khtml, official
47
- );
48
- }
49
-
50
- // Default flex group
51
- $default-box-flex-group: 1 !default;
52
-
53
- // mixin which takes an int argument for flexible grouping
54
- @mixin box-flex-group(
55
- $group: $default-box-flex-group
56
- ) {
57
- @include experimental(box-flex-group, $group,
58
- -moz, -webkit, not -o, -ms, not -khtml, official
59
- );
60
- }
61
-
62
- // default for ordinal group
63
- $default-box-ordinal-group: 1 !default;
64
-
65
- // mixin which takes an int argument for ordinal grouping and rearranging the order
66
- @mixin box-ordinal-group(
67
- $group: $default-box-ordinal-group
68
- ) {
69
- @include experimental(box-ordinal-group, $group,
70
- -moz, -webkit, not -o, -ms, not -khtml, official
71
- );
72
- }
73
-
74
- // Box direction default value
75
- $default-box-direction: normal !default;
76
-
77
- // mixin for box-direction [ normal | reverse | inherit ]
78
- @mixin box-direction(
79
- $direction: $default-box-direction
80
- ) {
81
- $direction: unquote($direction);
82
- @include experimental(box-direction, $direction,
83
- -moz, -webkit, not -o, -ms, not -khtml, official
84
- );
85
- }
86
-
87
- // default for box lines
88
- $default-box-lines: single !default;
89
-
90
- // mixin for box lines [ single | multiple ]
91
- @mixin box-lines(
92
- $lines: $default-box-lines
93
- ) {
94
- $lines: unquote($lines);
95
- @include experimental(box-lines, $lines,
96
- -moz, -webkit, not -o, -ms, not -khtml, official
97
- );
98
- }
99
-
100
- // default for box pack
101
- $default-box-pack: start !default;
102
-
103
- // mixin for box pack [ start | end | center | justify ]
104
- @mixin box-pack(
105
- $pack: $default-box-pack
106
- ) {
107
- $pack: unquote($pack);
108
- @include experimental(box-pack, $pack,
109
- -moz, -webkit, not -o, -ms, not -khtml, official
110
- );
111
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/css3/_columns.scss DELETED
@@ -1,157 +0,0 @@
1
- @import "shared";
2
-
3
- // Specify the shorthand `columns` property.
4
- //
5
- // Example:
6
- //
7
- // @include columns(20em 2)
8
- @mixin columns($width-and-count) {
9
- @include experimental(columns, $width-and-count,
10
- -moz, -webkit, -o, -ms, not -khtml, official
11
- );
12
- }
13
-
14
- // Specify the number of columns
15
- @mixin column-count($count) {
16
- @include experimental(column-count, $count,
17
- -moz, -webkit, -o, -ms, not -khtml, official
18
- );
19
- }
20
-
21
- // Specify the gap between columns e.g. `20px`
22
- @mixin column-gap($width) {
23
- @include experimental(column-gap, $width,
24
- -moz, -webkit, -o, -ms, not -khtml, official
25
- );
26
- }
27
-
28
- // Specify the width of columns e.g. `100px`
29
- @mixin column-width($width) {
30
- @include experimental(column-width, $width,
31
- -moz, -webkit, -o, -ms, not -khtml, official
32
- );
33
- }
34
-
35
- // Specify how many columns an element should span across.
36
- //
37
- // * legal values are 1, all
38
- @mixin column-span($columns) {
39
- @include experimental(column-span, $columns,
40
- -moz, -webkit, -o, -ms, not -khtml, official
41
- );
42
- }
43
-
44
- // Specify the width of the rule between columns e.g. `1px`
45
- @mixin column-rule-width($width) {
46
- @include experimental(column-rule-width, $width,
47
- -moz, -webkit, -o, -ms, not -khtml, official
48
- );
49
- }
50
-
51
- // Specify the style of the rule between columns e.g. `dotted`.
52
- // This works like border-style.
53
- @mixin column-rule-style($style) {
54
- @include experimental(column-rule-style, unquote($style),
55
- -moz, -webkit, -o, -ms, not -khtml, official
56
- );
57
- }
58
-
59
- // Specify the color of the rule between columns e.g. `blue`.
60
- // This works like border-color.
61
- @mixin column-rule-color($color) {
62
- @include experimental(column-rule-color, $color,
63
- -moz, -webkit, -o, -ms, not -khtml, official
64
- );
65
- }
66
-
67
- // Mixin encompassing all column rule properties
68
- // For example:
69
- //
70
- // @include column-rule(1px, solid, #c00)
71
- //
72
- // Or the values can be space separated:
73
- //
74
- // @include column-rule(1px solid #c00)
75
- @mixin column-rule($width, $style: false, $color: false) {
76
- $full : -compass-space-list(compact($width, $style, $color));
77
- @include experimental(column-rule, $full,
78
- -moz, -webkit, -o, -ms, not -khtml, official
79
- );
80
- }
81
-
82
- // Mixin for setting column-break-before
83
- //
84
- // * legal values are auto, always, avoid, left, right, page, column, avoid-page, avoid-column
85
- //
86
- // Example:
87
- // h2.before {@include column-break-before(always);}
88
- //
89
- // Which generates:
90
- //
91
- // h2.before {
92
- // -webkit-column-break-before: always;
93
- // column-break-before: always;}
94
- @mixin column-break-before($value: auto){
95
- @include experimental(column-break-before, $value, not -moz, -webkit, not -o, not -ms, not -khtml, official );
96
- }
97
-
98
- // Mixin for setting column-break-after
99
- //
100
- // * legal values are auto, always, avoid, left, right, page, column, avoid-page, avoid-column
101
- //
102
- // Example:
103
- // h2.after {@include column-break-after(always); }
104
- //
105
- // Which generates:
106
- //
107
- // h2.after {
108
- // -webkit-column-break-after: always;
109
- // column-break-after: always; }
110
- @mixin column-break-after($value: auto){
111
- @include experimental(column-break-after, $value, not -moz, -webkit, not -o, not -ms, not -khtml, official );
112
- }
113
-
114
- // Mixin for setting column-break-inside
115
- //
116
- // * legal values are auto, avoid, avoid-page, avoid-column
117
- //
118
- // Example:
119
- // h2.inside {@include column-break-inside();}
120
- // Which generates:
121
- //
122
- // h2.inside {
123
- // -webkit-column-break-inside: auto;
124
- // column-break-inside: auto;}
125
- @mixin column-break-inside($value: auto){
126
- @include experimental(column-break-inside, $value, not -moz, -webkit, not -o, not -ms, not -khtml, official );
127
- }
128
-
129
- // All-purpose mixin for setting column breaks.
130
- //
131
- // * legal values for $type : before, after, inside
132
- // * legal values for '$value' are dependent on $type
133
- // * when $type = before, legal values are auto, always, avoid, left, right, page, column, avoid-page, avoid-column
134
- // * when $type = after, legal values are auto, always, avoid, left, right, page, column, avoid-page, avoid-column
135
- // * when $type = inside, legal values are auto, avoid, avoid-page, avoid-column
136
- //
137
- // Examples:
138
- // h2.before {@include column-break(before, always);}
139
- // h2.after {@include column-break(after, always); }
140
- // h2.inside {@include column-break(inside); }
141
- //
142
- // Which generates:
143
- // h2.before {
144
- // -webkit-column-break-before: always;
145
- // column-break-before: always;}
146
- //
147
- // h2.after {
148
- // -webkit-column-break-after: always;
149
- // column-break-after: always; }
150
- //
151
- // h2.inside {
152
- // -webkit-column-break-inside: auto;
153
- // column-break-inside: auto;}
154
-
155
- @mixin column-break($type: before, $value: auto){
156
- @include experimental("column-break-#{$type}", $value, not -moz, -webkit, not -o, not -ms, not -khtml, official );
157
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/css3/_filter.scss DELETED
@@ -1,23 +0,0 @@
1
- @import "shared";
2
-
3
- // Provides cross-browser support for the upcoming (?) css3 filter property.
4
- //
5
- // Each filter argument should adhere to the standard css3 syntax for the
6
- // filter property.
7
- @mixin filter (
8
- $filter-1,
9
- $filter-2 : false,
10
- $filter-3 : false,
11
- $filter-4 : false,
12
- $filter-5 : false,
13
- $filter-6 : false,
14
- $filter-7 : false,
15
- $filter-8 : false,
16
- $filter-9 : false,
17
- $filter-10: false
18
- ) {
19
- $filter : compact($filter-1, $filter-2, $filter-3, $filter-4, $filter-5, $filter-6, $filter-7, $filter-8, $filter-9, $filter-10);
20
- @include experimental(filter, $filter,
21
- -moz, -webkit, not -o, not -ms, not -khtml, official
22
- );
23
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/css3/_font-face.scss DELETED
@@ -1,48 +0,0 @@
1
- @import "shared";
2
-
3
- // Cross-browser support for @font-face. Supports IE, Gecko, Webkit, Opera.
4
- //
5
- // * $name is required, arbitrary, and what you will use in font stacks.
6
- // * $font-files is required using font-files('relative/location', 'format').
7
- // for best results use this order: woff, opentype/truetype, svg
8
- // * $eot is required by IE, and is a relative location of the eot file.
9
- // * $weight shows if the font is bold, defaults to normal
10
- // * $style defaults to normal, might be also italic
11
- // * For android 2.2 Compatiblity, please ensure that your web page has
12
- // a meta viewport tag.
13
- // * To support iOS < 4.2, an SVG file must be provided
14
- //
15
- // If you need to generate other formats check out the Font Squirrel
16
- // [font generator](http://www.fontsquirrel.com/fontface/generator)
17
- //
18
-
19
- // In order to refer to a specific style of the font in your stylesheets as
20
- // e.g. "font-style: italic;", you may add a couple of @font-face includes
21
- // containing the respective font files for each style and specying
22
- // respective the $style parameter.
23
-
24
- // Order of the includes matters, and it is: normal, bold, italic, bold+italic.
25
-
26
- @mixin font-face(
27
- $name,
28
- $font-files,
29
- $eot: false,
30
- $weight: false,
31
- $style: false
32
- ) {
33
- $iefont: unquote("#{$eot}?#iefix");
34
- @font-face {
35
- font-family: quote($name);
36
- @if $eot {
37
- src: font-url($eot);
38
- $font-files: font-url($iefont) unquote("format('embedded-opentype')"), $font-files;
39
- }
40
- src: $font-files;
41
- @if $weight {
42
- font-weight: $weight;
43
- }
44
- @if $style {
45
- font-style: $style;
46
- }
47
- }
48
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/css3/_hyphenation.scss DELETED
@@ -1,77 +0,0 @@
1
- @import "shared";
2
-
3
- // Mixins to support specific CSS Text Level 3 elements
4
- //
5
- //
6
- //
7
- // Mixin for word-break properties
8
- // http://www.w3.org/css3-text/#word-break
9
- // * legal values for $type : normal, keep-all, break-all
10
- //
11
- // Example:
12
- // p.wordBreak {@include word-break(break-all);}
13
- //
14
- // Which generates:
15
- // p.wordBreak {
16
- // -ms-word-break: break-all;
17
- // word-break: break-all;
18
- // word-break: break-word;}
19
- //
20
- @mixin word-break($value: normal){
21
- @if $value == break-all {
22
- //Most browsers handle the break-all case the same...
23
- @include experimental(word-break, $value,
24
- not -moz, not -webkit, not -o, -ms, not -khtml, official
25
- );
26
- //Webkit handles break-all differently... as break-word
27
- @include experimental(word-break, break-word,
28
- not -moz, not -webkit, not -o, not -ms, not -khtml, official
29
- );
30
- }
31
- @else {
32
- @include experimental(word-break, $value,
33
- not -moz, not -webkit, not -o, -ms, not -khtml, official
34
- );
35
- }
36
- }
37
-
38
- // Mixin for the hyphens property
39
- //
40
- // W3C specification: http://www.w3.org/TR/css3-text/#hyphens
41
- // * legal values for $type : auto, manual, none
42
- //
43
- // Example:
44
- // p {
45
- // @include hyphens(auto);}
46
- // Which generates:
47
- // p {
48
- // -moz-hyphens: auto;
49
- // -webkit-hyphens: auto;
50
- // hyphens: auto;}
51
- //
52
- @mixin hyphens($value: auto){
53
- @include experimental(hyphens, $value,
54
- -moz, -webkit, not -o, not -ms, not -khtml, official
55
- );
56
- }
57
-
58
- // Mixin for x-browser hyphenation based on @auchenberg's post:
59
- // Removes the need for the <wbr/> HTML tag
60
- // http://blog.kenneth.io/blog/2012/03/04/word-wrapping-hypernation-using-css/
61
- //
62
- // Example:
63
- // div {@include hyphenation;}
64
- //
65
- // Which generates:
66
- // div {
67
- // -ms-word-break: break-all;
68
- // word-break: break-all;
69
- // word-break: break-word;
70
- // -moz-hyphens: auto;
71
- // -webkit-hyphens: auto;
72
- // hyphens: auto;}
73
- //
74
- @mixin hyphenation{
75
- @include word-break(break-all);
76
- @include hyphens;
77
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/css3/_images.scss DELETED
@@ -1,132 +0,0 @@
1
- @import "shared";
2
- @import "compass/utilities/general/hacks";
3
-
4
- // Background property support for vendor prefixing within values.
5
- @mixin background(
6
- $background-1,
7
- $background-2: false,
8
- $background-3: false,
9
- $background-4: false,
10
- $background-5: false,
11
- $background-6: false,
12
- $background-7: false,
13
- $background-8: false,
14
- $background-9: false,
15
- $background-10: false
16
- ) {
17
- $backgrounds: compact($background-1, $background-2, $background-3, $background-4, $background-5,
18
- $background-6, $background-7, $background-8, $background-9, $background-10);
19
- $mult-bgs: -compass-list-size($backgrounds) > 1;
20
- $add-pie-bg: prefixed(-pie, $backgrounds) or $mult-bgs;
21
- @if $experimental-support-for-svg and prefixed(-svg, $backgrounds) { background: -svg($backgrounds); }
22
- @if $support-for-original-webkit-gradients and prefixed(-owg, $backgrounds) { background: -owg($backgrounds); }
23
- @if $experimental-support-for-webkit and prefixed(-webkit, $backgrounds) { background: -webkit($backgrounds); }
24
- @if $experimental-support-for-mozilla and prefixed(-moz, $backgrounds) { background: -moz($backgrounds); }
25
- @if $experimental-support-for-opera and prefixed(-o, $backgrounds) { background: -o($backgrounds); }
26
- @if $experimental-support-for-pie and $add-pie-bg { -pie-background: -pie($backgrounds); }
27
- background: $backgrounds ;
28
- }
29
-
30
- @mixin background-with-css2-fallback(
31
- $background-1,
32
- $background-2: false,
33
- $background-3: false,
34
- $background-4: false,
35
- $background-5: false,
36
- $background-6: false,
37
- $background-7: false,
38
- $background-8: false,
39
- $background-9: false,
40
- $background-10: false
41
- ) {
42
- $backgrounds: compact($background-1, $background-2, $background-3, $background-4, $background-5,
43
- $background-6, $background-7, $background-8, $background-9, $background-10);
44
- $mult-bgs: -compass-list-size($backgrounds) > 1;
45
- $simple-background: if($mult-bgs or prefixed(-css2, $backgrounds), -css2(-compass-nth($backgrounds, last)), false);
46
- @if not blank($simple-background) { background: $simple-background; }
47
- @include background($background-1, $background-2, $background-3, $background-4, $background-5,
48
- $background-6, $background-7, $background-8, $background-9, $background-10);
49
- }
50
-
51
-
52
- // Background image property support for vendor prefixing within values.
53
- @mixin background-image(
54
- $image-1,
55
- $image-2: false,
56
- $image-3: false,
57
- $image-4: false,
58
- $image-5: false,
59
- $image-6: false,
60
- $image-7: false,
61
- $image-8: false,
62
- $image-9: false,
63
- $image-10: false
64
- ) {
65
- $images: compact($image-1, $image-2, $image-3, $image-4, $image-5, $image-6, $image-7, $image-8, $image-9, $image-10);
66
- $add-pie-bg: prefixed(-pie, $images) or -compass-list-size($images) > 1;
67
-
68
- @if $experimental-support-for-svg and prefixed(-svg, $images) { background-image: -svg($images); background-size: 100%; }
69
- @if $support-for-original-webkit-gradients and prefixed(-owg, $images) { background-image: -owg($images); }
70
- @if $experimental-support-for-webkit and prefixed(-webkit, $images) { background-image: -webkit($images); }
71
- @if $experimental-support-for-mozilla and prefixed(-moz, $images) { background-image: -moz($images); }
72
- @if $experimental-support-for-opera and prefixed(-o, $images) { background-image: -o($images); }
73
- @if $experimental-support-for-pie and $add-pie-bg { @warn "PIE does not support background-image. Use @include background(#{$images}) instead." }
74
- background-image: $images ;
75
- }
76
-
77
- // Emit a IE-Specific filters that renders a simple linear gradient.
78
- // For use in IE 6 - 8. Best practice would have you apply this via a
79
- // conditional IE stylesheet, but if you must, you should place this before
80
- // any background-image properties that you have specified.
81
- //
82
- // For the `$orientation` parameter, you can pass `vertical` or `horizontal`.
83
- @mixin filter-gradient($start-color, $end-color, $orientation: vertical) {
84
- @include has-layout;
85
- $gradient-type: if($orientation == vertical, 0, 1);
86
- @if $legacy-support-for-ie6 or $legacy-support-for-ie7 or $legacy-support-for-ie8 {
87
- filter: progid:DXImageTransform.Microsoft.gradient(gradientType=#{$gradient-type}, startColorstr='#{ie-hex-str($start-color)}', endColorstr='#{ie-hex-str($end-color)}');
88
- }
89
- }
90
-
91
-
92
- // Border image property support for vendor prefixing properties and values.
93
- @mixin border-image($value) {
94
- @if $experimental-support-for-mozilla { -moz-border-image: -moz(reject(-compass-list($value), fill)); }
95
- @if $support-for-original-webkit-gradients { -webkit-border-image: -owg(reject(-compass-list($value), fill)); }
96
- @if $experimental-support-for-webkit { -webkit-border-image: -webkit(reject(-compass-list($value), fill)); }
97
- @if $experimental-support-for-opera { -o-border-image: -o(reject(-compass-list($value), fill)); }
98
- @if $experimental-support-for-svg { border-image: -svg(reject(-compass-list($value), fill)); }
99
- border-image: $value;
100
- }
101
-
102
- // List style image property support for vendor prefixing within values.
103
- @mixin list-style-image($image) {
104
- @if $experimental-support-for-mozilla and prefixed(-moz, $image) { list-style-image: -moz($image); }
105
- @if $support-for-original-webkit-gradients and prefixed(-owg, $image) { list-style-image: -owg($image); }
106
- @if $experimental-support-for-webkit and prefixed(-webkit, $image) { list-style-image: -webkit($image); }
107
- @if $experimental-support-for-opera and prefixed(-o, $image) { list-style-image: -o($image); }
108
- @if $experimental-support-for-svg and prefixed(-svg, $image) { list-style-image: -svg($image); }
109
- list-style-image: $image ;
110
- }
111
-
112
- // List style property support for vendor prefixing within values.
113
- @mixin list-style($value) {
114
- $value: -compass-list($value);
115
- @if $experimental-support-for-mozilla and prefixed(-moz, $value) { list-style-image: -moz($value); }
116
- @if $support-for-original-webkit-gradients and prefixed(-owg, $value) { list-style-image: -owg($value); }
117
- @if $experimental-support-for-webkit and prefixed(-webkit, $value) { list-style-image: -webkit($value); }
118
- @if $experimental-support-for-opera and prefixed(-o, $value) { list-style-image: -o($value); }
119
- @if $experimental-support-for-svg and prefixed(-svg, $value) { list-style-image: -svg($value); }
120
- list-style-image: $value ;
121
- }
122
-
123
- // content property support for vendor prefixing within values.
124
- @mixin content($value) {
125
- $value: -compass-list($value);
126
- @if $experimental-support-for-mozilla and prefixed(-moz, $value) { content: -moz($value); }
127
- @if $support-for-original-webkit-gradients and prefixed(-owg, $value) { content: -owg($value); }
128
- @if $experimental-support-for-webkit and prefixed(-webkit, $value) { content: -webkit($value); }
129
- @if $experimental-support-for-opera and prefixed(-o, $value) { content: -o($value); }
130
- @if $experimental-support-for-svg and prefixed(-svg, $value) { content: -svg($value); }
131
- content: $value ;
132
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/css3/_inline-block.scss DELETED
@@ -1,22 +0,0 @@
1
- @import "shared";
2
-
3
- // Set `$inline-block-alignment` to `none` or `false` to disable the output
4
- // of a vertical-align property in the inline-block mixin.
5
- // Or set it to a legal value for `vertical-align` to change the default.
6
- $inline-block-alignment: middle !default;
7
-
8
- // Provides a cross-browser method to implement `display: inline-block;`
9
- @mixin inline-block($alignment: $inline-block-alignment) {
10
- @if $legacy-support-for-mozilla {
11
- display: -moz-inline-stack;
12
- }
13
- display: inline-block;
14
- @if $alignment and $alignment != none {
15
- vertical-align: $alignment;
16
- }
17
- @if $legacy-support-for-ie {
18
- *vertical-align: auto;
19
- zoom: 1;
20
- *display: inline;
21
- }
22
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/css3/_opacity.scss DELETED
@@ -1,19 +0,0 @@
1
- @import "shared";
2
-
3
- // Provides cross-browser CSS opacity. Takes a number between 0 and 1 as the argument, e.g. 0.5 for 50% opacity.
4
- //
5
- // @param $opacity
6
- // A number between 0 and 1, where 0 is transparent and 1 is opaque.
7
-
8
- @mixin opacity($opacity) {
9
- @if $legacy-support-for-ie6 or $legacy-support-for-ie7 or $legacy-support-for-ie8 {
10
- filter: unquote("progid:DXImageTransform.Microsoft.Alpha(Opacity=#{round($opacity * 100)})");
11
- }
12
- opacity: $opacity;
13
- }
14
-
15
- // Make an element completely transparent.
16
- @mixin transparent { @include opacity(0); }
17
-
18
- // Make an element completely opaque.
19
- @mixin opaque { @include opacity(1); }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/css3/_pie.scss DELETED
@@ -1,73 +0,0 @@
1
- $experimental-support-for-pie: true;
2
-
3
- // It is recommended that you use Sass's @extend directive to apply the behavior
4
- // to your PIE elements. To assist you, Compass provides this variable.
5
- // When set, it will cause the `@include pie` mixin to extend this class.
6
- // The class name you provide should **not** include the `.`.
7
- $pie-base-class: false !default;
8
-
9
- // The default approach to using PIE.
10
- // Can be one of:
11
- //
12
- // * relative (default)
13
- // * z-index
14
- // * none
15
- $pie-default-approach: relative !default;
16
-
17
- // The location of your PIE behavior file
18
- // This should be root-relative to your web server
19
- // relative assets don't work. It is recommended that
20
- // you set this yourself.
21
- $pie-behavior: stylesheet-url("PIE.htc") !default;
22
-
23
- // When using the z-index approach, the
24
- // first ancestor of the PIE element at
25
- // or before the container's opaque background
26
- // should have a z-index set as well to ensure
27
- // propert z-index stacking.
28
- //
29
- // The `$position` argument must be some non-static
30
- // value (absolute, relative, etc.)
31
- @mixin pie-container($z-index: 0, $position: relative) {
32
- z-index: $z-index;
33
- position: $position;
34
- }
35
-
36
- // PIE elements must have this behavior attached to them.
37
- // IE is broken -- it doesn't think of behavior urls as
38
- // relative to the stylesheet. It considers them relative
39
- // to the webpage. As a result, you cannot reliably use
40
- // compass's relative_assets with PIE.
41
- //
42
- // * `$approach` - one of: relative, z-index, or none
43
- // * `$z-index` - when using the z-index approach, this
44
- // is the z-index that is applied.
45
- @mixin pie-element(
46
- $approach: $pie-default-approach,
47
- $z-index: 0
48
- ) {
49
- behavior: $pie-behavior;
50
- @if $approach == relative {
51
- position: relative;
52
- }
53
- @else if $approach == z-index {
54
- z-index: $z-index;
55
- }
56
- }
57
-
58
- // a smart mixin that knows to extend or include pie-element according
59
- // to your stylesheet's configuration variables.
60
- @mixin pie($base-class: $pie-base-class) {
61
- @if $base-class {
62
- @extend .#{$base-class};
63
- }
64
- @else {
65
- @include pie-element;
66
- }
67
- }
68
-
69
- // Watch `$n` levels of ancestors for changes to their class attribute
70
- // So that cascading styles will work correctly on the PIE element.
71
- @mixin pie-watch-ancestors($n) {
72
- -pie-watch-ancestors: $n;
73
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/css3/_regions.scss DELETED
@@ -1,22 +0,0 @@
1
- @import "shared";
2
-
3
- // Webkit, IE10 and future support for [CSS Regions](http://dev.w3.org/csswg/css3-regions/)
4
- //
5
- // $target is a value you use to link two regions of your css. Give the source of your content the flow-into property, and give your target container the flow-from property.
6
- //
7
- // For a visual explanation, see the diagrams at Chris Coyier's
8
- // [CSS-Tricks](http://css-tricks.com/content-folding/)
9
-
10
- @mixin flow-into($target) {
11
- $target: unquote($target);
12
- @include experimental(flow-into, $target,
13
- not -moz, -webkit, not -o, -ms, not -khtml, not official
14
- );
15
- }
16
-
17
- @mixin flow-from($target) {
18
- $target: unquote($target);
19
- @include experimental(flow-from, $target,
20
- not -moz, -webkit, not -o, -ms, not -khtml, not official
21
- );
22
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/css3/_shared.scss DELETED
@@ -1,38 +0,0 @@
1
- @import "compass/support";
2
-
3
- // This mixin provides basic support for CSS3 properties and
4
- // their corresponding experimental CSS2 properties when
5
- // the implementations are identical except for the property
6
- // prefix.
7
- @mixin experimental($property, $value,
8
- $moz : $experimental-support-for-mozilla,
9
- $webkit : $experimental-support-for-webkit,
10
- $o : $experimental-support-for-opera,
11
- $ms : $experimental-support-for-microsoft,
12
- $khtml : $experimental-support-for-khtml,
13
- $official : true
14
- ) {
15
- @if $webkit and $experimental-support-for-webkit { -webkit-#{$property} : $value; }
16
- @if $khtml and $experimental-support-for-khtml { -khtml-#{$property} : $value; }
17
- @if $moz and $experimental-support-for-mozilla { -moz-#{$property} : $value; }
18
- @if $ms and $experimental-support-for-microsoft { -ms-#{$property} : $value; }
19
- @if $o and $experimental-support-for-opera { -o-#{$property} : $value; }
20
- @if $official { #{$property} : $value; }
21
- }
22
-
23
- // Same as experimental(), but for cases when the property is the same and the value is vendorized
24
- @mixin experimental-value($property, $value,
25
- $moz : $experimental-support-for-mozilla,
26
- $webkit : $experimental-support-for-webkit,
27
- $o : $experimental-support-for-opera,
28
- $ms : $experimental-support-for-microsoft,
29
- $khtml : $experimental-support-for-khtml,
30
- $official : true
31
- ) {
32
- @if $webkit and $experimental-support-for-webkit { #{$property} : -webkit-#{$value}; }
33
- @if $khtml and $experimental-support-for-khtml { #{$property} : -khtml-#{$value}; }
34
- @if $moz and $experimental-support-for-mozilla { #{$property} : -moz-#{$value}; }
35
- @if $ms and $experimental-support-for-microsoft { #{$property} : -ms-#{$value}; }
36
- @if $o and $experimental-support-for-opera { #{$property} : -o-#{$value}; }
37
- @if $official { #{$property} : #{$value}; }
38
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/css3/_text-shadow.scss DELETED
@@ -1,87 +0,0 @@
1
- @import "shared";
2
-
3
- // These defaults make the arguments optional for this mixin
4
- // If you like, set different defaults in your project
5
-
6
- $default-text-shadow-color: #aaa !default;
7
- $default-text-shadow-h-offset: 0px !default;
8
- $default-text-shadow-v-offset: 0px !default;
9
- $default-text-shadow-blur: 1px !default;
10
- $default-text-shadow-spread: false !default;
11
-
12
- // Provides cross-browser text shadows when one or more shadows are needed.
13
- // Each shadow argument should adhere to the standard css3 syntax for the
14
- // text-shadow property.
15
- //
16
- // Note: if any shadow has a spread parameter, this will cause the mixin
17
- // to emit the shadow declaration twice, first without the spread,
18
- // then with the spread included. This allows you to progressively
19
- // enhance the browsers that do support the spread parameter.
20
- @mixin text-shadow(
21
- $shadow-1 : default,
22
- $shadow-2 : false,
23
- $shadow-3 : false,
24
- $shadow-4 : false,
25
- $shadow-5 : false,
26
- $shadow-6 : false,
27
- $shadow-7 : false,
28
- $shadow-8 : false,
29
- $shadow-9 : false,
30
- $shadow-10: false
31
- ) {
32
- @if $shadow-1 == default {
33
- $shadow-1: compact($default-text-shadow-h-offset $default-text-shadow-v-offset $default-text-shadow-blur $default-text-shadow-spread $default-text-shadow-color);
34
- }
35
- $shadows-without-spread: join((),(),comma);
36
- $shadows: join((),(),comma);
37
- $has-spread: false;
38
- @each $shadow in compact($shadow-1, $shadow-2, $shadow-3, $shadow-4, $shadow-5,
39
- $shadow-6, $shadow-7, $shadow-8, $shadow-9, $shadow-10) {
40
- @if length($shadow) > 4 {
41
- $has-spread: true;
42
- $shadows-without-spread: append($shadows-without-spread, nth($shadow,1) nth($shadow,2) nth($shadow,3) nth($shadow,5));
43
- $shadows: append($shadows, $shadow);
44
- } else {
45
- $shadows-without-spread: append($shadows-without-spread, $shadow);
46
- $shadows: append($shadows, $shadow);
47
- }
48
- }
49
- @if $has-spread {
50
- text-shadow: $shadows-without-spread;
51
- }
52
- text-shadow: $shadows;
53
- }
54
-
55
- // Provides a single cross-browser CSS text shadow.
56
- //
57
- // Provides sensible defaults for the color, horizontal offset, vertical offset, blur, and spread
58
- // according to the configuration defaults above.
59
- @mixin single-text-shadow(
60
- $hoff: false,
61
- $voff: false,
62
- $blur: false,
63
- $spread: false,
64
- $color: false
65
- ) {
66
- // A lot of people think the color comes first. It doesn't.
67
- @if type-of($hoff) == color {
68
- $temp-color: $hoff;
69
- $hoff: $voff;
70
- $voff: $blur;
71
- $blur: $spread;
72
- $spread: $color;
73
- $color: $temp-color;
74
- }
75
- // Can't rely on default assignment with multiple supported argument orders.
76
- $hoff: if($hoff, $hoff, $default-text-shadow-h-offset);
77
- $voff: if($voff, $voff, $default-text-shadow-v-offset);
78
- $blur: if($blur, $blur, $default-text-shadow-blur );
79
- $spread: if($spread, $spread, $default-text-shadow-spread );
80
- $color: if($color, $color, $default-text-shadow-color );
81
- // We don't need experimental support for this property.
82
- @if $color == none or $hoff == none {
83
- @include text-shadow(none);
84
- } @else {
85
- @include text-shadow(compact($hoff $voff $blur $spread $color));
86
- }
87
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/css3/_transform-legacy.scss DELETED
@@ -1,87 +0,0 @@
1
- @import "shared";
2
-
3
- @warn "This version of the transform module has been deprecated and will be removed.";
4
-
5
- // CSS Transform and Transform-Origin
6
-
7
- // Apply a transform sent as a complete string.
8
-
9
- @mixin apply-transform($transform) {
10
- @include experimental(transform, $transform,
11
- -moz, -webkit, -o, not -ms, not -khtml, official
12
- );
13
- }
14
-
15
- // Apply a transform-origin sent as a complete string.
16
-
17
- @mixin apply-origin($origin) {
18
- @include experimental(transform-origin, $origin,
19
- -moz, -webkit, -o, not -ms, not -khtml, official
20
- );
21
- }
22
-
23
- // transform-origin requires x and y coordinates
24
- //
25
- // * only applies the coordinates if they are there so that it can be called by scale, rotate and skew safely
26
-
27
- @mixin transform-origin($originx: 50%, $originy: 50%) {
28
- @if $originx or $originy {
29
- @if $originy {
30
- @include apply-origin($originx or 50% $originy);
31
- } @else {
32
- @include apply-origin($originx);
33
- }
34
- }
35
- }
36
-
37
- // A full transform mixin with everything you could want
38
- //
39
- // * including origin adjustments if you want them
40
- // * scale, rotate and skew require units of degrees(deg)
41
- // * scale takes a multiplier, rotate and skew take degrees
42
-
43
- @mixin transform(
44
- $scale: 1,
45
- $rotate: 0deg,
46
- $transx: 0,
47
- $transy: 0,
48
- $skewx: 0deg,
49
- $skewy: 0deg,
50
- $originx: false,
51
- $originy: false
52
- ) {
53
- $transform : scale($scale) rotate($rotate) translate($transx, $transy) skew($skewx, $skewy);
54
- @include apply-transform($transform);
55
- @include transform-origin($originx, $originy);
56
- }
57
-
58
- // Transform Partials
59
- //
60
- // These work well on their own, but they don't add to each other, they override.
61
- // Use them with extra origin args, or along side +transform-origin
62
-
63
- // Adjust only the scale, with optional origin coordinates
64
-
65
- @mixin scale($scale: 1.25, $originx: false, $originy: false) {
66
- @include apply-transform(scale($scale));
67
- @include transform-origin($originx, $originy);
68
- }
69
-
70
- // Adjust only the rotation, with optional origin coordinates
71
-
72
- @mixin rotate($rotate: 45deg, $originx: false, $originy: false) {
73
- @include apply-transform(rotate($rotate));
74
- @include transform-origin($originx, $originy);
75
- }
76
-
77
- // Adjust only the translation
78
-
79
- @mixin translate($transx: 0, $transy: 0) {
80
- @include apply-transform(translate($transx, $transy));
81
- }
82
-
83
- // Adjust only the skew, with optional origin coordinates
84
- @mixin skew($skewx: 0deg, $skewy: 0deg, $originx: false, $originy: false) {
85
- @include apply-transform(skew($skewx, $skewy));
86
- @include transform-origin($originx, $originy);
87
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/css3/_transform.scss DELETED
@@ -1,598 +0,0 @@
1
- @import "shared";
2
-
3
- // @doc off
4
- // Note ----------------------------------------------------------------------
5
- // Safari, Chrome, and Firefox all support 3D transforms. However,
6
- // only in the most recent builds. You should also provide fallback 2d support for
7
- // Opera and IE. IE10 is slated to have 3d enabled, but is currently unreleased.
8
- // To make that easy, all 2D transforms include an browser-targeting toggle ($only3d)
9
- // to switch between the two support lists. The toggle defaults to 'false' (2D),
10
- // and also accepts 'true' (3D). Currently the lists are as follows:
11
- // 2D: Mozilla, Webkit, Opera, Official
12
- // 3D: Webkit, Firefox.
13
-
14
- // Available Transforms ------------------------------------------------------
15
- // - Scale (2d and 3d)
16
- // - Rotate (2d and 3d)
17
- // - Translate (2d and 3d)
18
- // - Skew (2d only)
19
-
20
- // Transform Parameters ------------------------------------------------------
21
- // - Transform Origin (2d and 3d)
22
- // - Perspective (3d)
23
- // - Perspective Origin (3d)
24
- // - Transform Style (3d)
25
- // - Backface Visibility (3d)
26
-
27
- // Mixins --------------------------------------------------------------------
28
- // transform-origin
29
- // - shortcuts: transform-origin2d, transform-origin3d
30
- // - helpers: apply-origin
31
- // transform
32
- // - shortcuts: transform2d, transform3d
33
- // - helpers: simple-transform, create-transform
34
- // perspective
35
- // - helpers: perspective-origin
36
- // transform-style
37
- // backface-visibility
38
- // scale
39
- // - shortcuts: scaleX, scaleY, scaleZ, scale3d
40
- // rotate
41
- // - shortcuts: rotateX, rotateY, rotate3d
42
- // translate
43
- // - shortcuts: translateX, translateY, translateZ, translate3d
44
- // skew
45
- // - shortcuts: skewX, skewY
46
-
47
- // Defaults ------------------------------------------------------------------
48
- // @doc on
49
-
50
- // The default x-origin for transforms
51
- $default-origin-x : 50% !default;
52
- // The default y-origin for transforms
53
- $default-origin-y : 50% !default;
54
- // The default z-origin for transforms
55
- $default-origin-z : 50% !default;
56
-
57
-
58
- // The default x-multiplier for scaling
59
- $default-scale-x : 1.25 !default;
60
- // The default y-multiplier for scaling
61
- $default-scale-y : $default-scale-x !default;
62
- // The default z-multiplier for scaling
63
- $default-scale-z : $default-scale-x !default;
64
-
65
-
66
- // The default angle for rotations
67
- $default-rotate : 45deg !default;
68
-
69
-
70
- // The default x-vector for the axis of 3d rotations
71
- $default-vector-x : 1 !default;
72
- // The default y-vector for the axis of 3d rotations
73
- $default-vector-y : 1 !default;
74
- // The default z-vector for the axis of 3d rotations
75
- $default-vector-z : 1 !default;
76
-
77
-
78
- // The default x-length for translations
79
- $default-translate-x : 1em !default;
80
- // The default y-length for translations
81
- $default-translate-y : $default-translate-x !default;
82
- // The default z-length for translations
83
- $default-translate-z : $default-translate-x !default;
84
-
85
-
86
- // The default x-angle for skewing
87
- $default-skew-x : 5deg !default;
88
- // The default y-angle for skewing
89
- $default-skew-y : 5deg !default;
90
-
91
-
92
- // **Transform-origin**
93
- // Transform-origin sent as a complete string
94
- //
95
- // @include apply-origin( origin [, 3D-only ] )
96
- //
97
- // where 'origin' is a space separated list containing 1-3 (x/y/z) coordinates
98
- // in percentages, absolute (px, cm, in, em etc..) or relative
99
- // (left, top, right, bottom, center) units
100
- //
101
- // @param only3d Set this to true to only apply this
102
- // mixin where browsers have 3D support.
103
- @mixin apply-origin($origin, $only3d) {
104
- $only3d: $only3d or -compass-list-size(-compass-list($origin)) > 2;
105
- @if $only3d {
106
- @include experimental(transform-origin, $origin,
107
- -moz, -webkit, -o, -ms, not -khtml, official
108
- );
109
- } @else {
110
- @include experimental(transform-origin, $origin,
111
- -moz, -webkit, -o, -ms, not -khtml, official
112
- );
113
- }
114
- }
115
-
116
- // Transform-origin sent as individual arguments:
117
- //
118
- // @include transform-origin( [ origin-x, origin-y, origin-z, 3D-only ] )
119
- //
120
- // where the 3 'origin-' arguments represent x/y/z coordinates.
121
- //
122
- // **NOTE:** setting z coordinates triggers 3D support list, leave false for 2D support
123
- @mixin transform-origin(
124
- $origin-x: $default-origin-x,
125
- $origin-y: $default-origin-y,
126
- $origin-z: false,
127
- $only3d: if($origin-z, true, false)
128
- ) {
129
- $origin: unquote('');
130
- @if $origin-x or $origin-y or $origin-z {
131
- @if $origin-x { $origin: $origin-x; } @else { $origin: 50%; }
132
- @if $origin-y { $origin: $origin $origin-y; } @else { @if $origin-z { $origin: $origin 50%; }}
133
- @if $origin-z { $origin: $origin $origin-z; }
134
- @include apply-origin($origin, $only3d);
135
- }
136
- }
137
-
138
-
139
- // Transform sent as a complete string:
140
- //
141
- // @include transform( transforms [, 3D-only ] )
142
- //
143
- // where 'transforms' is a space separated list of all the transforms to be applied.
144
- @mixin transform(
145
- $transform,
146
- $only3d: false
147
- ) {
148
- @if $only3d {
149
- @include experimental(transform, $transform,
150
- -moz, -webkit, -o, -ms, not -khtml, official
151
- );
152
- } @else {
153
- @include experimental(transform, $transform,
154
- -moz, -webkit, -o, -ms, not -khtml, official
155
- );
156
- }
157
- }
158
-
159
- // Shortcut to target all browsers with 2D transform support
160
- @mixin transform2d($trans) {
161
- @include transform($trans, false);
162
- }
163
-
164
- // Shortcut to target only browsers with 3D transform support
165
- @mixin transform3d($trans) {
166
- @include transform($trans, true);
167
- }
168
-
169
- // @doc off
170
- // 3D Parameters -------------------------------------------------------------
171
- // @doc on
172
-
173
- // Set the perspective of 3D transforms on the children of an element:
174
- //
175
- // @include perspective( perspective )
176
- //
177
- // where 'perspective' is a unitless number representing the depth of the
178
- // z-axis. The higher the perspective, the more exaggerated the foreshortening.
179
- // values from 500 to 1000 are more-or-less "normal" - a good starting-point.
180
- @mixin perspective($p) {
181
- @include experimental(perspective, $p,
182
- -moz, -webkit, -o, -ms, not -khtml, official
183
- );
184
- }
185
-
186
- // Set the origin position for the perspective
187
- //
188
- // @include perspective-origin(origin-x [origin-y])
189
- //
190
- // where the two arguments represent x/y coordinates
191
- @mixin perspective-origin($origin: 50%) {
192
- @include experimental(perspective-origin, $origin,
193
- -moz, -webkit, -o, -ms, not -khtml, official
194
- );
195
- }
196
-
197
- // Determine whether a 3D objects children also live in the given 3D space
198
- //
199
- // @include transform-style( [ style ] )
200
- //
201
- // where `style` can be either `flat` or `preserve-3d`.
202
- // Browsers default to `flat`, mixin defaults to `preserve-3d`.
203
- @mixin transform-style($style: preserve-3d) {
204
- @include experimental(transform-style, $style,
205
- -moz, -webkit, -o, -ms, not -khtml, official
206
- );
207
- }
208
-
209
- // Determine the visibility of an element when it's back is turned
210
- //
211
- // @include backface-visibility( [ visibility ] )
212
- //
213
- // where `visibility` can be either `visible` or `hidden`.
214
- // Browsers default to visible, mixin defaults to hidden
215
- @mixin backface-visibility($visibility: hidden) {
216
- @include experimental(backface-visibility, $visibility,
217
- -moz, -webkit, -o, -ms, not -khtml, official
218
- );
219
- }
220
-
221
- // @doc off
222
- // Transform Partials --------------------------------------------------------
223
- // These work well on their own, but they don't add to each other, they override.
224
- // Use along with transform parameter mixins to adjust origin, perspective and style
225
- // ---------------------------------------------------------------------------
226
-
227
-
228
- // Scale ---------------------------------------------------------------------
229
- // @doc on
230
-
231
- // Scale an object along the x and y axis:
232
- //
233
- // @include scale( [ scale-x, scale-y, perspective, 3D-only ] )
234
- //
235
- // where the 'scale-' arguments are unitless multipliers of the x and y dimensions
236
- // and perspective, which works the same as the stand-alone perspective property/mixin
237
- // but applies to the individual element (multiplied with any parent perspective)
238
- //
239
- // **Note** This mixin cannot be combined with other transform mixins.
240
- @mixin scale(
241
- $scale-x: $default-scale-x,
242
- $scale-y: $scale-x,
243
- $perspective: false,
244
- $only3d: false
245
- ) {
246
- $trans: scale($scale-x, $scale-y);
247
- @if $perspective { $trans: perspective($perspective) $trans; }
248
- @include transform($trans, $only3d);
249
- }
250
-
251
- // Scale an object along the x axis
252
- // @include scaleX( [ scale-x, perspective, 3D-only ] )
253
- //
254
- // **Note** This mixin cannot be combined with other transform mixins.
255
- @mixin scaleX(
256
- $scale: $default-scale-x,
257
- $perspective: false,
258
- $only3d: false
259
- ) {
260
- $trans: scaleX($scale);
261
- @if $perspective { $trans: perspective($perspective) $trans; }
262
- @include transform($trans, $only3d);
263
- }
264
-
265
- // Scale an object along the y axis
266
- // @include scaleY( [ scale-y, perspective, 3D-only ] )
267
- //
268
- // **Note** This mixin cannot be combined with other transform mixins.
269
- @mixin scaleY(
270
- $scale: $default-scale-y,
271
- $perspective: false,
272
- $only3d: false
273
- ) {
274
- $trans: scaleY($scale);
275
- @if $perspective { $trans: perspective($perspective) $trans; }
276
- @include transform($trans, $only3d);
277
- }
278
-
279
- // Scale an object along the z axis
280
- // @include scaleZ( [ scale-z, perspective ] )
281
- //
282
- // **Note** This mixin cannot be combined with other transform mixins.
283
- @mixin scaleZ(
284
- $scale: $default-scale-z,
285
- $perspective: false
286
- ) {
287
- $trans: scaleZ($scale);
288
- @if $perspective { $trans: perspective($perspective) $trans; }
289
- @include transform3d($trans);
290
- }
291
-
292
- // Scale and object along all three axis
293
- // @include scale3d( [ scale-x, scale-y, scale-z, perspective ] )
294
- //
295
- // **Note** This mixin cannot be combined with other transform mixins.
296
- @mixin scale3d(
297
- $scale-x: $default-scale-x,
298
- $scale-y: $default-scale-y,
299
- $scale-z: $default-scale-z,
300
- $perspective: false
301
- ) {
302
- $trans: scale3d($scale-x, $scale-y, $scale-z);
303
- @if $perspective { $trans: perspective($perspective) $trans; }
304
- @include transform3d($trans);
305
- }
306
-
307
- // @doc off
308
- // Rotate --------------------------------------------------------------------
309
- // @doc on
310
-
311
- // Rotate an object around the z axis (2D)
312
- // @include rotate( [ rotation, perspective, 3D-only ] )
313
- // where 'rotation' is an angle set in degrees (deg) or radian (rad) units
314
- //
315
- // **Note** This mixin cannot be combined with other transform mixins.
316
- @mixin rotate(
317
- $rotate: $default-rotate,
318
- $perspective: false,
319
- $only3d: false
320
- ) {
321
- $trans: rotate($rotate);
322
- @if $perspective { $trans: perspective($perspective) $trans; }
323
- @include transform($trans, $only3d);
324
- }
325
-
326
- // A longcut for 'rotate' in case you forget that 'z' is implied
327
- //
328
- // **Note** This mixin cannot be combined with other transform mixins.
329
- @mixin rotateZ(
330
- $rotate: $default-rotate,
331
- $perspective: false,
332
- $only3d: false
333
- ) {
334
- @include rotate($rotate, $perspective, $only3d);
335
- }
336
-
337
- // Rotate an object around the x axis (3D)
338
- // @include rotateX( [ rotation, perspective ] )
339
- //
340
- // **Note** This mixin cannot be combined with other transform mixins.
341
- @mixin rotateX(
342
- $rotate: $default-rotate,
343
- $perspective: false
344
- ) {
345
- $trans: rotateX($rotate);
346
- @if $perspective { $trans: perspective($perspective) $trans; }
347
- @include transform3d($trans);
348
- }
349
-
350
- // Rotate an object around the y axis (3D)
351
- // @include rotate( [ rotation, perspective ] )
352
- //
353
- // **Note** This mixin cannot be combined with other transform mixins.
354
- @mixin rotateY(
355
- $rotate: $default-rotate,
356
- $perspective: false
357
- ) {
358
- $trans: rotateY($rotate);
359
- @if $perspective { $trans: perspective($perspective) $trans; }
360
- @include transform3d($trans);
361
- }
362
-
363
- // Rotate an object around an arbitrary axis (3D)
364
- // @include rotate( [ vector-x, vector-y, vector-z, rotation, perspective ] )
365
- // where the 'vector-' arguments accept unitless numbers.
366
- // These numbers are not important on their own, but in relation to one another
367
- // creating an axis from your transform-origin, along the axis of Xx = Yy = Zz.
368
- //
369
- // **Note** This mixin cannot be combined with other transform mixins.
370
- @mixin rotate3d(
371
- $vector-x: $default-vector-x,
372
- $vector-y: $default-vector-y,
373
- $vector-z: $default-vector-z,
374
- $rotate: $default-rotate,
375
- $perspective: false
376
- ) {
377
- $trans: rotate3d($vector-x, $vector-y, $vector-z, $rotate);
378
- @if $perspective { $trans: perspective($perspective) $trans; }
379
- @include transform3d($trans);
380
- }
381
-
382
- // @doc off
383
- // Translate -----------------------------------------------------------------
384
- // @doc on
385
-
386
- // Move an object along the x or y axis (2D)
387
- // @include translate( [ translate-x, translate-y, perspective, 3D-only ] )
388
- // where the 'translate-' arguments accept any distance in percentages or absolute (px, cm, in, em etc..) units.
389
- //
390
- // **Note** This mixin cannot be combined with other transform mixins.
391
- @mixin translate(
392
- $translate-x: $default-translate-x,
393
- $translate-y: $default-translate-y,
394
- $perspective: false,
395
- $only3d: false
396
- ) {
397
- $trans: translate($translate-x, $translate-y);
398
- @if $perspective { $trans: perspective($perspective) $trans; }
399
- @include transform($trans, $only3d);
400
- }
401
-
402
- // Move an object along the x axis (2D)
403
- // @include translate( [ translate-x, perspective, 3D-only ] )
404
- //
405
- // **Note** This mixin cannot be combined with other transform mixins.
406
- @mixin translateX(
407
- $trans-x: $default-translate-x,
408
- $perspective: false,
409
- $only3d: false
410
- ) {
411
- $trans: translateX($trans-x);
412
- @if $perspective { $trans: perspective($perspective) $trans; }
413
- @include transform($trans, $only3d);
414
- }
415
-
416
- // Move an object along the y axis (2D)
417
- // @include translate( [ translate-y, perspective, 3D-only ] )
418
- //
419
- // **Note** This mixin cannot be combined with other transform mixins.
420
- @mixin translateY(
421
- $trans-y: $default-translate-y,
422
- $perspective: false,
423
- $only3d: false
424
- ) {
425
- $trans: translateY($trans-y);
426
- @if $perspective { $trans: perspective($perspective) $trans; }
427
- @include transform($trans, $only3d);
428
- }
429
-
430
- // Move an object along the z axis (3D)
431
- // @include translate( [ translate-z, perspective ] )
432
- //
433
- // **Note** This mixin cannot be combined with other transform mixins.
434
- @mixin translateZ(
435
- $trans-z: $default-translate-z,
436
- $perspective: false
437
- ) {
438
- $trans: translateZ($trans-z);
439
- @if $perspective { $trans: perspective($perspective) $trans; }
440
- @include transform3d($trans);
441
- }
442
-
443
- // Move an object along the x, y and z axis (3D)
444
- // @include translate( [ translate-x, translate-y, translate-z, perspective ] )
445
- //
446
- // **Note** This mixin cannot be combined with other transform mixins.
447
- @mixin translate3d(
448
- $translate-x: $default-translate-x,
449
- $translate-y: $default-translate-y,
450
- $translate-z: $default-translate-z,
451
- $perspective: false
452
- ) {
453
- $trans: translate3d($translate-x, $translate-y, $translate-z);
454
- @if $perspective { $trans: perspective($perspective) $trans; }
455
- @include transform3d($trans);
456
- }
457
-
458
- // @doc off
459
- // Skew ----------------------------------------------------------------------
460
- // @doc on
461
-
462
- // Skew an element:
463
- //
464
- // @include skew( [ skew-x, skew-y, 3D-only ] )
465
- //
466
- // where the 'skew-' arguments accept css angles in degrees (deg) or radian (rad) units.
467
- //
468
- // **Note** This mixin cannot be combined with other transform mixins.
469
- @mixin skew(
470
- $skew-x: $default-skew-x,
471
- $skew-y: $default-skew-y,
472
- $only3d: false
473
- ) {
474
- $trans: skew($skew-x, $skew-y);
475
- @include transform($trans, $only3d);
476
- }
477
-
478
- // Skew an element along the x axiz
479
- //
480
- // @include skew( [ skew-x, 3D-only ] )
481
- //
482
- // **Note** This mixin cannot be combined with other transform mixins.
483
- @mixin skewX(
484
- $skew-x: $default-skew-x,
485
- $only3d: false
486
- ) {
487
- $trans: skewX($skew-x);
488
- @include transform($trans, $only3d);
489
- }
490
-
491
- // Skew an element along the y axis
492
- //
493
- // @include skew( [ skew-y, 3D-only ] )
494
- //
495
- // **Note** This mixin cannot be combined with other transform mixins.
496
- @mixin skewY(
497
- $skew-y: $default-skew-y,
498
- $only3d: false
499
- ) {
500
- $trans: skewY($skew-y);
501
- @include transform($trans, $only3d);
502
- }
503
-
504
-
505
- // Full transform mixins
506
- // For settings any combination of transforms as arguments
507
- // These are complex and not highly recommended for daily use. They are mainly
508
- // here for backward-compatibility purposes.
509
- //
510
- // * they include origin adjustments
511
- // * scale takes a multiplier (unitless), rotate and skew take degrees (deg)
512
- //
513
- // **Note** This mixin cannot be combined with other transform mixins.
514
- @mixin create-transform(
515
- $perspective: false,
516
- $scale-x: false,
517
- $scale-y: false,
518
- $scale-z: false,
519
- $rotate-x: false,
520
- $rotate-y: false,
521
- $rotate-z: false,
522
- $rotate3d: false,
523
- $trans-x: false,
524
- $trans-y: false,
525
- $trans-z: false,
526
- $skew-x: false,
527
- $skew-y: false,
528
- $origin-x: false,
529
- $origin-y: false,
530
- $origin-z: false,
531
- $only3d: false
532
- ) {
533
- $trans: unquote("");
534
-
535
- // perspective
536
- @if $perspective { $trans: perspective($perspective) ; }
537
-
538
- // scale
539
- @if $scale-x and $scale-y {
540
- @if $scale-z { $trans: $trans scale3d($scale-x, $scale-y, $scale-z); }
541
- @else { $trans: $trans scale($scale-x, $scale-y); }
542
- } @else {
543
- @if $scale-x { $trans: $trans scaleX($scale-x); }
544
- @if $scale-y { $trans: $trans scaleY($scale-y); }
545
- @if $scale-z { $trans: $trans scaleZ($scale-z); }
546
- }
547
-
548
- // rotate
549
- @if $rotate-x { $trans: $trans rotateX($rotate-x); }
550
- @if $rotate-y { $trans: $trans rotateY($rotate-y); }
551
- @if $rotate-z { $trans: $trans rotateZ($rotate-z); }
552
- @if $rotate3d { $trans: $trans rotate3d($rotate3d); }
553
-
554
- // translate
555
- @if $trans-x and $trans-y {
556
- @if $trans-z { $trans: $trans translate3d($trans-x, $trans-y, $trans-z); }
557
- @else { $trans: $trans translate($trans-x, $trans-y); }
558
- } @else {
559
- @if $trans-x { $trans: $trans translateX($trans-x); }
560
- @if $trans-y { $trans: $trans translateY($trans-y); }
561
- @if $trans-z { $trans: $trans translateZ($trans-z); }
562
- }
563
-
564
- // skew
565
- @if $skew-x and $skew-y { $trans: $trans skew($skew-x, $skew-y); }
566
- @else {
567
- @if $skew-x { $trans: $trans skewX($skew-x); }
568
- @if $skew-y { $trans: $trans skewY($skew-y); }
569
- }
570
-
571
- // apply it!
572
- @include transform($trans, $only3d);
573
- @include transform-origin($origin-x, $origin-y, $origin-z, $only3d);
574
- }
575
-
576
-
577
- // A simplified set of options
578
- // backwards-compatible with the previous version of the 'transform' mixin
579
- @mixin simple-transform(
580
- $scale: false,
581
- $rotate: false,
582
- $trans-x: false,
583
- $trans-y: false,
584
- $skew-x: false,
585
- $skew-y: false,
586
- $origin-x: false,
587
- $origin-y: false
588
- ) {
589
- @include create-transform(
590
- false,
591
- $scale, $scale, false,
592
- false, false, $rotate, false,
593
- $trans-x, $trans-y, false,
594
- $skew-x, $skew-y,
595
- $origin-x, $origin-y, false,
596
- false
597
- );
598
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/css3/_transition.scss DELETED
@@ -1,221 +0,0 @@
1
- @import "shared";
2
-
3
- // CSS Transitions
4
- // Currently only works in Webkit.
5
- //
6
- // * expected in CSS3, FireFox 3.6/7 and Opera Presto 2.3
7
- // * We'll be prepared.
8
- //
9
- // Including this submodule sets following defaults for the mixins:
10
- //
11
- // $default-transition-property : all
12
- // $default-transition-duration : 1s
13
- // $default-transition-function : false
14
- // $default-transition-delay : false
15
- //
16
- // Override them if you like. Timing-function and delay are set to false for browser defaults (ease, 0s).
17
-
18
- $default-transition-property: all !default;
19
-
20
- $default-transition-duration: 1s !default;
21
-
22
- $default-transition-function: false !default;
23
-
24
- $default-transition-delay: false !default;
25
-
26
- $transitionable-prefixed-values: transform, transform-origin !default;
27
-
28
- // One or more properties to transition
29
- //
30
- // * for multiple, use a comma-delimited list
31
- // * also accepts "all" or "none"
32
-
33
- @mixin transition-property($property-1: $default-transition-property,
34
- $property-2 : false,
35
- $property-3 : false,
36
- $property-4 : false,
37
- $property-5 : false,
38
- $property-6 : false,
39
- $property-7 : false,
40
- $property-8 : false,
41
- $property-9 : false,
42
- $property-10: false
43
- ) {
44
- @if type-of($property-1) == string { $property-1: unquote($property-1); }
45
- $properties: compact($property-1, $property-2, $property-3, $property-4, $property-5, $property-6, $property-7, $property-8, $property-9, $property-10);
46
- @if $experimental-support-for-webkit { -webkit-transition-property : prefixed-for-transition(-webkit, $properties); }
47
- @if $experimental-support-for-mozilla { -moz-transition-property : prefixed-for-transition(-moz, $properties); }
48
- @if $experimental-support-for-opera { -o-transition-property : prefixed-for-transition(-o, $properties); }
49
- transition-property : $properties;
50
- }
51
-
52
- // One or more durations in seconds
53
- //
54
- // * for multiple, use a comma-delimited list
55
- // * these durations will affect the properties in the same list position
56
-
57
- @mixin transition-duration($duration-1: $default-transition-duration,
58
- $duration-2 : false,
59
- $duration-3 : false,
60
- $duration-4 : false,
61
- $duration-5 : false,
62
- $duration-6 : false,
63
- $duration-7 : false,
64
- $duration-8 : false,
65
- $duration-9 : false,
66
- $duration-10: false
67
- ) {
68
- @if type-of($duration-1) == string { $duration-1: unquote($duration-1); }
69
- $durations: compact($duration-1, $duration-2, $duration-3, $duration-4, $duration-5, $duration-6, $duration-7, $duration-8, $duration-9, $duration-10);
70
- @include experimental(transition-duration, $durations,
71
- -moz, -webkit, -o, not -ms, not -khtml, official
72
- );
73
- }
74
-
75
- // One or more timing functions
76
- //
77
- // * [ ease | linear | ease-in | ease-out | ease-in-out | cubic-bezier(x1, y1, x2, y2)]
78
- // * For multiple, use a comma-delimited list
79
- // * These functions will effect the properties in the same list position
80
-
81
- @mixin transition-timing-function($function-1: $default-transition-function,
82
- $function-2 : false,
83
- $function-3 : false,
84
- $function-4 : false,
85
- $function-5 : false,
86
- $function-6 : false,
87
- $function-7 : false,
88
- $function-8 : false,
89
- $function-9 : false,
90
- $function-10: false
91
- ) {
92
- $function-1: unquote($function-1);
93
- $functions: compact($function-1, $function-2, $function-3, $function-4, $function-5, $function-6, $function-7, $function-8, $function-9, $function-10);
94
- @include experimental(transition-timing-function, $functions,
95
- -moz, -webkit, -o, not -ms, not -khtml, official
96
- );
97
- }
98
-
99
- // One or more transition-delays in seconds
100
- //
101
- // * for multiple, use a comma-delimited list
102
- // * these delays will effect the properties in the same list position
103
-
104
- @mixin transition-delay($delay-1: $default-transition-delay,
105
- $delay-2 : false,
106
- $delay-3 : false,
107
- $delay-4 : false,
108
- $delay-5 : false,
109
- $delay-6 : false,
110
- $delay-7 : false,
111
- $delay-8 : false,
112
- $delay-9 : false,
113
- $delay-10: false
114
- ) {
115
- @if type-of($delay-1) == string { $delay-1: unquote($delay-1); }
116
- $delays: compact($delay-1, $delay-2, $delay-3, $delay-4, $delay-5, $delay-6, $delay-7, $delay-8, $delay-9, $delay-10);
117
- @include experimental(transition-delay, $delays,
118
- -moz, -webkit, -o, not -ms, not -khtml, official
119
- );
120
- }
121
-
122
- // Transition all-in-one shorthand
123
-
124
- @mixin single-transition(
125
- $property: $default-transition-property,
126
- $duration: $default-transition-duration,
127
- $function: $default-transition-function,
128
- $delay: $default-transition-delay
129
- ) {
130
- @include transition(compact($property $duration $function $delay));
131
- }
132
-
133
- @mixin transition(
134
- $transition-1 : default,
135
- $transition-2 : false,
136
- $transition-3 : false,
137
- $transition-4 : false,
138
- $transition-5 : false,
139
- $transition-6 : false,
140
- $transition-7 : false,
141
- $transition-8 : false,
142
- $transition-9 : false,
143
- $transition-10: false
144
- ) {
145
- @if $transition-1 == default {
146
- $transition-1 : compact($default-transition-property $default-transition-duration $default-transition-function $default-transition-delay);
147
- }
148
- $transitions: false;
149
- @if type-of($transition-1) == list and type-of(nth($transition-1,1)) == list {
150
- $transitions: join($transition-1, compact($transition-2, $transition-3, $transition-4, $transition-5, $transition-6, $transition-7, $transition-8, $transition-9, $transition-10), comma);
151
- } @else {
152
- $transitions : compact($transition-1, $transition-2, $transition-3, $transition-4, $transition-5, $transition-6, $transition-7, $transition-8, $transition-9, $transition-10);
153
- }
154
- $delays: comma-list();
155
- $has-delays: false;
156
- $webkit-value: comma-list();
157
- $moz-value: comma-list();
158
- $o-value: comma-list();
159
-
160
- // This block can be made considerably simpler at the point in time that
161
- // we no longer need to deal with the differences in how delays are treated.
162
- @each $transition in $transitions {
163
- // Extract the values from the list
164
- // (this would be cleaner if nth took a 3rd argument to provide a default value).
165
- $property: nth($transition, 1);
166
- $duration: false;
167
- $timing-function: false;
168
- $delay: false;
169
- @if length($transition) > 1 { $duration: nth($transition, 2); }
170
- @if length($transition) > 2 { $timing-function: nth($transition, 3); }
171
- @if length($transition) > 3 { $delay: nth($transition, 4); $has-delays: true; }
172
-
173
- // If a delay is provided without a timing function
174
- @if is-time($timing-function) and not $delay { $delay: $timing-function; $timing-function: false; $has-delays: true; }
175
-
176
- // Keep a list of delays in case one is specified
177
- $delays: append($delays, if($delay, $delay, 0s));
178
-
179
- $webkit-value: append($webkit-value, compact(prefixed-for-transition(-webkit, $property) $duration $timing-function));
180
- $moz-value: append( $moz-value, compact(prefixed-for-transition( -moz, $property) $duration $timing-function $delay));
181
- $o-value: append( $o-value, compact(prefixed-for-transition( -o, $property) $duration $timing-function $delay));
182
- }
183
-
184
- @if $experimental-support-for-webkit { -webkit-transition : $webkit-value;
185
- // old webkit doesn't support the delay parameter in the shorthand so we progressively enhance it.
186
- @if $has-delays { -webkit-transition-delay : $delays; } }
187
- @if $experimental-support-for-mozilla { -moz-transition : $moz-value; }
188
- @if $experimental-support-for-opera { -o-transition : $o-value; }
189
- transition : $transitions;
190
- }
191
-
192
- // coerce a list to be comma delimited or make a new, empty comma delimited list.
193
- @function comma-list($list: ()) {
194
- @return join((), $list, comma);
195
- }
196
-
197
- // Returns `$property` with the given prefix if it is found in `$transitionable-prefixed-values`.
198
- @function prefixed-for-transition($prefix, $property) {
199
- @if type-of($property) == list {
200
- $new-list: comma-list();
201
- @each $v in $property {
202
- $new-list: append($new-list, prefixed-for-transition($prefix, $v));
203
- }
204
- @return $new-list;
205
- } @else {
206
- @if index($transitionable-prefixed-values, $property) {
207
- @return #{$prefix}-#{$property};
208
- } @else {
209
- @return $property;
210
- }
211
- }
212
- }
213
-
214
- // Checks if the value given is a unit of time.
215
- @function is-time($value) {
216
- @if type-of($value) == number {
217
- @return not not index(s ms, unit($value));
218
- } @else {
219
- @return false;
220
- }
221
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/css3/_user-interface.scss DELETED
@@ -1,17 +0,0 @@
1
- // User Interface ------------------------------------------------------------
2
- // This file can be expanded to handle all the user interface properties as
3
- // they become available in browsers:
4
- // http://www.w3.org/TR/2000/WD-css3-userint-20000216
5
- @import "shared";
6
-
7
-
8
- // This property controls the selection model and granularity of an element.
9
- //
10
- // @param $select
11
- // [ none | text | toggle | element | elements | all | inherit ]
12
- @mixin user-select($select) {
13
- $select: unquote($select);
14
- @include experimental(user-select, $select,
15
- -moz, -webkit, not -o, not -ms, -khtml, official
16
- );
17
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/layout/_grid-background.scss DELETED
@@ -1,178 +0,0 @@
1
- @import "compass/css3/images";
2
- @import "compass/css3/background-size";
3
-
4
- // Set the color of your columns
5
- $grid-background-column-color : rgba(100, 100, 225, 0.25) !default;
6
- // Set the color of your gutters
7
- $grid-background-gutter-color : rgba(0, 0, 0, 0) !default;
8
-
9
- // Set the total number of columns in your grid
10
- $grid-background-total-columns : 24 !default;
11
- // Set the width of your columns
12
- $grid-background-column-width : 30px !default;
13
- // Set the width of your gutters
14
- $grid-background-gutter-width : 10px !default;
15
- // Set the offset, if your columns are padded in from the container edge
16
- $grid-background-offset : 0px !default;
17
-
18
- // Set the color of your baseline
19
- $grid-background-baseline-color : rgba(0, 0, 0, 0.5) !default;
20
- // Set the height of your baseline grid
21
- $grid-background-baseline-height : 1.5em !default;
22
-
23
- // toggle your columns grids on and off
24
- $show-column-grid-backgrounds : true !default;
25
- // toggle your vertical grids on and off
26
- $show-baseline-grid-backgrounds : true !default;
27
- // toggle all your grids on and off
28
- $show-grid-backgrounds : true !default;
29
-
30
- // optionally force your grid-image to remain fluid
31
- // no matter what units you used to declared your grid.
32
- $grid-background-force-fluid : false !default;
33
-
34
-
35
- // Create the gradient needed for baseline grids
36
- @function get-baseline-gradient(
37
- $color : $grid-background-baseline-color
38
- ) {
39
- $gradient: linear-gradient(bottom, $color 5%, rgba($color,0) 5%);
40
- @return $gradient;
41
- }
42
-
43
- // Create the color-stops needed for horizontal grids
44
- @function build-grid-background(
45
- $total : $grid-background-total-columns,
46
- $column : $grid-background-column-width,
47
- $gutter : $grid-background-gutter-width,
48
- $offset : $grid-background-offset,
49
- $column-color : $grid-background-column-color,
50
- $gutter-color : $grid-background-gutter-color
51
- ) {
52
- $grid: compact();
53
- $grid: append($grid, $gutter-color $offset, comma);
54
- @for $i from 0 to $total {
55
-
56
- // $a represents the start of this column, initially equal to the offset
57
- $a: $offset;
58
- @if $i > 0 { $a: $a + (($column + $gutter) * $i); }
59
-
60
- // $g represents the start of this gutter, equal to $a plus one column-width
61
- $g: $a + $column;
62
-
63
- // $z represents the end of a gutter, equal to $g plus one gutter-width
64
- $z: $g + $gutter;
65
-
66
- @if (unit($a) == "%") and ($i == ($total - 1)) {
67
- $z: 100%;
68
- }
69
-
70
- // and we add this column/gutter pair to our grid
71
- $grid: join($grid, ($column-color $a, $column-color $g, $gutter-color $g, $gutter-color $z));
72
- }
73
-
74
- @return $grid;
75
- }
76
-
77
- // Return the gradient needed for horizontal grids
78
- @function get-column-gradient(
79
- $total : $grid-background-total-columns,
80
- $column : $grid-background-column-width,
81
- $gutter : $grid-background-gutter-width,
82
- $offset : $grid-background-offset,
83
- $column-color : $grid-background-column-color,
84
- $gutter-color : $grid-background-gutter-color,
85
- $force-fluid : $grid-background-force-fluid
86
- ) {
87
- $grid: unquote("");
88
-
89
- // don't force fluid grids when they are already fluid.
90
- @if unit($column) == "%" { $force-fluid: false; }
91
-
92
- @if $force-fluid {
93
- $grid: get-column-fluid-grid($total,$column,$gutter,$offset,$column-color,$gutter-color);
94
- } @else {
95
- $grid: build-grid-background($total,$column,$gutter,$offset,$column-color,$gutter-color);
96
- }
97
-
98
- // return the horizontal grid as a gradient
99
- $gradient: linear-gradient(left, $grid);
100
- @return $gradient;
101
- }
102
-
103
- // Convert a grid from fixed units into percentages.
104
- @function get-column-fluid-grid(
105
- $total : $grid-background-total-columns,
106
- $column : $grid-background-column-width,
107
- $gutter : $grid-background-gutter-width,
108
- $offset : $grid-background-offset,
109
- $column-color : $grid-background-column-color,
110
- $gutter-color : $grid-background-gutter-color
111
- ) {
112
- $context: ($column * $total) + ($gutter * ($total - 1) + ($offset * 2));
113
- $offset: $offset / $context * 100%;
114
- $column: $column / $context * 100%;
115
- $gutter: $gutter / $context * 100%;
116
-
117
- // return the horizontal grid as a set of color-stops
118
- $grid: build-grid-background($total,$column,$gutter,$offset,$column-color,$gutter-color);
119
- @return $grid;
120
- }
121
-
122
-
123
- // Add just the baseline grid to an element's background
124
- @mixin baseline-grid-background(
125
- $baseline : $grid-background-baseline-height,
126
- $color : $grid-background-baseline-color
127
- ) {
128
- @if $show-grid-backgrounds and $show-baseline-grid-backgrounds {
129
- @include background-image(get-baseline-gradient($color));
130
- @include background-size(100% $baseline);
131
- background-position: left top;
132
- }
133
- }
134
-
135
- // Add just the horizontal grid to an element's background
136
- @mixin column-grid-background(
137
- $total : $grid-background-total-columns,
138
- $column : $grid-background-column-width,
139
- $gutter : $grid-background-gutter-width,
140
- $offset : $grid-background-offset,
141
- $column-color : $grid-background-column-color,
142
- $gutter-color : $grid-background-gutter-color,
143
- $force-fluid : $grid-background-force-fluid
144
- ) {
145
- @if $show-grid-backgrounds and $show-column-grid-backgrounds {
146
- @include background-image(
147
- get-column-gradient($total,$column,$gutter,$offset,$column-color,$gutter-color, $force-fluid)
148
- );
149
- background-position: left top;
150
- }
151
- }
152
-
153
- // Add both horizontal and baseline grids to an element's background
154
- @mixin grid-background(
155
- $total : $grid-background-total-columns,
156
- $column : $grid-background-column-width,
157
- $gutter : $grid-background-gutter-width,
158
- $baseline : $grid-background-baseline-height,
159
- $offset : $grid-background-offset,
160
- $column-color : $grid-background-column-color,
161
- $gutter-color : $grid-background-gutter-color,
162
- $baseline-color : $grid-background-baseline-color,
163
- $force-fluid : $grid-background-force-fluid
164
- ) {
165
- @if $show-grid-backgrounds {
166
- @if $show-baseline-grid-backgrounds and $show-column-grid-backgrounds {
167
- @include background-image(
168
- get-baseline-gradient($baseline-color),
169
- get-column-gradient($total,$column,$gutter,$offset,$column-color,$gutter-color, $force-fluid)
170
- );
171
- @include background-size(100% $baseline, auto);
172
- background-position: left top;
173
- } @else {
174
- @include baseline-grid-background($baseline, $baseline-color);
175
- @include column-grid-background($total,$column,$gutter,$offset,$column-color,$gutter-color, $force-fluid);
176
- }
177
- }
178
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/layout/_sticky-footer.scss DELETED
@@ -1,23 +0,0 @@
1
- // Based on a [blog post by Ryan Fait](http://ryanfait.com/resources/footer-stick-to-bottom-of-page/).
2
- //
3
- // Must be mixed into the top level of your stylesheet.
4
- //
5
- // Footer element must be outside of root wrapper element.
6
- //
7
- // Footer must be a fixed height.
8
-
9
- @mixin sticky-footer($footer-height, $root-selector: unquote("#root"), $root-footer-selector: unquote("#root_footer"), $footer-selector: unquote("#footer")) {
10
- html, body {
11
- height: 100%; }
12
- #{$root-selector} {
13
- clear: both;
14
- min-height: 100%;
15
- height: auto !important;
16
- height: 100%;
17
- margin-bottom: -$footer-height;
18
- #{$root-footer-selector} {
19
- height: $footer-height; } }
20
- #{$footer-selector} {
21
- clear: both;
22
- position: relative;
23
- height: $footer-height; } }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/layout/_stretching.scss DELETED
@@ -1,24 +0,0 @@
1
-
2
- // stretch element height to specified top and bottom position
3
-
4
- @mixin stretch-y($offset-top:0, $offset-bottom:0) {
5
- @include stretch($offset-top, false, $offset-bottom, false);
6
- }
7
-
8
-
9
- // stretch element width to specified left and right position
10
-
11
- @mixin stretch-x($offset-left:0, $offset-right:0) {
12
- @include stretch(false, $offset-right, false, $offset-left);
13
- }
14
-
15
-
16
- // shorthand to stretch element height and width
17
-
18
- @mixin stretch($offset-top:0, $offset-right:0, $offset-bottom:0, $offset-left:0) {
19
- position: absolute;
20
- @if $offset-top { top: $offset-top; }
21
- @if $offset-bottom { bottom: $offset-bottom; }
22
- @if $offset-left { left: $offset-left; }
23
- @if $offset-right { right: $offset-right; }
24
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/reset/_utilities-legacy.scss DELETED
@@ -1,135 +0,0 @@
1
- // Based on [Eric Meyer's reset](http://meyerweb.com/eric/thoughts/2007/05/01/reset-reloaded/)
2
- // Global reset rules.
3
- // For more specific resets, use the reset mixins provided below
4
- //
5
- // *Please Note*: tables still need `cellspacing="0"` in the markup.
6
- @mixin global-reset {
7
- html, body, div, span, applet, object, iframe,
8
- h1, h2, h3, h4, h5, h6, p, blockquote, pre,
9
- a, abbr, acronym, address, big, cite, code,
10
- del, dfn, em, font, img, ins, kbd, q, s, samp,
11
- small, strike, strong, sub, sup, tt, var,
12
- dl, dt, dd, ol, ul, li,
13
- fieldset, form, label, legend,
14
- table, caption, tbody, tfoot, thead, tr, th, td {
15
- @include reset-box-model;
16
- @include reset-font; }
17
- body {
18
- @include reset-body; }
19
- ol, ul {
20
- @include reset-list-style; }
21
- table {
22
- @include reset-table; }
23
- caption, th, td {
24
- @include reset-table-cell; }
25
- q, blockquote {
26
- @include reset-quotation; }
27
- a img {
28
- @include reset-image-anchor-border; } }
29
-
30
- // Reset all elements within some selector scope. To reset the selector itself,
31
- // mixin the appropriate reset mixin for that element type as well. This could be
32
- // useful if you want to style a part of your page in a dramatically different way.
33
- //
34
- // *Please Note*: tables still need `cellspacing="0"` in the markup.
35
- @mixin nested-reset {
36
- div, span, object, iframe, h1, h2, h3, h4, h5, h6, p,
37
- pre, a, abbr, acronym, address, code, del, dfn, em, img,
38
- dl, dt, dd, ol, ul, li, fieldset, form, label, legend, caption, tbody, tfoot, thead, tr {
39
- @include reset-box-model;
40
- @include reset-font; }
41
- table {
42
- @include reset-table; }
43
- caption, th, td {
44
- @include reset-table-cell; }
45
- q, blockquote {
46
- @include reset-quotation; }
47
- a img {
48
- @include reset-image-anchor-border; } }
49
-
50
- // Reset the box model measurements.
51
- @mixin reset-box-model {
52
- margin: 0;
53
- padding: 0;
54
- border: 0;
55
- outline: 0; }
56
-
57
- // Reset the font and vertical alignment.
58
- @mixin reset-font {
59
- font: {
60
- weight: inherit;
61
- style: inherit;
62
- size: 100%;
63
- family: inherit; };
64
- vertical-align: baseline; }
65
-
66
- // Resets the outline when focus.
67
- // For accessibility you need to apply some styling in its place.
68
- @mixin reset-focus {
69
- outline: 0; }
70
-
71
- // Reset a body element.
72
- @mixin reset-body {
73
- line-height: 1;
74
- color: black;
75
- background: white; }
76
-
77
- // Reset the list style of an element.
78
- @mixin reset-list-style {
79
- list-style: none; }
80
-
81
- // Reset a table
82
- @mixin reset-table {
83
- border-collapse: separate;
84
- border-spacing: 0;
85
- vertical-align: middle; }
86
-
87
- // Reset a table cell (`th`, `td`)
88
- @mixin reset-table-cell {
89
- text-align: left;
90
- font-weight: normal;
91
- vertical-align: middle; }
92
-
93
- // Reset a quotation (`q`, `blockquote`)
94
- @mixin reset-quotation {
95
- quotes: "" "";
96
- &:before, &:after {
97
- content: ""; } }
98
-
99
- // Resets the border.
100
- @mixin reset-image-anchor-border {
101
- border: none; }
102
-
103
- // Unrecognized elements are displayed inline.
104
- // This reset provides a basic reset for html5 elements
105
- // so they are rendered correctly in browsers that don't recognize them
106
- // and reset in browsers that have default styles for them.
107
- @mixin reset-html5 {
108
- #{elements-of-type(html5-block)} {
109
- @include reset-box-model;
110
- display: block; } }
111
-
112
- // Resets the display of inline and block elements to their default display
113
- // according to their tag type. Elements that have a default display that varies across
114
- // versions of html or browser are not handled here, but this covers the 90% use case.
115
- // Usage Example:
116
- //
117
- // // Turn off the display for both of these classes
118
- // .unregistered-only, .registered-only
119
- // display: none
120
- // // Now turn only one of them back on depending on some other context.
121
- // body.registered
122
- // +reset-display(".registered-only")
123
- // body.unregistered
124
- // +reset-display(".unregistered-only")
125
- @mixin reset-display($selector: "", $important: false) {
126
- #{append-selector(elements-of-type("inline"), $selector)} {
127
- @if $important {
128
- display: inline !important; }
129
- @else {
130
- display: inline; } }
131
- #{append-selector(elements-of-type("block"), $selector)} {
132
- @if $important {
133
- display: block !important; }
134
- @else {
135
- display: block; } } }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/reset/_utilities.scss DELETED
@@ -1,142 +0,0 @@
1
- // Based on [Eric Meyer's reset 2.0](http://meyerweb.com/eric/tools/css/reset/index.html)
2
- // Global reset rules.
3
- // For more specific resets, use the reset mixins provided below
4
- @mixin global-reset {
5
- html, body, div, span, applet, object, iframe,
6
- h1, h2, h3, h4, h5, h6, p, blockquote, pre,
7
- a, abbr, acronym, address, big, cite, code,
8
- del, dfn, em, img, ins, kbd, q, s, samp,
9
- small, strike, strong, sub, sup, tt, var,
10
- b, u, i, center,
11
- dl, dt, dd, ol, ul, li,
12
- fieldset, form, label, legend,
13
- table, caption, tbody, tfoot, thead, tr, th, td,
14
- article, aside, canvas, details, embed,
15
- figure, figcaption, footer, header, hgroup,
16
- menu, nav, output, ruby, section, summary,
17
- time, mark, audio, video {
18
- @include reset-box-model;
19
- @include reset-font; }
20
- // Unlike Eric's original reset, we reset the html element to be compatible
21
- // with the vertical rhythm mixins.
22
- html {
23
- @include reset-body; }
24
- ol, ul {
25
- @include reset-list-style; }
26
- table {
27
- @include reset-table; }
28
- caption, th, td {
29
- @include reset-table-cell; }
30
- q, blockquote {
31
- @include reset-quotation; }
32
- a img {
33
- @include reset-image-anchor-border; }
34
- @include reset-html5; }
35
-
36
- // Reset all elements within some selector scope. To reset the selector itself,
37
- // mixin the appropriate reset mixin for that element type as well. This could be
38
- // useful if you want to style a part of your page in a dramatically different way.
39
- @mixin nested-reset {
40
- div, span, applet, object, iframe,
41
- h1, h2, h3, h4, h5, h6, p, blockquote, pre,
42
- a, abbr, acronym, address, big, cite, code,
43
- del, dfn, em, img, ins, kbd, q, s, samp,
44
- small, strike, strong, sub, sup, tt, var,
45
- b, u, i, center,
46
- dl, dt, dd, ol, ul, li,
47
- fieldset, form, label, legend,
48
- table, caption, tbody, tfoot, thead, tr, th, td,
49
- article, aside, canvas, details, embed,
50
- figure, figcaption, footer, header, hgroup,
51
- menu, nav, output, ruby, section, summary,
52
- time, mark, audio, video {
53
- @include reset-box-model;
54
- @include reset-font; }
55
- table {
56
- @include reset-table; }
57
- caption, th, td {
58
- @include reset-table-cell; }
59
- q, blockquote {
60
- @include reset-quotation; }
61
- a img {
62
- @include reset-image-anchor-border; } }
63
-
64
- // Reset the box model measurements.
65
- @mixin reset-box-model {
66
- margin: 0;
67
- padding: 0;
68
- border: 0; }
69
-
70
- // Reset the font and vertical alignment.
71
- @mixin reset-font {
72
- font: inherit;
73
- font-size: 100%;
74
- vertical-align: baseline; }
75
-
76
- // Resets the outline when focus.
77
- // For accessibility you need to apply some styling in its place.
78
- @mixin reset-focus {
79
- outline: 0; }
80
-
81
- // Reset a body element.
82
- @mixin reset-body {
83
- line-height: 1; }
84
-
85
- // Reset the list style of an element.
86
- @mixin reset-list-style {
87
- list-style: none; }
88
-
89
- // Reset a table
90
- @mixin reset-table {
91
- border-collapse: collapse;
92
- border-spacing: 0; }
93
-
94
- // Reset a table cell (`th`, `td`)
95
- @mixin reset-table-cell {
96
- text-align: left;
97
- font-weight: normal;
98
- vertical-align: middle; }
99
-
100
- // Reset a quotation (`q`, `blockquote`)
101
- @mixin reset-quotation {
102
- quotes: none;
103
- &:before, &:after {
104
- content: "";
105
- content: none; } }
106
-
107
- // Resets the border.
108
- @mixin reset-image-anchor-border {
109
- border: none; }
110
-
111
- // Unrecognized elements are displayed inline.
112
- // This reset provides a basic reset for block html5 elements
113
- // so they are rendered correctly in browsers that don't recognize them
114
- // and reset in browsers that have default styles for them.
115
- @mixin reset-html5 {
116
- #{elements-of-type(html5-block)} {
117
- display: block; } }
118
-
119
- // Resets the display of inline and block elements to their default display
120
- // according to their tag type. Elements that have a default display that varies across
121
- // versions of html or browser are not handled here, but this covers the 90% use case.
122
- // Usage Example:
123
- //
124
- // // Turn off the display for both of these classes
125
- // .unregistered-only, .registered-only
126
- // display: none
127
- // // Now turn only one of them back on depending on some other context.
128
- // body.registered
129
- // +reset-display(".registered-only")
130
- // body.unregistered
131
- // +reset-display(".unregistered-only")
132
- @mixin reset-display($selector: "", $important: false) {
133
- #{append-selector(elements-of-type("inline"), $selector)} {
134
- @if $important {
135
- display: inline !important; }
136
- @else {
137
- display: inline; } }
138
- #{append-selector(elements-of-type("block"), $selector)} {
139
- @if $important {
140
- display: block !important; }
141
- @else {
142
- display: block; } } }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/typography/_links.scss DELETED
@@ -1,3 +0,0 @@
1
- @import "links/hover-link";
2
- @import "links/link-colors";
3
- @import "links/unstyled-link";
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/typography/_lists.scss DELETED
@@ -1,4 +0,0 @@
1
- @import "lists/horizontal-list";
2
- @import "lists/inline-list";
3
- @import "lists/inline-block-list";
4
- @import "lists/bullets";
 
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/typography/_text.scss DELETED
@@ -1,4 +0,0 @@
1
- @import "text/ellipsis";
2
- @import "text/nowrap";
3
- @import "text/replacement";
4
- @import "text/force-wrap";
 
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/typography/links/_hover-link.scss DELETED
@@ -1,5 +0,0 @@
1
- // a link that only has an underline when you hover over it
2
- @mixin hover-link {
3
- text-decoration: none;
4
- &:hover {
5
- text-decoration: underline; } }
 
 
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/typography/links/_link-colors.scss DELETED
@@ -1,28 +0,0 @@
1
- // Set all the colors for a link with one mixin call.
2
- // Order of arguments is:
3
- //
4
- // 1. normal
5
- // 2. hover
6
- // 3. active
7
- // 4. visited
8
- // 5. focus
9
- //
10
- // Those states not specified will inherit.
11
- // Mixin to an anchor link like so:
12
- // a
13
- // +link-colors(#00c, #0cc, #c0c, #ccc, #cc0)
14
-
15
- @mixin link-colors($normal, $hover: false, $active: false, $visited: false, $focus: false) {
16
- color: $normal;
17
- @if $visited {
18
- &:visited {
19
- color: $visited; } }
20
- @if $focus {
21
- &:focus {
22
- color: $focus; } }
23
- @if $hover {
24
- &:hover {
25
- color: $hover; } }
26
- @if $active {
27
- &:active {
28
- color: $active; } } }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/typography/links/_unstyled-link.scss DELETED
@@ -1,7 +0,0 @@
1
- // A link that looks and acts like the text it is contained within
2
- @mixin unstyled-link {
3
- color: inherit;
4
- text-decoration: inherit;
5
- cursor: inherit;
6
- &:active, &:focus {
7
- outline: none; } }
 
 
 
 
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/typography/lists/_bullets.scss DELETED
@@ -1,34 +0,0 @@
1
- // Turn off the bullet for an element of a list
2
- @mixin no-bullet {
3
- list-style-image : none;
4
- list-style-type : none;
5
- margin-left : 0;
6
- }
7
-
8
- // turns off the bullets for an entire list
9
- @mixin no-bullets {
10
- list-style: none;
11
- li { @include no-bullet; }
12
- }
13
-
14
- // Make a list(ul/ol) have an image bullet.
15
- //
16
- // The mixin should be used like this for an icon that is 5x7:
17
- //
18
- // ul.pretty
19
- // +pretty-bullets("my-icon.png", 5px, 7px)
20
- //
21
- // Additionally, if the image dimensions are not provided,
22
- // The image dimensions will be extracted from the image itself.
23
- //
24
- // ul.pretty
25
- // +pretty-bullets("my-icon.png")
26
- //
27
- @mixin pretty-bullets($bullet-icon, $width: image-width($bullet-icon), $height: image-height($bullet-icon), $line-height: 18px, $padding: 14px) {
28
- margin-left: 0;
29
- li {
30
- padding-left: $padding;
31
- background: image-url($bullet-icon) no-repeat ($padding - $width) / 2 ($line-height - $height) / 2;
32
- list-style-type: none;
33
- }
34
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/typography/lists/_horizontal-list.scss DELETED
@@ -1,61 +0,0 @@
1
- // Horizontal list layout module.
2
- //
3
- // Easy mode using simple descendant li selectors:
4
- //
5
- // ul.nav
6
- // +horizontal-list
7
- //
8
- // Advanced mode:
9
- // If you need to target the list items using a different selector then use
10
- // +horizontal-list-container on your ul/ol and +horizontal-list-item on your li.
11
- // This may help when working on layouts involving nested lists. For example:
12
- //
13
- // ul.nav
14
- // +horizontal-list-container
15
- // > li
16
- // +horizontal-list-item
17
-
18
- @import "bullets";
19
- @import "compass/utilities/general/clearfix";
20
- @import "compass/utilities/general/reset";
21
- @import "compass/utilities/general/float";
22
-
23
- // Can be mixed into any selector that target a ul or ol that is meant
24
- // to have a horizontal layout. Used to implement +horizontal-list.
25
- @mixin horizontal-list-container {
26
- @include reset-box-model;
27
- @include clearfix; }
28
-
29
- // Can be mixed into any li selector that is meant to participate in a horizontal layout.
30
- // Used to implement +horizontal-list.
31
- //
32
- // :last-child is not fully supported
33
- // see http://www.quirksmode.org/css/contents.html#t29 for the support matrix
34
- //
35
- // IE8 ignores rules that are included on the same line as :last-child
36
- // see http://www.richardscarrott.co.uk/posts/view/ie8-last-child-bug for details
37
- //
38
- // Setting `$padding` to `false` disables the padding between list elements
39
- @mixin horizontal-list-item($padding: 4px, $direction: left) {
40
- @include no-bullet;
41
- white-space: nowrap;
42
- @include float($direction);
43
- @if $padding {
44
- padding: {
45
- left: $padding;
46
- right: $padding;
47
- }
48
- &:first-child, &.first { padding-#{$direction}: 0; }
49
- &:last-child { padding-#{opposite-position($direction)}: 0; }
50
- &.last { padding-#{opposite-position($direction)}: 0; }
51
- }
52
- }
53
-
54
- // A list(ol,ul) that is layed out such that the elements are floated left and won't wrap.
55
- // This is not an inline list.
56
- //
57
- // Setting `$padding` to `false` disables the padding between list elements
58
- @mixin horizontal-list($padding: 4px, $direction: left) {
59
- @include horizontal-list-container;
60
- li {
61
- @include horizontal-list-item($padding, $direction); } }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/typography/lists/_inline-block-list.scss DELETED
@@ -1,50 +0,0 @@
1
- // Inline-Block list layout module.
2
- //
3
- // Easy mode using simple descendant li selectors:
4
- //
5
- // ul.nav {
6
- // @import inline-block-list;
7
- // }
8
- //
9
- // Advanced mode:
10
- // If you need to target the list items using a different selector then use
11
- // `@include inline-block-list-container` on your ul/ol and
12
- // `@include inline-block-list-item` on your li. This may help when working
13
- // on layouts involving nested lists. For example:
14
- //
15
- // ul.nav {
16
- // @include inline-block-list-container;
17
- // > li {
18
- // @include inline-block-list-item;
19
- // }
20
- // }
21
-
22
- @import "bullets";
23
- @import "horizontal-list";
24
- @import "compass/utilities/general/float";
25
- @import "compass/css3/inline-block";
26
-
27
- // Can be mixed into any selector that target a ul or ol that is meant
28
- // to have an inline-block layout. Used to implement `inline-block-list`.
29
- @mixin inline-block-list-container {
30
- @include horizontal-list-container; }
31
-
32
- // Can be mixed into any li selector that is meant to participate in a horizontal layout.
33
- // Used to implement `inline-block-list`.
34
- @mixin inline-block-list-item($padding: false) {
35
- @include no-bullet;
36
- @include inline-block;
37
- white-space: nowrap;
38
- @if $padding {
39
- padding: {
40
- left: $padding;
41
- right: $padding;
42
- };
43
- }
44
- }
45
-
46
- // A list(ol,ul) that is layed out such that the elements are inline-block and won't wrap.
47
- @mixin inline-block-list($padding: false) {
48
- @include inline-block-list-container;
49
- li {
50
- @include inline-block-list-item($padding); } }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/typography/lists/_inline-list.scss DELETED
@@ -1,44 +0,0 @@
1
- // makes a list inline.
2
-
3
- @mixin inline-list {
4
- list-style-type: none;
5
- &, & li {
6
- margin: 0px;
7
- padding: 0px;
8
- display: inline;
9
- }
10
- }
11
-
12
- // makes an inline list delimited with the passed string.
13
- // Defaults to making a comma-separated list.
14
- //
15
- // Please make note of the browser support issues before using this mixin:
16
- //
17
- // use of `content` and `:after` is not fully supported in all browsers.
18
- // See quirksmode for the [support matrix](http://www.quirksmode.org/css/contents.html#t15)
19
- //
20
- // `:last-child` is not fully supported.
21
- // see quirksmode for the [support matrix](http://www.quirksmode.org/css/contents.html#t29).
22
- //
23
- // IE8 ignores rules that are included on the same line as :last-child
24
- // see http://www.richardscarrott.co.uk/posts/view/ie8-last-child-bug for details
25
-
26
- @mixin delimited-list($separator: ", ") {
27
- @include inline-list;
28
- li {
29
- &:after { content: $separator; }
30
- &:last-child {
31
- &:after { content: ""; }
32
- }
33
- &.last {
34
- &:after { content: ""; }
35
- }
36
- }
37
- }
38
-
39
- // See [delimited-list](#mixin-delimited-list)
40
- // @deprecated
41
- @mixin comma-delimited-list {
42
- @warn "comma-delimited-list is deprecated. Please use delimited-list instead.";
43
- @include delimited-list;
44
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/typography/text/_ellipsis.scss DELETED
@@ -1,25 +0,0 @@
1
- @import "compass/css3/shared";
2
-
3
- // To get full firefox support, you must install the ellipsis pattern:
4
- //
5
- // compass install compass/ellipsis
6
- $use-mozilla-ellipsis-binding: false !default;
7
-
8
- // This technique, by [Justin Maxwell](http://code404.com/), was originally
9
- // published [here](http://mattsnider.com/css/css-string-truncation-with-ellipsis/).
10
- // Firefox implementation by [Rikkert Koppes](http://www.rikkertkoppes.com/thoughts/2008/6/).
11
- @mixin ellipsis($no-wrap: true) {
12
- @if $no-wrap { white-space: nowrap; }
13
- overflow: hidden;
14
- @include experimental(text-overflow, ellipsis,
15
- not -moz,
16
- not -webkit,
17
- -o,
18
- -ms,
19
- not -khtml,
20
- official
21
- );
22
- @if $experimental-support-for-mozilla and $use-mozilla-ellipsis-binding {
23
- -moz-binding: stylesheet-url(unquote("xml/ellipsis.xml#ellipsis"));
24
- }
25
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/typography/text/_force-wrap.scss DELETED
@@ -1,12 +0,0 @@
1
- // Prevent long urls and text from breaking layouts
2
- // [originally from perishablepress.com](http://perishablepress.com/press/2010/06/01/wrapping-content/)
3
- @mixin force-wrap {
4
- white-space: pre; // CSS 2.0
5
- white-space: pre-wrap; // CSS 2.1
6
- white-space: pre-line; // CSS 3.0
7
- white-space: -pre-wrap; // Opera 4-6
8
- white-space: -o-pre-wrap; // Opera 7
9
- white-space: -moz-pre-wrap; // Mozilla
10
- white-space: -hp-pre-wrap; // HP Printers
11
- word-wrap: break-word; // IE 5+
12
- }
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/typography/text/_nowrap.scss DELETED
@@ -1,2 +0,0 @@
1
- // When remembering whether or not there's a hyphen in white-space is too hard
2
- @mixin nowrap { white-space: nowrap; }
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/typography/text/_replacement.scss DELETED
@@ -1,68 +0,0 @@
1
- // Indicates the direction you prefer to move your text
2
- // when hiding it.
3
- //
4
- // `left` is more robust, especially in older browsers.
5
- // `right` seems have better runtime performance.
6
- $hide-text-direction: left !default;
7
-
8
- // Hides html text and replaces it with an image.
9
- // If you use this on an inline element, you will need to change the display to block or inline-block.
10
- // Also, if the size of the image differs significantly from the font size, you'll need to set the width and/or height.
11
- //
12
- // Parameters:
13
- //
14
- // * `img` -- the relative path from the project image directory to the image, or a url literal.
15
- // * `x` -- the x position of the background image.
16
- // * `y` -- the y position of the background image.
17
- @mixin replace-text($img, $x: 50%, $y: 50%) {
18
- @include hide-text;
19
- background: {
20
- @if is-url($img) {
21
- image: $img;
22
- } @else {
23
- image: image-url($img);
24
- }
25
- repeat: no-repeat;
26
- position: $x $y;
27
- };
28
- }
29
-
30
- // Like the `replace-text` mixin, but also sets the width
31
- // and height of the element according the dimensions of the image.
32
- //
33
- // If you set `$inline` to true, then an inline image (data uri) will be used.
34
- @mixin replace-text-with-dimensions($img, $x: 50%, $y: 50%, $inline: false) {
35
- @include replace-text(if($inline, inline-image($img), $img), $x, $y);
36
- width: image-width($img);
37
- height: image-height($img);
38
- }
39
-
40
- // Hides text in an element so you can see the background.
41
- //
42
- // The direction indicates how the text should be moved out of view.
43
- //
44
- // See `$hide-text-direction` for more information and to set this globally
45
- // for your application.
46
- @mixin hide-text($direction: $hide-text-direction) {
47
- @if $direction == left {
48
- $approximate-em-value: 12px / 1em;
49
- $wider-than-any-screen: -9999em;
50
- text-indent: $wider-than-any-screen * $approximate-em-value;
51
- overflow: hidden;
52
- text-align: left;
53
- } @else {
54
- // slightly wider than the box prevents issues with inline-block elements
55
- text-indent: 110%;
56
- white-space: nowrap;
57
- overflow: hidden;
58
- }
59
- }
60
-
61
- // Hides text in an element by squishing the text into oblivion.
62
- // Use this if you need to hide text contained in an inline element
63
- // but still have it read by a screen reader.
64
- @mixin squish-text {
65
- font: 0/0 serif;
66
- text-shadow: none;
67
- color: transparent;
68
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/utilities/_color.scss DELETED
@@ -1 +0,0 @@
1
- @import "color/contrast";
 
lib/phpsass/Extensions/Compass/stylesheets/compass/utilities/_general.scss DELETED
@@ -1,6 +0,0 @@
1
- @import "general/reset";
2
- @import "general/clearfix";
3
- @import "general/float";
4
- @import "general/tag-cloud";
5
- @import "general/hacks";
6
- @import "general/min";
 
 
 
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/utilities/_links.scss DELETED
@@ -1,5 +0,0 @@
1
- @warn "This import is deprecated. Use 'compass/typography/links' instead.";
2
-
3
- @import "../typography/links/hover-link";
4
- @import "../typography/links/link-colors";
5
- @import "../typography/links/unstyled-link";
 
 
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/utilities/_lists.scss DELETED
@@ -1,6 +0,0 @@
1
- @warn "This import is deprecated. Use 'compass/typography/lists' instead.";
2
-
3
- @import "../typography/lists/horizontal-list";
4
- @import "../typography/lists/inline-list";
5
- @import "../typography/lists/inline-block-list";
6
- @import "../typography/lists/bullets";
 
 
 
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/utilities/_print.scss DELETED
@@ -1,17 +0,0 @@
1
- // Classes that are useful for controlling what gets printed.
2
- // You must mix `+print-utilities` into your print stylesheet
3
- // and `+print-utilities(screen)` into your screen stylesheet.
4
- // Note: these aren't semantic.
5
- @mixin print-utilities($media: print) {
6
- @if $media == print {
7
- .noprint, .no-print { display: none; }
8
- #{elements-of-type(block)} {
9
- &.print-only { display: block; }
10
- }
11
- #{elements-of-type(inline)} {
12
- &.print-only { display: inline; }
13
- }
14
- } @else {
15
- .print-only { display: none; }
16
- }
17
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/utilities/_sprites.scss DELETED
@@ -1,2 +0,0 @@
1
- @import "sprites/base";
2
- @import "sprites/sprite-img";
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/utilities/_tables.scss DELETED
@@ -1,3 +0,0 @@
1
- @import "tables/alternating-rows-and-columns";
2
- @import "tables/borders";
3
- @import "tables/scaffolding";
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/utilities/_text.scss DELETED
@@ -1,5 +0,0 @@
1
- @warn "This import is deprecated. Use 'compass/typography/text' instead.";
2
-
3
- @import "../typography/text/ellipsis";
4
- @import "../typography/text/nowrap";
5
- @import "../typography/text/replacement";
 
 
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/utilities/color/_contrast.scss DELETED
@@ -1,28 +0,0 @@
1
- $contrasted-dark-default: #000 !default;
2
- $contrasted-light-default: #fff !default;
3
- $contrasted-lightness-threshold: 30% !default;
4
-
5
- // Returns the `$light` color when the `$color` is dark
6
- // and the `$dark` color when the `$color` is light.
7
- // The `$threshold` is a percent between `0%` and `100%` and it determines
8
- // when the lightness of `$color` changes from "dark" to "light".
9
- @function contrast-color(
10
- $color,
11
- $dark: $contrasted-dark-default,
12
- $light: $contrasted-light-default,
13
- $threshold: $contrasted-lightness-threshold
14
- ) {
15
- @return if(lightness($color) < $threshold, $light, $dark)
16
- }
17
-
18
- // Sets the specified background color and calculates a dark or light contrasted text color.
19
- // The arguments are passed through to the [contrast-color function](#function-contrast-color).
20
- @mixin contrasted(
21
- $background-color,
22
- $dark: $contrasted-dark-default,
23
- $light: $contrasted-light-default,
24
- $threshold: $contrasted-lightness-threshold
25
- ) {
26
- background-color: $background-color;
27
- color: contrast-color($background-color, $dark, $light, $threshold);
28
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/utilities/general/_clearfix.scss DELETED
@@ -1,44 +0,0 @@
1
- // @doc off
2
- // Extends the bottom of the element to enclose any floats it contains.
3
- // @doc on
4
-
5
- @import "hacks";
6
-
7
- // This basic method is preferred for the usual case, when positioned
8
- // content will not show outside the bounds of the container.
9
- //
10
- // Recommendations include using this in conjunction with a width.
11
- // Credit: [quirksmode.org](http://www.quirksmode.org/blog/archives/2005/03/clearing_floats.html)
12
- @mixin clearfix {
13
- overflow: hidden;
14
- @include has-layout;
15
- }
16
-
17
- // This older method from Position Is Everything called
18
- // [Easy Clearing](http://www.positioniseverything.net/easyclearing.html)
19
- // has the advantage of allowing positioned elements to hang
20
- // outside the bounds of the container at the expense of more tricky CSS.
21
- @mixin legacy-pie-clearfix {
22
- &:after {
23
- content : "\0020";
24
- display : block;
25
- height : 0;
26
- clear : both;
27
- overflow : hidden;
28
- visibility : hidden;
29
- }
30
- @include has-layout;
31
- }
32
-
33
- // This is an updated version of the PIE clearfix method that reduces the amount of CSS output.
34
- // If you need to support Firefox before 3.5 you need to use `legacy-pie-clearfix` instead.
35
- //
36
- // Adapted from: [A new micro clearfix hack](http://nicolasgallagher.com/micro-clearfix-hack/)
37
- @mixin pie-clearfix {
38
- &:after {
39
- content: "";
40
- display: table;
41
- clear: both;
42
- }
43
- @include has-layout;
44
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/utilities/general/_float.scss DELETED
@@ -1,30 +0,0 @@
1
- // Implementation of float:left with fix for the
2
- // [double-margin bug in IE5/6](http://www.positioniseverything.net/explorer/doubled-margin.html)
3
- @mixin float-left {
4
- @include float(left); }
5
-
6
- // Implementation of float:right with fix for the
7
- // [double-margin bug in IE5/6](http://www.positioniseverything.net/explorer/doubled-margin.html)
8
- @mixin float-right {
9
- @include float(right); }
10
-
11
- // Direction independent float mixin that fixes the
12
- // [double-margin bug in IE5/6](http://www.positioniseverything.net/explorer/doubled-margin.html)
13
- @mixin float($side: left) {
14
- display: inline;
15
- float: unquote($side); }
16
-
17
- // Resets floated elements back to their default of `float: none` and defaults
18
- // to `display: block` unless you pass `inline` as an argument
19
- //
20
- // Usage Example:
21
- //
22
- // body.homepage
23
- // #footer li
24
- // +float-left
25
- // body.signup
26
- // #footer li
27
- // +reset-float
28
- @mixin reset-float($display: block) {
29
- float: none;
30
- display: $display; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/utilities/general/_hacks.scss DELETED
@@ -1,46 +0,0 @@
1
- @import "compass/support";
2
-
3
- // The `zoom` approach generates less CSS but does not validate.
4
- // Set this to `block` to use the display-property to hack the
5
- // element to gain layout.
6
- $default-has-layout-approach: zoom !default;
7
-
8
- // This mixin causes an element matching the selector
9
- // to gain the "hasLayout" property in internet explorer.
10
- // More information on [hasLayout](http://reference.sitepoint.com/css/haslayout).
11
- @mixin has-layout($approach: $default-has-layout-approach) {
12
- @if $legacy-support-for-ie {
13
- @if $approach == zoom {
14
- @include has-layout-zoom;
15
- } @else if $approach == block {
16
- @include has-layout-block;
17
- } @else {
18
- @warn "Unknown has-layout approach: #{$approach}";
19
- @include has-layout-zoom;
20
- }
21
- }
22
- }
23
-
24
- @mixin has-layout-zoom {
25
- @if $legacy-support-for-ie6 or $legacy-support-for-ie7 {
26
- *zoom: 1;
27
- }
28
- }
29
-
30
- @mixin has-layout-block {
31
- @if $legacy-support-for-ie {
32
- // This makes ie6 get layout
33
- display: inline-block;
34
- // and this puts it back to block
35
- & { display: block; }
36
- }
37
- }
38
-
39
- // A hack to supply IE6 (and below) with a different property value.
40
- // [Read more](http://www.cssportal.com/css-hacks/#in_css-important).
41
- @mixin bang-hack($property, $value, $ie6-value) {
42
- @if $legacy-support-for-ie6 {
43
- #{$property}: #{$value} !important;
44
- #{$property}: #{$ie6-value};
45
- }
46
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/utilities/general/_min.scss DELETED
@@ -1,16 +0,0 @@
1
- @import "hacks";
2
-
3
- //**
4
- // Cross browser min-height mixin.
5
- @mixin min-height($value) {
6
- @include hacked-minimum(height, $value); }
7
-
8
- //**
9
- // Cross browser min-width mixin.
10
- @mixin min-width($value) {
11
- @include hacked-minimum(width, $value); }
12
-
13
- // @private This mixin is not meant to be used directly.
14
- @mixin hacked-minimum($property, $value) {
15
- min-#{$property}: $value;
16
- @include bang-hack($property, auto, $value); }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/utilities/general/_reset.scss DELETED
@@ -1,2 +0,0 @@
1
- // This module has moved.
2
- @import "compass/reset/utilities";
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/utilities/general/_tabs.scss DELETED
@@ -1 +0,0 @@
1
-
 
lib/phpsass/Extensions/Compass/stylesheets/compass/utilities/general/_tag-cloud.scss DELETED
@@ -1,18 +0,0 @@
1
- // Emits styles for a tag cloud
2
- @mixin tag-cloud($base-size: 1em) {
3
- font-size: $base-size;
4
- line-height: 1.2 * $base-size;
5
- .xxs, .xs, .s, .l, .xl, .xxl {
6
- line-height: 1.2 * $base-size; }
7
- .xxs {
8
- font-size: $base-size / 2; }
9
- .xs {
10
- font-size: 2 * $base-size / 3; }
11
- .s {
12
- font-size: 3 * $base-size / 4; }
13
- .l {
14
- font-size: 4 * $base-size / 3; }
15
- .xl {
16
- font-size: 3 * $base-size / 2; }
17
- .xxl {
18
- font-size: 2 * $base-size; } }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/utilities/links/_hover-link.scss DELETED
@@ -1,3 +0,0 @@
1
- @warn "This import is deprecated. Use 'compass/typography/links/hover-link' instead.";
2
-
3
- @import "../../typography/links/hover-link";
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/utilities/links/_link-colors.scss DELETED
@@ -1,3 +0,0 @@
1
- @warn "This import is deprecated. Use 'compass/typography/links/link-colors' instead.";
2
-
3
- @import "../../typography/links/link-colors";
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/utilities/links/_unstyled-link.scss DELETED
@@ -1,3 +0,0 @@
1
- @warn "This import is deprecated. Use 'compass/typography/links/unstyled-link' instead.";
2
-
3
- @import "../../typography/links/unstyled-link";
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/utilities/lists/_bullets.scss DELETED
@@ -1,3 +0,0 @@
1
- @warn "This import is deprecated. Use 'compass/typography/lists/bullets' instead.";
2
-
3
- @import "../../typography/lists/bullets";
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/utilities/lists/_horizontal-list.scss DELETED
@@ -1,3 +0,0 @@
1
- @warn "This import is deprecated. Use 'compass/typography/lists/horizontal-list' instead.";
2
-
3
- @import "../../typography/lists/horizontal-list";
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/utilities/lists/_inline-block-list.scss DELETED
@@ -1,3 +0,0 @@
1
- @warn "This import is deprecated. Use 'compass/typography/lists/inline-block-list' instead.";
2
-
3
- @import "../../typography/lists/inline-block-list";
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/utilities/lists/_inline-list.scss DELETED
@@ -1,3 +0,0 @@
1
- @warn "This import is deprecated. Use 'compass/typography/lists/inline-list' instead.";
2
-
3
- @import "../../typography/lists/inline-list";
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/utilities/sprites/_base.scss DELETED
@@ -1,66 +0,0 @@
1
- // Determines those states for which you want to enable magic sprite selectors
2
- $sprite-selectors: hover, target, active !default;
3
-
4
- // Set the width and height of an element to the original
5
- // dimensions of an image before it was included in the sprite.
6
- @mixin sprite-dimensions($map, $sprite) {
7
- height: image-height(sprite-file($map, $sprite));
8
- width: image-width(sprite-file($map, $sprite));
9
- }
10
-
11
- // Set the background position of the given sprite `$map` to display the
12
- // sprite of the given `$sprite` name. You can move the image relative to its
13
- // natural position by passing `$offset-x` and `$offset-y`.
14
- @mixin sprite-background-position($map, $sprite, $offset-x: 0, $offset-y: 0) {
15
- background-position: sprite-position($map, $sprite, $offset-x, $offset-y);
16
- }
17
-
18
-
19
- // Determines if you want to include magic selectors in your sprites
20
- $disable-magic-sprite-selectors:false !default;
21
-
22
- // Include the position and (optionally) dimensions of this `$sprite`
23
- // in the given sprite `$map`. The sprite url should come from either a base
24
- // class or you can specify the `sprite-url` explicitly like this:
25
- //
26
- // background: $map no-repeat;
27
- @mixin sprite($map, $sprite, $dimensions: false, $offset-x: 0, $offset-y: 0) {
28
- @include sprite-background-position($map, $sprite, $offset-x, $offset-y);
29
- @if $dimensions {
30
- @include sprite-dimensions($map, $sprite);
31
- }
32
- @if not $disable-magic-sprite-selectors {
33
- @include sprite-selectors($map, $sprite, $sprite, $offset-x, $offset-y);
34
- }
35
- }
36
-
37
- // Include the selectors for the `$sprite` given the `$map` and the
38
- // `$full-sprite-name`
39
- // @private
40
- @mixin sprite-selectors($map, $sprite-name, $full-sprite-name, $offset-x: 0, $offset-y: 0) {
41
- @each $selector in $sprite-selectors {
42
- @if sprite_has_selector($map, $sprite-name, $selector) {
43
- &:#{$selector}, &.#{$full-sprite-name}_#{$selector}, &.#{$full-sprite-name}-#{$selector} {
44
- @include sprite-background-position($map, "#{$sprite-name}_#{$selector}", $offset-x, $offset-y);
45
- }
46
- }
47
- }
48
- }
49
-
50
- // Generates a class for each space separated name in `$sprite-names`.
51
- // The class will be of the form .<map-name>-<sprite-name>.
52
- //
53
- // If a base class is provided, then each class will extend it.
54
- //
55
- // If `$dimensions` is `true`, the sprite dimensions will specified.
56
- @mixin sprites($map, $sprite-names, $base-class: false, $dimensions: false, $prefix: sprite-map-name($map), $offset-x: 0, $offset-y: 0) {
57
- @each $sprite-name in $sprite-names {
58
- @if sprite_does_not_have_parent($map, $sprite-name) {
59
- $full-sprite-name: "#{$prefix}-#{$sprite-name}";
60
- .#{$full-sprite-name} {
61
- @if $base-class { @extend #{$base-class}; }
62
- @include sprite($map, $sprite-name, $dimensions, $offset-x, $offset-y);
63
- }
64
- }
65
- }
66
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/utilities/sprites/_sprite-img.scss DELETED
@@ -1,79 +0,0 @@
1
- // @doc off
2
- // Example 1:
3
- //
4
- // a.twitter
5
- // +sprite-img("icons-32.png", 1)
6
- // a.facebook
7
- // +sprite-img("icons-32png", 2)
8
- //
9
- // Example 2:
10
- //
11
- // a
12
- // +sprite-background("icons-32.png")
13
- // a.twitter
14
- // +sprite-column(1)
15
- // a.facebook
16
- // +sprite-row(2)
17
- // @doc on
18
-
19
- $sprite-default-size: 32px !default;
20
-
21
- $sprite-default-margin: 0px !default;
22
-
23
- $sprite-image-default-width: $sprite-default-size !default;
24
-
25
- $sprite-image-default-height: $sprite-default-size !default;
26
-
27
- // Sets all the rules for a sprite from a given sprite image to show just one of the sprites.
28
- // To reduce duplication use a sprite-bg mixin for common properties and a sprite-select mixin for positioning.
29
- @mixin sprite-img($img, $col, $row: 1, $width: $sprite-image-default-width, $height: $sprite-image-default-height, $margin: $sprite-default-margin) {
30
- @include sprite-background($img, $width, $height);
31
- @include sprite-position($col, $row, $width, $height, $margin);
32
- }
33
-
34
- // Sets rules common for all sprites, assumes you want a square, but allows a rectangular region.
35
- @mixin sprite-background($img, $width: $sprite-default-size, $height: $width) {
36
- @include sprite-background-rectangle($img, $width, $height);
37
- }
38
-
39
- // Sets rules common for all sprites, assumes a rectangular region.
40
- @mixin sprite-background-rectangle($img, $width: $sprite-image-default-width, $height: $sprite-image-default-height) {
41
- background: image-url($img) no-repeat;
42
- width: $width;
43
- height: $height;
44
- overflow: hidden;
45
- }
46
-
47
- // Allows horizontal sprite positioning optimized for a single row of sprites.
48
- @mixin sprite-column($col, $width: $sprite-image-default-width, $margin: $sprite-default-margin) {
49
- @include sprite-position($col, 1, $width, 0px, $margin);
50
- }
51
-
52
- // Allows vertical sprite positioning optimized for a single column of sprites.
53
- @mixin sprite-row($row, $height: $sprite-image-default-height, $margin: $sprite-default-margin) {
54
- @include sprite-position(1, $row, 0px, $height, $margin);
55
- }
56
-
57
- // Allows vertical and horizontal sprite positioning from a grid of equal dimensioned sprites.
58
- @mixin sprite-position($col, $row: 1, $width: $sprite-image-default-width, $height: $sprite-image-default-height, $margin: $sprite-default-margin) {
59
- $x: ($col - 1) * -$width - ($col - 1) * $margin;
60
- $y: ($row - 1) * -$height - ($row - 1) * $margin;
61
- background-position: $x $y;
62
- }
63
-
64
-
65
-
66
- // Similar to 'sprite-replace-text-with-dimensions' but does not autmaticly set the demensions
67
- @mixin sprite-replace-text ($map, $sprite, $dimensions: false, $offset-x: 0, $offset-y: 0) {
68
- @include hide-text;
69
- @include sprite($map, $sprite, $dimensions, $offset-x, $offset-y);
70
- background-image: $map;
71
- background-repeat: no-repeat;
72
- }
73
-
74
- // Similar to 'replace-text-with-dimensions' but with sprites
75
- // To use, create your sprite and then pass it in the `$map` param
76
- // The name of the image in the sprite folder should be `$img-name`
77
- @mixin sprite-replace-text-with-dimensions ($map, $sprite, $offset-x: 0, $offset-y: 0){
78
- @include sprite-replace-text ($map, $sprite, true, $offset-x, $offset-y);
79
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/utilities/tables/_alternating-rows-and-columns.scss DELETED
@@ -1,22 +0,0 @@
1
- @mixin alternating-rows-and-columns($even-row-color, $odd-row-color, $dark-intersection, $header-color: white, $footer-color: white) {
2
- th {
3
- background-color: $header-color;
4
- &.even, &:nth-child(2n) {
5
- background-color: $header-color - $dark-intersection; } }
6
- tr {
7
- &.odd, &:nth-child(2n+1) {
8
- td {
9
- background-color: $odd-row-color;
10
- &.even, &:nth-child(2n) {
11
- background-color: $odd-row-color - $dark-intersection; } } }
12
- }
13
- tr.even {
14
- td {
15
- background-color: $even-row-color;
16
- &.even, &:nth-child(2n) {
17
- background-color: $even-row-color - $dark-intersection; } } }
18
- tfoot {
19
- th, td {
20
- background-color: $footer-color;
21
- &.even, &:nth-child(2n) {
22
- background-color: $footer-color - $dark-intersection; } } } }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/utilities/tables/_borders.scss DELETED
@@ -1,33 +0,0 @@
1
- @mixin outer-table-borders($width: 2px, $color: black) {
2
- border: $width solid $color;
3
- thead {
4
- th {
5
- border-bottom: $width solid $color; } }
6
- tfoot {
7
- th, td {
8
- border-top: $width solid $color; } }
9
- th {
10
- &:first-child {
11
- border-right: $width solid $color; } } }
12
-
13
- @mixin inner-table-borders($width: 2px, $color: black) {
14
- th, td {
15
- border: {
16
- right: $width solid $color;
17
- bottom: $width solid $color;
18
- left-width: 0px;
19
- top-width: 0px; };
20
- &:last-child,
21
- &.last {
22
- border-right-width: 0px; } }
23
-
24
- // IE8 ignores rules that are included on the same line as :last-child
25
- // see http://www.richardscarrott.co.uk/posts/view/ie8-last-child-bug for details
26
-
27
- tbody, tfoot {
28
- tr:last-child {
29
- th, td {
30
- border-bottom-width: 0px; } }
31
- tr.last {
32
- th, td {
33
- border-bottom-width: 0px; } } } }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/utilities/tables/_scaffolding.scss DELETED
@@ -1,9 +0,0 @@
1
- @mixin table-scaffolding {
2
- th {
3
- text-align: center;
4
- font-weight: bold; }
5
- td,
6
- th {
7
- padding: 2px;
8
- &.numeric {
9
- text-align: right; } } }
 
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/utilities/text/_ellipsis.scss DELETED
@@ -1,3 +0,0 @@
1
- @warn "This import is deprecated. Use 'compass/typography/text/ellipsis' instead.";
2
-
3
- @import "../../typography/text/ellipsis";
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/utilities/text/_nowrap.scss DELETED
@@ -1,3 +0,0 @@
1
- @warn "This import is deprecated. Use 'compass/typography/text/nowrap' instead.";
2
-
3
- @import "../../typography/text/nowrap";
 
 
 
lib/phpsass/Extensions/Compass/stylesheets/compass/utilities/text/_replacement.scss DELETED
@@ -1,3 +0,0 @@
1
- @warn "This import is deprecated. Use 'compass/typography/text/replacement' instead.";
2
-
3
- @import "../../typography/text/replacement";
 
 
 
lib/phpsass/Extensions/Compass/test.php DELETED
@@ -1,62 +0,0 @@
1
- <?php
2
- function loadCallback($file, $parser)
3
- {
4
- $paths = array();
5
- foreach ($parser->extensions as $extensionName) {
6
- $namespace = ucwords(preg_replace('/[^0-9a-z]+/', '_', strtolower($extensionName)));
7
- $extensionPath = realpath(__DIR__.'/../' . $namespace . '/' . $namespace . '.php');
8
- if (file_exists($extensionPath)) {
9
- require_once($extensionPath);
10
- $hook = $namespace . '::resolveExtensionPath';
11
- $returnPath = call_user_func($hook, $file, $parser);
12
- if (!empty($returnPath)) {
13
- $paths[] = $returnPath;
14
- }
15
-
16
- }
17
- }
18
-
19
- return $paths;
20
- }
21
-
22
- function getFunctions($extensions)
23
- {
24
- $output = array();
25
- if (!empty($extensions)) {
26
- foreach ($extensions as $extension) {
27
- $name = explode('/', $extension, 2);
28
- $namespace = ucwords(preg_replace('/[^0-9a-z]+/', '_', strtolower(array_shift($name))));
29
- $extensionPath = realpath(__DIR__.'/../' . $namespace . '/' . $namespace . '.php');
30
- if (file_exists(
31
- $extensionPath
32
- )
33
- ) {
34
- require_once($extensionPath);
35
- $namespace = $namespace . '::';
36
- $function = 'getFunctions';
37
- $output = array_merge($output, call_user_func($namespace . $function, $namespace));
38
- }
39
- }
40
- }
41
-
42
- return $output;
43
- }
44
-
45
- $path = realpath(__DIR__).'/../..';
46
- $library = $path . '/SassParser.php';
47
-
48
- require_once ($library);
49
-
50
- $options = array(
51
- 'style' => 'expanded',
52
- 'cache' => false,
53
- 'syntax' => 'scss',
54
- 'debug' => false,
55
- 'debug_info' => false,
56
- 'load_path_functions' => array('loadCallback'),
57
- 'load_paths' => array(dirname($file)),
58
- 'functions' => getFunctions(array('Compass','Own')),
59
- 'extensions' => array('Compass','Own')
60
- );
61
- $parser = new SassParser($options);
62
- return $parser->toCss($file);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/ExtensionInterface.php DELETED
@@ -1,7 +0,0 @@
1
- <?php
2
- interface ExtensionInterface
3
- {
4
- public static function getFunctions($namespace);
5
-
6
- public static function resolveExtensionPath($filename, $parser, $syntax = 'scss');
7
- }
 
 
 
 
 
 
 
lib/phpsass/Extensions/Own/Own.php DELETED
@@ -1,91 +0,0 @@
1
- <?php
2
- require_once dirname(__FILE__) . '/../ExtensionInterface.php';
3
- class Own implements ExtensionInterface
4
- {
5
-
6
- public static $filesFolder = 'css';
7
- public static $filePaths = null;
8
-
9
- /**
10
- * List with alias functions in Compass
11
- * @var array
12
- */
13
- public static $functions = array(
14
- 'demo-function',
15
- );
16
-
17
- public static function getFunctions($namespace)
18
- {
19
-
20
- $output = array();
21
- foreach (self::$functions as $function) {
22
- $originalFunction = $function;
23
- $function[0] = strtoupper($function[0]);
24
- $func = create_function('$c', 'return strtoupper($c[1]);');
25
- $function = preg_replace_callback('/-([a-z])/', $func, $function);
26
- $output[$originalFunction] = $namespace . strtolower(__CLASS__) . $function;
27
- }
28
-
29
- return $output;
30
- }
31
-
32
- /**
33
- * Returns an array with all files in $root path recursively and assign each array Key with clean alias
34
- * @param $root
35
- * @return array
36
- */
37
- public static function getFilesArray($root)
38
- {
39
-
40
- $alias = array();
41
- $directories = array();
42
- $last_letter = $root[strlen($root) - 1];
43
- $root = ($last_letter == '\\' || $last_letter == '/') ? $root : $root . DIRECTORY_SEPARATOR;
44
-
45
- $directories[] = $root;
46
-
47
- while (sizeof($directories)) {
48
- $dir = array_pop($directories);
49
- if ($handle = opendir($dir)) {
50
- while (false !== ($file = readdir($handle))) {
51
- if ($file == '.' || $file == '..') {
52
- continue;
53
- }
54
- $file = $dir . $file;
55
- if (is_dir($file)) {
56
- $directory_path = $file . DIRECTORY_SEPARATOR;
57
- array_push($directories, $directory_path);
58
- } elseif (is_file($file)) {
59
- $key = basename($file);
60
- $alias[substr($key, 1, strpos($key, '.') - 1)] = $file;
61
- }
62
- }
63
- closedir($handle);
64
- }
65
- }
66
-
67
- return $alias;
68
- }
69
-
70
- /**
71
- * Implementation of hook_resolve_path_NAMESPACE().
72
- */
73
- public static function resolveExtensionPath($callerImport, $parser, $syntax = 'scss')
74
- {
75
- $alias = str_replace('/_', '/', str_replace(array('.scss', '.sass'), '', $callerImport));
76
- if (strrpos($alias, '/') !== false) {
77
- $alias = substr($alias, strrpos($alias, '/') + 1);
78
- }
79
- if (self::$filePaths == null) {
80
- self::$filePaths = self::getFilesArray(dirname(__FILE__) . '/' . self::$filesFolder . '/');
81
- }
82
- if (isset(self::$filePaths[$alias])) {
83
- return self::$filePaths[$alias];
84
- }
85
- }
86
-
87
- public static function ownDemoFunction()
88
- {
89
- return new SassString("'This is my own Demo Function'");
90
- }
91
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/Own/css/test/test2/test.scss DELETED
@@ -1,3 +0,0 @@
1
- a{
2
- color:blue;
3
- }
 
 
 
lib/phpsass/Extensions/README.md DELETED
@@ -1,10 +0,0 @@
1
- compass-phpsass
2
- ===============
3
-
4
- Hi all,
5
- this is a Compass Sass Framework http://compass-style.org for Phpsass based on the Compass extension integrated in Sassy for Drupal http://drupalcode.org/project/sassy.git/tree/HEAD:/extensions/compass
6
- I only removed the specific code for Drupal and chaged it to Classes instead of *.module and *.inc
7
-
8
- I hope that you enjoy.
9
-
10
- Juan Manuel Vergés Solanas.
 
 
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/Susy/Susy.php DELETED
@@ -1,75 +0,0 @@
1
- <?php
2
- require_once dirname(__FILE__) . '/../ExtensionInterface.php';
3
- class Susy implements ExtensionInterface
4
- {
5
- public static $filesFolder = 'stylesheets';
6
- public static $filePaths = null;
7
-
8
- /**
9
- * List with alias functions in Susy
10
- * @var array
11
- */
12
- public static $functions = array();
13
-
14
- public static function getFunctions($namespace)
15
- {
16
- return array();
17
- }
18
-
19
- /**
20
- * Returns an array with all files in $root path recursively and assign each array Key with clean alias
21
- * @param $root
22
- * @return array
23
- */
24
- public static function getFilesArray($root)
25
- {
26
-
27
- $alias = array();
28
- $directories = array();
29
- $last_letter = $root[strlen($root) - 1];
30
- $root = ($last_letter == '\\' || $last_letter == '/') ? $root : $root . DIRECTORY_SEPARATOR;
31
-
32
- $directories[] = $root;
33
-
34
- while (sizeof($directories)) {
35
- $dir = array_pop($directories);
36
- if ($handle = opendir($dir)) {
37
- while (false !== ($file = readdir($handle))) {
38
- if ($file == '.' || $file == '..') {
39
- continue;
40
- }
41
- $file = $dir . $file;
42
- if (is_dir($file)) {
43
- $directory_path = $file . DIRECTORY_SEPARATOR;
44
- array_push($directories, $directory_path);
45
- } elseif (is_file($file)) {
46
- $key = basename($file);
47
- $alias[substr($key, 1, strpos($key, '.') - 1)] = $file;
48
- }
49
- }
50
- closedir($handle);
51
- }
52
- }
53
-
54
- return $alias;
55
- }
56
-
57
- /**
58
- * Implementation of hook_resolve_path_NAMESPACE().
59
- */
60
- public static function resolveExtensionPath($callerImport, $parser, $syntax = 'scss')
61
- {
62
- $extension = '';
63
- $alias = str_replace('/_', '/', str_replace(array('.scss', '.sass'), '', $callerImport));
64
- if (strrpos($alias, '/') !== false) {
65
- $extension = substr($alias, 0, strpos($alias, '/'));
66
- $alias = substr($alias, strrpos($alias, '/') + 1);
67
- }
68
- if (self::$filePaths == null) {
69
- self::$filePaths = self::getFilesArray(dirname(__FILE__) . '/' . self::$filesFolder . '/');
70
- }
71
- if (isset(self::$filePaths[$alias]) && $extension != 'compass') {
72
- return self::$filePaths[$alias];
73
- }
74
- }
75
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/Susy/stylesheets/_susy.scss DELETED
@@ -1,16 +0,0 @@
1
- // ---------------------------------------------------------------------------
2
- // Partials
3
-
4
- // temporary
5
- @import "susy/support";
6
- @import "susy/units";
7
-
8
- // permanent
9
- @import "susy/settings";
10
- @import "susy/functions";
11
- @import "susy/grid";
12
- @import "susy/isolation";
13
- @import "susy/padding";
14
- @import "susy/margin";
15
- @import "susy/media";
16
- @import "susy/background";
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/Susy/stylesheets/susy/_background.scss DELETED
@@ -1,18 +0,0 @@
1
- // ---------------------------------------------------------------------------
2
- // Imports
3
-
4
- @import "compass/layout/grid-background";
5
- @import "compass/css3/background-origin";
6
- @import "compass/css3/background-clip";
7
-
8
- // ---------------------------------------------------------------------------
9
- // Susy Grid Background
10
- //
11
- // A wrapper for the compass "column-grid-background" mixin
12
- // Uses all your settings to create a grid background for a container element.
13
- // Note: Sub-pixel rounding can lead to several pixels of variation between browsers.
14
- @mixin susy-grid-background(){
15
- @include column-grid-background($total-columns, column(), gutter(), 0);
16
- @include background-origin(content-box);
17
- @include background-clip(content-box);
18
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/Susy/stylesheets/susy/_functions.scss DELETED
@@ -1,376 +0,0 @@
1
- // ---------------------------------------------------------------------------
2
- // Imports
3
-
4
- // We need access to some basic font settings for handling media-queries.
5
- @import "compass/typography/vertical_rhythm";
6
-
7
- // For now, we also need this...
8
- $browser-default-font-size-px : 16px;
9
- $browser-default-font-size-percent : 100%;
10
- $browser-default-font-size-pt : 12pt;
11
-
12
- $rem-with-px-fallback : true !default;
13
-
14
- // ---------------------------------------------------------------------------
15
- // Sass list Functions
16
-
17
- // Return a list with specific items removed
18
- //
19
- // filter($list, $target)
20
- // - $list : The list to filter.
21
- // - $target : An item to be removed from the list.
22
- @function filter($list, $target) {
23
- $clean: compact();
24
- @if index($list, $target) {
25
- @each $item in $list {
26
- $clean: if($item == $target, $clean, append($clean, $item));
27
- }
28
- } @else { $clean: $list; }
29
- @return $clean;
30
- }
31
-
32
- // ---------------------------------------------------------------------------
33
- // Don't use static output when it will break things
34
-
35
- // Switch element-level output to fluid, when container-width is wrong for static
36
- //
37
- // fix-static-misalignment([$style, $width])
38
- // - $style: $container-style.
39
- // - $width: $container-width.
40
- @function fix-static-misalignment(
41
- $style: $container-style,
42
- $width: $container-width
43
- ) {
44
- @if $container-width and $container-width != container-outer-width($width: false) {
45
- $style: fluid;
46
- }
47
- @return $style;
48
- }
49
-
50
- // ---------------------------------------------------------------------------
51
- // Grid Functions
52
-
53
- // Returns the full width of a grid based on your grid settings.
54
- //
55
- // $columns : The number of columns to get width for.
56
- @function columns-width(
57
- $columns : $total-columns
58
- ) {
59
- @if round($columns) != $columns {
60
- @warn "Susy works best with integer column-spans.
61
- For partial-columns, you may need to finesse the math by hand using functions directly.";
62
- }
63
- @return ($columns * $column-width) + (if($columns >= 1, ceil($columns - 1), 0) * $gutter-width);
64
- }
65
-
66
- // Return the grid width after adding or subtracting grid padding
67
- //
68
- // $width : the width of the grid without padding;
69
- // $operation : ( add | subtract ) if padding should be added or subtracted;
70
- @function handle-grid-padding(
71
- $width,
72
- $operation : subtract
73
- ) {
74
- $pad: $grid-padding*2;
75
-
76
- @if comparable($width, $grid-padding) {
77
- $width: if($operation == subtract, $width - $pad, $width + $pad);
78
- } @else {
79
- @warn "$grid-padding must be set in units comparable to the container width.";
80
- }
81
-
82
- @return $width;
83
- }
84
-
85
- // Return the full outer width of a Container element.
86
- //
87
- // $columns : The number of columns in the Grid Layout.
88
- @function container-outer-width(
89
- $columns : $total-columns,
90
- $width : $container-width
91
- ) {
92
- $outerwidth: if($width, $width, columns-width($columns));
93
-
94
- @if $width {
95
- @if not $border-box-sizing { $outerwidth: handle-grid-padding($outerwidth, subtract); }
96
- } @else {
97
- @if $border-box-sizing { $outerwidth: handle-grid-padding($outerwidth, add); }
98
- }
99
-
100
- @return $outerwidth;
101
- }
102
-
103
- // Return the percentage width of a single column in a given 'context'.
104
- //
105
- // $context : The grid context in columns, if nested.
106
- // $style : The container style to use.
107
- @function column(
108
- $context : $total-columns,
109
- $style : fix-static-misalignment()
110
- ) {
111
- @return if($style == static, $column-width, relative-width($column-width, $context));
112
- }
113
-
114
- // Return the percentage width of multiple 'columns' in a given 'context'.
115
- //
116
- // $columns : The number of columns to get relative width for.
117
- // $context : The grid context in columns, if nested.
118
- // $style : The container style to use.
119
- @function columns(
120
- $columns,
121
- $context : $total-columns,
122
- $style : fix-static-misalignment()
123
- ) {
124
- @return if($style == static, columns-width($columns), relative-width(columns-width($columns), $context));
125
- }
126
-
127
- // Return the percentage width of a single gutter in a given 'context'.
128
- //
129
- // $context : The grid context in columns, if nested.
130
- // $style : The container style to use.
131
- @function gutter(
132
- $context : $total-columns,
133
- $style : fix-static-misalignment()
134
- ) {
135
- @return if($style == static, $gutter-width, relative-width($gutter-width, $context));
136
- }
137
-
138
- // Return the percentage width of a given value in a given 'context'.
139
- //
140
- // $width : Any given width value.
141
- // $context : The grid context in columns, if nested.
142
- @function relative-width(
143
- $width,
144
- $context : $total-columns
145
- ) {
146
- @return percentage($width / columns-width($context));
147
- }
148
-
149
- // Return the total space occupied by multiple columns and associated gutters.
150
- // Useful for adding padding or margins (prefix, suffix, push, pull, etc.)
151
- //
152
- // $columns : The number of columns to get relative space for.
153
- // $context : The grid context in columns, if nested.
154
- // $style : The container style to use.
155
- @function space(
156
- $columns,
157
- $context : $total-columns,
158
- $style : fix-static-misalignment()
159
- ) {
160
- @return columns($columns, $context, $style) + if($columns >= 1, gutter($context, $style), 0);
161
- }
162
-
163
- // Accept a list including column-count and (optional) position.
164
- // Return either the column count or the position alone.
165
- //
166
- // $columns : the list to split and interprate.
167
- // $request : The value to return, either 'columns' or 'position'.
168
- @function split-columns-value(
169
- $columns,
170
- $request : columns
171
- ) {
172
- $pos : false;
173
- $cols : false;
174
-
175
- @each $var in $columns {
176
- @if (type-of($var) == 'string') {
177
- $pos: $var;
178
- } @else {
179
- @if (type-of($var) == 'number') and (unitless($var)) {
180
- $cols: $var;
181
- } @else {
182
- @warn '"#{$var}" is not a valid part of "$columns: #{$columns}" in the columns() mixin.';
183
- }
184
- }
185
- }
186
-
187
- @if $request == 'columns' {
188
- @return $cols;
189
- } @else {
190
- @if $request == 'position' {
191
- @return $pos;
192
- } @else {
193
- @warn '"#{$request}"" is not a valid value for $request';
194
- }
195
- }
196
- }
197
-
198
- // Accept nth-selector variables, and format them as a valid CSS3 selector.
199
- //
200
- // $n : [first | only | last | <equation>]
201
- // $selector : [child | last-child | of-type | last-of-type ]
202
- @function format-nth(
203
- $n : last,
204
- $selector : child
205
- ) {
206
- @if ($n == 'last') or ($n =='first') or ($n =='only') {
207
- $selector: '#{$n}-#{$selector}';
208
- } @else {
209
- $selector: 'nth-#{$selector}(#{$n})';
210
- }
211
- @return $selector;
212
- }
213
-
214
- // ---------------------------------------------------------------------------
215
- // Media Functions
216
-
217
- // Return an em value adjusted to match the browser default font size.
218
- // Note: This only works if actual sizes are set relative to browser defaults.
219
- //
220
- // $ems : The initial value to be converted.
221
- // $font-size : The current font-size in.
222
- @function base-ems(
223
- $ems,
224
- $font-size: $base-font-size
225
- ){
226
- $font-size : if(unit($ems) == 'rem', $base-font-size, $font-size);
227
- $unit : unit($font-size);
228
- $mult : $ems / ($ems * 0 + 1);
229
-
230
- @if $unit == 'px' {
231
- @return $font-size / $browser-default-font-size-px * $mult * 1em;
232
- }
233
- @else if $unit == '%' {
234
- @return $font-size / $browser-default-font-size-percent * $mult * 1em;
235
- }
236
- @else if $unit == 'em' {
237
- @return $font-size / 1em * $mult * 1em;
238
- }
239
- @else if $unit == 'pt' {
240
- @return $font-size / $browser-default-font-size-pt * $mult * 1em;
241
- }
242
- @else {
243
- @warn 'Variable $base-font-size does not have a valid font unit. Valid units for fonts in CSS are px, pt, em, and %.';
244
- }
245
- }
246
-
247
- // This name will be deprecated...
248
- @function absolute-ems($ems, $font-size: $base-font-size){ @return base-ems($ems, $font-size); }
249
-
250
- // Return a length, after any em-values have been sent through absolute-ems().
251
- //
252
- // $length : The length value to be checked and adjusted if necessary.
253
- // $font-size : The current font-size in px.
254
- @function fix-ems(
255
- $length,
256
- $font-size: $base-font-size
257
- ){
258
- @if $length {
259
- @if (unit($length) == 'em') or (unit($length) == 'rem') {
260
- $length: absolute-ems($length,$font-size);
261
- }
262
- }
263
- @return $length;
264
- }
265
-
266
- // Sort a list of arguments into "$min $layout $max $ie" order, and return the list.
267
- //
268
- // $media-layout : a list of values [$min $layout $max $ie] including...
269
- // : - one unitless number (columns in a layout)
270
- // : - two optional lengths (min and max-width media-query breakpoints).
271
- // : - one optional boolean or string to trigger fallback support for IE.
272
- // $font-size : [optional] The base font-size of your layout, if you are using ems.
273
- // : - defaults to $base-font-size
274
- @function medialayout(
275
- $media-layout,
276
- $font-size: $base-font-size
277
- ) {
278
- $media : false;
279
- $min : false;
280
- $layout : false;
281
- $max : false;
282
- $ie : false;
283
- $has-layout : false;
284
-
285
- @each $val in $media-layout {
286
- @if (type-of($val) == "number") {
287
- @if unitless($val) {
288
- $layout : $val;
289
- $has-layout : true;
290
- } @else {
291
- @if ($has-layout) and (not $media) {
292
- $max: $val;
293
- } @else {
294
- @if $media {
295
- $media: join($media,$val);
296
- } @else {
297
- $media: $val;
298
- }
299
- }
300
- }
301
- } @else {
302
- $ie: $val;
303
- }
304
- }
305
- @if (length($media) > 0) {
306
- @if (length($media) == 1) {
307
- $min: nth($media,1);
308
- } @else {
309
- $min: nth($media,1);
310
- $max: nth($media,2);
311
- @if comparable($min, $max) {
312
- @if ($min > $max) {
313
- $max: nth($media,1);
314
- $min: nth($media,2);
315
- }
316
- } @else {
317
- @warn "Can't compare incompatible units.
318
- Using #{$min} for min-width, and #{$max} for max-width";
319
- }
320
- @if (length($media) > 2) {
321
- @warn "You can only send two lengths: a min-width and an (optional) max-width.
322
- You sent #{length($media)}: #{$media}";
323
- }
324
- }
325
- }
326
-
327
- // media-queries must be set in ems relative to the browser default
328
- // rather than the font-size set in CSS.
329
- $min: fix-ems($min,$font-size);
330
- $max: fix-ems($max,$font-size);
331
-
332
- @return $min $layout $max $ie;
333
- }
334
-
335
- // Return the nearest layout (column-count) above a given breakpoint.
336
- //
337
- // $min : The min-width media-query breakpoint above which to establish a new layout.
338
- @function get-layout (
339
- $min
340
- ) {
341
- $columns : 1;
342
- $layout-width : container-outer-width($columns);
343
- $return : false;
344
- $min : fix-ems($min);
345
-
346
- @if comparable($min, $layout-width) {
347
- @while $min >= $layout-width {
348
- $columns : $columns + 1;
349
- $layout-width : container-outer-width($columns);
350
- }
351
- $return : $columns;
352
- }
353
-
354
- @return $return;
355
- }
356
-
357
- // Check to see if a given $media-layout list is simply the default.
358
- //
359
- // $media-layout : a list of values including -
360
- // : One unitless number (columns in a layout)
361
- // : Two optional lengths (min and max-width media-query breakpoints).
362
- // : One optional boolean or string to trigger fallback support for IE.
363
- @function is-default-layout(
364
- $media-layout
365
- ) {
366
- $media-layout : medialayout($media-layout);
367
- $min : nth($media-layout,1);
368
- $layout-cols : nth($media-layout,2);
369
- $max : nth($media-layout,3);
370
-
371
- @if $min or $max {
372
- @return false;
373
- } @else {
374
- @return if($layout-cols == $total-columns,true,false);
375
- }
376
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/Susy/stylesheets/susy/_grid.scss DELETED
@@ -1,286 +0,0 @@
1
- // ---------------------------------------------------------------------------
2
- // Imports
3
-
4
- @import "compass/utilities/general/clearfix";
5
- @import "compass/css3/box-sizing";
6
-
7
- // ---------------------------------------------------------------------------
8
- // Border-Box Sizing
9
-
10
- // Apply the border-box sizing model to all elements
11
- // and adjust the grid math appropriately.
12
- @mixin border-box-sizing {
13
- $border-box-sizing: true;
14
- * { @include box-sizing(border-box); }
15
- }
16
-
17
- // ---------------------------------------------------------------------------
18
- // Container
19
-
20
- // Set the width of a container
21
- //
22
- // $columns : The number of columns in the Grid Layout.
23
- @mixin set-container-width(
24
- $columns : $total-columns,
25
- $style : $container-style
26
- ){
27
- $width: container-outer-width($columns);
28
-
29
- @if $style == 'static' {
30
- @include if-rem(width, $width);
31
- } @else {
32
- @if $style == 'fluid' {
33
- @if unit($width) == '%' { @include if-rem(width, $width); }
34
- } @else {
35
- @include if-rem(max-width, $width);
36
- @if $legacy-support-for-ie6 {
37
- @if unit($width) == 'rem' {
38
- _width: round(convert-length($width, px));
39
- } @else {
40
- _width: $width;
41
- }
42
- }
43
- }
44
- }
45
- }
46
-
47
- // Set the outer grid-containing element(s).
48
- //
49
- // $columns : The number of columns in the container.
50
- @mixin apply-container(
51
- $columns : $total-columns
52
- ){
53
- @include pie-clearfix;
54
- @include set-container-width($columns);
55
- @include if-rem(padding-left, $grid-padding);
56
- @include if-rem(padding-right, $grid-padding);
57
- margin: { left: auto; right: auto; }
58
- }
59
-
60
- // Set one or more layouts on a grid-containing element at any number of media-query breakpoints.
61
- //
62
- // $media-layout-1 : [default:$total-columns] A list of values including -
63
- // : One unitless number (representing columns in a layout)
64
- // : Two optional lengths (representing min and max-width media-query breakpoints).
65
- // $media-layout-2 ...-10 : [optional] Same as $media-layout-1
66
- @mixin container(
67
- $media-layout-1 : $total-columns,
68
- $media-layout-2 : false,
69
- $media-layout-3 : false,
70
- $media-layout-4 : false,
71
- $media-layout-5 : false,
72
- $media-layout-6 : false,
73
- $media-layout-7 : false,
74
- $media-layout-8 : false,
75
- $media-layout-9 : false,
76
- $media-layout-10 : false
77
- ){
78
- $media-layouts : compact($media-layout-2,$media-layout-3,$media-layout-4,$media-layout-5,$media-layout-6,$media-layout-7,$media-layout-8,$media-layout-9,$media-layout-10);
79
-
80
- @if is-default-layout($media-layout-1) {
81
- @include apply-container();
82
- } @else {
83
- @include at-breakpoint($media-layout-1) {
84
- @include apply-container();
85
- }
86
- }
87
-
88
- @each $ml in $media-layouts {
89
- @if $ml {
90
- @include at-breakpoint($ml) {
91
- @include set-container-width;
92
- }
93
- }
94
- }
95
- }
96
-
97
- // ---------------------------------------------------------------------------
98
- // Columns
99
-
100
- // Create a grid element spanning any number of 'columns' in a grid 'context'.
101
- // $columns : The number of columns to span.
102
- // $context : [optional] The context (columns spanned by parent).
103
- // : Context is required on any nested elements.
104
- // : Context MUST NOT be declared on a root element.
105
- // $padding : [optional] Padding applied to the inside of individual grid columns.
106
- // : Padding is only output if one or two values are specified (e.g. 1em or 10px 20px)
107
- // : Padding values are applied only on the horizontal axis in from-to order
108
- // $from : The start direction of your layout (e.g. 'left' for ltr languages)
109
- // $style : The container style to use.
110
- @mixin span-columns(
111
- $columns,
112
- $context : $total-columns,
113
- $padding : false,
114
- $from : $from-direction,
115
- $style : fix-static-misalignment()
116
- ) {
117
- $from : unquote($from);
118
- $to : opposite-position($from);
119
- $pos : split-columns-value($columns,position);
120
- $cols : split-columns-value($columns,columns);
121
- $pad-from : if($style == static, 0 * $gutter-width, relative-width(0 * $gutter-width, $context));
122
- $pad-to : if($style == static, 0 * $gutter-width, relative-width(0 * $gutter-width, $context));
123
-
124
- @if $padding != false {
125
- $pad-from : nth($padding, 1);
126
-
127
- @if length($padding) > 1 {
128
- $pad-to: nth($padding, 2);
129
- } @else {
130
- $pad-to: $pad-from;
131
- }
132
-
133
- $pad-from : if($style == static, $pad-from, relative-width($pad-from, $context));
134
- $pad-to : if($style == static, $pad-to, relative-width($pad-to, $context));
135
-
136
- padding-#{$from}: $pad-from;
137
- padding-#{$to}: $pad-to;
138
- }
139
-
140
- width: columns($cols, $context, $style) - if($border-box-sizing, 0, $pad-to + $pad-from);
141
-
142
- @if ($pos == 'omega') {
143
- @include omega($from);
144
- } @else {
145
- float: $from;
146
- margin-#{$to}: gutter($context, $style);
147
- @if $legacy-support-for-ie6 { display: inline; }
148
- }
149
- }
150
-
151
- // Apply to elements spanning the last column, to account for the page edge.
152
- // Only needed as an override. Normally 'omega' can just be called by `columns`.
153
- //
154
- // $from : The start-direction for your document.
155
- @mixin omega(
156
- $from : $from-direction
157
- ) {
158
- $from : unquote($from);
159
- $to : opposite-position($from);
160
- $hack : opposite-position($omega-float);
161
-
162
- float: $omega-float;
163
- margin-#{$to}: 0;
164
-
165
- @if $legacy-support-for-ie6 or $legacy-support-for-ie7 {
166
- *margin-#{$hack}: - $gutter-width;
167
- @if $legacy-support-for-ie6 { display: inline; }
168
- }
169
- }
170
-
171
- // Shortcut to apply omega to a specific subset of elements.
172
- //
173
- // $n : [first | only | last | <equation>]
174
- // $selector : [child | last-child | of-type | last-of-type ]
175
- // $from : The start-direction for your document.
176
- @mixin nth-omega(
177
- $n : last,
178
- $selector : child,
179
- $from : $from-direction
180
- ) {
181
- $from : unquote($from);
182
- $ie: if($n == "first", true, false);
183
- @include adjust-support-for($ie6: $ie, $ie7: $ie, $ie8: $ie) {
184
- &:#{format-nth($n,$selector)} { @include omega($from); }
185
- }
186
- }
187
-
188
- // ---------------------------------------------------------------------------
189
- // Resets
190
-
191
- // Reset a '+columns' grid element to default block behavior
192
- //
193
- // $from : The start direction of your layout (e.g. 'left' for ltr languages)
194
- @mixin reset-columns(
195
- $from: $from-direction
196
- ) {
197
- $from : unquote($from);
198
- $to : opposite-position($from);
199
- $hack : opposite-position($omega-float);
200
-
201
- float: none;
202
- width: auto;
203
- margin-#{$to}: auto;
204
-
205
- @if $legacy-support-for-ie6 or $legacy-support-for-ie7 {
206
- *margin-#{$hack}: auto;
207
- @if $legacy-support-for-ie6 { display: block; }
208
- }
209
- }
210
-
211
- // Apply to elements previously set as omega.
212
- // This will return floats and margins back to non-omega settigns.
213
- //
214
- // $context : [optional] The context (columns spanned by parent).
215
- // $from : The start-direction for your document.
216
- // $style : The container style to use.
217
- @mixin remove-omega(
218
- $context : $total-columns,
219
- $from : $from-direction,
220
- $style : fix-static-misalignment()
221
- ) {
222
- $from : unquote($from);
223
- $to : opposite-position($from);
224
- $hack : opposite-position($omega-float);
225
-
226
- float: $from;
227
- margin-#{$to}: gutter($context, $style);
228
-
229
- @if $legacy-support-for-ie6 or $legacy-support-for-ie7 {
230
- *margin-#{$hack}: auto;
231
- }
232
- }
233
-
234
- // Shortcut to apply remove-omega to a specific subset of elements.
235
- //
236
- // $n : [first | only | last | <equation>]
237
- // $selector : [child | last-child | of-type | last-of-type ]
238
- // $context : [optional] The context (columns spanned by parent).
239
- // $from : The start-direction for your document.
240
- // $style : The container style to use.
241
- @mixin remove-nth-omega(
242
- $n : last,
243
- $selector : child,
244
- $context : $total-columns,
245
- $from : $from-direction,
246
- $style : fix-static-misalignment()
247
- ) {
248
- $from : unquote($from);
249
- $ie: if($n == "first", true, false);
250
- @include adjust-support-for($ie6: $ie, $ie7: $ie, $ie8: $ie) {
251
- &:#{format-nth($n,$selector)} {
252
- @include remove-omega($context, $from, $style);
253
- }
254
- }
255
- }
256
-
257
- // ---------------------------------------------------------------------------
258
- // Change Settings
259
-
260
- @mixin with-grid-settings(
261
- $columns: $total-columns,
262
- $width: $column-width,
263
- $gutter: $gutter-width,
264
- $padding: $grid-padding
265
- ) {
266
- // keep the defaults around
267
- $default-columns: $total-columns;
268
- $default-width: $column-width;
269
- $default-gutter: $gutter-width;
270
- $default-padding: $grid-padding;
271
-
272
- // use the new settings
273
- $total-columns: $columns;
274
- $column-width: $width;
275
- $gutter-width: $gutter;
276
- $grid-padding: $padding;
277
-
278
- // apply to contents
279
- @content;
280
-
281
- // re-instate the defaults
282
- $total-columns: $default-columns;
283
- $column-width: $default-width;
284
- $gutter-width: $default-gutter;
285
- $grid-padding: $default-padding;
286
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/Susy/stylesheets/susy/_isolation.scss DELETED
@@ -1,48 +0,0 @@
1
- // ---------------------------------------------------------------------------
2
- // Isolation
3
-
4
- // Isolate the position of a grid element (use in addition to span-columns)
5
- //
6
- // $location : The grid column to isolate in, relative to the container;
7
- // $context : [optional] The context (columns spanned by parent).
8
- // $from : The start direction of your layout (e.g. 'left' for ltr languages)
9
- @mixin isolate(
10
- $location,
11
- $context: $total-columns,
12
- $from: $from-direction,
13
- $style: fix-static-misalignment()
14
- ) {
15
- $to: opposite-position($from);
16
- margin-#{$to}: -100%;
17
- margin-#{$from}: space($location - 1, $context, $style);
18
- }
19
-
20
- // Isolate a group of elements in a grid, using nth-child selectors
21
- //
22
- // $columns : The column-width of each item on the grid;
23
- // $context : [optional] The context (columns spanned by parent).
24
- // $from : The start direction of your layout (e.g. 'left' for ltr languages)
25
- @mixin isolate-grid(
26
- $columns,
27
- $context: $total-columns,
28
- $from: $from-direction,
29
- $style: fix-static-misalignment()
30
- ) {
31
- $to: opposite-position($from);
32
- $location: 1;
33
- $line: floor($context / $columns);
34
-
35
- @include span-columns($columns, $context, $from: $from, $style: $style);
36
- margin-#{$to}: -100%;
37
-
38
- @for $item from 1 through $line {
39
- $nth: '#{$line}n + #{$item}';
40
- &:nth-child(#{$nth}) {
41
- margin-#{$from}: space($location - 1, $context, $style);
42
- @if $location == 1 { clear: $from; }
43
-
44
- $location: $location + $columns;
45
- @if $location > $context { $location: 1; }
46
- }
47
- }
48
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/Susy/stylesheets/susy/_margin.scss DELETED
@@ -1,93 +0,0 @@
1
- // ---------------------------------------------------------------------------
2
- // Margin Mixins
3
-
4
- // Apply 'columns' margin before an element to push it along the grid.
5
- //
6
- // $columns : The number of columns to span.
7
- // $context : [optional] The context (columns spanned by parent).
8
- // : Context is required on any nested elements.
9
- // : Context MUST NOT be declared on a root element.
10
- // $from : The start direction of your layout (e.g. 'left' for ltr languages)
11
- // $style : The container style to use.
12
- @mixin pre(
13
- $columns,
14
- $context : $total-columns,
15
- $from : $from-direction,
16
- $style : fix-static-misalignment()
17
- ) {
18
- $from : unquote($from);
19
- margin-#{$from}: space($columns, $context, $style);
20
- }
21
-
22
- // 'push' is a synonymn for 'pre'
23
- @mixin push(
24
- $columns,
25
- $context : $total-columns,
26
- $from : $from-direction,
27
- $style : fix-static-misalignment()
28
- ) {
29
- $from : unquote($from);
30
- @include pre($columns, $context, $from, $style);
31
- }
32
-
33
- // Apply negative 'columns' margin before an element to pull it along the grid.
34
- //
35
- // $columns : The number of columns to span.
36
- // $context : [optional] The context (columns spanned by parent).
37
- // : Context is required on any nested elements.
38
- // : Context MUST NOT be declared on a root element.
39
- // $from : The start direction of your layout (e.g. 'left' for ltr languages)
40
- // $style : The container style to use.
41
- @mixin pull(
42
- $columns,
43
- $context : $total-columns,
44
- $from : $from-direction,
45
- $style : fix-static-misalignment()
46
- ) {
47
- $from : unquote($from);
48
- margin-#{$from}: 0 - space($columns, $context, $style);
49
- }
50
-
51
- // Apply 'columns' margin after an element to contain it in a grid.
52
- //
53
- // $columns : The number of columns to span.
54
- // $context : [optional] The context (columns spanned by parent).
55
- // : Context is required on any nested elements.
56
- // : Context MUST NOT be declared on a root element.
57
- // $from : The start direction of your layout (e.g. 'left' for ltr languages)
58
- // $style : The container style to use.
59
- @mixin post(
60
- $columns,
61
- $context : $total-columns,
62
- $from : $from-direction,
63
- $style : fix-static-misalignment()
64
- ) {
65
- $from : unquote($from);
66
- $to : opposite-position($from);
67
- margin-#{$to}: space($columns, $context, $style);
68
- }
69
-
70
- // Apply 'columns' before and/or after an element to contain it on a grid.
71
- //
72
- // $pre : The number of columns to add as margin before.
73
- // $post : The number of columns to add as margin after.
74
- // $context : [optional] The context (columns spanned by parent).
75
- // : Context is required on any nested elements.
76
- // : Context MUST NOT be declared on a root element.
77
- // $from : The start direction of your layout (e.g. 'left' for ltr languages)
78
- // $style : The container style to use.
79
- @mixin squish(
80
- $pre : false,
81
- $post : false,
82
- $context : $total-columns,
83
- $from : $from-direction,
84
- $style : fix-static-misalignment()
85
- ) {
86
- $from : unquote($from);
87
- @if $pre {
88
- @include pre($pre, $context, $from, $style)
89
- }
90
- @if $post {
91
- @include post($post, $context, $from, $style)
92
- }
93
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/Susy/stylesheets/susy/_media.scss DELETED
@@ -1,112 +0,0 @@
1
- // ---------------------------------------------------------------------------
2
- // Media Mixins
3
-
4
- // Create a new layout context for (@content) descendants.
5
- //
6
- // $layout-cols : a (unitless) number of columns to use for this layout.
7
- @mixin layout(
8
- $layout-cols
9
- ) {
10
- // store default $total-columns setting for later, then change it.
11
- $default-layout : $total-columns;
12
- $total-columns : $layout-cols;
13
-
14
- // apply children in this new layout context.
15
- @content;
16
-
17
- // return to default $total-columns setting.
18
- $total-columns : $default-layout;
19
- }
20
-
21
- // Nest a block of code inside a new media-query and layout context.
22
- //
23
- // $media-layout : a list of values [$min $layout $max $ie] including...
24
- // : - one unitless number (columns in a layout)
25
- // : - two optional lengths (min and max-width media-query breakpoints).
26
- // : - one optional boolean or string to trigger fallback support for IE.
27
- // $font-size : [optional] The base font-size of your layout, if you are using ems.
28
- // : - defaults to $base-font-size
29
- @mixin at-breakpoint(
30
- $media-layout,
31
- $font-size: $base-font-size
32
- ) {
33
- $media-layout : medialayout($media-layout,$font-size);
34
- $min : nth($media-layout,1);
35
- $layout : nth($media-layout,2);
36
- $max : nth($media-layout,3);
37
- $ie : nth($media-layout,4);
38
-
39
- @if (not $breakpoint-media-output) and (not $breakpoint-ie-output) and (not $breakpoint-raw-output) {
40
- @warn "Either $breakpoint-media-output, $breakpoint-ie-output, or $breakpoint-raw-output must be true for at-breakpoint to work.";
41
- }
42
-
43
- // We need to have either a min-width breakpoint or a layout in order to proceed.
44
- @if $min or $layout or $max {
45
-
46
- // If we don't have a layout, we create one based on the min-width.
47
- @if not $layout {
48
- $layout: get-layout($min);
49
- }
50
-
51
- // If we still don't have a layout, we have a problem.
52
- @if $layout {
53
- // Set our new layout context.
54
- @include layout($layout) {
55
- @if $breakpoint-media-output {
56
- // Capture current state of ie support and set new
57
- $atbreak-legacy-ie-matrix: capture-legacy-ie-matrix();
58
- @include set-legacy-ie-support;
59
-
60
- @if $min and $max {
61
- // Both $min and $max
62
- @media (min-width: $min) and (max-width: $max) {
63
- @content;
64
- }
65
- } @else {
66
- @if (not $min) and (not $max) {
67
- // Neither $min nor $max:
68
- // We can create a breakpoint based on the number of columns in the layout.
69
- $min: fix-ems(container-outer-width($width: false));
70
- }
71
- @if $min {
72
- // Min only:
73
- @media (min-width: $min) {
74
- @content;
75
- }
76
- } @else {
77
- // Max only:
78
- @media (max-width: $max) {
79
- @content;
80
- }
81
- }
82
- }
83
- // Return legacy-ie support to original
84
- @include set-legacy-ie-support($atbreak-legacy-ie-matrix...);
85
- }
86
- // Set an IE fallback
87
- @if $ie and $breakpoint-ie-output {
88
- @if (type-of($ie) == 'bool') {
89
- $ie: 'lt-ie9';
90
- }
91
- .#{$ie} & {
92
- $atbreak-experimental-matrix: capture-experimental-matrix();
93
- @include set-experimental-support($ms: true);
94
- @content;
95
- @include set-experimental-support($atbreak-experimental-matrix...);
96
- }
97
- }
98
-
99
- @if $breakpoint-raw-output {
100
- @content;
101
- }
102
- }
103
- } @else {
104
- @warn "Something went horribly wrong here. Try adjusting your variables.";
105
- }
106
-
107
- } @else {
108
- @warn "You need to provide either a valid layout (number of columns)
109
- or a valid media-query min-width breakpoint (length).";
110
- }
111
-
112
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/Susy/stylesheets/susy/_padding.scss DELETED
@@ -1,92 +0,0 @@
1
- // ---------------------------------------------------------------------------
2
- // Padding Mixins
3
-
4
- // add empty colums as padding before an element.
5
- // $columns : The number of columns to prefix.
6
- // $context : [optional] The context (columns spanned by parent).
7
- // : Context is required on any nested elements.
8
- // : Context MUST NOT be declared on a root element.
9
- // $from : The start direction of your layout (e.g. 'left' for ltr languages)
10
- // $style : The container style to use.
11
- @mixin prefix(
12
- $columns,
13
- $context : $total-columns,
14
- $from : $from-direction,
15
- $style : fix-static-misalignment()
16
- ) {
17
- $from : unquote($from);
18
- padding-#{$from}: space($columns, $context, $style);
19
- }
20
-
21
- // add empty colums as padding after an element.
22
- // $columns : The number of columns to suffix.
23
- // $context : [optional] The context (columns spanned by parent).
24
- // : Context is required on any nested elements.
25
- // : Context MUST NOT be declared on a root element.
26
- // $from : The start direction of your layout (e.g. 'left' for ltr languages)
27
- // $style : The container style to use.
28
- @mixin suffix(
29
- $columns,
30
- $context : $total-columns,
31
- $from : $from-direction,
32
- $style : fix-static-misalignment()
33
- ) {
34
- $from : unquote($from);
35
- $to : opposite-position($from);
36
- padding-#{$to}: space($columns, $context, $style);
37
- }
38
-
39
- // add empty colums as padding before and after an element.
40
- // $columns : The number of columns to pad.
41
- // $context : [optional] The context (columns spanned by parent).
42
- // : Context is required on any nested elements.
43
- // : Context MUST NOT be declared on a root element.
44
- // $from : The start direction of your layout (e.g. 'left' for ltr languages)
45
- // $style : The container style to use.
46
- @mixin pad(
47
- $prefix : false,
48
- $suffix : false,
49
- $context : $total-columns,
50
- $from : $from-direction,
51
- $style : fix-static-misalignment()
52
- ) {
53
- $from : unquote($from);
54
- @if $prefix {
55
- @include prefix($prefix, $context, $from, $style);
56
- }
57
- @if $suffix {
58
- @include suffix($suffix, $context, $from, $style);
59
- }
60
- }
61
-
62
- // Bleed into colums with margin/padding on any side of an element.
63
- // $width : The side of the bleed.
64
- // : Any unit-length will be used directly.
65
- // : Any unitless number will be used as a column-count.
66
- // : Use "2 of 6" format to represent 2 cals in a 6-col nested context.
67
- // $sides : One or more sides to bleed [ top | right | bottom | left | all ].
68
- // $style : The container style to use.
69
- @mixin bleed(
70
- $width: $grid-padding,
71
- $sides: left right,
72
- $style: fix-static-misalignment()
73
- ) {
74
- @if $border-box-sizing { @include box-sizing(content-box) }
75
-
76
- @if type-of($width) == 'list' {
77
- $width: filter($width, of);
78
- $width: space(nth($width,1), nth($width,2), $style);
79
- } @else if unitless($width) {
80
- $width: space($width, $style: $style);
81
- }
82
-
83
- @if $sides == 'all' {
84
- margin: - $width;
85
- padding: $width;
86
- } @else {
87
- @each $side in $sides {
88
- margin-#{$side}: - $width;
89
- padding-#{$side}: $width;
90
- }
91
- }
92
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/Susy/stylesheets/susy/_settings.scss DELETED
@@ -1,56 +0,0 @@
1
- // ---------------------------------------------------------------------------
2
- // Susy Settings
3
-
4
- // The total number of columns in the grid
5
- $total-columns : 12 !default;
6
-
7
- // The width of columns and gutters.
8
- // These must all be set with the comparable units.
9
- $column-width : 4em !default;
10
- $gutter-width : 1em !default;
11
-
12
- // Padding on the left and right of a Grid Container.
13
- $grid-padding : $gutter-width !default;
14
-
15
- // ---------------------------------------------------------------------------
16
- // Advanced Settings
17
-
18
- // From Direction:
19
- // Controls for right-to-left or bi-directional sites.
20
- $from-direction : left !default;
21
-
22
- // Omega Float Direction:
23
- // The direction that +omega elements are floated by deafult.
24
- $omega-float : opposite-position($from-direction) !default;
25
-
26
- // Container Width:
27
- // Override the total width of your grid, using any length (50em, 75%, etc.)
28
- $container-width : false !default;
29
-
30
- // Container Style:
31
- // 'magic' - Static (fixed or elastic) when there's enough space,
32
- // fluid when there isn't. This is the SUSY MAGIC SAUCE(TM).
33
- // 'static' - Forces the grid container to remain static at all times.
34
- // 'fluid' - Forces the grid to remain fluid at all times.
35
- // (this will overrule any static $container-width settings)
36
- $container-style : magic !default;
37
-
38
- // Border-Box Sizing
39
- // Adjust the grid math appropriately for box-sizing: border-box;
40
- // Warning: This does not actually apply the new box model!
41
- // In most cases you can ignore this setting,
42
- // and simply apply the border-box-sizing mixin.
43
- $border-box-sizing : false !default;
44
-
45
- // ---------------------------------------------------------------------------
46
- // IE Settings
47
-
48
- // When you are using a seperate IE stylesheet,
49
- // you can use these settings to control the output of at-breakpoint.
50
- // By default, at-breakpoint will output media-queries as well as
51
- // any defined ie-fallback classes.
52
- $breakpoint-media-output : true !default;
53
- $breakpoint-ie-output : true !default;
54
-
55
- // Danger Zone! Only set as 'true' in IE-specific style sheets.
56
- $breakpoint-raw-output : false !default;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/Susy/stylesheets/susy/_support.scss DELETED
@@ -1,198 +0,0 @@
1
- // @@@ These helpers only live here until they land in Compass.
2
-
3
- // ---------------------------------------------------------------------------
4
- // Imports
5
-
6
- @import "compass/support";
7
-
8
- // ---------------------------------------------------------------------------
9
- // Helpers
10
-
11
- // A debug tool for checking browser support
12
- @mixin debug-support-matrix($experimental: true, $ie: true) {
13
- @debug #{'$moz-'}$experimental-support-for-mozilla
14
- #{'$webkit-'}$experimental-support-for-webkit
15
- #{'$microsoft-'}$experimental-support-for-microsoft
16
- #{'$opera-'}$experimental-support-for-opera
17
- #{'$khtml-'}$experimental-support-for-khtml;
18
- @debug #{'$ie6-'}$legacy-support-for-ie6
19
- #{'$ie7-'}$legacy-support-for-ie7
20
- #{'$ie8-'}$legacy-support-for-ie8;
21
- }
22
-
23
- // Capture the current exerimental support settings
24
- @function capture-experimental-matrix() {
25
- @return $experimental-support-for-mozilla
26
- $experimental-support-for-webkit
27
- $experimental-support-for-microsoft
28
- $experimental-support-for-opera
29
- $experimental-support-for-khtml;
30
- }
31
-
32
- // Capture the current legacy-ie support settings
33
- @function capture-legacy-ie-matrix() {
34
- @return $legacy-support-for-ie6
35
- $legacy-support-for-ie7
36
- $legacy-support-for-ie8;
37
- }
38
-
39
- // Capture and store support
40
- $experimental-matrix: capture-experimental-matrix();
41
- $legacy-ie-matrix: capture-legacy-ie-matrix();
42
-
43
- @mixin capture-experimental-matrix {
44
- $experimental-matrix: capture-experimental-matrix();
45
- }
46
-
47
- @mixin capture-legacy-ie-matrix {
48
- $legacy-ie-matrix: capture-legacy-ie-matrix();
49
- }
50
-
51
- @mixin capture-support-matrix {
52
- @include capture-experimental-matrix;
53
- @include capture-legacy-ie-matrix;
54
- }
55
-
56
- // Change the experimental-support settings in specific contexts.
57
- @mixin set-experimental-support(
58
- $moz : false,
59
- $webkit : false,
60
- $ms : false,
61
- $o : false,
62
- $khtml : false
63
- ) {
64
- $experimental-support-for-mozilla : $moz;
65
- $experimental-support-for-webkit : $webkit;
66
- $experimental-support-for-microsoft : $ms;
67
- $experimental-support-for-opera : $o;
68
- $experimental-support-for-khtml : $khtml;
69
- }
70
-
71
- @mixin capture-and-set-experimental(
72
- $moz : false,
73
- $webkit : false,
74
- $ms : false,
75
- $o : false,
76
- $khtml : false
77
- ) {
78
- @include capture-experimental-matrix;
79
- @include set-experimental-support($moz, $webkit, $ms, $o, $khtml);
80
- }
81
-
82
- @mixin capture-and-adjust-experimental(
83
- $moz : $experimental-support-for-mozilla,
84
- $webkit : $experimental-support-for-webkit,
85
- $ms : $experimental-support-for-microsoft,
86
- $o : $experimental-support-for-opera,
87
- $khtml : $experimental-support-for-khtml
88
- ) {
89
- @include capture-experimental-matrix;
90
- @include set-experimental-support($moz, $webkit, $ms, $o, $khtml);
91
- }
92
-
93
- // Change the legacy-support-for-ie* settings in specific contexts.
94
- @mixin set-legacy-ie-support(
95
- $ie6: false,
96
- $ie7: false,
97
- $ie8: false
98
- ) {
99
- $legacy-support-for-ie6: $ie6;
100
- $legacy-support-for-ie7: $ie7;
101
- $legacy-support-for-ie8: $ie8;
102
- }
103
-
104
- @mixin capture-and-set-legacy-ie(
105
- $ie6: false,
106
- $ie7: false,
107
- $ie8: false
108
- ) {
109
- @include capture-legacy-ie-matrix;
110
- @include set-legacy-ie-support($ie6, $ie7, $ie8);
111
- }
112
-
113
- @mixin capture-and-adjust-legacy-ie(
114
- $ie6: $legacy-support-for-ie6,
115
- $ie7: $legacy-support-for-ie7,
116
- $ie8: $legacy-support-for-ie8
117
- ) {
118
- @include capture-and-set-legacy-ie($ie6, $ie7, $ie8);
119
- }
120
-
121
- // Capture current browser support matrix, and set a new matrix of support.
122
- @mixin capture-and-set-support(
123
- $moz : false,
124
- $webkit : false,
125
- $ms : false,
126
- $o : false,
127
- $khtml : false,
128
- $ie6 : false,
129
- $ie7 : false,
130
- $ie8 : false
131
- ) {
132
- // Capture the current state
133
- @include capture-support-matrix;
134
-
135
- // Change support settings
136
- @include set-experimental-support($moz, $webkit, $ms, $o, $khtml);
137
- @include set-legacy-ie-support($ie6, $ie7, $ie8);
138
- }
139
-
140
- // Capture current browser support matrix, and set a new matrix of support.
141
- @mixin capture-and-adjust-support(
142
- $moz : $experimental-support-for-mozilla,
143
- $webkit : $experimental-support-for-webkit,
144
- $ms : $experimental-support-for-microsoft,
145
- $o : $experimental-support-for-opera,
146
- $khtml : $experimental-support-for-khtml,
147
- $ie6 : $legacy-support-for-ie6,
148
- $ie7 : $legacy-support-for-ie7,
149
- $ie8 : $legacy-support-for-ie8
150
- ) {
151
- @include capture-and-set-support($moz, $webkit, $ms, $o, $khtml, $ie6, $ie7, $ie8);
152
- }
153
-
154
-
155
- // This mixin allows you to change the experimental support settings for
156
- // child (@content) styles.
157
- @mixin with-only-support-for(
158
- $moz : false,
159
- $webkit : false,
160
- $ms : false,
161
- $o : false,
162
- $khtml : false,
163
- $ie6 : false,
164
- $ie7 : false,
165
- $ie8 : false
166
- ) {
167
- // Capture current state
168
- $wo-experimental-matrix : capture-experimental-matrix();
169
- $wo-legacy-ie-matrix : capture-legacy-ie-matrix();
170
-
171
- // Set new states
172
- @include set-experimental-support($moz, $webkit, $ms, $o, $khtml);
173
- @include set-legacy-ie-support($ie6, $ie7, $ie8);
174
-
175
- // Apply styles
176
- @content;
177
-
178
- // Return to original support settings
179
- @include set-experimental-support($wo-experimental-matrix...);
180
- @include set-legacy-ie-support($wo-legacy-ie-matrix...);
181
- }
182
-
183
- // This mixin is a shortcut for making slight adjustments to browser support
184
- // for child (@content) styles
185
- @mixin adjust-support-for(
186
- $moz : $experimental-support-for-mozilla,
187
- $webkit : $experimental-support-for-webkit,
188
- $ms : $experimental-support-for-microsoft,
189
- $o : $experimental-support-for-opera,
190
- $khtml : $experimental-support-for-khtml,
191
- $ie6 : $legacy-support-for-ie6,
192
- $ie7 : $legacy-support-for-ie7,
193
- $ie8 : $legacy-support-for-ie8
194
- ) {
195
- @include with-only-support-for($moz, $webkit, $ms, $o, $khtml, $ie6, $ie7, $ie8) {
196
- @content;
197
- }
198
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/Susy/stylesheets/susy/_units.scss DELETED
@@ -1,159 +0,0 @@
1
- // @private Default font-size for all browsers
2
- $browser-default-font-size: 16px;
3
-
4
- // Base font size in pixels, if not already defined.
5
- // Should be the same as the font-size of the html element.
6
- $base-font-size: 16px !default;
7
-
8
- // Whether to output fallback values in px when outputting rems.
9
- $rem-with-px-fallback: true !default;
10
-
11
- // Convert any CSS <length> or <percentage> value to any another.
12
- //
13
- // @param $length
14
- // A css <length> or <percentage> value
15
- //
16
- // @param $to-unit
17
- // String matching a css unit keyword, e.g. 'em', '%', etc.
18
- //
19
- // @param $from-context
20
- // When converting from relative units, the absolute length (in px) to
21
- // which $length refers (e.g. for $lengths in em units, would normally be the
22
- // font-size of the current element).
23
- //
24
- // @param $to-context
25
- // For converting to relative units, the absolute length in px to which the
26
- // output value will refer. Defaults to the same as $from-context, since it is
27
- // rarely needed.
28
- @function convert-length(
29
- $length,
30
- $to-unit,
31
- $from-context: $base-font-size,
32
- $to-context: $from-context
33
- ) {
34
-
35
- $from-unit: unit($length);
36
-
37
- // Optimize for cases where `from` and `to` units are accidentally the same.
38
- @if $from-unit == $to-unit { @return $length; }
39
-
40
- // Context values must be in px so we can determine a conversion ratio for
41
- // relative units.
42
- @if unit($from-context) != 'px' { @warn "Paremeter $from-context must resolve to a value in pixel units."; }
43
- @if unit($to-context) != 'px' { @warn "Parameter $to-context must resolve to a value in pixel units."; }
44
-
45
- // Convert input length to pixels
46
- $px-length: $length;
47
-
48
- @if $from-unit != 'px' {
49
- // Convert relative units using the from-context parameter.
50
- @if $from-unit == 'em' { $px-length: $length * $from-context / 1em }
51
- @else if $from-unit == 'rem' { $px-length: $length * $base-font-size / 1rem }
52
- @else if $from-unit == '%' { $px-length: $length * $from-context / 100% }
53
- @else if $from-unit == 'ex' { $px-length: $length * $from-context / 2ex }
54
- // Convert absolute units using Sass' conversion table.
55
- @else if $from-unit == 'in' or
56
- $from-unit == 'mm' or
57
- $from-unit == 'cm' or
58
- $from-unit == 'pt' or
59
- $from-unit == 'pc' { $px-length: 0px + $length }
60
- // Certain units can't be converted.
61
- @else if $from-unit == 'ch' or
62
- $from-unit == 'vw' or
63
- $from-unit == 'vh' or
64
- $from-unit == 'vmin' {
65
- @warn "#{$from-unit} units can't be reliably converted; Returning original value.";
66
- @return $length;
67
- }
68
- @else {
69
- @warn "#{$from-unit} is an unknown length unit. Returning original value.";
70
- @return $length;
71
- }
72
- }
73
-
74
- // Convert length in pixels to the output unit
75
- $output-length: $px-length;
76
- @if $to-unit != 'px' {
77
- // Relative units
78
- @if $to-unit == 'em' { $output-length: $px-length * 1em / $to-context }
79
- @else if $to-unit == 'rem' { $output-length: $px-length * 1rem / $base-font-size }
80
- @else if $to-unit == '%' { $output-length: $px-length * 100% / $to-context }
81
- @else if $to-unit == 'ex' { $output-length: $px-length * 2ex / $to-context }
82
- // Absolute units
83
- @else if $to-unit == 'in' { $output-length: 0in + $px-length }
84
- @else if $to-unit == 'mm' { $output-length: 0mm + $px-length }
85
- @else if $to-unit == 'cm' { $output-length: 0cm + $px-length }
86
- @else if $to-unit == 'pt' { $output-length: 0pt + $px-length }
87
- @else if $to-unit == 'pc' { $output-length: 0pc + $px-length }
88
- // Non-convertible units
89
- @else if $to-unit == 'ch' or
90
- $to-unit == 'vw' or
91
- $to-unit == 'vh' or
92
- $to-unit == 'vmin' {
93
- @warn "#{$to-unit} units can't be reliably converted; Returning original value.";
94
- @return $length;
95
- }
96
- @else {
97
- @warn "#{$to-unit} is an unknown length unit. Returning original value.";
98
- @return $length;
99
- }
100
- }
101
-
102
- @return $output-length;
103
- }
104
-
105
-
106
- // Output a given style rule containing rem values along with an (optional)
107
- // fallback rule for older browsers (with rem values converted to px).
108
- //
109
- // @param $property
110
- // The css property name.
111
- //
112
- // @param $values
113
- // The value (or space-separated list of values) for the property.
114
- //
115
- // @param $use-px-fallback
116
- // [ true | false ]
117
- //
118
- @mixin rem($property, $values, $use-px-fallback: $rem-with-px-fallback) {
119
- // Create a couple of empty lists as output buffers.
120
- $px-values: ();
121
- $rem-values: ();
122
-
123
- // Loop through the $values list
124
- @each $value in $values {
125
- // For each property value, if it's in rem or px, derive both rem and
126
- // px values for it and add those to the end of the appropriate buffer.
127
- // Ensure all pixel values are rounded to the nearest pixel.
128
- @if type-of($value) == number and not unitless($value) and (unit($value) == px or unit($value) == rem) {
129
- @if unit($value) == px {
130
- $px-values: join($px-values, round($value));
131
- $rem-values: join($rem-values, convert-length($value, rem));
132
- }
133
- @else {
134
- $px-values: join($px-values, round(convert-length($value, px)));
135
- $rem-values: join($rem-values, $value);
136
- }
137
- }
138
- @else {
139
- $px-values: join($px-values, $value);
140
- $rem-values: join($rem-values, $value);
141
- }
142
- }
143
-
144
- // Use pixel fallback for browsers that don't understand rem units.
145
- @if $use-px-fallback {
146
- #{$property}: $px-values;
147
- }
148
-
149
- // Use rem values for everyone else (overrides pixel values).
150
- #{$property}: $rem-values;
151
- }
152
-
153
- @mixin if-rem($property, $values, $use-px-fallback: $rem-with-px-fallback) {
154
- $has-rem: false;
155
- @each $value in $values { $has-rem: if(unit($value) == 'rem', true, $has-rem); }
156
- @if $has-rem { @include rem($property, $values, $use-px-fallback); }
157
- @else { #{$property}: $values; }
158
- }
159
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/example.php DELETED
@@ -1,82 +0,0 @@
1
- <?php
2
- function loadCallback($file, $parser)
3
- {
4
- $paths = array();
5
- foreach ($parser->extensions as $extensionName) {
6
- $namespace = ucwords(preg_replace('/[^0-9a-z]+/', '_', strtolower($extensionName)));
7
- $extensionPath = './' . $namespace . '/' . $namespace . '.php';
8
- if (file_exists($extensionPath)) {
9
- require_once($extensionPath);
10
- $hook = $namespace . '::resolveExtensionPath';
11
- $returnPath = call_user_func($hook, $file, $parser);
12
- if (!empty($returnPath)) {
13
- $paths[] = $returnPath;
14
- }
15
-
16
- }
17
- }
18
-
19
- return $paths;
20
- }
21
-
22
- function getFunctions($extensions)
23
- {
24
- $output = array();
25
- if (!empty($extensions)) {
26
- foreach ($extensions as $extension) {
27
- $name = explode('/', $extension, 2);
28
- $namespace = ucwords(preg_replace('/[^0-9a-z]+/', '_', strtolower(array_shift($name))));
29
- $extensionPath = './' . $namespace . '/' . $namespace . '.php';
30
- if (file_exists(
31
- $extensionPath
32
- )
33
- ) {
34
- require_once($extensionPath);
35
- $namespace = $namespace . '::';
36
- $function = 'getFunctions';
37
- $output = array_merge($output, call_user_func($namespace . $function, $namespace));
38
- }
39
- }
40
- }
41
-
42
- return $output;
43
- }
44
-
45
- $file = 'example.scss';
46
- $path = '../';
47
- $library = $path . '/SassParser.php';
48
-
49
- if ($path && file_exists($library)) {
50
-
51
- try {
52
- require_once ($library);
53
-
54
- $options = array(
55
- 'style' => 'expanded',
56
- 'cache' => false,
57
- 'syntax' => 'scss',
58
- 'debug' => false,
59
- 'debug_info' => false,
60
- 'load_path_functions' => array('loadCallback'),
61
- 'load_paths' => array(dirname($file)),
62
- 'functions' => getFunctions(array('Compass','Own')),
63
- 'extensions' => array('Compass','Own')
64
- );
65
- // Execute the compiler.
66
- $parser = new SassParser($options);
67
- print $parser->toCss($file);
68
- } catch (Exception $e) {
69
- print "body::before {
70
- display: block;
71
- padding: 5px;
72
- white-space: pre;
73
- font-family: monospace;
74
- font-size: 8pt;
75
- line-height: 17px;
76
- overflow: hidden;
77
- content: '" . $e->getMessage() . "';
78
- }";
79
- }
80
- } else {
81
- echo 'Path or library are wrong';
82
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/example.scss DELETED
@@ -1,8 +0,0 @@
1
- @import "test";
2
- @import "compass/compass";
3
-
4
-
5
- body {
6
- content: demo-function();
7
- @include border-radius();
8
- }
 
 
 
 
 
 
 
 
lib/phpsass/Extensions/theme.scss DELETED
@@ -1 +0,0 @@
1
- $blue:#fff;
 
lib/phpsass/README.md DELETED
@@ -1,28 +0,0 @@
1
- #PHPSass [![build status](https://travis-ci.org/richthegeek/phpsass.png)](https://travis-ci.org/richthegeek/phpsass) [![GiTip donations gladly recieved](https://www.gittip.com/assets/8.0.15/logo.png)](https://www.gittip.com/richthegeek/)
2
-
3
- #IMPORTANT NOTICE
4
- We will soon be implementing PSR standards, and so compatibility requirements will move to PHP 5.3. A separate branch will be made for older versions, although it may not be updated.
5
-
6
- ## Try online
7
- You can compile and compare SCSS against the ruby compiler at <http://phpsass.com/try>
8
-
9
- ## About
10
- This is fork of phamlp primarily for inclusiong as a Drupal pre-processor.
11
- However, there is no Drupal-specific code and it will work for any PHP system.
12
-
13
- This version of the compiler is NOT compatible with other forks of PHamlP, and
14
- the name has been changed to reflect this. Please take a look at the "sassy"
15
- module on Drupal.org for information on how to add frameworks and custom
16
- functions. Docs will be coming when we aren't doing more important things.
17
-
18
- ## Contributors:
19
- * Richard Lyon - [@richthegeek](https://github.com/richthegeek)
20
- * Sebastian Siemssen - [@thefuhby](https://twitter.com/thefubhy)
21
- * Steve Jones - [@darthsteven](https://github.com/darthsteven)
22
- * Sam Richard - [@snugug](https://github.com/snugug)
23
-
24
- ## Other info
25
- Origin: <http://code.google.com/p/phamlp/>
26
-
27
- License: <http://www.opensource.org/licenses/bsd-license.php>
28
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/SassException.php DELETED
@@ -1,29 +0,0 @@
1
- <?php
2
- /* SVN FILE: $Id$ */
3
- /**
4
- * Sass exception.
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
10
- */
11
-
12
- /**
13
- * Sass exception class.
14
- * @package PHamlP
15
- * @subpackage Sass
16
- */
17
- class SassException extends Exception
18
- {
19
- /**
20
- * Sass Exception.
21
- * @param string Exception message
22
- * @param array parameters to be applied to the message using <code>strtr</code>.
23
- * @param object object with source code and meta data
24
- */
25
- public function __construct($message, $object)
26
- {
27
- parent::__construct($message . (is_object($object) ? ": {$object->filename}::{$object->line}\nSource: {$object->source}" : ''));
28
- }
29
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/SassFile.php DELETED
@@ -1,166 +0,0 @@
1
- <?php
2
- /* SVN FILE: $Id$ */
3
- /**
4
- * SassFile class file.
5
- * File handling utilites.
6
- * @author Chris Yates <chris.l.yates@gmail.com>
7
- * @copyright Copyright (c) 2010 PBM Web Development
8
- * @license http://phamlp.googlecode.com/files/license.txt
9
- * @package PHamlP
10
- * @subpackage Sass
11
- */
12
-
13
- /**
14
- * SassFile class.
15
- * @package PHamlP
16
- * @subpackage Sass
17
- */
18
- class SassFile
19
- {
20
- const CSS = 'css';
21
- const SASS = 'sass';
22
- const SCSS = 'scss';
23
- // const SASSC = 'sassc'; # tests for E_NOTICE
24
-
25
- private static $extensions = array(self::SASS, self::SCSS);
26
-
27
- public static $path = FALSE;
28
- public static $parser = FALSE;
29
-
30
- /**
31
- * Returns the parse tree for a file.
32
- * @param string filename to parse
33
- * @param SassParser Sass parser
34
- * @return SassRootNode
35
- */
36
- public static function get_tree($filename, &$parser)
37
- {
38
- $contents = self::get_file_contents($filename, $parser);
39
-
40
- $options = array_merge($parser->options, array('line'=>1));
41
-
42
- # attempt at cross-syntax imports.
43
- $ext = substr($filename, strrpos($filename, '.') + 1);
44
- if ($ext == self::SASS || $ext == self::SCSS) {
45
- $options['syntax'] = $ext;
46
- }
47
-
48
- $dirname = dirname($filename);
49
- $options['load_paths'][] = $dirname;
50
- if (!in_array($dirname, $parser->load_paths)) {
51
- $parser->load_paths[] = dirname($filename);
52
- }
53
-
54
- $sassParser = new SassParser($options);
55
- $tree = $sassParser->parse($contents, FALSE);
56
-
57
- return $tree;
58
- }
59
-
60
- public static function get_file_contents($filename, $parser)
61
- {
62
- $contents = file_get_contents($filename) . "\n\n "; #add some whitespace to fix bug
63
- # strip // comments at this stage, with allowances for http:// style locations.
64
- $contents = preg_replace("/(^|\s)\/\/[^\n]+/", '', $contents);
65
- // SassFile::$parser = $parser;
66
- // SassFile::$path = $filename;
67
- // $contents = preg_replace_callback('/url\(\s*[\'"]?(?![a-z]+:|\/+)([^\'")]+)[\'"]?\s*\)/i', 'SassFile::resolve_paths', $contents);
68
- return $contents;
69
- }
70
-
71
- public static function resolve_paths($matches)
72
- {
73
- // Resolve the path into something nicer...
74
- return 'url("' . self::resolve_path($matches[1]) . '")';
75
- }
76
-
77
- public static function resolve_path($name)
78
- {
79
- $path = self::$parser->basepath . self::$path;
80
- $path = substr($path, 0, strrpos($path, '/')) . '/';
81
- $path = $path . $name;
82
- $last = '';
83
- while ($path != $last) {
84
- $last = $path;
85
- $path = preg_replace('`(^|/)(?!\.\./)([^/]+)/\.\./`', '$1', $path);
86
- }
87
-
88
- return $path;
89
- }
90
-
91
- /**
92
- * Returns the full path to a file to parse.
93
- * The file is looked for recursively under the load_paths directories
94
- * If the filename does not end in .sass or .scss try the current syntax first
95
- * then, if a file is not found, try the other syntax.
96
- * @param string filename to find
97
- * @param SassParser Sass parser
98
- * @return array of string path(s) to file(s) or FALSE if no such file
99
- */
100
- public static function get_file($filename, &$parser, $sass_only = TRUE)
101
- {
102
- $ext = substr($filename, strrpos($filename, '.') + 1);
103
- // if the last char isn't *, and it's not (.sass|.scss|.css)
104
- if ($sass_only && substr($filename, -1) != '*' && $ext !== self::SASS && $ext !== self::SCSS && $ext !== self::CSS) {
105
- $sass = self::get_file($filename . '.' . self::SASS, $parser);
106
-
107
- return $sass ? $sass : self::get_file($filename . '.' . self::SCSS, $parser);
108
- }
109
- if (file_exists($filename)) {
110
- return array($filename);
111
- }
112
- $paths = $parser->load_paths;
113
- if (is_string($parser->filename) && $path = dirname($parser->filename)) {
114
- $paths[] = $path;
115
- if (!in_array($path, $parser->load_paths)) {
116
- $parser->load_paths[] = $path;
117
- }
118
- }
119
- foreach ($paths as $path) {
120
- $filepath = self::find_file($filename, realpath($path));
121
- if ($filepath !== false) {
122
- return array($filepath);
123
- }
124
- }
125
- foreach ($parser->load_path_functions as $function) {
126
- if (is_callable($function) && $paths = call_user_func($function, $filename, $parser)) {
127
- return $paths;
128
- }
129
- }
130
-
131
- return FALSE;
132
- }
133
-
134
- /**
135
- * Looks for the file recursively in the specified directory.
136
- * This will also look for _filename to handle Sass partials.
137
- * @param string filename to look for
138
- * @param string path to directory to look in and under
139
- * @return mixed string: full path to file if found, false if not
140
- */
141
- public static function find_file($filename, $dir)
142
- {
143
- $partialname = dirname($filename).DIRECTORY_SEPARATOR.'_'.basename($filename);
144
-
145
- foreach (array($filename, $partialname) as $file) {
146
- if (file_exists($dir . DIRECTORY_SEPARATOR . $file)) {
147
- return realpath($dir . DIRECTORY_SEPARATOR . $file);
148
- }
149
- }
150
-
151
- if (is_dir($dir)) {
152
- $files = array_slice(scandir($dir), 2);
153
-
154
- foreach ($files as $file) {
155
- if (substr($file, 0, 1) != '.' && is_dir($dir . DIRECTORY_SEPARATOR . $file)) {
156
- $path = self::find_file($filename, $dir . DIRECTORY_SEPARATOR . $file);
157
- if ($path !== false) {
158
- return $path;
159
- }
160
- }
161
- }
162
- }
163
-
164
- return false;
165
- }
166
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/SassParser.php DELETED
@@ -1,890 +0,0 @@
1
- <?php
2
-
3
- /* SVN FILE: $Id$ */
4
- /**
5
- * SassParser class file.
6
- * See the {@link http://sass-lang.com/docs Sass documentation}
7
- * for details of Sass.
8
- *
9
- * Credits:
10
- * This is a port of Sass to PHP. All the genius comes from the people that
11
- * invented and develop Sass; in particular:
12
- * + {@link http://hamptoncatlin.com/ Hampton Catlin},
13
- * + {@link http://nex-3.com/ Nathan Weizenbaum},
14
- * + {@link http://chriseppstein.github.com/ Chris Eppstein}
15
- *
16
- * The bugs are mine. Please report any found at {@link http://code.google.com/p/phamlp/issues/list}
17
- *
18
- * @author Chris Yates <chris.l.yates@gmail.com>
19
- * @copyright Copyright (c) 2010 PBM Web Development
20
- * @license http://phamlp.googlecode.com/files/license.txt
21
- * @package PHamlP
22
- * @subpackage Sass
23
- */
24
-
25
- require_once 'SassFile.php';
26
- require_once 'SassException.php';
27
- require_once 'tree/SassNode.php';
28
-
29
- /**
30
- * SassParser class.
31
- * Parses {@link http://sass-lang.com/ .sass and .sccs} files.
32
- * @package PHamlP
33
- * @subpackage Sass
34
- */
35
- class SassParser
36
- {
37
- /**#@+
38
- * Default option values
39
- */
40
- const BEGIN_COMMENT = '/';
41
- const BEGIN_CSS_COMMENT = '/*';
42
- const END_CSS_COMMENT = '*/';
43
- const BEGIN_SASS_COMMENT = '//';
44
- const BEGIN_INTERPOLATION = '#';
45
- const BEGIN_INTERPOLATION_BLOCK = '#{';
46
- const BEGIN_BLOCK = '{';
47
- const END_BLOCK = '}';
48
- const END_STATEMENT = ';';
49
- const DOUBLE_QUOTE = '"';
50
- const SINGLE_QUOTE = "'";
51
-
52
- /**
53
- * Static holder for last instance of a SassParser
54
- */
55
- public static $instance;
56
-
57
- /**
58
- * @var string the character used for indenting
59
- * @see indentChars
60
- * @see indentSpaces
61
- */
62
- public $indentChar;
63
- /**
64
- * @var array allowable characters for indenting
65
- */
66
- public $indentChars = array(' ', "\t");
67
- /**
68
- * @var integer number of spaces for indentation.
69
- * Used to calculate {@link Level} if {@link indentChar} is space.
70
- */
71
- public $indentSpaces = 2;
72
-
73
- /**
74
- * @var string source
75
- */
76
- public $source;
77
-
78
- /**#@+
79
- * Option
80
- */
81
-
82
- public $basepath;
83
-
84
- /**
85
- * debug_info:
86
- * @var boolean When true the line number and file where a selector is defined
87
- * is emitted into the compiled CSS in a format that can be understood by the
88
- * {@link https://addons.mozilla.org/en-US/firefox/addon/103988/
89
- * FireSass Firebug extension}.
90
- * Disabled when using the compressed output style.
91
- *
92
- * Defaults to false.
93
- * @see style
94
- */
95
- public $debug_info;
96
-
97
- /**
98
- * filename:
99
- * @var string The filename of the file being rendered.
100
- * This is used solely for reporting errors.
101
- */
102
- public $filename;
103
-
104
- /**
105
- * function:
106
- * @var An array of (function_name => callback) items.
107
- */
108
- public static $functions;
109
-
110
- /**
111
- * line:
112
- * @var integer The number of the first line of the Sass template. Used for
113
- * reporting line numbers for errors. This is useful to set if the Sass
114
- * template is embedded.
115
- *
116
- * Defaults to 1.
117
- */
118
- public $line;
119
-
120
- /**
121
- * line_numbers:
122
- * @var boolean When true the line number and filename where a selector is
123
- * defined is emitted into the compiled CSS as a comment. Useful for debugging
124
- * especially when using imports and mixins.
125
- * Disabled when using the compressed output style or the debug_info option.
126
- *
127
- * Defaults to false.
128
- * @see debug_info
129
- * @see style
130
- */
131
- public $line_numbers;
132
-
133
- /**
134
- * load_paths:
135
- * @var array An array of filesystem paths which should be searched for
136
- * Sass templates imported with the @import directive.
137
- *
138
- * Defaults to './sass-templates'.
139
- */
140
- public $load_paths;
141
- public $load_path_functions;
142
-
143
- /**
144
- * property_syntax:
145
- * @var string Forces the document to use one syntax for
146
- * properties. If the correct syntax isn't used, an error is thrown.
147
- * Value can be:
148
- * + new - forces the use of a colon or equals sign after the property name.
149
- * For example color: #0f3 or width: $main_width.
150
- * + old - forces the use of a colon before the property name.
151
- * For example: :color #0f3 or :width = $main_width.
152
- *
153
- * By default, either syntax is valid.
154
- *
155
- * Ignored for SCSS files which alaways use the new style.
156
- */
157
- public $property_syntax;
158
-
159
- /**
160
- * quiet:
161
- * @var boolean When set to true, causes warnings to be disabled.
162
- * Defaults to false.
163
- */
164
- public $quiet;
165
-
166
- /**
167
- * callbacks:
168
- * @var array listing callbacks for @warn and @debug directives.
169
- * Callbacks are executed by call_user_func and thus must conform
170
- * to that standard.
171
- */
172
- public $callbacks;
173
-
174
- /**
175
- * style:
176
- * @var string the style of the CSS output.
177
- * Value can be:
178
- * + nested - Nested is the default Sass style, because it reflects the
179
- * structure of the document in much the same way Sass does. Each selector
180
- * and rule has its own line with indentation is based on how deeply the rule
181
- * is nested. Nested style is very useful when looking at large CSS files as
182
- * it allows you to very easily grasp the structure of the file without
183
- * actually reading anything.
184
- * + expanded - Expanded is the typical human-made CSS style, with each selector
185
- * and property taking up one line. Selectors are not indented; properties are
186
- * indented within the rules.
187
- * + compact - Each CSS rule takes up only one line, with every property defined
188
- * on that line. Nested rules are placed with each other while groups of rules
189
- * are separated by a blank line.
190
- * + compressed - Compressed has no whitespace except that necessary to separate
191
- * selectors and properties. It's not meant to be human-readable.
192
- *
193
- * Defaults to 'nested'.
194
- */
195
- public $style;
196
-
197
- /**
198
- * syntax:
199
- * @var string The syntax of the input file.
200
- * 'sass' for the indented syntax and 'scss' for the CSS-extension syntax.
201
- *
202
- * This is set automatically when parsing a file, else defaults to 'sass'.
203
- */
204
- public $syntax;
205
-
206
- /**
207
- * debug:
208
- * If enabled it causes exceptions to be thrown on errors. This can be
209
- * useful for tracking down a bug in your sourcefile but will cause a
210
- * site to break if used in production unless the parser in wrapped in
211
- * a try/catch structure.
212
- *
213
- * Defaults to FALSE
214
- */
215
- public $debug = FALSE;
216
-
217
- /**
218
- * Constructor.
219
- * Sets parser options
220
- * @param array $options
221
- * @return SassParser
222
- */
223
- public function __construct($options = array())
224
- {
225
- if (!is_array($options)) {
226
- if (isset($options['debug']) && $options['debug']) {
227
- throw new SassException('Options must be an array');
228
- }
229
- $options = count((array) $options) ? (array) $options : array();
230
- }
231
- unset($options['language']);
232
-
233
- $basepath = $_SERVER['PHP_SELF'];
234
- $basepath = substr($basepath, 0, strrpos($basepath, '/') + 1);
235
-
236
- $defaultOptions = array(
237
- 'basepath' => $basepath,
238
- 'debug_info' => FALSE,
239
- 'filename' => array('dirname' => '', 'basename' => ''),
240
- 'functions' => array(),
241
- 'load_paths' => array(),
242
- 'load_path_functions' => array(),
243
- 'line' => 1,
244
- 'line_numbers' => FALSE,
245
- 'style' => SassRenderer::STYLE_NESTED,
246
- 'syntax' => SassFile::SASS,
247
- 'debug' => FALSE,
248
- 'quiet' => FALSE,
249
- 'callbacks' => array(
250
- 'warn' => FALSE,
251
- 'debug' => FALSE,
252
- ),
253
- );
254
-
255
- if (isset(self::$instance)) {
256
- $defaultOptions['load_paths'] = self::$instance->load_paths;
257
- }
258
-
259
- $options = array_merge($defaultOptions, $options);
260
-
261
- // We don't want to allow setting of internal only property syntax value
262
- if (isset($options["property_syntax"]) && $options["property_syntax"] == "scss") {
263
- unset($options["property_syntax"]);
264
- }
265
-
266
- self::$instance = $this;
267
- self::$functions = $options['functions'];
268
- unset($options['functions']);
269
-
270
- foreach ($options as $name=>$value) {
271
- $this->$name = $value;
272
- }
273
-
274
- if (!$this->property_syntax && $this->syntax == SassFile::SCSS) {
275
- $this->property_syntax = "scss";
276
- }
277
-
278
- $GLOBALS['SassParser_debug'] = $this->debug;
279
- }
280
-
281
- /**
282
- * Getter.
283
- * @param string name of property to get
284
- * @return mixed return value of getter function
285
- */
286
- public function __get($name)
287
- {
288
- $getter = 'get' . ucfirst($name);
289
- if (method_exists($this, $getter)) {
290
- return $this->$getter();
291
- }
292
- if (property_exists($this, $name)) {
293
- return $this->$name;
294
- }
295
- if ($this->debug) {
296
- throw new SassException('No getter function for ' . $name);
297
- }
298
- }
299
-
300
- public function getBasepath()
301
- {
302
- return $this->basepath;
303
- }
304
-
305
- public function getDebug_info()
306
- {
307
- return $this->debug_info;
308
- }
309
-
310
- public function getFilename()
311
- {
312
- return $this->filename;
313
- }
314
-
315
- public function getLine()
316
- {
317
- return $this->line;
318
- }
319
-
320
- public function getSource()
321
- {
322
- return $this->source;
323
- }
324
-
325
- public function getLine_numbers()
326
- {
327
- return $this->line_numbers;
328
- }
329
-
330
- public function getFunctions()
331
- {
332
- return self::$functions;
333
- }
334
-
335
- public function getLoad_paths()
336
- {
337
- return $this->load_paths;
338
- }
339
-
340
- public function getLoad_path_functions()
341
- {
342
- return $this->load_path_functions;
343
- }
344
-
345
- public function getProperty_syntax()
346
- {
347
- return $this->property_syntax;
348
- }
349
-
350
- public function getQuiet()
351
- {
352
- return $this->quiet;
353
- }
354
-
355
- public function getStyle()
356
- {
357
- return $this->style;
358
- }
359
-
360
- public function getSyntax()
361
- {
362
- return $this->syntax;
363
- }
364
-
365
- public function getDebug()
366
- {
367
- return $this->debug;
368
- }
369
-
370
- public function getCallbacks()
371
- {
372
- return $this->callbacks + array(
373
- 'warn' => NULL,
374
- 'debug' => NULL,
375
- );
376
- }
377
-
378
- public function getOptions()
379
- {
380
- return array(
381
- 'callbacks' => $this->callbacks,
382
- // 'debug' => $this->debug,
383
- 'filename' => $this->filename,
384
- 'functions' => $this->functions,
385
- 'line' => $this->line,
386
- 'line_numbers' => $this->line_numbers,
387
- 'load_path_functions' => $this->load_path_functions,
388
- 'load_paths' => $this->load_paths,
389
- 'property_syntax' => ($this->property_syntax == "scss" ? null : $this->property_syntax),
390
- 'quiet' => $this->quiet,
391
- 'style' => $this->style,
392
- 'syntax' => $this->syntax,
393
- );
394
- }
395
-
396
- /**
397
- * Parse a sass file or Sass source code and returns the CSS.
398
- * @param string name of source file or Sass source
399
- * @return string CSS
400
- */
401
- public function toCss($source, $isFile = true)
402
- {
403
- return $this->parse($source, $isFile)->render();
404
- }
405
-
406
- /**
407
- * Parse a sass file or Sass source code and
408
- * returns the document tree that can then be rendered.
409
- * The file will be searched for in the directories specified by the
410
- * load_paths option.
411
- * @param string name of source file or Sass source
412
- * @return SassRootNode Root node of document tree
413
- */
414
- public function parse($source, $isFile = true)
415
- {
416
- # Richard Lyon - 2011-10-25 - ignore unfound files
417
- # Richard Lyon - 2011-10-25 - add multiple files to load functions
418
- if (!$source) {
419
- return $this->toTree($source);
420
- }
421
-
422
- if (is_array($source)) {
423
- $return = null;
424
- foreach ($source as $key => $value) {
425
- if (is_numeric($key)) {
426
- $code = $value;
427
- $type = true;
428
- } else {
429
- $code = $key;
430
- $type = $value;
431
- }
432
- if ($return===null) {
433
- $return = $this->parse($code, $type);
434
- } else {
435
- $newNode = $this->parse($code, $type);
436
- foreach ($newNode->children as $children) {
437
- array_push($return->children, $children);
438
- }
439
- }
440
- }
441
-
442
- return $return;
443
- }
444
-
445
- if ($isFile && $files = SassFile::get_file($source, $this)) {
446
- $files_source = '';
447
- foreach ($files as $file) {
448
- $this->filename = $file;
449
- $this->syntax = substr(strrchr($file, '.'), 1);
450
- if ($this->syntax == SassFile::CSS) {
451
- $this->property_syntax = "css";
452
- } elseif (!$this->property_syntax && $this->syntax == SassFile::SCSS) {
453
- $this->property_syntax = "scss";
454
- }
455
-
456
- if ($this->syntax !== SassFile::SASS && $this->syntax !== SassFile::SCSS && $this->syntax !== SassFile::CSS) {
457
- if ($this->debug) {
458
- throw new SassException('Invalid {what}', array('{what}' => 'syntax option'));
459
- }
460
-
461
- return FALSE;
462
- }
463
- $files_source .= SassFile::get_file_contents($this->filename, $this);
464
- }
465
-
466
- return $this->toTree($files_source);
467
- } else {
468
- return $this->toTree($source);
469
- }
470
- }
471
-
472
- /**
473
- * Parse Sass source into a document tree.
474
- * If the tree is already created return that.
475
- * @param string Sass source
476
- * @return SassRootNode the root of this document tree
477
- */
478
- public function toTree($source)
479
- {
480
- if ($this->syntax === SassFile::SASS) {
481
- $source = str_replace(array("\r\n", "\n\r", "\r"), "\n", $source);
482
- $this->source = explode("\n", $source);
483
- $this->setIndentChar();
484
- } else {
485
- $this->source = $source;
486
- }
487
- unset($source);
488
- $root = new SassRootNode($this);
489
- $this->buildTree($root);
490
-
491
- return $root;
492
- }
493
-
494
- /**
495
- * Builds a parse tree under the parent node.
496
- * Called recursivly until the source is parsed.
497
- * @param SassNode the node
498
- */
499
- public function buildTree($parent)
500
- {
501
- $node = $this->getNode($parent);
502
- while (is_object($node) && $node->isChildOf($parent)) {
503
- $parent->addChild($node);
504
- $node = $this->buildTree($node);
505
- }
506
-
507
- return $node;
508
- }
509
-
510
- /**
511
- * Creates and returns the next SassNode.
512
- * The tpye of SassNode depends on the content of the SassToken.
513
- * @return SassNode a SassNode of the appropriate type. Null when no more
514
- * source to parse.
515
- */
516
- public function getNode($node)
517
- {
518
- $token = $this->getToken();
519
- if (empty($token)) return null;
520
- switch (true) {
521
- case SassDirectiveNode::isa($token):
522
- return $this->parseDirective($token, $node);
523
- case SassCommentNode::isa($token):
524
- return new SassCommentNode($token);
525
- case SassVariableNode::isa($token):
526
- return new SassVariableNode($token);
527
- case SassPropertyNode::isa(array('token' => $token, 'syntax' => $this->property_syntax)):
528
- return new SassPropertyNode($token, $this->property_syntax);
529
- case SassFunctionDefinitionNode::isa($token):
530
- return new SassFunctionDefinitionNode($token);
531
- case SassMixinDefinitionNode::isa($token):
532
- if ($this->syntax === SassFile::SCSS) {
533
- if ($this->debug) {
534
- throw new SassException('Mixin definition shortcut not allowed in SCSS', $this);
535
- }
536
-
537
- return;
538
- } else {
539
- return new SassMixinDefinitionNode($token);
540
- }
541
- case SassMixinNode::isa($token):
542
- if ($this->syntax === SassFile::SCSS) {
543
- if ($this->debug) {
544
- throw new SassException('Mixin include shortcut not allowed in SCSS', $this);
545
- }
546
-
547
- return;
548
- } else {
549
- return new SassMixinNode($token);
550
- }
551
- default:
552
- return new SassRuleNode($token);
553
- break;
554
- } // switch
555
- }
556
-
557
- /**
558
- * Returns a token object that contains the next source statement and
559
- * meta data about it.
560
- * @return object
561
- */
562
- public function getToken()
563
- {
564
- return ($this->syntax === SassFile::SASS ? $this->sass2Token() : $this->scss2Token());
565
- }
566
-
567
- /**
568
- * Returns an object that contains the next source statement and meta data
569
- * about it from SASS source.
570
- * Sass statements are passed over. Statements spanning multiple lines, e.g.
571
- * CSS comments and selectors, are assembled into a single statement.
572
- * @return object Statement token. Null if end of source.
573
- */
574
- public function sass2Token()
575
- {
576
- $statement = ''; // source line being tokenised
577
- $token = null;
578
-
579
- while (is_null($token) && !empty($this->source)) {
580
- while (empty($statement) && is_array($this->source) && !empty($this->source)) {
581
- $source = array_shift($this->source);
582
- $statement = trim($source);
583
- $this->line++;
584
- }
585
-
586
- if (empty($statement)) {
587
- break;
588
- }
589
-
590
- $level = $this->getLevel($source);
591
-
592
- // Comment statements can span multiple lines
593
- if ($statement[0] === self::BEGIN_COMMENT) {
594
- // Consume Sass comments
595
- if (substr($statement, 0, strlen(self::BEGIN_SASS_COMMENT)) === self::BEGIN_SASS_COMMENT) {
596
- unset($statement);
597
- while ($this->getLevel($this->source[0]) > $level) {
598
- array_shift($this->source);
599
- $this->line++;
600
- }
601
- continue;
602
- }
603
- // Build CSS comments
604
- elseif (substr($statement, 0, strlen(self::BEGIN_CSS_COMMENT))
605
- === self::BEGIN_CSS_COMMENT) {
606
- while ($this->getLevel($this->source[0]) > $level) {
607
- $statement .= "\n" . ltrim(array_shift($this->source));
608
- $this->line++;
609
- }
610
- } else {
611
- $this->source = $statement;
612
-
613
- if ($this->debug) {
614
- throw new SassException('Illegal comment type', $this);
615
- }
616
- }
617
- }
618
- // Selector statements can span multiple lines
619
- elseif (substr($statement, -1) === SassRuleNode::CONTINUED) {
620
- // Build the selector statement
621
- while ($this->getLevel($this->source[0]) === $level) {
622
- $statement .= ltrim(array_shift($this->source));
623
- $this->line++;
624
- }
625
- }
626
-
627
- $token = (object) array(
628
- 'source' => $statement,
629
- 'level' => $level,
630
- 'filename' => $this->filename,
631
- 'line' => $this->line - 1,
632
- );
633
- }
634
-
635
- return $token;
636
- }
637
-
638
- /**
639
- * Returns the level of the line.
640
- * Used for .sass source
641
- * @param string the source
642
- * @return integer the level of the source
643
- * @throws Exception if the source indentation is invalid
644
- */
645
- public function getLevel($source)
646
- {
647
- $indent = strlen($source) - strlen(ltrim($source));
648
- $level = $indent/$this->indentSpaces;
649
- if (is_float($level)) {
650
- $level = (int) ceil($level);
651
- }
652
- if (!is_int($level) || preg_match("/[^{$this->indentChar}]/", substr($source, 0, $indent))) {
653
- $this->source = $source;
654
-
655
- if ($this->debug) {
656
- throw new SassException('Invalid indentation', $this);
657
- } else {
658
- return 0;
659
- }
660
- }
661
-
662
- return $level;
663
- }
664
-
665
- /**
666
- * Returns an object that contains the next source statement and meta data
667
- * about it from SCSS source.
668
- * @return object Statement token. Null if end of source.
669
- */
670
- public function scss2Token()
671
- {
672
- static $srcpos = 0; // current position in the source stream
673
- static $srclen; // the length of the source stream
674
-
675
- $statement = '';
676
- $token = null;
677
- if (empty($srclen)) {
678
- $srclen = strlen($this->source);
679
- }
680
- while (is_null($token) && $srcpos < strlen($this->source)) {
681
- $c = $this->source[$srcpos++];
682
- switch ($c) {
683
- case self::BEGIN_COMMENT:
684
- if (substr($this->source, $srcpos-1, strlen(self::BEGIN_SASS_COMMENT)) === self::BEGIN_SASS_COMMENT) {
685
- while ($this->source[$srcpos++] !== "\n") {
686
- if ($srcpos >= $srclen)
687
- throw new SassException('Unterminated commend', (object) array(
688
- 'source' => $statement,
689
- 'filename' => $this->filename,
690
- 'line' => $this->line,
691
- ));
692
- }
693
- $statement .= "\n";
694
- } elseif (substr($this->source, $srcpos-1, strlen(self::BEGIN_CSS_COMMENT)) === self::BEGIN_CSS_COMMENT) {
695
- if (ltrim($statement)) {
696
- if ($this->debug) {
697
- throw new SassException('Invalid comment', (object) array(
698
- 'source' => $statement,
699
- 'filename' => $this->filename,
700
- 'line' => $this->line,
701
- ));
702
- }
703
- }
704
- $statement .= $c.$this->source[$srcpos++];
705
- while (substr($this->source, $srcpos, strlen(self::END_CSS_COMMENT)) !== self::END_CSS_COMMENT) {
706
- $statement .= $this->source[$srcpos++];
707
- }
708
- $srcpos += strlen(self::END_CSS_COMMENT);
709
- $token = $this->createToken($statement.self::END_CSS_COMMENT);
710
- } else {
711
- $statement .= $c;
712
- }
713
- break;
714
- case self::DOUBLE_QUOTE:
715
- case self::SINGLE_QUOTE:
716
- $statement .= $c;
717
- while (isset($this->source[$srcpos]) && $this->source[$srcpos] !== $c) {
718
- $statement .= $this->source[$srcpos++];
719
- }
720
- if (isset($this->source[$srcpos+1])) {
721
- $statement .= $this->source[$srcpos++];
722
- }
723
- break;
724
- case self::BEGIN_INTERPOLATION:
725
- $statement .= $c;
726
- if (substr($this->source, $srcpos-1, strlen(self::BEGIN_INTERPOLATION_BLOCK)) === self::BEGIN_INTERPOLATION_BLOCK) {
727
- while ($this->source[$srcpos] !== self::END_BLOCK) {
728
- $statement .= $this->source[$srcpos++];
729
- }
730
- $statement .= $this->source[$srcpos++];
731
- }
732
- break;
733
- case self::BEGIN_BLOCK:
734
- case self::END_BLOCK:
735
- case self::END_STATEMENT:
736
- $token = $this->createToken($statement . $c);
737
- if (is_null($token)) {
738
- $statement = '';
739
- }
740
- break;
741
- default:
742
- $statement .= $c;
743
- break;
744
- }
745
- }
746
-
747
- if (is_null($token)) {
748
- $srclen = $srcpos = 0;
749
- }
750
-
751
- return $token;
752
- }
753
-
754
- /**
755
- * Returns an object that contains the source statement and meta data about
756
- * it.
757
- * If the statement is just and end block we update the meta data and return null.
758
- * @param string source statement
759
- * @return SassToken
760
- */
761
- public function createToken($statement)
762
- {
763
- static $level = 0;
764
-
765
- $this->line += substr_count($statement, "\n");
766
- $statement = trim($statement);
767
- if (substr($statement, 0, strlen(self::BEGIN_CSS_COMMENT)) !== self::BEGIN_CSS_COMMENT) {
768
- $statement = str_replace(array("\n","\r"), '', $statement);
769
- }
770
- $last = substr($statement, -1);
771
- // Trim the statement removing whitespace, end statement (;), begin block ({), and (unless the statement ends in an interpolation block) end block (})
772
- $statement = rtrim($statement, ' '.self::BEGIN_BLOCK.self::END_STATEMENT);
773
- $statement = (preg_match('/#\{.+?\}$/i', $statement) ? $statement : rtrim($statement, self::END_BLOCK));
774
- $token = ($statement ? (object) array(
775
- 'source' => $statement,
776
- 'level' => $level,
777
- 'filename' => $this->filename,
778
- 'line' => $this->line,
779
- ) : null);
780
- $level += ($last === self::BEGIN_BLOCK ? 1 : ($last === self::END_BLOCK ? -1 : 0));
781
-
782
- return $token;
783
- }
784
-
785
- /**
786
- * Parses a directive
787
- * @param SassToken token to parse
788
- * @param SassNode parent node
789
- * @return SassNode a Sass directive node
790
- */
791
- public function parseDirective($token, $parent)
792
- {
793
- switch (SassDirectiveNode::extractDirective($token)) {
794
- case '@content':
795
- return new SassContentNode($token);
796
- break;
797
- case '@extend':
798
- return new SassExtendNode($token);
799
- break;
800
- case '@function':
801
- return new SassFunctionDefinitionNode($token);
802
- break;
803
- case '@return':
804
- return new SassReturnNode($token);
805
- break;
806
- case '@media':
807
- return new SassMediaNode($token);
808
- break;
809
- case '@mixin':
810
- return new SassMixinDefinitionNode($token);
811
- break;
812
- case '@include':
813
- return new SassMixinNode($token);
814
- break;
815
- case '@import':
816
- if ($this->syntax == SassFile::SASS) {
817
- $i = 0;
818
- $source = '';
819
- while (sizeof($this->source) > $i && empty($source) && isset($this->source[$i + 1])) {
820
- $source = $this->source[$i++];
821
- }
822
- if (!empty($source) && $this->getLevel($source) > $token->level) {
823
- if ($this->debug) {
824
- throw new SassException('Nesting not allowed beneath @import directive', $token);
825
- }
826
- }
827
- }
828
-
829
- return new SassImportNode($token, $parent);
830
- break;
831
- case '@each':
832
- return new SassEachNode($token);
833
- break;
834
- case '@for':
835
- return new SassForNode($token);
836
- break;
837
- case '@if':
838
- return new SassIfNode($token);
839
- break;
840
- case '@else': // handles else and else if directives
841
-
842
- return new SassElseNode($token);
843
- break;
844
- case '@do':
845
- case '@while':
846
- return new SassWhileNode($token);
847
- break;
848
- case '@warn':
849
- return new SassWarnNode($token);
850
- break;
851
- case '@debug':
852
- return new SassDebugNode($token);
853
- break;
854
- default:
855
- return new SassDirectiveNode($token);
856
- break;
857
- }
858
- }
859
-
860
- /**
861
- * Determine the indent character and indent spaces.
862
- * The first character of the first indented line determines the character.
863
- * If this is a space the number of spaces determines the indentSpaces; this
864
- * is always 1 if the indent character is a tab.
865
- * Only used for .sass files.
866
- * @throws SassException if the indent is mixed or
867
- * the indent character can not be determined
868
- */
869
- public function setIndentChar()
870
- {
871
- foreach ($this->source as $l=>$source) {
872
- if (!empty($source) && in_array($source[0], $this->indentChars)) {
873
- $this->indentChar = $source[0];
874
- for ($i = 0, $len = strlen($source); $i < $len && $source[$i] == $this->indentChar; $i++);
875
- if ($i < $len && in_array($source[$i], $this->indentChars)) {
876
- $this->line = ++$l;
877
- $this->source = $source;
878
- if ($this->debug) {
879
- throw new SassException('Mixed indentation not allowed', $this);
880
- }
881
- }
882
- $this->indentSpaces = ($this->indentChar == ' ' ? $i : 1);
883
-
884
- return;
885
- }
886
- } // foreach
887
- $this->indentChar = ' ';
888
- $this->indentSpaces = 2;
889
- }
890
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/VERSION DELETED
@@ -1,23 +0,0 @@
1
- Version 201206271500 - Verbump, merge pr #119
2
- Version 201206181400 - Run PHP-CS-Fixer on all files to fix coding style
3
- Version 201306071300 - Version bump to reflect multiple merged pull requests
4
- Version 201304222300 - Version bump to reflect multiple merged pull requests
5
- Version 201211282000 - Version bump to reflect multiple pull requests being merged over time.
6
- Version 201209040040 - Fixed a bunch of issues
7
- Version 201209031740 - Almost up to 3.2.1; Directive interp, splats, new functions, some fixes
8
- Version 201207301030 - Fix to issue 28, extending from included files
9
- Version 201207271000 - Fixed scale-color function (attrib: Steve Jones)
10
- Version 201207262300 - Various issue fixes, better testing framework
11
- Version 201206291700 - Fixed some tests, minor changes to string and import handling
12
- Version 201203071100 - Hotfix to functions, overhauled evaluation method to be less rubbish
13
- Version 201203061130 - Added min/max functions, fix to lists (evaluation instead of just lexing of values)
14
- Version 201203042100 - Fixes to interpolation in selectors, test coverage, and some cleanup
15
- Version 201203021700 - Placeholder selectors! Fixes to [selectors] when nested leaving a space.
16
- Version 201203011100 - Hotfix for unfound function arguments in url() turning up empty from @imported files.
17
- Version 201203010930 - Fix to minor issues and notices (regressions due to changes in prior version)
18
- Version 201203010000 - Proper list support, functions: if, adjust-color, scale-color, change-color, named parameters for functions+mixins, various minor bugfixes
19
- Version 201202100115 - fix to @import parsing of url(x.css)
20
- Version 201202100100 - fix to @each parsing of things like rgba(*,*,*,*) which previously removed braces incorrectly.
21
- Version 201202092300 - fix to @mixins calling @mixins involving variable-name collisions, minor fix to interpolation fail
22
- Version 201202081100 - fix to @media contexts
23
- Version 201202072300 - first version with versions!
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/compile-apache.php DELETED
@@ -1,42 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * This file is intended to be used in conjunction with Apache2's mod_actions,
5
- * wherein you can have a .htaccess file like so for automatic compilation:
6
- * Action compile-sass /git/phpsass/compile-apache.php
7
- * AddHandler compile-sass .sass .scss
8
- */
9
-
10
- header('Content-type: text/css');
11
-
12
- require_once './SassParser.php';
13
-
14
- function warn($text, $context) {
15
- print "/** WARN: $text, on line {$context->node->token->line} of {$context->node->token->filename} **/\n";
16
- }
17
- function debug($text, $context) {
18
- print "/** DEBUG: $text, on line {$context->node->token->line} of {$context->node->token->filename} **/\n";
19
- }
20
-
21
-
22
- $file = $_SERVER['DOCUMENT_ROOT'] . $_SERVER['PATH_INFO'];
23
- $syntax = substr($file, -4, 4);
24
-
25
- $options = array(
26
- 'style' => 'expanded',
27
- 'cache' => FALSE,
28
- 'syntax' => $syntax,
29
- 'debug' => FALSE,
30
- 'callbacks' => array(
31
- 'warn' => 'warn',
32
- 'debug' => 'debug'
33
- ),
34
- );
35
-
36
- // Execute the compiler.
37
- $parser = new SassParser($options);
38
- try {
39
- print "\n\n" . $parser->toCss($file);
40
- } catch (Exception $e) {
41
- print $e->getMessage();
42
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/composer.json DELETED
@@ -1,38 +0,0 @@
1
- {
2
- "name": "richthegeek/phpsass",
3
- "description": "PHPSass is a PHP compiler for SASS, a popular CSS pre-processor language.",
4
- "license": "BSD-2-Clause",
5
- "homepage": "http://phpsass.com",
6
- "support": {
7
- "issues": "https://github.com/richthegeek/phpsass/issues",
8
- "source": "https://github.com/richthegeek/phpsass"
9
- },
10
- "authors": [
11
- {
12
- "name": "Richard Lyon",
13
- "homepage": "https://github.com/richthegeek"
14
- },
15
- {
16
- "name": "Sebastian Siemssen",
17
- "homepage": "https://twitter.com/thefubhy"
18
- },
19
- {
20
- "name": "Steve Jones",
21
- "homepage": "https://github.com/darthsteven"
22
- },
23
- {
24
- "name": "Sam Richard",
25
- "homepage": "https://github.com/snugug"
26
- }
27
- ],
28
- "autoload": {
29
- "classmap": [
30
- "script/",
31
- "renderers/",
32
- "tree/",
33
- "SassException.php",
34
- "SassFile.php",
35
- "SassParser.php"
36
- ]
37
- }
38
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/renderers/SassCompactRenderer.php DELETED
@@ -1,144 +0,0 @@
1
- <?php
2
- /* SVN FILE: $Id$ */
3
- /**
4
- * SassCompactRenderer 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.renderers
10
- */
11
-
12
- require_once 'SassCompressedRenderer.php';
13
-
14
- /**
15
- * SassCompactRenderer class.
16
- * Each CSS rule takes up only one line, with every property defined on that
17
- * line. Nested rules are placed next to each other with no newline, while
18
- * groups of rules have newlines between them.
19
- * @package PHamlP
20
- * @subpackage Sass.renderers
21
- */
22
- class SassCompactRenderer extends SassCompressedRenderer
23
- {
24
- const DEBUG_INFO_RULE = '@media -sass-debug-info';
25
- const DEBUG_INFO_PROPERTY = 'font-family';
26
-
27
- /**
28
- * Renders the brace between the selectors and the properties
29
- * @return string the brace between the selectors and the properties
30
- */
31
- protected function between()
32
- {
33
- return ' { ';
34
- }
35
-
36
- /**
37
- * Renders the brace at the end of the rule
38
- * @return string the brace between the rule and its properties
39
- */
40
- protected function end()
41
- {
42
- return " }\n";
43
- }
44
-
45
- /**
46
- * Renders a comment.
47
- * Comments preceeding a rule are on their own line.
48
- * Comments within a rule are on the same line as the rule.
49
- * @param SassNode the node being rendered
50
- * @return string the rendered commnt
51
- */
52
- public function renderComment($node)
53
- {
54
- $nl = ($node->parent instanceof SassRuleNode?'':"\n");
55
-
56
- return "$nl/* " . join("\n * ", $node->children) . " */$nl" ;
57
- }
58
-
59
- /**
60
- * Renders a directive.
61
- * @param SassNode the node being rendered
62
- * @param array properties of the directive
63
- * @return string the rendered directive
64
- */
65
- public function renderDirective($node, $properties)
66
- {
67
- return str_replace("\n", '', parent::renderDirective($node, $properties)) .
68
- "\n\n";
69
- }
70
-
71
- /**
72
- * Renders properties.
73
- * @param SassNode the node being rendered
74
- * @param array properties to render
75
- * @return string the rendered properties
76
- */
77
- public function renderProperties($node, $properties)
78
- {
79
- return join(' ', $properties);
80
- }
81
-
82
- /**
83
- * Renders a property.
84
- * @param SassNode the node being rendered
85
- * @return string the rendered property
86
- */
87
- public function renderProperty($node)
88
- {
89
- $node->important = $node->important ? ' !important' : '';
90
-
91
- return "{$node->name}: {$node->value}{$node->important};";
92
- }
93
-
94
- /**
95
- * Renders a rule.
96
- * @param SassNode the node being rendered
97
- * @param array rule properties
98
- * @param string rendered rules
99
- * @return string the rendered rule
100
- */
101
- public function renderRule($node, $properties, $rules)
102
- {
103
- return $this->renderDebug($node) . parent::renderRule($node, $properties,
104
- str_replace("\n\n", "\n", $rules)) . "\n";
105
- }
106
-
107
- /**
108
- * Renders debug information.
109
- * If the node has the debug_info options set true the line number and filename
110
- * are rendered in a format compatible with
111
- * {@link https://addons.mozilla.org/en-US/firefox/addon/103988/ FireSass}.
112
- * Else if the node has the line_numbers option set true the line number and
113
- * filename are rendered in a comment.
114
- * @param SassNode the node being rendered
115
- * @return string the debug information
116
- */
117
- protected function renderDebug($node)
118
- {
119
- $indent = $this->getIndent($node);
120
- $debug = '';
121
-
122
- if ($node->debug_info) {
123
-
124
- $debug = $indent . self::DEBUG_INFO_RULE . '{';
125
- $debug .= 'filename{' . self::DEBUG_INFO_PROPERTY . ':' . preg_replace('/([^-\w])/', '\\\\\1', "file://{$node->filename}") . ';}';
126
- $debug .= 'line{' . self::DEBUG_INFO_PROPERTY . ":'{$node->line}';}";
127
- $debug .= "}\n";
128
- } elseif ($node->line_numbers) {
129
- $debug .= "$indent/* line {$node->line} {$node->filename} */\n";
130
- }
131
-
132
- return $debug;
133
- }
134
-
135
- /**
136
- * Renders rule selectors.
137
- * @param SassNode the node being rendered
138
- * @return string the rendered selectors
139
- */
140
- protected function renderSelectors($node)
141
- {
142
- return join(', ', $node->selectors);
143
- }
144
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/renderers/SassCompressedRenderer.php DELETED
@@ -1,124 +0,0 @@
1
- <?php
2
- /* SVN FILE: $Id$ */
3
- /**
4
- * SassCompressedRenderer 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.renderers
10
- */
11
- /**
12
- * SassCompressedRenderer class.
13
- * Compressed style takes up the minimum amount of space possible, having no
14
- * whitespace except that necessary to separate selectors and a newline at the
15
- * end of the file. It's not meant to be human-readable
16
- * @package PHamlP
17
- * @subpackage Sass.renderers
18
- */
19
- class SassCompressedRenderer extends SassRenderer
20
- {
21
- /**
22
- * Renders the brace between the selectors and the properties
23
- * @return string the brace between the selectors and the properties
24
- */
25
- protected function between()
26
- {
27
- return '{';
28
- }
29
-
30
- /**
31
- * Renders the brace at the end of the rule
32
- * @return string the brace between the rule and its properties
33
- */
34
- protected function end()
35
- {
36
- return '}';
37
- }
38
-
39
- /**
40
- * Returns the indent string for the node
41
- * @param SassNode the node to return the indent string for
42
- * @return string the indent string for this SassNode
43
- */
44
- protected function getIndent($node)
45
- {
46
- return '';
47
- }
48
-
49
- /**
50
- * Renders a comment.
51
- * @param SassNode the node being rendered
52
- * @return string the rendered comment
53
- */
54
- public function renderComment($node)
55
- {
56
- return '';
57
- }
58
-
59
- /**
60
- * Renders a directive.
61
- * @param SassNode the node being rendered
62
- * @param array properties of the directive
63
- * @return string the rendered directive
64
- */
65
- public function renderDirective($node, $properties)
66
- {
67
- return $node->directive . $this->between() . $this->renderProperties($node, $properties) . $this->end();
68
- }
69
-
70
- /**
71
- * Renders properties.
72
- * @param SassNode the node being rendered
73
- * @param array properties to render
74
- * @return string the rendered properties
75
- */
76
- public function renderProperties($node, $properties)
77
- {
78
- return join('', $properties);
79
- }
80
-
81
- /**
82
- * Renders a property.
83
- * @param SassNode the node being rendered
84
- * @return string the rendered property
85
- */
86
- public function renderProperty($node)
87
- {
88
- $node->important = $node->important ? '!important' : '';
89
-
90
- return "{$node->name}:{$node->value}{$node->important};";
91
- }
92
-
93
- /**
94
- * Renders a rule.
95
- * @param SassNode the node being rendered
96
- * @param array rule properties
97
- * @param string rendered rules
98
- * @return string the rendered directive
99
- */
100
- public function renderRule($node, $properties, $rules)
101
- {
102
- $selectors = $this->renderSelectors($node);
103
- if ($selectors) {
104
- return (!empty($properties) ? $selectors . $this->between() . $this->renderProperties($node, $properties) . $this->end() : '') . $rules;
105
- }
106
- }
107
-
108
- /**
109
- * Renders the rule's selectors
110
- * @param SassNode the node being rendered
111
- * @return string the rendered selectors
112
- */
113
- protected function renderSelectors($node)
114
- {
115
- $selectors = array();
116
- foreach ($node->selectors as $selector) {
117
- if (!$node->isPlaceholder($selector)) {
118
- $selectors[] = $selector;
119
- }
120
- }
121
-
122
- return join(',', $selectors);
123
- }
124
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/renderers/SassExpandedRenderer.php DELETED
@@ -1,69 +0,0 @@
1
- <?php
2
- /* SVN FILE: $Id$ */
3
- /**
4
- * SassExpandedRenderer 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.renderers
10
- */
11
-
12
- require_once 'SassCompactRenderer.php';
13
-
14
- /**
15
- * SassExpandedRenderer class.
16
- * Expanded is the typical human-made CSS style, with each property and rule
17
- * taking up one line. Properties are indented within the rules, but the rules
18
- * are not indented in any special way.
19
- * @package PHamlP
20
- * @subpackage Sass.renderers
21
- */
22
- class SassExpandedRenderer extends SassCompactRenderer
23
- {
24
- /**
25
- * Renders the brace between the selectors and the properties
26
- * @return string the brace between the selectors and the properties
27
- */
28
- protected function between()
29
- {
30
- return " {\n" ;
31
- }
32
-
33
- /**
34
- * Renders the brace at the end of the rule
35
- * @return string the brace between the rule and its properties
36
- */
37
- protected function end()
38
- {
39
- return "\n}\n\n";
40
- }
41
-
42
- /**
43
- * Renders a comment.
44
- * @param SassNode the node being rendered
45
- * @return string the rendered commnt
46
- */
47
- public function renderComment($node)
48
- {
49
- $indent = $this->getIndent($node);
50
- $lines = explode("\n", $node->value);
51
- foreach ($lines as &$line) {
52
- $line = trim($line);
53
- }
54
-
55
- return "$indent/*\n$indent * ".join("\n$indent * ", $lines)."\n$indent */".(empty($indent)?"\n":'');
56
- }
57
-
58
- /**
59
- * Renders properties.
60
- * @param array properties to render
61
- * @return string the rendered properties
62
- */
63
- public function renderProperties($node, $properties)
64
- {
65
- $indent = $this->getIndent($node).self::INDENT;
66
-
67
- return $indent.join("\n$indent", $properties);
68
- }
69
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/renderers/SassNestedRenderer.php DELETED
@@ -1,75 +0,0 @@
1
- <?php
2
- /* SVN FILE: $Id$ */
3
- /**
4
- * SassNestedRenderer 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.renderers
10
- */
11
-
12
- require_once 'SassExpandedRenderer.php';
13
-
14
- /**
15
- * SassNestedRenderer class.
16
- * Nested style is the default Sass style, because it reflects the structure of
17
- * the document in much the same way Sass does. Each rule is indented based on
18
- * how deeply it's nested. Each property has its own line and is indented
19
- * within the rule.
20
- * @package PHamlP
21
- * @subpackage Sass.renderers
22
- */
23
- class SassNestedRenderer extends SassExpandedRenderer
24
- {
25
- /**
26
- * Renders the brace at the end of the rule
27
- * @return string the brace between the rule and its properties
28
- */
29
- protected function end()
30
- {
31
- return " }\n";
32
- }
33
-
34
- /**
35
- * Returns the indent string for the node
36
- * @param SassNode the node being rendered
37
- * @return string the indent string for this SassNode
38
- */
39
- protected function getIndent($node)
40
- {
41
- return str_repeat(self::INDENT, $node->level);
42
- }
43
-
44
- /**
45
- * Renders a directive.
46
- * @param SassNode the node being rendered
47
- * @param array properties of the directive
48
- * @return string the rendered directive
49
- */
50
- public function renderDirective($node, $properties)
51
- {
52
- $directive = $this->getIndent($node) . $node->directive . $this->between() . $this->renderProperties($node, $properties);
53
-
54
- return preg_replace('/(.*})\n$/', '\1', $directive) . $this->end();
55
- }
56
-
57
- /**
58
- * Renders rule selectors.
59
- * @param SassNode the node being rendered
60
- * @return string the rendered selectors
61
- */
62
- protected function renderSelectors($node)
63
- {
64
- $selectors = array();
65
- foreach ($node->selectors as $selector) {
66
- if (!$node->isPlaceholder($selector)) {
67
- $selectors[] = $selector;
68
- }
69
- }
70
-
71
- $indent = $this->getIndent($node);
72
-
73
- return $indent.join(",\n$indent", $selectors);
74
- }
75
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/renderers/SassRenderer.php DELETED
@@ -1,53 +0,0 @@
1
- <?php
2
- /* SVN FILE: $Id$ */
3
- /**
4
- * SassRenderer 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.renderers
10
- */
11
-
12
- require_once 'SassCompactRenderer.php';
13
- require_once 'SassCompressedRenderer.php';
14
- require_once 'SassExpandedRenderer.php';
15
- require_once 'SassNestedRenderer.php';
16
-
17
- /**
18
- * SassRenderer class.
19
- * @package PHamlP
20
- * @subpackage Sass.renderers
21
- */
22
- class SassRenderer
23
- {
24
- /**#@+
25
- * Output Styles
26
- */
27
- const STYLE_COMPRESSED = 'compressed';
28
- const STYLE_COMPACT = 'compact';
29
- const STYLE_EXPANDED = 'expanded';
30
- const STYLE_NESTED = 'nested';
31
- /**#@-*/
32
-
33
- const INDENT = ' ';
34
-
35
- /**
36
- * Returns the renderer for the required render style.
37
- * @param string render style
38
- * @return SassRenderer
39
- */
40
- public static function getRenderer($style)
41
- {
42
- switch ($style) {
43
- case self::STYLE_COMPACT:
44
- return new SassCompactRenderer();
45
- case self::STYLE_COMPRESSED:
46
- return new SassCompressedRenderer();
47
- case self::STYLE_EXPANDED:
48
- return new SassExpandedRenderer();
49
- case self::STYLE_NESTED:
50
- return new SassNestedRenderer();
51
- } // switch
52
- }
53
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/script/SassScriptFunction.php DELETED
@@ -1,317 +0,0 @@
1
- <?php
2
- /**
3
- * SassScriptFunction class file.
4
- * @author Chris Yates <chris.l.yates@gmail.com>
5
- * @copyright Copyright (c) 2010 PBM Web Development
6
- * @license http://phamlp.googlecode.com/files/license.txt
7
- * @package PHamlP
8
- * @subpackage Sass.script
9
- */
10
-
11
- require_once 'SassScriptFunctions.php';
12
-
13
- /**
14
- * SassScriptFunction class.
15
- * Preforms a SassScript function.
16
- * @package PHamlP
17
- * @subpackage Sass.script
18
- */
19
- class SassScriptFunction
20
- {
21
- /**@#+
22
- * Regexes for matching and extracting functions and arguments
23
- */
24
- const MATCH = '/^(((-\w)|(\w))[-\w:.]*)\(/';
25
- const MATCH_FUNC = '/^((?:(?:-\w)|(?:\w))[-\w:.]*)\((.*)\)/';
26
- const SPLIT_ARGS = '/\s*((?:[\'"].*?["\'])|(?:.+?(?:\(.*\).*?)?))\s*(?:,|$)/';
27
- const NAME = 1;
28
- const ARGS = 2;
29
-
30
- private $name;
31
- private $args;
32
-
33
- public static $context;
34
-
35
- /**
36
- * SassScriptFunction constructor
37
- * @param string name of the function
38
- * @param array arguments for the function
39
- * @return SassScriptFunction
40
- */
41
- public function __construct($name, $args)
42
- {
43
- $this->name = $name;
44
- $this->args = $args;
45
- }
46
-
47
- private function process_arguments($input)
48
- {
49
- if (is_array($input)) {
50
- $output = array();
51
- foreach ($input as $k => $token) {
52
- $output[$k] = trim($this->process_arguments($token), '\'"');
53
- }
54
-
55
- return $output;
56
- }
57
-
58
- $token = $input;
59
- if (is_null($token))
60
- return ' ';
61
-
62
- if (!is_object($token))
63
- return (string) $token;
64
-
65
- if (method_exists($token, 'toString'))
66
- return $token->toString();
67
-
68
- if (method_exists($token, '__toString'))
69
- return $token->__toString();
70
-
71
- if (method_exists($token, 'perform'))
72
- return $token->perform();
73
-
74
- return '';
75
- }
76
-
77
- /**
78
- * Evaluates the function.
79
- * Look for a user defined function first - this allows users to override
80
- * pre-defined functions, then try the pre-defined functions.
81
- * @return Function the value of this Function
82
- */
83
- public function perform()
84
- {
85
- self::$context = new SassContext(SassScriptParser::$context);
86
-
87
- $name = preg_replace('/[^a-z0-9_]/', '_', strtolower($this->name));
88
- $args = $this->process_arguments($this->args);
89
-
90
- foreach ($this->args as $k => $v) {
91
- if (!is_numeric($k)) {
92
- self::$context->setVariable($k, $v);
93
- }
94
- }
95
-
96
- try {
97
- if (SassScriptParser::$context->hasFunction($this->name)) {
98
- $return = SassScriptParser::$context->getFunction($this->name)->execute(SassScriptParser::$context, $this->args);
99
-
100
- return $return;
101
- } elseif (SassScriptParser::$context->hasFunction($name)) {
102
- $return = SassScriptParser::$context->getFunction($name)->execute(SassScriptParser::$context, $this->args);
103
-
104
- return $return;
105
- }
106
- } catch (Exception $e) {
107
- throw $e;
108
- }
109
-
110
- if (isset(SassParser::$functions) && count(SassParser::$functions)) {
111
- foreach (SassParser::$functions as $fn => $callback) {
112
- if (($fn == $name || $fn == $this->name) && is_callable($callback)) {
113
- $result = call_user_func_array($callback, $args);
114
- if (!is_object($result)) {
115
- $lexed = SassScriptLexer::$instance->lex($result, self::$context);
116
- if (count($lexed) === 1) {
117
- return $lexed[0];
118
- }
119
-
120
- return new SassString(implode('', $this->process_arguments($lexed)));
121
- }
122
-
123
- return $result;
124
- }
125
- }
126
- }
127
-
128
- if (method_exists('SassScriptFunctions', $name) || method_exists('SassScriptFunctions', $name = '_' . $name)) {
129
- $sig = self::get_reflection(array('SassScriptFunctions', $name));
130
- list($args) = self::fill_parameters($sig, $this->args, SassScriptParser::$context, $this);
131
-
132
- return call_user_func_array(array('SassScriptFunctions', $name), $args);
133
- }
134
-
135
- foreach ($this->args as $i => $arg) {
136
- if (is_object($arg) && isset($arg->quote)) {
137
- $args[$i] = $arg->toString();
138
- }
139
- if (!is_numeric($i) && SassScriptParser::$context->hasVariable($i)) {
140
- $args[$i] = SassScriptParser::$context->getVariable($i);
141
- }
142
- }
143
-
144
- // CSS function: create a SassString that will emit the function into the CSS
145
- return new SassString($this->name . '(' . join(', ', $args) . ')');
146
- }
147
-
148
- /**
149
- * Imports files in the specified directory.
150
- * @param string path to directory to import
151
- * @return array filenames imported
152
- */
153
- private function import($dir)
154
- {
155
- $files = array();
156
-
157
- foreach (array_slice(scandir($dir), 2) as $file) {
158
- if (is_file($dir . DIRECTORY_SEPARATOR . $file)) {
159
- $files[] = $file;
160
- require_once($dir . DIRECTORY_SEPARATOR . $file);
161
- }
162
- } // foreach
163
-
164
- return $files;
165
- }
166
-
167
- /**
168
- * Returns a value indicating if a token of this type can be matched at
169
- * the start of the subject string.
170
- * @param string the subject string
171
- * @return mixed match at the start of the string or false if no match
172
- */
173
- public static function isa($subject)
174
- {
175
- if (!preg_match(self::MATCH, $subject, $matches))
176
- return false;
177
-
178
- $match = $matches[0];
179
- $paren = 1;
180
- $strpos = strlen($match);
181
- $strlen = strlen($subject);
182
- $subject_str = (string) $subject;
183
-
184
- while ($paren && $strpos < $strlen) {
185
- $c = $subject_str[$strpos++];
186
-
187
- $match .= $c;
188
- if ($c === '(') {
189
- $paren += 1;
190
- } elseif ($c === ')') {
191
- $paren -= 1;
192
- }
193
- }
194
-
195
- return $match;
196
- }
197
-
198
- public static function extractArgs($string, $include_null = TRUE, $context)
199
- {
200
- $args = array();
201
- $arg = '';
202
- $paren = 0;
203
- $strpos = 0;
204
- $strlen = strlen($string);
205
-
206
- $list = SassList::_build_list($string, ',');
207
- $return = array();
208
-
209
- foreach ($list as $k => $value) {
210
- if (substr($value, -3, 3) == '...' && preg_match(SassVariableNode::MATCH, substr($value, 0, -3) . ':', $match)) {
211
- $list = new SassList($context->getVariable($match[SassVariableNode::NAME]));
212
- if (count($list->value) > 1) {
213
- $return = array_merge($return, $list->value);
214
- continue;
215
- }
216
- }
217
-
218
- if (strpos($value, ':') !== false && preg_match(SassVariableNode::MATCH, $value, $match)) {
219
- $return[$match[SassVariableNode::NAME]] = $match[SassVariableNode::VALUE];
220
- } elseif (substr($value, 0, 1) == '$' && $include_null) {
221
- $return[str_replace('$', '', $value)] = NULL;
222
- } elseif ($include_null || $value !== NULL) {
223
- $return[] = $value;
224
- }
225
- }
226
-
227
- return $return;
228
- }
229
-
230
- public static function get_reflection($method)
231
- {
232
- if (is_array($method)) {
233
- $class = new ReflectionClass($method[0]);
234
- $function = $class->getMethod($method[1]);
235
- } else {
236
- $function = new ReflectionFunction($method);
237
- }
238
-
239
- $return = array();
240
- foreach ($function->getParameters() as $parameter) {
241
- $default = $parameter->isDefaultValueAvailable() ? $parameter->getDefaultValue() : NULL;
242
- if ($default !== NULL) {
243
- $parsed = is_bool($default) ? new SassBoolean($default) : SassScriptParser::$instance->evaluate($default, new SassContext());
244
- $parsed = ($parsed === NULL) ? new SassString($default) : $parsed;
245
- } else {
246
- $parsed = $default;
247
- }
248
- $return[$parameter->getName()] = $parsed; # we evaluate the defaults to get Sass objects.
249
- }
250
-
251
- return $return;
252
- }
253
-
254
- public static function fill_parameters($required, $provided, $context, $source)
255
- {
256
- $context = new SassContext($context);
257
- $_required = array_merge(array(), $required); // need to array_merge?
258
- $fill = $_required;
259
-
260
- foreach ($required as $name=>$default) {
261
- // we require that named variables provide a default.
262
- if (isset($provided[$name]) && $default !== NULL) {
263
- $_required[$name] = $provided[$name];
264
- unset($provided[$name]);
265
- unset($required[$name]);
266
- }
267
- }
268
-
269
- // print_r(array($required, $provided, $_required));
270
- $provided_copy = $provided;
271
-
272
- foreach ($required as $name=>$default) {
273
- if ($default === null && strpos($name, '=') !== FALSE) {
274
- list($name, $default) = explode('=', $name);
275
- $name = trim($name);
276
- $default = trim($default);
277
- }
278
- if (count($provided)) {
279
- $arg = array_shift($provided);
280
- } elseif ($default !== NULL) {
281
- $arg = $default;
282
-
283
- // for mixins with default values that refer to other arguments
284
- // (e.g. border-radius($topright: 0, $bottomright: $topright, $bottomleft: $topright, $topleft: $topright)
285
- if (is_string($default) && $default[0]=='$') {
286
- $referred = trim(trim($default, '$'));
287
- $pos = array_search($referred, array_keys($required));
288
- if ($pos!==false && array_key_exists($pos, $provided_copy)) {
289
- $arg = $provided_copy[$pos];
290
- }
291
- }
292
- } else {
293
- throw new SassMixinNodeException("Function::$name: Required variable ($name) not given.\nFunction defined: " . $source->token->filename . '::' . $source->token->line . "\nFunction used", $source);
294
- }
295
- // splats
296
- if (substr($name, -3, 3) == '...') {
297
- unset ($_required[$name]);
298
- $name = substr($name, 0, -3);
299
- $_required[$name] = new SassList('', ',');
300
- $_required[$name]->value = array_merge(array($arg), $provided);
301
- continue;
302
- } else {
303
- $_required[$name] = $arg;
304
- }
305
- }
306
-
307
- $_required = array_merge($_required, $provided); // any remaining args get tacked onto the end
308
-
309
- foreach ($_required as $key => $value) {
310
- if (!is_object($value)) {
311
- $_required[$key] = SassScriptParser::$instance->evaluate($value, $context);
312
- }
313
- }
314
-
315
- return array($_required, $context);
316
- }
317
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/script/SassScriptFunctions.php DELETED
@@ -1,1053 +0,0 @@
1
- <?php
2
- /**
3
- * SassScript functions class file.
4
- *
5
- * Methods in this module are accessible from the SassScript context.
6
- * For example, you can write:
7
- *
8
- * $colour = hsl(120, 100%, 50%)
9
- * and it will call SassFunctions::hsl().
10
- *
11
- * There are a few things to keep in mind when modifying this module.
12
- * First of all, the arguments passed are SassLiteral objects.
13
- * Literal objects are also expected to be returned.
14
- *
15
- * Most Literal objects support the SassLiteral->value accessor
16
- * for getting their values. Colour objects, though, must be accessed using
17
- * SassColour::rgb().
18
- *
19
- * Second, making functions accessible from Sass introduces the temptation
20
- * to do things like database access within stylesheets.
21
- * This temptation must be resisted.
22
- * Keep in mind that Sass stylesheets are only compiled once and then left as
23
- * static CSS files. Any dynamic CSS should be left in <style> tags in the
24
- * HTML.
25
- *
26
- * @author Chris Yates <chris.l.yates@gmail.com>
27
- * @copyright Copyright (c) 2010 PBM Web Development
28
- * @license http://phamlp.googlecode.com/files/license.txt
29
- * @package PHamlP
30
- * @subpackage Sass.script
31
- */
32
-
33
- /**
34
- * SassScript functions class.
35
- * A collection of functions for use in SassSCript.
36
- * @package PHamlP
37
- * @subpackage Sass.script
38
- */
39
- class SassScriptFunctions
40
- {
41
- const DECREASE = false;
42
- const INCREASE = true;
43
-
44
- public static $parser = FALSE;
45
- public static function option($name)
46
- {
47
- $options = SassParser::$instance->getOptions();
48
- if (isset($options[$name->value])) {
49
- return new SassString($options[$name->value]);
50
- }
51
-
52
- return new SassBoolean(false);
53
- }
54
-
55
- /*
56
- * Colour Creation
57
- */
58
-
59
- /**
60
- * Creates a SassColour object from red, green, and blue values.
61
- * @param SassNumber the red component.
62
- * A number between 0 and 255 inclusive, or between 0% and 100% inclusive
63
- * @param SassNumber the green component.
64
- * A number between 0 and 255 inclusive, or between 0% and 100% inclusive
65
- * @param SassNumber the blue component.
66
- * A number between 0 and 255 inclusive, or between 0% and 100% inclusive
67
- * @return new SassColour SassColour object
68
- * @throws SassScriptFunctionException if red, green, or blue are out of bounds
69
- */
70
- public static function rgb($red, $green, $blue)
71
- {
72
- return self::rgba($red, $green, $blue, new SassNumber(1));
73
- }
74
-
75
- /**
76
- * Creates a SassColour object from red, green, and blue values and alpha
77
- * channel (opacity).
78
- * There are two overloads:
79
- * * rgba(red, green, blue, alpha)
80
- * @param SassNumber the red component.
81
- * A number between 0 and 255 inclusive, or between 0% and 100% inclusive
82
- * @param SassNumber the green component.
83
- * A number between 0 and 255 inclusive, or between 0% and 100% inclusive
84
- * @param SassNumber the blue component.
85
- * A number between 0 and 255 inclusive, or between 0% and 100% inclusive
86
- * @param SassNumber The alpha channel. A number between 0 and 1.
87
- *
88
- * * rgba(colour, alpha)
89
- * @param SassColour a SassColour object
90
- * @param SassNumber The alpha channel. A number between 0 and 1.
91
- *
92
- * @return new SassColour SassColour object
93
- * @throws SassScriptFunctionException if any of the red, green, or blue
94
- * colour components are out of bounds, or or the colour is not a colour, or
95
- * alpha is out of bounds
96
- */
97
- public static function rgba()
98
- {
99
- switch (func_num_args()) {
100
- case 2:
101
- $colour = func_get_arg(0);
102
- $alpha = func_get_arg(1);
103
- SassLiteral::assertType($colour, 'SassColour');
104
- SassLiteral::assertType($alpha, 'SassNumber');
105
- SassLiteral::assertInRange($alpha, 0, 1);
106
-
107
- return $colour->with(array('alpha' => $alpha->value));
108
- break;
109
- case 4:
110
- $rgba = array();
111
- $components = func_get_args();
112
- $alpha = array_pop($components);
113
- foreach ($components as $component) {
114
- SassLiteral::assertType($component, 'SassNumber');
115
- if ($component->units == '%') {
116
- SassLiteral::assertInRange($component, 0, 100, '%');
117
- $rgba[] = $component->value * 2.55;
118
- } else {
119
- SassLiteral::assertInRange($component, 0, 255);
120
- $rgba[] = $component->value;
121
- }
122
- }
123
- SassLiteral::assertType($alpha, 'SassNumber');
124
- SassLiteral::assertInRange($alpha, 0, 1);
125
- $rgba[] = $alpha->value;
126
-
127
- return new SassColour($rgba);
128
- break;
129
- default:
130
- throw new SassScriptFunctionException('Incorrect argument count for ' . __METHOD__ . '; expected 2 or 4, received ' . func_num_args(), SassScriptParser::$context->node);
131
- }
132
- }
133
-
134
- /**
135
- * Creates a SassColour object from hue, saturation, and lightness.
136
- * Uses the algorithm from the
137
- * {@link http://www.w3.org/TR/css3-colour/#hsl-colour CSS3 spec}.
138
- * @param float The hue of the colour in degrees.
139
- * Should be between 0 and 360 inclusive
140
- * @param mixed The saturation of the colour as a percentage.
141
- * Must be between '0%' and 100%, inclusive
142
- * @param mixed The lightness of the colour as a percentage.
143
- * Must be between 0% and 100%, inclusive
144
- * @return new SassColour The resulting colour
145
- * @throws SassScriptFunctionException if saturation or lightness are out of bounds
146
- */
147
- public static function hsl($h, $s, $l)
148
- {
149
- SassLiteral::assertInRange($s, 0, 100, '%');
150
- SassLiteral::assertInRange($l, 0, 100, '%');
151
-
152
- return self::hsla($h, $s, $l, new SassNumber(1));
153
- }
154
-
155
- /**
156
- * Creates a SassColour object from hue, saturation, lightness and alpha
157
- * channel (opacity).
158
- * @param SassNumber The hue of the colour in degrees.
159
- * Should be between 0 and 360 inclusive
160
- * @param SassNumber The saturation of the colour as a percentage.
161
- * Must be between 0% and 100% inclusive
162
- * @param SassNumber The lightness of the colour as a percentage.
163
- * Must be between 0% and 100% inclusive
164
- * @param float The alpha channel. A number between 0 and 1.
165
- * @return new SassColour The resulting colour
166
- * @throws SassScriptFunctionException if saturation, lightness or alpha are
167
- * out of bounds
168
- */
169
- public static function hsla($h, $s, $l, $a)
170
- {
171
- SassLiteral::assertType($h, 'SassNumber');
172
- SassLiteral::assertType($s, 'SassNumber');
173
- SassLiteral::assertType($l, 'SassNumber');
174
- SassLiteral::assertType($a, 'SassNumber');
175
- SassLiteral::assertInRange($s, 0, 100, '%');
176
- SassLiteral::assertInRange($l, 0, 100, '%');
177
- SassLiteral::assertInRange($a, 0, 1);
178
-
179
- return new SassColour(array('hue' => $h, 'saturation' => $s, 'lightness' => $l, 'alpha' => $a));
180
- }
181
-
182
- /*
183
- * Colour Information
184
- */
185
-
186
- /**
187
- * Returns the red component of a colour.
188
- * @param SassColour The colour
189
- * @return new SassNumber The red component of colour
190
- * @throws SassScriptFunctionException If $colour is not a colour
191
- */
192
- public static function red($colour)
193
- {
194
- SassLiteral::assertType($colour, 'SassColour');
195
-
196
- return new SassNumber($colour->red);
197
- }
198
-
199
- /**
200
- * Returns the green component of a colour.
201
- * @param SassColour The colour
202
- * @return new SassNumber The green component of colour
203
- * @throws SassScriptFunctionException If $colour is not a colour
204
- */
205
- public static function green($colour)
206
- {
207
- SassLiteral::assertType($colour, 'SassColour');
208
-
209
- return new SassNumber($colour->green);
210
- }
211
-
212
- /**
213
- * Returns the blue component of a colour.
214
- * @param SassColour The colour
215
- * @return new SassNumber The blue component of colour
216
- * @throws SassScriptFunctionException If $colour is not a colour
217
- */
218
- public static function blue($colour)
219
- {
220
- SassLiteral::assertType($colour, 'SassColour');
221
-
222
- return new SassNumber($colour->blue);
223
- }
224
-
225
- /**
226
- * Returns the hue component of a colour.
227
- * @param SassColour The colour
228
- * @return new SassNumber The hue component of colour
229
- * @throws SassScriptFunctionException If $colour is not a colour
230
- */
231
- public static function hue($colour)
232
- {
233
- SassLiteral::assertType($colour, 'SassColour');
234
-
235
- return new SassNumber($colour->getHue() . 'deg');
236
- }
237
-
238
- /**
239
- * Returns the saturation component of a colour.
240
- * @param SassColour The colour
241
- * @return new SassNumber The saturation component of colour
242
- * @throws SassScriptFunctionException If $colour is not a colour
243
- */
244
- public static function saturation($colour)
245
- {
246
- SassLiteral::assertType($colour, 'SassColour');
247
-
248
- return new SassNumber($colour->getSaturation() . '%');
249
- }
250
-
251
- /**
252
- * Returns the lightness component of a colour.
253
- * @param SassColour The colour
254
- * @return new SassNumber The lightness component of colour
255
- * @throws SassScriptFunctionException If $colour is not a colour
256
- */
257
- public static function lightness($colour)
258
- {
259
- SassLiteral::assertType($colour, 'SassColour');
260
-
261
- return new SassNumber($colour->getLightness() . '%');
262
- }
263
-
264
- /**
265
- * Returns the alpha component (opacity) of a colour.
266
- * @param SassColour The colour
267
- * @return new SassNumber The alpha component (opacity) of colour
268
- * @throws SassScriptFunctionException If $colour is not a colour
269
- *
270
- * RL modified so that the filter: alpha function doesn't bork
271
- */
272
- public static function alpha($colour)
273
- {
274
- try {
275
- SassLiteral::assertType($colour, 'SassColour');
276
- } catch (Exception $e) {
277
- return new SassString('alpha(100)');
278
- }
279
-
280
- return new SassNumber($colour->alpha);
281
- }
282
-
283
- /**
284
- * Returns the alpha component (opacity) of a colour.
285
- * @param SassColour The colour
286
- * @return new SassNumber The alpha component (opacity) of colour
287
- * @throws SassScriptFunctionException If $colour is not a colour
288
- */
289
- public static function opacity($colour)
290
- {
291
- SassLiteral::assertType($colour, 'SassColour');
292
-
293
- return new SassNumber($colour->alpha);
294
- }
295
-
296
- /*
297
- * Colour Adjustments
298
- */
299
-
300
- /**
301
- * Changes the hue of a colour while retaining the lightness and saturation.
302
- * @param SassColour The colour to adjust
303
- * @param SassNumber The amount to adjust the colour by
304
- * @return new SassColour The adjusted colour
305
- * @throws SassScriptFunctionException If $colour is not a colour or
306
- * $degrees is not a number
307
- */
308
- public static function adjust_hue($colour, $degrees)
309
- {
310
- SassLiteral::assertType($colour, 'SassColour');
311
- SassLiteral::assertType($degrees, 'SassNumber');
312
-
313
- return $colour->with(array('hue' => $colour->getHue(true) + $degrees->value));
314
- }
315
-
316
- /**
317
- * Makes a colour lighter.
318
- * @param SassColour The colour to lighten
319
- * @param SassNumber The amount to lighten the colour by
320
- * @param SassBoolean Whether the amount is a proportion of the current value
321
- * (true) or the total range (false).
322
- * The default is false - the amount is a proportion of the total range.
323
- * If the colour lightness value is 40% and the amount is 50%,
324
- * the resulting colour lightness value is 90% if the amount is a proportion
325
- * of the total range, whereas it is 60% if the amount is a proportion of the
326
- * current value.
327
- * @return new SassColour The lightened colour
328
- * @throws SassScriptFunctionException If $colour is not a colour or
329
- * $amount is not a number
330
- * @see lighten_rel
331
- */
332
- public static function lighten($colour, $amount, $ofCurrent = false)
333
- {
334
- return self::adjust($colour, $amount, $ofCurrent, 'lightness', self::INCREASE, 0, 100, '%');
335
- }
336
-
337
- /**
338
- * Makes a colour darker.
339
- * @param SassColour The colour to darken
340
- * @param SassNumber The amount to darken the colour by
341
- * @param SassBoolean Whether the amount is a proportion of the current value
342
- * (true) or the total range (false).
343
- * The default is false - the amount is a proportion of the total range.
344
- * If the colour lightness value is 80% and the amount is 50%,
345
- * the resulting colour lightness value is 30% if the amount is a proportion
346
- * of the total range, whereas it is 40% if the amount is a proportion of the
347
- * current value.
348
- * @return new SassColour The darkened colour
349
- * @throws SassScriptFunctionException If $colour is not a colour or
350
- * $amount is not a number
351
- * @see adjust
352
- */
353
- public static function darken($colour, $amount, $ofCurrent = false)
354
- {
355
- return self::adjust($colour, $amount, $ofCurrent, 'lightness', self::DECREASE, 0, 100, '%');
356
- }
357
-
358
- /**
359
- * Makes a colour more saturated.
360
- * @param SassColour The colour to saturate
361
- * @param SassNumber The amount to saturate the colour by
362
- * @param SassBoolean Whether the amount is a proportion of the current value
363
- * (true) or the total range (false).
364
- * The default is false - the amount is a proportion of the total range.
365
- * If the colour saturation value is 40% and the amount is 50%,
366
- * the resulting colour saturation value is 90% if the amount is a proportion
367
- * of the total range, whereas it is 60% if the amount is a proportion of the
368
- * current value.
369
- * @return new SassColour The saturated colour
370
- * @throws SassScriptFunctionException If $colour is not a colour or
371
- * $amount is not a number
372
- * @see adjust
373
- */
374
- public static function saturate($colour, $amount, $ofCurrent = false)
375
- {
376
- return self::adjust($colour, $amount, $ofCurrent, 'saturation', self::INCREASE, 0, 100, '%');
377
- }
378
-
379
- /**
380
- * Makes a colour less saturated.
381
- * @param SassColour The colour to desaturate
382
- * @param SassNumber The amount to desaturate the colour by
383
- * @param SassBoolean Whether the amount is a proportion of the current value
384
- * (true) or the total range (false).
385
- * The default is false - the amount is a proportion of the total range.
386
- * If the colour saturation value is 80% and the amount is 50%,
387
- * the resulting colour saturation value is 30% if the amount is a proportion
388
- * of the total range, whereas it is 40% if the amount is a proportion of the
389
- * current value.
390
- * @return new SassColour The desaturateed colour
391
- * @throws SassScriptFunctionException If $colour is not a colour or
392
- * $amount is not a number
393
- * @see adjust
394
- */
395
- public static function desaturate($colour, $amount, $ofCurrent = false)
396
- {
397
- return self::adjust($colour, $amount, $ofCurrent, 'saturation', self::DECREASE, 0, 100, '%');
398
- }
399
-
400
- /**
401
- * Makes a colour more opaque.
402
- * @param SassColour The colour to opacify
403
- * @param SassNumber The amount to opacify the colour by
404
- * If this is a unitless number between 0 and 1 the adjustment is absolute,
405
- * if it is a percentage the adjustment is relative.
406
- * If the colour alpha value is 0.4
407
- * if the amount is 0.5 the resulting colour alpha value is 0.9,
408
- * whereas if the amount is 50% the resulting colour alpha value is 0.6.
409
- * @return new SassColour The opacified colour
410
- * @throws SassScriptFunctionException If $colour is not a colour or
411
- * $amount is not a number
412
- * @see opacify_rel
413
- */
414
- public static function opacify($colour, $amount, $ofCurrent = false)
415
- {
416
- $units = self::units($amount);
417
-
418
- return self::adjust($colour, $amount, $ofCurrent, 'alpha', self::INCREASE, 0, ($units === '%' ? 100 : 1), $units);
419
- }
420
-
421
- /**
422
- * Makes a colour more transparent.
423
- * @param SassColour The colour to transparentize
424
- * @param SassNumber The amount to transparentize the colour by.
425
- * If this is a unitless number between 0 and 1 the adjustment is absolute,
426
- * if it is a percentage the adjustment is relative.
427
- * If the colour alpha value is 0.8
428
- * if the amount is 0.5 the resulting colour alpha value is 0.3,
429
- * whereas if the amount is 50% the resulting colour alpha value is 0.4.
430
- * @return new SassColour The transparentized colour
431
- * @throws SassScriptFunctionException If $colour is not a colour or
432
- * $amount is not a number
433
- */
434
- public static function transparentize($colour, $amount, $ofCurrent = false)
435
- {
436
- $units = self::units($amount);
437
-
438
- return self::adjust($colour, $amount, $ofCurrent, 'alpha', self::DECREASE, 0, ($units === '%' ? 100 : 1), $units);
439
- }
440
-
441
- /**
442
- * Makes a colour more opaque.
443
- * Alias for {@link opacify}.
444
- * @param SassColour The colour to opacify
445
- * @param SassNumber The amount to opacify the colour by
446
- * @param SassBoolean Whether the amount is a proportion of the current value
447
- * (true) or the total range (false).
448
- * @return new SassColour The opacified colour
449
- * @throws SassScriptFunctionException If $colour is not a colour or
450
- * $amount is not a number
451
- * @see opacify
452
- */
453
- public static function fade_in($colour, $amount, $ofCurrent = false)
454
- {
455
- return self::opacify($colour, $amount, $ofCurrent);
456
- }
457
-
458
- /**
459
- * Makes a colour more transparent.
460
- * Alias for {@link transparentize}.
461
- * @param SassColour The colour to transparentize
462
- * @param SassNumber The amount to transparentize the colour by
463
- * @param SassBoolean Whether the amount is a proportion of the current value
464
- * (true) or the total range (false).
465
- * @return new SassColour The transparentized colour
466
- * @throws SassScriptFunctionException If $colour is not a colour or
467
- * $amount is not a number
468
- * @see transparentize
469
- */
470
- public static function fade_out($colour, $amount, $ofCurrent = false)
471
- {
472
- return self::transparentize($colour, $amount, $ofCurrent);
473
- }
474
-
475
- /**
476
- * Returns the complement of a colour.
477
- * Rotates the hue by 180 degrees.
478
- * @param SassColour The colour
479
- * @return new SassColour The comlemented colour
480
- * @uses adjust_hue()
481
- */
482
- public static function complement($colour)
483
- {
484
- // return self::adjust($colour, new SassNumber('180deg'), true, 'hue', self::INCREASE, 0, 360, '');
485
- return self::adjust_hue($colour, new SassNumber('180deg'));
486
- }
487
-
488
- /**
489
- * Greyscale for non-english speakers.
490
- * @param SassColour The colour
491
- * @return new SassColour The greyscale colour
492
- * @see desaturate
493
- */
494
- public static function grayscale($colour)
495
- {
496
- return self::desaturate($colour, new SassNumber(100));
497
- }
498
-
499
- /**
500
- * Converts a colour to greyscale.
501
- * Reduces the saturation to zero.
502
- * @param SassColour The colour
503
- * @return new SassColour The greyscale colour
504
- * @see desaturate
505
- */
506
- public static function greyscale($colour)
507
- {
508
- return self::desaturate($colour, new SassNumber(100));
509
- }
510
-
511
- /**
512
- * Inverts a colour.
513
- * The red, green, and blue values are inverted value = (255 - value)
514
- * @param SassColour: the colour
515
- * @return new SassColour: the inverted colour
516
- */
517
- public static function invert($colour)
518
- {
519
- SassLiteral::assertType($colour, 'SassColour');
520
-
521
- return $colour->with(array(
522
- 'red' => 255 - $colour->getRed(true),
523
- 'blue' => 255 - $colour->getBlue(true),
524
- 'green' => 255 - $colour->getGreen(true)
525
- ));
526
- }
527
-
528
- /**
529
- * Mixes two colours together.
530
- * Takes the average of each of the RGB components, optionally weighted by the
531
- * given percentage. The opacity of the colours is also considered when
532
- * weighting the components.
533
- * The weight specifies the amount of the first colour that should be included
534
- * in the returned colour. The default, 50%, means that half the first colour
535
- * and half the second colour should be used. 25% means that a quarter of the
536
- * first colour and three quarters of the second colour should be used.
537
- * For example:
538
- * mix(#f00, #00f) => #7f007f
539
- * mix(#f00, #00f, 25%) => #3f00bf
540
- * mix(rgba(255, 0, 0, 0.5), #00f) => rgba(63, 0, 191, 0.75)
541
- *
542
- * @param SassColour The first colour
543
- * @param SassColour The second colour
544
- * @param float Percentage of the first colour to use
545
- * @return new SassColour The mixed colour
546
- * @throws SassScriptFunctionException If $colour1 or $colour2 is
547
- * not a colour
548
- */
549
- public static function mix($colour1, $colour2, $weight = '50%')
550
- {
551
- if (is_object($weight)) {
552
- $weight = new SassNumber($weight);
553
- }
554
- SassLiteral::assertType($colour1, 'SassColour');
555
- SassLiteral::assertType($colour2, 'SassColour');
556
- SassLiteral::assertType($weight, 'SassNumber');
557
- SassLiteral::assertInRange($weight, 0, 100, '%');
558
- /*
559
- * This algorithm factors in both the user-provided weight
560
- * and the difference between the alpha values of the two colours
561
- * to decide how to perform the weighted average of the two RGB values.
562
- *
563
- * It works by first normalizing both parameters to be within [-1, 1],
564
- * where 1 indicates "only use colour1", -1 indicates "only use colour 0",
565
- * and all values in between indicated a proportionately weighted average.
566
- *
567
- * Once we have the normalized variables w and a,
568
- * we apply the formula (w + a)/(1 + w*a)
569
- * to get the combined weight (in [-1, 1]) of colour1.
570
- * This formula has two especially nice properties:
571
- *
572
- * * When either w or a are -1 or 1, the combined weight is also that number
573
- * (cases where w * a == -1 are undefined, and handled as a special case).
574
- *
575
- * * When a is 0, the combined weight is w, and vice versa
576
- *
577
- * Finally, the weight of colour1 is renormalized to be within [0, 1]
578
- * and the weight of colour2 is given by 1 minus the weight of colour1.
579
- */
580
-
581
- $p = $weight->value/100;
582
- $w = $p * 2 - 1;
583
- $a = $colour1->alpha - $colour2->alpha;
584
-
585
-
586
- $w1 = ((($w * $a == -1) ? $w : ($w + $a)/(1 + $w * $a)) + 1) / 2;
587
- $w2 = 1 - $w1;
588
-
589
- $rgb1 = $colour1->getRgb();
590
- $rgb2 = $colour2->getRgb();
591
- $rgba = array();
592
- foreach ($rgb1 as $key=>$value) {
593
- $rgba[$key] = floor(($value * $w1) + ($rgb2[$key] * $w2));
594
- } // foreach
595
- $rgba[] = floor($colour1->alpha * $p + $colour2->alpha * (1 - $p));
596
-
597
- return new SassColour($rgba);
598
- }
599
-
600
- /**
601
- * Adjusts one or more property of the color by the value requested.
602
- * @param SassColour the colour to adjust
603
- * @param SassNumber (red, green, blue, hue, saturation, lightness, alpha) - the amount(s) to adjust by
604
- * @return SassColour
605
- */
606
- public static function adjust_color($color, $red = 0, $green = 0, $blue = 0, $hue = 0, $saturation = 0, $lightness = 0, $alpha = 0)
607
- {
608
- foreach (array('red', 'green', 'blue', 'hue', 'saturation', 'lightness', 'alpha') as $property) {
609
- $obj = $$property;
610
- $color = self::adjust($color, $$property, FALSE, $property, self::INCREASE, 0, 255);
611
- }
612
-
613
- return $color;
614
- }
615
-
616
- /**
617
- * Scales one or more property of the color by the percentage requested.
618
- * @param SassColour the colour to adjust
619
- * @param SassNumber (red, green, blue, saturation, lightness, alpha) - the amount(s) to scale by
620
- * @return SassColour
621
- */
622
- public static function scale_color($color, $red = 0, $green = 0, $blue = 0, $saturation = 0, $lightness = 0, $alpha = 0)
623
- {
624
- $maxes = array(
625
- 'red' => 255,
626
- 'green' => 255,
627
- 'blue' => 255,
628
- 'saturation' => 100,
629
- 'lightness' => 100,
630
- 'alpha' => 1,
631
- );
632
- $color->rgb2hsl();
633
- foreach ($maxes as $property => $max) {
634
- $obj = $$property;
635
- $scale = 0.01 * $obj->value;
636
- $diff = $scale > 0 ? $max - $color->$property : $color->$property;
637
- $color->$property = $color->$property + $diff * $scale;
638
- }
639
- $color->hsl2rgb();
640
-
641
- return $color;
642
- }
643
-
644
- /**
645
- * Changes one or more properties of the color to the requested value
646
- * @param SassColour - the color to change
647
- * @param SassNumber (red, green, blue, hue, saturation, lightness, alpha) - the amounts to scale by
648
- * @return SassColour
649
- */
650
- public static function change_color($color, $red = false, $green = false, $blue = false, $hue = false, $saturation = false, $lightness = false, $alpha = false)
651
- {
652
- $attrs = array();
653
- foreach (array('red', 'green', 'blue', 'hue', 'saturation', 'lightness', 'alpha') as $i => $property) {
654
- $obj = $$property;
655
- if ($obj instanceof SassNumber) {
656
- $attrs[$property] = $obj->value;
657
- }
658
- }
659
-
660
- return $color->with($attrs);
661
- }
662
-
663
- /**
664
- * Adjusts the colour
665
- * @param SassColour the colour to adjust
666
- * @param SassNumber the amount to adust by
667
- * @param boolean whether the amount is a proportion of the current value or
668
- * the total range
669
- * @param string the attribute to adjust
670
- * @param boolean whether to decrease (false) or increase (true) the value of the attribute
671
- * @param float minimum value the amount can be
672
- * @param float maximum value the amount can bemixed
673
- * @param string amount units
674
- */
675
- public static function adjust($colour, $amount, $ofCurrent, $att, $op, $min, $max, $units='')
676
- {
677
- SassLiteral::assertType($colour, 'SassColour');
678
- SassLiteral::assertType($amount, 'SassNumber');
679
- // SassLiteral::assertInRange($amount, $min, $max, $units);
680
- if (!is_bool($ofCurrent)) {
681
- SassLiteral::assertType($ofCurrent, 'SassBoolean');
682
- $ofCurrent = $ofCurrent->value;
683
- }
684
- $colour = clone $colour; # clone here to stop it altering original value
685
-
686
- $amount = $amount->value * (($att === 'alpha' && $ofCurrent && $units === '') ? 100 : 1);
687
-
688
- if ($att == 'red' || $att == 'blue' || $att == 'green') {
689
- $colour->hsl2rgb();
690
- $colour->$att = $ofCurrent ? $colour->$att * (1 + ($amount * ($op === self::INCREASE ? 1 : -1))/100) : $colour->$att + ($amount * ($op === self::INCREASE ? 1 : -1));
691
- $colour->rgb2hsl();
692
- } else {
693
- $colour->rgb2hsl();
694
- $colour->$att = $ofCurrent ? $colour->$att * (1 + ($amount * ($op === self::INCREASE ? 1 : -1))/100) : $colour->$att + ($amount * ($op === self::INCREASE ? 1 : -1));
695
- $colour->$att = max($min, min($max, $colour->$att));
696
- $colour->hsl2rgb();
697
- }
698
-
699
- return $colour;
700
- }
701
-
702
- /**
703
- * returns an IE hex string for a color with an alpha channel
704
- * suitable for passing to IE filters.
705
- */
706
- public static function ie_hex_str($color)
707
- {
708
- if (!($color instanceof SassColour)) {
709
- $color = new SassColour($color);
710
- }
711
- $alpha = str_replace(',','.',round($color->alpha * 255));
712
- $alpha_str = str_pad(dechex($alpha), 2, '0', STR_PAD_LEFT);
713
- $col = $color->asHex(FALSE);
714
-
715
- return new SassString(strtoupper('#' . $alpha_str . $col));
716
- }
717
-
718
-
719
- /*
720
- * Number Functions
721
- */
722
-
723
- /**
724
- * Finds the absolute value of a number.
725
- * For example:
726
- * abs(10px) => 10px
727
- * abs(-10px) => 10px
728
- *
729
- * @param SassNumber The number to round
730
- * @return SassNumber The absolute value of the number
731
- * @throws SassScriptFunctionException If $number is not a number
732
- */
733
- public static function abs($number)
734
- {
735
- SassLiteral::assertType($number, 'SassNumber');
736
-
737
- return new SassNumber(abs($number->value).$number->units);
738
- }
739
-
740
- /**
741
- * Rounds a number up to the nearest whole number.
742
- * For example:
743
- * ceil(10.4px) => 11px
744
- * ceil(10.6px) => 11px
745
- *
746
- * @param SassNumber The number to round
747
- * @return new SassNumber The rounded number
748
- * @throws SassScriptFunctionException If $number is not a number
749
- */
750
- public static function ceil($number)
751
- {
752
- SassLiteral::assertType($number, 'SassNumber');
753
-
754
- return new SassNumber(ceil($number->value).$number->units);
755
- }
756
-
757
- /**
758
- * Rounds down to the nearest whole number.
759
- * For example:
760
- * floor(10.4px) => 10px
761
- * floor(10.6px) => 10px
762
- *
763
- * @param SassNumber The number to round
764
- * @return new SassNumber The rounded number
765
- * @throws SassScriptFunctionException If $value is not a number
766
- */
767
- public static function floor($number)
768
- {
769
- SassLiteral::assertType($number, 'SassNumber');
770
-
771
- return new SassNumber(floor($number->value).$number->units);
772
- }
773
-
774
- /**
775
- * Rounds a number to the nearest whole number.
776
- * For example:
777
- * round(10.4px) => 10px
778
- * round(10.6px) => 11px
779
- *
780
- * @param SassNumber The number to round
781
- * @return new SassNumber The rounded number
782
- * @throws SassScriptFunctionException If $number is not a number
783
- */
784
- public static function round($number)
785
- {
786
- SassLiteral::assertType($number, 'SassNumber');
787
-
788
- return new SassNumber(str_replace(',','.',round($number->value)).$number->units);
789
- }
790
-
791
- /**
792
- * Returns true if two numbers are similar enough to be added, subtracted,
793
- * or compared.
794
- * @param SassNumber The first number to test
795
- * @param SassNumber The second number to test
796
- * @return new SassBoolean True if the numbers are similar
797
- * @throws SassScriptFunctionException If $number1 or $number2 is not
798
- * a number
799
- */
800
- public static function comparable($number1, $number2)
801
- {
802
- SassLiteral::assertType($number1, 'SassNumber');
803
- SassLiteral::assertType($number2, 'SassNumber');
804
-
805
- return new SassBoolean($number1->isComparableTo($number2));
806
- }
807
-
808
- /**
809
- * Converts a decimal number to a percentage.
810
- * For example:
811
- * percentage(100px / 50px) => 200%
812
- *
813
- * @param SassNumber The decimal number to convert to a percentage
814
- * @return new SassNumber The number as a percentage
815
- * @throws SassScriptFunctionException If $number isn't a unitless number
816
- */
817
- public static function percentage($number)
818
- {
819
- $number->value *= 100;
820
- $number->units = '%';
821
-
822
- return $number;
823
- }
824
-
825
- public static function max()
826
- {
827
- $max = func_get_arg(0);
828
- foreach (func_get_args() as $var) {
829
- if ($var instanceOf SassNumber && $var->op_gt($max)->value) {
830
- $max = $var;
831
- }
832
- }
833
-
834
- return $max;
835
- }
836
-
837
- public static function min()
838
- {
839
- $min = func_get_arg(0);
840
- foreach (func_get_args() as $var) {
841
- if ($var instanceOf SassNumber && $var->op_lt($min)->value) {
842
- $min = $var;
843
- }
844
- }
845
-
846
- return $min;
847
- }
848
-
849
- /**
850
- * Inspects the unit of the number, returning it as a quoted string.
851
- * Alias for units.
852
- * @param SassNumber The number to inspect
853
- * @return new SassString The units of the number
854
- * @throws SassScriptFunctionException If $number is not a number
855
- * @see units
856
- */
857
- public static function unit($number)
858
- {
859
- return self::units($number);
860
- }
861
-
862
- /**
863
- * Inspects the units of the number, returning it as a quoted string.
864
- * @param SassNumber The number to inspect
865
- * @return new SassString The units of the number
866
- * @throws SassScriptFunctionException If $number is not a number
867
- */
868
- public static function units($number)
869
- {
870
- SassLiteral::assertType($number, 'SassNumber');
871
-
872
- return new SassString($number->units);
873
- }
874
-
875
- /**
876
- * Inspects the unit of the number, returning a boolean indicating if it is
877
- * unitless.
878
- * @param SassNumber The number to inspect
879
- * @return new SassBoolean True if the number is unitless, false if it has units.
880
- * @throws SassScriptFunctionException If $number is not a number
881
- */
882
- public static function unitless($number)
883
- {
884
- SassLiteral::assertType($number, 'SassNumber');
885
-
886
- return new SassBoolean($number->isUnitless());
887
- }
888
-
889
- /*
890
- * String Functions
891
- */
892
-
893
- /**
894
- * Add quotes to a string if the string isn't quoted,
895
- * or returns the same string if it is.
896
- * @param string String to quote
897
- * @return new SassString Quoted string
898
- * @throws SassScriptFunctionException If $string is not a string
899
- * @see unquote
900
- */
901
- public static function quote($string)
902
- {
903
- SassLiteral::assertType($string, 'SassString');
904
-
905
- return new SassString('"'.$string->value.'"');
906
- }
907
-
908
- /**
909
- * Removes quotes from a string if the string is quoted, or returns the same
910
- * string if it's not.
911
- * @param string String to unquote
912
- * @return new SassString Unuoted string
913
- * @throws SassScriptFunctionException If $string is not a string
914
- * @see quote
915
- */
916
- public static function unquote($string)
917
- {
918
- if ($string instanceof SassString) {
919
- return new SassString($string->value);
920
- }
921
-
922
- return $string;
923
- }
924
-
925
- /**
926
- * Returns the variable whose name is the string.
927
- * @param string String to unquote
928
- * @return
929
- * @throws SassScriptFunctionException If $string is not a string
930
- */
931
- public static function get_var($string)
932
- {
933
- SassLiteral::assertType($string, 'SassString');
934
-
935
- return new SassString($string->toVar());
936
- }
937
-
938
- /**
939
- * List Functions - taken mostly from Compass
940
- */
941
-
942
- /**
943
- * Returns the length of the $list
944
- * @param SassList - the list to count
945
- * @return SassNumber
946
- */
947
- public static function length($list)
948
- {
949
- if ($list instanceOf SassString) {
950
- $list = new SassList($list->toString());
951
- }
952
-
953
- return new SassNumber($list->length());
954
- }
955
-
956
- /**
957
- * Returns the nth value ofthe $list
958
- * @param SassList - the list to get from
959
- * @param SassNumber - the value to get
960
- * @return anything
961
- */
962
- public static function nth($list, $n)
963
- {
964
- SassLiteral::assertType($n, 'SassNumber');
965
-
966
- if ($list instanceof SassString) {
967
- $list = new SassList($list->toString());
968
- }
969
-
970
- return $list->nth($n->value);
971
- }
972
-
973
- public static function join($one, $two, $sep = ', ')
974
- {
975
- return self::append($one, $two, $sep);
976
- }
977
-
978
- public static function append($list, $val, $sep = ', ')
979
- {
980
- if ($list instanceOf SassString) {
981
- $list = new SassList($list->toString());
982
- }
983
- $list->append($val, $sep);
984
-
985
- return $list;
986
- }
987
-
988
- public static function index($list, $value)
989
- {
990
- if (!($list instanceOf SassList)) {
991
- $list = new SassList($list->toString());
992
- }
993
-
994
- return $list->index($value);
995
- }
996
-
997
- // New function zip allows several lists to be combined into one list of lists. For example: zip(1px 1px 3px, solid dashed solid, red green blue) becomes 1px solid red, 1px dashed green, 3px solid blue
998
- public function zip()
999
- {
1000
- $result = new SassList('', ',');
1001
- foreach (func_get_args() as $i => $arg) {
1002
- $list = new SassList($arg);
1003
- foreach ($list->value as $j => $val) {
1004
- $result->value += array($j => new SassList('', 'space'));
1005
- $result->value[$j]->value[] = (string) $val;
1006
- }
1007
- }
1008
-
1009
- return $result;
1010
- }
1011
-
1012
- /*
1013
- * Misc. Functions
1014
- */
1015
-
1016
- /**
1017
- * An inline "if-else" statement.
1018
- * @param SassBoolean condition - values are loosely-evaulated by PHP, so
1019
- * 'false' includes null, false, 0, ''
1020
- * @param anything - returns if Condition is true
1021
- * @param anything - returns if Condition is false
1022
- */
1023
- public static function _if($condition, $if_true, $if_false)
1024
- {
1025
- return ($condition->value ? $if_true : $if_false);
1026
- }
1027
-
1028
- /**
1029
- * Inspects the type of the argument, returning it as an unquoted string.
1030
- * @param SassLiteral The object to inspect
1031
- * @return new SassString The type of object
1032
- * @throws SassScriptFunctionException If $obj is not an instance of a
1033
- * SassLiteral
1034
- */
1035
- public static function type_of($obj)
1036
- {
1037
- SassLiteral::assertType($obj, 'SassLiteral');
1038
-
1039
- return new SassString($obj->typeOf);
1040
- }
1041
-
1042
- /**
1043
- * Ensures the value is within the given range, clipping it if needed.
1044
- * @param float the value to test
1045
- * @param float the minimum value
1046
- * @param float the maximum value
1047
- * @return the value clipped to the range
1048
- */
1049
- public static function inRange($value, $min, $max)
1050
- {
1051
- return ($value < $min ? $min : ($value > $max ? $max : $value));
1052
- }
1053
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/script/SassScriptLexer.php DELETED
@@ -1,129 +0,0 @@
1
- <?php
2
- /* SVN FILE: $Id$ */
3
- /**
4
- * SassScriptLexer 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.script
10
- */
11
-
12
- require_once 'literals/SassBoolean.php';
13
- require_once 'literals/SassColour.php';
14
- require_once 'literals/SassNumber.php';
15
- require_once 'literals/SassString.php';
16
- require_once 'literals/SassList.php';
17
- require_once 'SassScriptFunction.php';
18
- require_once 'SassScriptOperation.php';
19
- require_once 'SassScriptVariable.php';
20
-
21
- /**
22
- * SassScriptLexer class.
23
- * Lexes SassSCript into tokens for the parser.
24
- *
25
- * Implements a {@link http://en.wikipedia.org/wiki/Shunting-yard_algorithm Shunting-yard algorithm} to provide {@link http://en.wikipedia.org/wiki/Reverse_Polish_notation Reverse Polish notation} output.
26
- * @package PHamlP
27
- * @subpackage Sass.script
28
- */
29
- class SassScriptLexer
30
- {
31
- const MATCH_WHITESPACE = '/^\s+/';
32
-
33
- /**
34
- * Static holder for last instance of SassScriptLexer
35
- */
36
- public static $instance;
37
-
38
- /**
39
- * @var SassScriptParser the parser object
40
- */
41
- public $parser;
42
-
43
- /**
44
- * SassScriptLexer constructor.
45
- * @return SassScriptLexer
46
- */
47
- public function __construct($parser)
48
- {
49
- $this->parser = $parser;
50
- self::$instance = $this;
51
- }
52
-
53
- /**
54
- * Lex an expression into SassScript tokens.
55
- * @param string expression to lex
56
- * @param SassContext the context in which the expression is lexed
57
- * @return array tokens
58
- */
59
- public function lex($string, $context)
60
- {
61
- // if it's already lexed, just return it as-is
62
- if (is_object($string)) {
63
- return array($string);
64
- }
65
- if (is_array($string)) {
66
- return $string;
67
- }
68
- // whilst the string is not empty, split it into it's tokens.
69
- while ($string !== false) {
70
- if (($match = $this->isWhitespace($string)) !== false) {
71
- $tokens[] = null;
72
- } elseif (($match = SassScriptFunction::isa($string)) !== false) {
73
- preg_match(SassScriptFunction::MATCH_FUNC, $match, $matches);
74
- $args = array();
75
- foreach (SassScriptFunction::extractArgs($matches[SassScriptFunction::ARGS], false, $context) as $key => $expression) {
76
- $args[$key] = $this->parser->evaluate($expression, $context);
77
- }
78
- $tokens[] = new SassScriptFunction($matches[SassScriptFunction::NAME], $args);
79
- } elseif (($match = SassBoolean::isa($string)) !== false) {
80
- $tokens[] = new SassBoolean($match);
81
- } elseif (($match = SassColour::isa($string)) !== false) {
82
- $tokens[] = new SassColour($match);
83
- } elseif (($match = SassNumber::isa($string)) !== false) {
84
- $tokens[] = new SassNumber($match);
85
- } elseif (($match = SassString::isa($string)) !== false) {
86
- $stringed = new SassString($match);
87
- if (strlen($stringed->quote) == 0 && SassList::isa($string) !== false) {
88
- $tokens[] = new SassList($string);
89
- } else {
90
- $tokens[] = $stringed;
91
- }
92
- } elseif ($string == '()') {
93
- $match = $string;
94
- $tokens[] = new SassList($match);
95
- } elseif (($match = SassScriptOperation::isa($string)) !== false) {
96
- $tokens[] = new SassScriptOperation($match);
97
- } elseif (($match = SassScriptVariable::isa($string)) !== false) {
98
- $tokens[] = new SassScriptVariable($match);
99
- } else {
100
- $_string = $string;
101
- $match = '';
102
- while (strlen($_string) && !$this->isWhitespace($_string)) {
103
- foreach (SassScriptOperation::$inStrOperators as $operator) {
104
- if (substr($_string, 0, strlen($operator)) == $operator) {
105
- break 2;
106
- }
107
- }
108
- $match .= $_string[0];
109
- $_string = substr($_string, 1);
110
- }
111
- $tokens[] = new SassString($match);
112
- }
113
- $string = substr($string, strlen($match));
114
- }
115
-
116
- return $tokens;
117
- }
118
-
119
- /**
120
- * Returns a value indicating if a token of this type can be matched at
121
- * the start of the subject string.
122
- * @param string the subject string
123
- * @return mixed match at the start of the string or false if no match
124
- */
125
- public function isWhitespace($subject)
126
- {
127
- return (preg_match(self::MATCH_WHITESPACE, $subject, $matches) ? $matches[0] : false);
128
- }
129
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/script/SassScriptOperation.php DELETED
@@ -1,195 +0,0 @@
1
- <?php
2
- /* SVN FILE: $Id$ */
3
- /**
4
- * SassScriptOperation 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.script
10
- */
11
-
12
- /**
13
- * SassScriptOperation class.
14
- * The operation to perform.
15
- * @package PHamlP
16
- * @subpackage Sass.script
17
- */
18
- class SassScriptOperation
19
- {
20
- const MATCH = '/^(\(|\)|\+|-|\*|\/|%|<=|>=|<|>|==|!=|=|#{|}|,|and\b|or\b|xor\b|not\b)/';
21
-
22
- /**
23
- * @var array map symbols to tokens.
24
- * A token is function, associativity, precedence, number of operands
25
- */
26
- public static $operators = array(
27
- '*' => array('times', 'l', 8, 2),
28
- '/' => array('div', 'l', 8, 2),
29
- '%' => array('modulo', 'l', 8, 2),
30
- '+' => array('plus', 'l', 7, 2),
31
- '-' => array('minus', 'l', 7, 2),
32
- '<<' => array('shiftl', 'l', 6, 2),
33
- '>>' => array('shiftr', 'l', 6, 2),
34
- '<=' => array('lte', 'l', 5, 2),
35
- '>=' => array('gte', 'l', 5, 2),
36
- '<' => array('lt', 'l', 5, 2),
37
- '>' => array('gt', 'l', 5, 2),
38
- '==' => array('eq', 'l', 4, 2),
39
- '!=' => array('neq', 'l', 4, 2),
40
- 'and' => array('and', 'l', 3, 2),
41
- 'or' => array('or', 'l', 3, 2),
42
- 'xor' => array('xor', 'l', 3, 2),
43
- 'not' => array('not', 'l', 4, 1), # precedence higher than and.
44
- '=' => array('assign', 'l', 2, 2),
45
- ')' => array('rparen', 'l', 10),
46
- '(' => array('lparen', 'l', 10),
47
- ',' => array('comma', 'l', 0, 2),
48
- '#{' => array('begin_interpolation'),
49
- '}' => array('end_interpolation'),
50
- );
51
-
52
- /**
53
- * @var array operators with meaning in uquoted strings;
54
- * selectors, property names and values
55
- */
56
- public static $inStrOperators = array(',', '#{', ')', '(');
57
-
58
- /**
59
- * @var array default operator token.
60
- */
61
- public static $defaultOperator = array('concat', 'l', 0, 2);
62
-
63
- /**
64
- * @var string operator for this operation
65
- */
66
- private $operator;
67
- /**
68
- * @var string associativity of the operator; left or right
69
- */
70
- private $associativity;
71
- /**
72
- * @var integer precedence of the operator
73
- */
74
- private $precedence;
75
- /**
76
- * @var integer number of operands required by the operator
77
- */
78
- private $operandCount = 0;
79
-
80
- /**
81
- * SassScriptOperation constructor
82
- *
83
- * @param mixed string: operator symbol; array: operator token
84
- * @return SassScriptOperation
85
- */
86
- public function __construct($operation)
87
- {
88
- if (is_string($operation)) {
89
- $operation = self::$operators[$operation];
90
- }
91
- $this->operator = $operation[0];
92
- if (isset($operation[1])) {
93
- $this->associativity = $operation[1];
94
- $this->precedence = $operation[2];
95
- $this->operandCount = (isset($operation[3]) ? $operation[3] : 0);
96
- }
97
- }
98
-
99
- /**
100
- * Getter function for properties
101
- * @param string name of property
102
- * @return mixed value of the property
103
- * @throws SassScriptOperationException if the property does not exist
104
- */
105
- public function __get($name)
106
- {
107
- if (property_exists($this, $name)) {
108
- return $this->$name;
109
- } else {
110
- throw new SassScriptOperationException('Unknown property: ' . $name, SassScriptParser::$context->node);
111
- }
112
- }
113
-
114
- /**
115
- * Performs this operation.
116
- * @param array operands for the operation. The operands are SassLiterals
117
- * @return SassLiteral the result of the operation
118
- * @throws SassScriptOperationException if the oprand count is incorrect or
119
- * the operation is undefined
120
- */
121
- public function perform($operands)
122
- {
123
- if (count($operands) !== $this->operandCount) {
124
- throw new SassScriptOperationException('Incorrect operand count for ' . get_class($operands[0]) . '; expected ' . $this->operandCount . ', received ' . count($operands), SassScriptParser::$context->node);
125
- }
126
-
127
- if (!count($operands)) {
128
- return $operands;
129
- }
130
-
131
- // fix a bug of unknown origin
132
- foreach ($operands as $i => $op) {
133
- if (!is_object($op)) {
134
- $operands[] = null;
135
- unset ($operands[$i]);
136
- }
137
- }
138
- $operands = array_values($operands);
139
-
140
- if (count($operands) > 1 && is_null($operands[1])) {
141
- $operation = 'op_unary_' . $this->operator;
142
- } else {
143
- $operation = 'op_' . $this->operator;
144
- if ($this->associativity == 'l') {
145
- $operands = array_reverse($operands);
146
- }
147
- }
148
-
149
- if (method_exists($operands[0], $operation)) {
150
- $op = clone $operands[0];
151
-
152
- return $op->$operation(!empty($operands[1]) ? $operands[1] : null);
153
- }
154
-
155
- # avoid failures in case of null operands
156
- $count = count($operands);
157
- foreach ($operands as $i => $op) {
158
- if (is_null($op)) {
159
- $count--;
160
- }
161
- }
162
-
163
- if ($count) {
164
- throw new SassScriptOperationException('Undefined operation "' . $operation . '" for ' . get_class($operands[0]), SassScriptParser::$context->node);
165
- }
166
- }
167
-
168
- /**
169
- * Returns a value indicating if a token of this type can be matched at
170
- * the start of the subject string.
171
- * @param string the subject string
172
- * @return mixed match at the start of the string or false if no match
173
- */
174
- public static function isa($subject)
175
- {
176
- # begins with a "/x", almost always a path without quotes.
177
- if (preg_match('/^\/[^0-9\.\-\s]+/', $subject)) {
178
- return FALSE;
179
- }
180
-
181
- return (preg_match(self::MATCH, $subject, $matches) ? trim($matches[1]) : false);
182
- }
183
-
184
- /**
185
- * Converts the operation back into it's SASS representation
186
- */
187
- public function __toString()
188
- {
189
- foreach (SassScriptOperation::$operators as $char => $operator) {
190
- if ($operator[0] == trim($this->operator)) {
191
- return $char;
192
- }
193
- }
194
- }
195
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/script/SassScriptParser.php DELETED
@@ -1,256 +0,0 @@
1
- <?php
2
- /* SVN FILE: $Id$ */
3
- /**
4
- * SassScriptParser 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.script
10
- */
11
-
12
- require_once 'SassScriptLexer.php';
13
- require_once 'SassScriptParserExceptions.php';
14
-
15
- /**
16
- * SassScriptParser class.
17
- * Parses SassScript. SassScript is lexed into {@link http://en.wikipedia.org/wiki/Reverse_Polish_notation Reverse Polish notation} by the SassScriptLexer and
18
- * the calculated result returned.
19
- * @package PHamlP
20
- * @subpackage Sass.script
21
- */
22
- class SassScriptParser
23
- {
24
- const MATCH_INTERPOLATION = '/(?<!\\\\)#\{(.*?)\}/';
25
- const DEFAULT_ENV = 0;
26
- const CSS_RULE = 1;
27
- const CSS_PROPERTY = 2;
28
-
29
- /**
30
- * @var SassContext Used for error reporting
31
- */
32
- public static $context;
33
-
34
- /**
35
- * @var SassScriptLexer the lexer object
36
- */
37
- public $lexer;
38
-
39
- /**
40
- * Hold a copy of a parser available to the general public.
41
- */
42
- public static $instance;
43
-
44
- /**
45
- * SassScriptParser constructor.
46
- * @return SassScriptParser
47
- */
48
- public function __construct()
49
- {
50
- $this->lexer = new SassScriptLexer($this);
51
- self::$instance = $this;
52
- }
53
-
54
- /**
55
- * Replace interpolated SassScript contained in '#{}' with the parsed value.
56
- * @param string the text to interpolate
57
- * @param SassContext the context in which the string is interpolated
58
- * @return string the interpolated text
59
- */
60
- public function interpolate($string, $context)
61
- {
62
- for ($i = 0, $n = preg_match_all(self::MATCH_INTERPOLATION, $string, $matches); $i < $n; $i++) {
63
- $var = $this->evaluate($matches[1][$i], $context);
64
-
65
- if ($var instanceOf SassString) {
66
- $var = $var->value;
67
- } else {
68
- $var = $var->toString();
69
- }
70
-
71
- if (preg_match('/^unquote\((["\'])(.*)\1\)$/', $var, $match)) {
72
- $val = $match[2];
73
- } elseif ($var == '""') {
74
- $val = "";
75
- } elseif (preg_match('/^(["\'])(.*)\1$/', $var, $match)) {
76
- $val = $match[2];
77
- } else {
78
- $val = $var;
79
- }
80
- $matches[1][$i] = $val;
81
- }
82
-
83
- return str_replace($matches[0], $matches[1], $string);
84
- }
85
-
86
- /**
87
- * Evaluate a SassScript.
88
- * @param string expression to parse
89
- * @param SassContext the context in which the expression is evaluated
90
- * @param integer the environment in which the expression is evaluated
91
- * @return SassLiteral parsed value
92
- */
93
- public function evaluate($expression, $context, $environment = self::DEFAULT_ENV)
94
- {
95
- self::$context = $context;
96
- $operands = array();
97
-
98
- $tokens = $this->parse($expression, $context, $environment);
99
-
100
- while (count($tokens)) {
101
- $token = array_shift($tokens);
102
- if ($token instanceof SassScriptFunction) {
103
- $perform = $token->perform();
104
- array_push($operands, $perform);
105
- } elseif ($token instanceof SassLiteral) {
106
- if ($token instanceof SassString) {
107
- $token = new SassString($this->interpolate($token->toString(), self::$context));
108
- }
109
- array_push($operands, $token);
110
- } else {
111
- $args = array();
112
- for ($i = 0, $c = $token->operandCount; $i < $c; $i++) {
113
- $args[] = array_pop($operands);
114
- }
115
- array_push($operands, $token->perform($args));
116
- }
117
- }
118
-
119
- return self::makeSingular($operands);
120
- }
121
-
122
- /**
123
- * Parse SassScript to a set of tokens in RPN
124
- * using the Shunting Yard Algorithm.
125
- * @param string expression to parse
126
- * @param SassContext the context in which the expression is parsed
127
- * @param integer the environment in which the expression is parsed
128
- * @return array tokens in RPN
129
- */
130
- public function parse($expression, $context, $environment=self::DEFAULT_ENV)
131
- {
132
- $outputQueue = array();
133
- $operatorStack = array();
134
- $parenthesis = 0;
135
-
136
- $tokens = $this->lexer->lex($expression, $context);
137
-
138
- foreach ($tokens as $i=>$token) {
139
- // If two literals/expessions are seperated by whitespace use the concat operator
140
- if (empty($token)) {
141
- if (isset($tokens[$i+1])) {
142
- if ($i > 0 && (!$tokens[$i-1] instanceof SassScriptOperation || $tokens[$i-1]->operator === SassScriptOperation::$operators[')'][0]) &&
143
- (!$tokens[$i+1] instanceof SassScriptOperation || $tokens[$i+1]->operator === SassScriptOperation::$operators['('][0])) {
144
- $token = new SassScriptOperation(SassScriptOperation::$defaultOperator, $context);
145
- } else {
146
- continue;
147
- }
148
- }
149
- } elseif ($token instanceof SassScriptVariable) {
150
- $token = $token->evaluate($context);
151
- $environment = self::DEFAULT_ENV;
152
- }
153
-
154
- // If the token is a number or function add it to the output queue.
155
- if ($token instanceof SassLiteral || $token instanceof SassScriptFunction) {
156
- if ($environment === self::CSS_PROPERTY && $token instanceof SassNumber && !$parenthesis) {
157
- $token->inExpression = false;
158
- }
159
- array_push($outputQueue, $token);
160
- }
161
- // If the token is an operation
162
- elseif ($token instanceof SassScriptOperation) {
163
- // If the token is a left parenthesis push it onto the stack.
164
- if ($token->operator == SassScriptOperation::$operators['('][0]) {
165
- array_push($operatorStack, $token);
166
- $parenthesis++;
167
- }
168
- // If the token is a right parenthesis:
169
- elseif ($token->operator == SassScriptOperation::$operators[')'][0]) {
170
- $parenthesis--;
171
- while ($c = count($operatorStack)) {
172
- // If the token at the top of the stack is a left parenthesis
173
- if ($operatorStack[$c - 1]->operator == SassScriptOperation::$operators['('][0]) {
174
- // Pop the left parenthesis from the stack, but not onto the output queue.
175
- array_pop($operatorStack);
176
- break;
177
- }
178
- // else pop the operator off the stack onto the output queue.
179
- array_push($outputQueue, array_pop($operatorStack));
180
- }
181
- // If the stack runs out without finding a left parenthesis
182
- // there are mismatched parentheses.
183
- if ($c <= 0) {
184
- array_push($outputQueue, new SassString(')'));
185
- break;
186
- throw new SassScriptParserException('Unmatched parentheses', $context->node);
187
- }
188
- }
189
- // the token is an operator, o1, so:
190
- else {
191
- // while there is an operator, o2, at the top of the stack
192
- while ($c = count($operatorStack)) {
193
- $operation = $operatorStack[$c - 1];
194
- // if o2 is left parenthesis, or
195
- // the o1 has left associativty and greater precedence than o2, or
196
- // the o1 has right associativity and lower or equal precedence than o2
197
- if (($operation->operator == SassScriptOperation::$operators['('][0]) ||
198
- ($token->associativity == 'l' && $token->precedence > $operation->precedence) ||
199
- ($token->associativity == 'r' && $token->precedence <= $operation->precedence)) {
200
- break; // stop checking operators
201
- }
202
- //pop o2 off the stack and onto the output queue
203
- array_push($outputQueue, array_pop($operatorStack));
204
- }
205
- // push o1 onto the stack
206
- array_push($operatorStack, $token);
207
- }
208
- }
209
- }
210
-
211
- // When there are no more tokens
212
- while ($c = count($operatorStack)) { // While there are operators on the stack:
213
- if ($operatorStack[$c - 1]->operator !== SassScriptOperation::$operators['('][0]) {
214
- array_push($outputQueue, array_pop($operatorStack));
215
- } else {
216
- throw new SassScriptParserException('Unmatched parentheses', $context->node);
217
- }
218
- }
219
-
220
- return $outputQueue;
221
- }
222
-
223
- /**
224
- * Reduces a set down to a singular form
225
- */
226
- public static function makeSingular($operands)
227
- {
228
- if (count($operands) == 1) {
229
- return $operands[0];
230
- }
231
-
232
- $result = null;
233
- foreach ($operands as $i => $operand) {
234
- if (is_object($operand)) {
235
- if (!$result) {
236
- $result = $operand;
237
- continue;
238
- }
239
- if ($result instanceOf SassString) {
240
- $result = $result->op_concat($operand);
241
- } else {
242
- $result = $result->op_plus($operand);
243
- }
244
- } else {
245
- $string = new SassString(' ');
246
- if (!$result) {
247
- $result = $string;
248
- } else {
249
- $result = $result->op_plus($string);
250
- }
251
- }
252
- }
253
-
254
- return $result ? $result : array_shift($operands);
255
- }
256
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/script/SassScriptParserExceptions.php DELETED
@@ -1,40 +0,0 @@
1
- <?php
2
- /* SVN FILE: $Id$ */
3
- /**
4
- * SassScript Parser exception 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.script
10
- */
11
-
12
- require_once(dirname(__FILE__).'/../SassException.php');
13
-
14
- /**
15
- * SassScriptParserException class.
16
- * @package PHamlP
17
- * @subpackage Sass.script
18
- */
19
- class SassScriptParserException extends SassException {}
20
-
21
- /**
22
- * SassScriptLexerException class.
23
- * @package PHamlP
24
- * @subpackage Sass.script
25
- */
26
- class SassScriptLexerException extends SassScriptParserException {}
27
-
28
- /**
29
- * SassScriptOperationException class.
30
- * @package PHamlP
31
- * @subpackage Sass.script
32
- */
33
- class SassScriptOperationException extends SassScriptParserException {}
34
-
35
- /**
36
- * SassScriptFunctionException class.
37
- * @package PHamlP
38
- * @subpackage Sass.script
39
- */
40
- class SassScriptFunctionException extends SassScriptParserException {}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/script/SassScriptVariable.php DELETED
@@ -1,61 +0,0 @@
1
- <?php
2
- /* SVN FILE: $Id: SassVariable.php 49 2010-04-04 10:51:24Z chris.l.yates $ */
3
- /**
4
- * SassVariable 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.script.literals
10
- */
11
-
12
- /**
13
- * SassVariable class.
14
- * @package PHamlP
15
- * @subpackage Sass.script.literals
16
- */
17
- class SassScriptVariable
18
- {
19
- /**
20
- * Regex for matching and extracting Variables
21
- */
22
- const MATCH = '/^(?<!\\\\)(?(?!!important\b)[!\$]([\w-]+))/';
23
-
24
- /**
25
- * @var string name of variable
26
- */
27
- private $name;
28
-
29
- /**
30
- * SassVariable constructor
31
- * @param string value of the Variable type
32
- * @return SassVariable
33
- */
34
- public function __construct($value)
35
- {
36
- $this->name = substr($value, 1);
37
- }
38
-
39
- /**
40
- * Returns the SassScript object for this variable.
41
- * @param SassContext context of the variable
42
- * @return SassLiteral the SassScript object for this variable
43
- */
44
- public function evaluate($context)
45
- {
46
- return $context->getVariable($this->name);
47
- }
48
-
49
- /**
50
- * Returns a value indicating if a token of this type can be matched at
51
- * the start of the subject string.
52
- * @param string the subject string
53
- * @return mixed match at the start of the string or false if no match
54
- */
55
- public static function isa($subject)
56
- {
57
- // we need to do the check as preg_match returns a count of 1 if
58
- // subject == '!important'; the match being an empty match
59
- return (preg_match(self::MATCH, $subject, $matches) ? (empty($matches[0]) ? false : $matches[0]) : false);
60
- }
61
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/script/literals/SassBoolean.php DELETED
@@ -1,84 +0,0 @@
1
- <?php
2
- /* SVN FILE: $Id$ */
3
- /**
4
- * SassBoolean 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.script.literals
10
- */
11
-
12
- require_once 'SassLiteral.php';
13
-
14
- /**
15
- * SassBoolean class.
16
- * @package PHamlP
17
- * @subpackage Sass.script.literals
18
- */
19
- class SassBoolean extends SassLiteral
20
- {
21
- /**@#+
22
- * Regex for matching and extracting booleans
23
- */
24
- const MATCH = '/^(true|false)\b/';
25
-
26
- /**
27
- * SassBoolean constructor
28
- * @param string value of the boolean type
29
- * @return SassBoolean
30
- */
31
- public function __construct($value)
32
- {
33
- if (is_bool($value)) {
34
- $this->value = $value;
35
- } elseif ($value === 'true' || $value === 'false') {
36
- $this->value = ($value === 'true' ? true : false);
37
- } else {
38
- throw new SassBooleanException('Invalid SassBoolean', SassScriptParser::$context->node);
39
- }
40
- }
41
-
42
- /**
43
- * Returns the value of this boolean.
44
- * @return boolean the value of this boolean
45
- */
46
- public function getValue()
47
- {
48
- return $this->value;
49
- }
50
-
51
- /**
52
- * Returns a string representation of the value.
53
- * @return string string representation of the value.
54
- */
55
- public function toString()
56
- {
57
- return $this->getValue() ? 'true' : 'false';
58
- }
59
-
60
- public function length()
61
- {
62
- return 1;
63
- }
64
-
65
- public function nth($i)
66
- {
67
- if ($i == 1 && isset($this->value)) {
68
- return new SassBoolean($this->value);
69
- }
70
-
71
- return new SassBoolean(false);
72
- }
73
-
74
- /**
75
- * Returns a value indicating if a token of this type can be matched at
76
- * the start of the subject string.
77
- * @param string the subject string
78
- * @return mixed match at the start of the string or false if no match
79
- */
80
- public static function isa($subject)
81
- {
82
- return (preg_match(self::MATCH, $subject, $matches) ? $matches[0] : false);
83
- }
84
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/script/literals/SassColour.php DELETED
@@ -1,956 +0,0 @@
1
- <?php
2
- /* SVN FILE: $Id$ */
3
- /**
4
- * SassColour 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.script.literals
10
- */
11
-
12
- require_once 'SassLiteral.php';
13
-
14
- /**
15
- * SassColour class.
16
- * A SassScript object representing a CSS colour.
17
- *
18
- * A colour may be represented internally as RGBA, HSLA, or both. It is
19
- * originally represented as whatever its input is; if it’s created with RGB
20
- * values, it’s represented as RGBA, and if it’s created with HSL values, it’s
21
- * represented as HSLA. Once a property is accessed that requires the other
22
- * representation – for example, SassColour::red for an HSL color – that
23
- * component is calculated and cached.
24
- *
25
- * The alpha channel of a color is independent of its RGB or HSL representation.
26
- * It’s always stored, as 1 if nothing else is specified. If only the alpha
27
- * channel is modified using SassColour::with(), the cached RGB and HSL values
28
- * are retained.
29
- *
30
- * Colour operations are all piecewise, e.g. when adding two colours each
31
- * component is added independantly; Rr = R1 + R2, Gr = G1 + G2, Br = B1 + B2.
32
- *
33
- * Colours are returned as a named colour if possible or #rrggbb.
34
- *
35
- * @package PHamlP
36
- * @subpackage Sass.script.literals
37
- */
38
- class SassColour extends SassLiteral
39
- {
40
- /**@#+
41
- * Regexes for matching and extracting colours
42
- */
43
- const MATCH = '/^((#([\da-f]{6}|[\da-f]{3}))|transparent|{CSS_COLOURS})/';
44
- const EXTRACT_3 = '/#([\da-f])([\da-f])([\da-f])$/';
45
- const EXTRACT_6 = '/#([\da-f]{2})([\da-f]{2})([\da-f]{2})/';
46
- const TRANSPARENT = 'transparent';
47
- /**@#-*/
48
-
49
- /**@#-*/
50
- public static $svgColours = array(
51
- 'aliceblue' => '#f0f8ff',
52
- 'antiquewhite' => '#faebd7',
53
- 'aqua' => '#00ffff',
54
- 'aquamarine' => '#7fffd4',
55
- 'azure' => '#f0ffff',
56
- 'beige' => '#f5f5dc',
57
- 'bisque' => '#ffe4c4',
58
- 'black' => '#000000',
59
- 'blanchedalmond' => '#ffebcd',
60
- 'blue' => '#0000ff',
61
- 'blueviolet' => '#8a2be2',
62
- 'brown' => '#a52a2a',
63
- 'burlywood' => '#deb887',
64
- 'cadetblue' => '#5f9ea0',
65
- 'chartreuse' => '#7fff00',
66
- 'chocolate' => '#d2691e',
67
- 'coral' => '#ff7f50',
68
- 'cornflowerblue' => '#6495ed',
69
- 'cornsilk' => '#fff8dc',
70
- 'crimson' => '#dc143c',
71
- 'cyan' => '#00ffff',
72
- 'darkblue' => '#00008b',
73
- 'darkcyan' => '#008b8b',
74
- 'darkgoldenrod' => '#b8860b',
75
- 'darkgreen' => '#006400',
76
- 'darkkhaki' => '#bdb76b',
77
- 'darkmagenta' => '#8b008b',
78
- 'darkolivegreen' => '#556b2f',
79
- 'darkorange' => '#ff8c00',
80
- 'darkorchid' => '#9932cc',
81
- 'darkred' => '#8b0000',
82
- 'darksalmon' => '#e9967a',
83
- 'darkseagreen' => '#8fbc8f',
84
- 'darkslateblue' => '#483d8b',
85
- 'darkslategray' => '#2f4f4f',
86
- 'darkslategrey' => '#2f4f4f',
87
- 'darkturquoise' => '#00ced1',
88
- 'darkviolet' => '#9400d3',
89
- 'deeppink' => '#ff1493',
90
- 'deepskyblue' => '#00bfff',
91
- 'dimgray' => '#696969',
92
- 'dimgrey' => '#696969',
93
- 'dodgerblue' => '#1e90ff',
94
- 'firebrick' => '#b22222',
95
- 'floralwhite' => '#fffaf0',
96
- 'forestgreen' => '#228b22',
97
- 'fuchsia' => '#ff00ff',
98
- 'gainsboro' => '#dcdcdc',
99
- 'ghostwhite' => '#f8f8ff',
100
- 'gold' => '#ffd700',
101
- 'goldenrod' => '#daa520',
102
- 'gray' => '#808080',
103
- 'green' => '#008000',
104
- 'greenyellow' => '#adff2f',
105
- 'grey' => '#808080',
106
- 'honeydew' => '#f0fff0',
107
- 'hotpink' => '#ff69b4',
108
- 'indianred' => '#cd5c5c',
109
- 'indigo' => '#4b0082',
110
- 'ivory' => '#fffff0',
111
- 'khaki' => '#f0e68c',
112
- 'lavender' => '#e6e6fa',
113
- 'lavenderblush' => '#fff0f5',
114
- 'lawngreen' => '#7cfc00',
115
- 'lemonchiffon' => '#fffacd',
116
- 'lightblue' => '#add8e6',
117
- 'lightcoral' => '#f08080',
118
- 'lightcyan' => '#e0ffff',
119
- 'lightgoldenrodyellow' => '#fafad2',
120
- 'lightgray' => '#d3d3d3',
121
- 'lightgreen' => '#90ee90',
122
- 'lightgrey' => '#d3d3d3',
123
- 'lightpink' => '#ffb6c1',
124
- 'lightsalmon' => '#ffa07a',
125
- 'lightseagreen' => '#20b2aa',
126
- 'lightskyblue' => '#87cefa',
127
- 'lightslategray' => '#778899',
128
- 'lightslategrey' => '#778899',
129
- 'lightsteelblue' => '#b0c4de',
130
- 'lightyellow' => '#ffffe0',
131
- 'lime' => '#00ff00',
132
- 'limegreen' => '#32cd32',
133
- 'linen' => '#faf0e6',
134
- 'magenta' => '#ff00ff',
135
- 'maroon' => '#800000',
136
- 'mediumaquamarine' => '#66cdaa',
137
- 'mediumblue' => '#0000cd',
138
- 'mediumorchid' => '#ba55d3',
139
- 'mediumpurple' => '#9370db',
140
- 'mediumseagreen' => '#3cb371',
141
- 'mediumslateblue' => '#7b68ee',
142
- 'mediumspringgreen' => '#00fa9a',
143
- 'mediumturquoise' => '#48d1cc',
144
- 'mediumvioletred' => '#c71585',
145
- 'midnightblue' => '#191970',
146
- 'mintcream' => '#f5fffa',
147
- 'mistyrose' => '#ffe4e1',
148
- 'moccasin' => '#ffe4b5',
149
- 'navajowhite' => '#ffdead',
150
- 'navy' => '#000080',
151
- 'oldlace' => '#fdf5e6',
152
- 'olive' => '#808000',
153
- 'olivedrab' => '#6b8e23',
154
- 'orange' => '#ffa500',
155
- 'orangered' => '#ff4500',
156
- 'orchid' => '#da70d6',
157
- 'palegoldenrod' => '#eee8aa',
158
- 'palegreen' => '#98fb98',
159
- 'paleturquoise' => '#afeeee',
160
- 'palevioletred' => '#db7093',
161
- 'papayawhip' => '#ffefd5',
162
- 'peachpuff' => '#ffdab9',
163
- 'peru' => '#cd853f',
164
- 'pink' => '#ffc0cb',
165
- 'plum' => '#dda0dd',
166
- 'powderblue' => '#b0e0e6',
167
- 'purple' => '#800080',
168
- 'red' => '#ff0000',
169
- 'rosybrown' => '#bc8f8f',
170
- 'royalblue' => '#4169e1',
171
- 'saddlebrown' => '#8b4513',
172
- 'salmon' => '#fa8072',
173
- 'sandybrown' => '#f4a460',
174
- 'seagreen' => '#2e8b57',
175
- 'seashell' => '#fff5ee',
176
- 'sienna' => '#a0522d',
177
- 'silver' => '#c0c0c0',
178
- 'skyblue' => '#87ceeb',
179
- 'slateblue' => '#6a5acd',
180
- 'slategray' => '#708090',
181
- 'slategrey' => '#708090',
182
- 'snow' => '#fffafa',
183
- 'springgreen' => '#00ff7f',
184
- 'steelblue' => '#4682b4',
185
- 'tan' => '#d2b48c',
186
- 'teal' => '#008080',
187
- 'thistle' => '#d8bfd8',
188
- 'tomato' => '#ff6347',
189
- 'turquoise' => '#40e0d0',
190
- 'violet' => '#ee82ee',
191
- 'wheat' => '#f5deb3',
192
- 'white' => '#ffffff',
193
- 'whitesmoke' => '#f5f5f5',
194
- 'yellow' => '#ffff00',
195
- 'yellowgreen' => '#9acd32'
196
- );
197
-
198
- /**
199
- * @var array reverse array (value => name) of named SVG1.0 colours
200
- */
201
- public static $_svgColours;
202
-
203
- /**
204
- * @var array reverse array (value => name) of named HTML4 colours
205
- */
206
- public static $_html4Colours = array(
207
- '#000000' => 'black',
208
- '#000080' => 'navy',
209
- '#0000ff' => 'blue',
210
- '#008000' => 'green',
211
- '#008080' => 'teal',
212
- '#00ff00' => 'lime',
213
- '#00ffff' => 'aqua',
214
- '#800000' => 'maroon',
215
- '#800080' => 'purple',
216
- '#808000' => 'olive',
217
- '#808080' => 'gray',
218
- '#c0c0c0' => 'silver',
219
- '#ff0000' => 'red',
220
- '#ff00ff' => 'fuchsia',
221
- '#ffff00' => 'yellow',
222
- '#ffffff' => 'white',
223
- );
224
-
225
- public static $regex;
226
-
227
- /**@#+
228
- * RGB colour components
229
- */
230
- /**
231
- * @var array RGB colour components. Used to check for RGB attributes.
232
- */
233
- public static $rgb = array('red', 'green', 'blue');
234
- /**
235
- * @var integer red component. 0 - 255
236
- */
237
- public $red;
238
- /**
239
- * @var integer green component. 0 - 255
240
- */
241
- public $green;
242
- /**
243
- * @var integer blue component. 0 - 255
244
- */
245
- public $blue;
246
- /**@#-*/
247
- /**@#+
248
- * HSL colour components
249
- */
250
- /**
251
- * @var array HSL colour components. Used to check for HSL attributes.
252
- */
253
- public static $hsl = array('hue', 'saturation', 'lightness');
254
- /**
255
- * @var float hue component. 0 - 360
256
- */
257
- public $hue;
258
- /**
259
- * @var float saturation component. 0 - 100
260
- */
261
- public $saturation;
262
- /**
263
- * @var float lightness component. 0 - 100
264
- */
265
- public $lightness;
266
- /**@#-*/
267
- /**
268
- * @var float alpha component. 0 - 1
269
- */
270
- public $alpha = 1;
271
-
272
- /**
273
- * Constructs an RGB or HSL color object, optionally with an alpha channel.
274
- * RGB values must be between 0 and 255. Saturation and lightness values must
275
- * be between 0 and 100. The alpha value must be between 0 and 1.
276
- * The colour can be specified as:
277
- * + a string that is an SVG colour or of the form #rgb or #rrggbb
278
- * + an array with either 'red', 'green', and 'blue' keys, and optionally
279
- * an alpha key.
280
- * + an array with 'hue', 'saturation', and 'lightness' keys, and optionally
281
- * an alpha key.
282
- * + an array of red, green, and blue values, and optionally an alpha value.
283
- * @param mixed the colour
284
- * @return SassColour
285
- */
286
- public function __construct($colour)
287
- {
288
- if (is_string($colour)) {
289
- $colour = strtolower($colour);
290
- if ($colour === self::TRANSPARENT) {
291
- $this->red = 0;
292
- $this->green = 0;
293
- $this->blue = 0;
294
- $this->alpha = 0;
295
- } else {
296
- if (array_key_exists($colour, self::$svgColours)) {
297
- $colour = self::$svgColours[$colour];
298
- }
299
- if (preg_match(self::EXTRACT_3, $colour, $matches)) {
300
- for ($i = 1; $i < 4; $i++) {
301
- $matches[$i] = str_repeat($matches[$i], 2);
302
- }
303
- } else {
304
- preg_match(self::EXTRACT_6, $colour, $matches);
305
- }
306
-
307
- if (empty($matches)) {
308
- throw new SassColourException('Invalid SassColour string', SassScriptParser::$context->node);
309
- }
310
- $this->red = intval($matches[1], 16);
311
- $this->green = intval($matches[2], 16);
312
- $this->blue = intval($matches[3], 16);
313
- $this->alpha = 1;
314
- }
315
- } elseif (is_array($colour)) {
316
- $scheme = $this->assertValid($colour);
317
- if ($scheme == 'rgb') {
318
- $this->red = $colour['red'];
319
- $this->green = $colour['green'];
320
- $this->blue = $colour['blue'];
321
- $this->alpha = (isset($colour['alpha']) ? $colour['alpha'] : 1);
322
- } elseif ($scheme == 'hsl') {
323
- $this->hue = $colour['hue'];
324
- $this->saturation = $colour['saturation'];
325
- $this->lightness = $colour['lightness'];
326
- $this->alpha = (isset($colour['alpha']) ? $colour['alpha'] : 1);
327
- } else {
328
- $this->red = $colour[0];
329
- $this->green = $colour[1];
330
- $this->blue = $colour[2];
331
- $this->alpha = (isset($colour[3]) ? $colour[3] : 1);
332
- }
333
- } else {
334
- throw new SassColourException('Colour must be a array', SassScriptParser::$context->node);
335
- }
336
- }
337
-
338
- /**
339
- * Colour addition
340
- * @param mixed SassColour|SassNumber value to add
341
- * @return sassColour the colour result
342
- */
343
- public function op_plus($other)
344
- {
345
- if ($other instanceof SassNumber) {
346
- if (!$other->isUnitless()) {
347
- return new SassString($this->toString() . $other->value);
348
- throw new SassColourException('Number must be a unitless number', SassScriptParser::$context->node);
349
- }
350
- $this->red = $this->getRed() + $other->value;
351
- $this->green = $this->getGreen() + $other->value;
352
- $this->blue = $this->getBlue() + $other->value;
353
- } elseif (!$other instanceof SassColour) {
354
- return new SassString($this->toString() . $other->value);
355
- throw new SassColourException('Argument must be a SassColour or SassNumber', SassScriptParser::$context->node);
356
- } else {
357
- $this->red = $this->getRed() + $other->getRed();
358
- $this->green = $this->getGreen() + $other->getGreen();
359
- $this->blue = $this->getBlue() + $other->getBlue();
360
- }
361
-
362
- return $this;
363
- }
364
-
365
- /**
366
- * Colour subraction
367
- * @param mixed value (SassColour or SassNumber) to subtract
368
- * @return sassColour the colour result
369
- */
370
- public function op_minus($other)
371
- {
372
- if ($other instanceof SassNumber) {
373
- if (!$other->isUnitless()) {
374
- throw new SassColourException('Number must be a unitless number', SassScriptParser::$context->node);
375
- }
376
- $this->red = $this->getRed() - $other->value;
377
- $this->green = $this->getGreen() - $other->value;
378
- $this->blue = $this->getBlue() - $other->value;
379
- } elseif (!$other instanceof SassColour) {
380
- throw new SassColourException('Argument must be a SassColour or SassNumber', SassScriptParser::$context->node);
381
- } else {
382
- $this->red = $this->getRed() - $other->getRed();
383
- $this->green = $this->getGreen() - $other->getGreen();
384
- $this->blue = $this->getBlue() - $other->getBlue();
385
- }
386
-
387
- return $this;
388
- }
389
-
390
- /**
391
- * Colour multiplication
392
- * @param mixed SassColour|SassNumber value to multiply by
393
- * @return sassColour the colour result
394
- */
395
- public function op_times($other)
396
- {
397
- if ($other instanceof SassNumber) {
398
- if (!$other->isUnitless()) {
399
- throw new SassColourException('Number must be a unitless number', SassScriptParser::$context->node);
400
- }
401
- $this->red = $this->getRed() * $other->value;
402
- $this->green = $this->getGreen() * $other->value;
403
- $this->blue = $this->getBlue() * $other->value;
404
- } elseif (!$other instanceof SassColour) {
405
- throw new SassColourException('Argument must be a SassColour or SassNumber', SassScriptParser::$context->node);
406
- } else {
407
- $this->red = $this->getRed() * $other->getRed();
408
- $this->green = $this->getGreen() * $other->getGreen();
409
- $this->blue = $this->getBlue() * $other->getBlue();
410
- }
411
-
412
- return $this;
413
- }
414
-
415
- /**
416
- * Colour division
417
- * @param mixed value (SassColour or SassNumber) to divide by
418
- * @return sassColour the colour result
419
- */
420
- public function op_div($other)
421
- {
422
- if ($other instanceof SassNumber) {
423
- if (!$other->isUnitless()) {
424
- throw new SassColourException('Number must be a unitless number', SassScriptParser::$context->node);
425
- }
426
- $this->red = $this->getRed() / $other->value;
427
- $this->green = $this->getGreen() / $other->value;
428
- $this->blue = $this->getBlue() / $other->value;
429
- } elseif (!$other instanceof SassColour) {
430
- throw new SassColourException('Argument must be a SassColour or SassNumber', SassScriptParser::$context->node);
431
- } else {
432
- $this->red = $this->getRed() / $other->getRed();
433
- $this->green = $this->getGreen() / $other->getGreen();
434
- $this->blue = $this->getBlue() / $other->getBlue();
435
- }
436
-
437
- return $this;
438
- }
439
-
440
- /**
441
- * Colour modulus
442
- * @param mixed value (SassColour or SassNumber) to divide by
443
- * @return sassColour the colour result
444
- */
445
- public function op_modulo($other)
446
- {
447
- if ($other instanceof SassNumber) {
448
- if (!$other->isUnitless()) {
449
- throw new SassColourException('Number must be a unitless number', SassScriptParser::$context->node);
450
- }
451
- $this->red = fmod($this->getRed(), $other->value);
452
- $this->green = fmod($this->getGreen(), $other->value);
453
- $this->blue = fmod($this->getBlue(), $other->value);
454
- } elseif (!$other instanceof SassColour) {
455
- throw new SassColourException('Argument must be a SassColour or SassNumber', SassScriptParser::$context->node);
456
- } else {
457
- $this->red = fmod($this->getRed(), $other->getRed());
458
- $this->green = fmod($this->getGreen(), $other->getGreen());
459
- $this->blue = fmod($this->getBlue(), $other->getBlue());
460
- }
461
-
462
- return $this;
463
- }
464
-
465
- /**
466
- * Colour bitwise AND
467
- * @param mixed value (SassColour or SassNumber) to bitwise AND with
468
- * @return sassColour the colour result
469
- */
470
- public function op_bw_and($other)
471
- {
472
- if ($other instanceof SassNumber) {
473
- if (!$other->isUnitless()) {
474
- throw new SassColourException('Number must be a unitless number', SassScriptParser::$context->node);
475
- }
476
- $this->red = $this->getRed() & $other->value;
477
- $this->green = $this->getGreen() & $other->value;
478
- $this->blue = $this->getBlue() & $other->value;
479
- } elseif (!$other instanceof SassColour) {
480
- throw new SassColourException('Argument must be a SassColour or SassNumber', SassScriptParser::$context->node);
481
- } else {
482
- $this->red = $this->getRed() & $other->getRed();
483
- $this->green = $this->getGreen() & $other->getGreen();
484
- $this->blue = $this->getBlue() & $other->getBlue();
485
- }
486
-
487
- return $this;
488
- }
489
-
490
- /**
491
- * Colour bitwise OR
492
- * @param mixed value (SassColour or SassNumber) to bitwise OR with
493
- * @return sassColour the colour result
494
- */
495
- public function op_bw_or($other)
496
- {
497
- if ($other instanceof SassNumber) {
498
- if (!$other->isUnitless()) {
499
- throw new SassColourException('Number must be a unitless number', SassScriptParser::$context->node);
500
- }
501
- $this->red = $this->getRed() | $other->value;
502
- $this->green = $this->getGreen() | $other->value;
503
- $this->blue = $this->getBlue() | $other->value;
504
- } elseif (!$other instanceof SassColour) {
505
- throw new SassColourException('Argument must be a SassColour or SassNumber', SassScriptParser::$context->node);
506
- } else {
507
- $this->red = $this->getRed() | $other->getRed();
508
- $this->green = $this->getGreen() | $other->getGreen();
509
- $this->blue = $this->getBlue() | $other->getBlue();
510
- }
511
-
512
- return $this;
513
- }
514
-
515
- /**
516
- * Colour bitwise XOR
517
- * @param mixed value (SassColour or SassNumber) to bitwise XOR with
518
- * @return sassColour the colour result
519
- */
520
- public function op_bw_xor($other)
521
- {
522
- if ($other instanceof SassNumber) {
523
- if (!$other->isUnitless()) {
524
- throw new SassColourException('Number must be a unitless number', SassScriptParser::$context->node);
525
- }
526
- $this->red = $this->getRed() ^ $other->value;
527
- $this->green = $this->getGreen() ^ $other->value;
528
- $this->blue = $this->getBlue() ^ $other->value;
529
- } elseif (!$other instanceof SassColour) {
530
- throw new SassColourException('Argument must be a SassColour or SassNumber', SassScriptParser::$context->node);
531
- } else {
532
- $this->red = $this->getRed() ^ $other->getRed();
533
- $this->green = $this->getGreen() ^ $other->getGreen();
534
- $this->blue = $this->getBlue() ^ $other->getBlue();
535
- }
536
-
537
- return $this;
538
- }
539
-
540
- /**
541
- * Colour bitwise NOT
542
- * @return sassColour the colour result
543
- */
544
- public function op_not()
545
- {
546
- $this->red = ~$this->getRed();
547
- $this->green = ~$this->getGreen();
548
- $this->blue = ~$this->getBlue();
549
-
550
- return $this;
551
- }
552
-
553
- /**
554
- * Colour bitwise Shift Left
555
- * @param sassNumber amount to shift left by
556
- * @return sassColour the colour result
557
- */
558
- public function op_shiftl($other)
559
- {
560
- if (!$other instanceof SassNumber ||!$other->isUnitless()) {
561
- throw new SassColourException('Number must be a unitless number', SassScriptParser::$context->node);
562
- }
563
- $this->red = $this->getRed() << $other->value;
564
- $this->green = $this->getGreen() << $other->value;
565
- $this->blue = $this->getBlue() << $other->value;
566
-
567
- return $this;
568
- }
569
-
570
- /**
571
- * Colour bitwise Shift Right
572
- * @param sassNumber amount to shift right by
573
- * @return sassColour the colour result
574
- */
575
- public function op_shiftr($other)
576
- {
577
- if (!$other instanceof SassNumber || !$other->isUnitless()) {
578
- throw new SassColourException('Number must be a unitless number', SassScriptParser::$context->node);
579
- }
580
- $this->red = $this->getRed() >> $other->value;
581
- $this->green = $this->getGreen() >> $other->value;
582
- $this->blue = $this->getBlue() >> $other->value;
583
-
584
- return $this;
585
- }
586
-
587
- /**
588
- * Returns a copy of this colour with one or more channels changed.
589
- * RGB or HSL attributes may be changed, but not both at once.
590
- * @param array attributes to change
591
- */
592
- public function with($attributes)
593
- {
594
- if ($this->assertValid($attributes, false) === 'hsl') {
595
- $colour = array_merge(array(
596
- 'hue' => $this->getHue(),
597
- 'saturation' => $this->getSaturation(),
598
- 'lightness' => $this->getLightness(),
599
- 'alpha' => $this->alpha
600
- ), $attributes);
601
- } else {
602
- $colour = array_merge(array(
603
- 'red' => $this->getRed(),
604
- 'green' => $this->getGreen(),
605
- 'blue' => $this->getBlue(),
606
- 'alpha' => $this->alpha
607
- ), $attributes);
608
- }
609
-
610
- $colour = new SassColour($colour);
611
- $colour->getRed(); # will get RGB and HSL
612
-
613
- return $colour;
614
- }
615
-
616
- /**
617
- * Returns the alpha component (opacity) of this colour.
618
- * @return float the alpha component (opacity) of this colour.
619
- */
620
- public function getAlpha($value = false)
621
- {
622
- if ($value && isset($this->alpha->$value)) {
623
- return $this->alpha->value;
624
- }
625
-
626
- return $this->alpha;
627
- }
628
-
629
- /**
630
- * Returns the hue of this colour.
631
- * @return float the hue of this colour.
632
- */
633
- public function getHue($value = false)
634
- {
635
- if (is_null($this->hue)) {
636
- $this->rgb2hsl();
637
- }
638
- if ($value && isset($this->hue->value)) {
639
- return $this->hue->value;
640
- }
641
-
642
- return $this->hue;
643
- }
644
-
645
- /**
646
- * Returns the saturation of this colour.
647
- * @return float the saturation of this colour.
648
- */
649
- public function getSaturation($value = false)
650
- {
651
- if (is_null($this->saturation)) {
652
- $this->rgb2hsl();
653
- }
654
- if ($value && isset($this->saturation->value)) {
655
- return $this->saturation->value;
656
- }
657
-
658
- return $this->saturation;
659
- }
660
-
661
- /**
662
- * Returns the lightness of this colour.
663
- * @return float the lightness of this colour.
664
- */
665
- public function getLightness($value = false)
666
- {
667
- if (is_null($this->lightness)) {
668
- $this->rgb2hsl();
669
- }
670
- if ($value && isset($this->lightness->value)) {
671
- return $this->lightness->value;
672
- }
673
-
674
- return $this->lightness;
675
- }
676
-
677
- /**
678
- * Returns the blue component of this colour.
679
- * @return integer the blue component of this colour.
680
- */
681
- public function getBlue($value = false)
682
- {
683
- if (is_null($this->blue)) {
684
- $this->hsl2rgb();
685
- }
686
- if ($value && isset($this->blue->value)) {
687
- return $this->blue->value;
688
- }
689
-
690
- return max(0, min(255, str_replace(',','.',round($this->blue))));
691
- }
692
-
693
- /**
694
- * Returns the green component of this colour.
695
- * @return integer the green component of this colour.
696
- */
697
- public function getGreen($value = false)
698
- {
699
- if (is_null($this->green)) {
700
- $this->hsl2rgb();
701
- }
702
- if ($value && isset($this->green->value)) {
703
- return $this->green->value;
704
- }
705
-
706
- return max(0, min(255, str_replace(',','.',round($this->green))));
707
- }
708
-
709
- /**
710
- * Returns the red component of this colour.
711
- * @return integer the red component of this colour.
712
- */
713
- public function getRed($value = false)
714
- {
715
- if (is_null($this->red)) {
716
- $this->hsl2rgb();
717
- }
718
- if ($value && isset($this->red->value)) {
719
- return $this->red->value;
720
- }
721
-
722
- return max(0, min(255, str_replace(',','.',round($this->red))));
723
- }
724
-
725
- /**
726
- * Returns an array with the RGB components of this colour.
727
- * @return array the RGB components of this colour
728
- */
729
- public function getRgb()
730
- {
731
- return array($this->red, $this->green, $this->blue);
732
- }
733
-
734
- /**
735
- * Returns an array with the RGB and alpha components of this colour.
736
- * @return array the RGB and alpha components of this colour
737
- */
738
- public function getRgba()
739
- {
740
- return array($this->getRed(), $this->getGreen(), $this->getBlue(), $this->alpha);
741
- }
742
-
743
- /**
744
- * Returns an array with the HSL components of this colour.
745
- * @return array the HSL components of this colour
746
- */
747
- public function getHsl()
748
- {
749
- return array($this->getHue(), $this->getSaturation(), $this->getLightness());
750
- }
751
-
752
- /**
753
- * Returns an array with the HSL and alpha components of this colour.
754
- * @return array the HSL and alpha components of this colour
755
- */
756
- public function getHsla()
757
- {
758
- return array($this->getHue(), $this->getSaturation(), $this->getLightness(), $this->alpha);
759
- }
760
-
761
- /**
762
- * Returns the value of this colour.
763
- * @return array the colour
764
- * @deprecated
765
- */
766
- public function getValue()
767
- {
768
- return $this->rgb;
769
- }
770
-
771
- /**
772
- * Returns whether this colour object is translucent; that is, whether the alpha channel is non-1.
773
- * @return boolean true if this colour is translucent, false if not
774
- */
775
- public function isTranslucent()
776
- {
777
- return $this->alpha < 1;
778
- }
779
-
780
- /**
781
- * Converts the colour to a string.
782
- * @param boolean whether to use CSS3 SVG1.0 colour names
783
- * @return string the colour as a named colour, rgba(r,g,g,a) or #rrggbb
784
- */
785
- public function toString($css3 = true)
786
- {
787
- $rgba = $this->getRgba();
788
-
789
- foreach ($rgba as $k => $v) {
790
- if (is_object($v)) {
791
- $rgba[$k] = $v->value;
792
- }
793
- }
794
-
795
- if ($rgba[3] == 0) {
796
- return 'transparent';
797
- } elseif ($rgba[3] < 1) {
798
- $rgba[3] = str_replace(',','.',round($rgba[3], 2));
799
-
800
- return sprintf('rgba(%d, %d, %d, %s)', $rgba[0], $rgba[1], $rgba[2], $rgba[3]);
801
- } else {
802
- $colour = sprintf('#%02x%02x%02x', str_replace(',','.',round($rgba[0])), str_replace(',','.',round($rgba[1])), str_replace(',','.',round($rgba[2])));
803
- }
804
-
805
- if ($css3) {
806
- if (empty(self::$_svgColours)) {
807
- self::$_svgColours = array_flip(self::$svgColours);
808
- }
809
-
810
- return (array_key_exists($colour, self::$_svgColours) ? self::$_svgColours[$colour] : $colour);
811
- } else {
812
- return (array_key_exists($colour, self::$_html4Colours) ? self::$_html4Colours[$colour] : $colour);
813
- }
814
- }
815
-
816
- public function asHex($inc_hash = TRUE)
817
- {
818
- return sprintf(($inc_hash ? '#' : '') . '%02x%02x%02x', str_replace(',','.',round($this->red)), str_replace(',','.',round($this->green)), str_replace(',','.',round($this->blue)));
819
- }
820
-
821
- /**
822
- * Converts from HSL to RGB colourspace
823
- * Algorithm from the CSS3 spec: {@link http://www.w3.org/TR/css3-color/#hsl-color}
824
- * @uses hue2rgb()
825
- */
826
- public function hsl2rgb()
827
- {
828
- $h = $this->getHue(true) / 360;
829
- $s = $this->getSaturation(true) / 100;
830
- $l = $this->getLightness(true) / 100;
831
-
832
- $q = $l < 0.5 ? $l * (1 + $s)
833
- : $l + $s - $l * $s;
834
- $p = 2 * $l - $q;
835
-
836
- $this->red = $this->hue2rgb($p, $q, $h + 1/3);
837
- $this->green = $this->hue2rgb($p, $q, $h);
838
- $this->blue = $this->hue2rgb($p, $q, $h - 1/3);
839
- }
840
-
841
- /**
842
- * Converts from hue to RGB colourspace
843
- */
844
- public function hue2rgb($p, $q, $t)
845
- {
846
- if ($t < 0)
847
- $t += 1;
848
- if ($t > 1)
849
- $t -= 1;
850
-
851
- if ($t < 1/6)
852
- $p = $p + ($q - $p) * 6 * $t;
853
- else if ($t < 1/2)
854
- $p = $q;
855
- else if ($t < 2/3)
856
- $p = $p + ($q - $p) * (2/3 - $t) * 6;
857
-
858
- return str_replace(',','.',round($p * 255));
859
- }
860
-
861
- /**
862
- * Converts from RGB to HSL colourspace
863
- * Algorithm adapted from {@link http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript}
864
- */
865
- public function rgb2hsl()
866
- {
867
- list($r, $g, $b) = array($this->red / 255, $this->green / 255, $this->blue / 255);
868
-
869
- $max = max($r, $g, $b);
870
- $min = min($r, $g, $b);
871
- $d = $max - $min;
872
-
873
- if ($max == $min) {
874
- $h = 0;
875
- $s = 0;
876
- } elseif ($max == $r)
877
- $h = 60 * ($g - $b) / $d;
878
- else if ($max == $g)
879
- $h = 60 * ($b - $r) / $d + 120;
880
- else if ($max == $b)
881
- $h = 60 * ($r - $g) / $d + 240;
882
-
883
- $l = ($max + $min) / 2;
884
-
885
- if ($l > 0.5)
886
- $s = (2 - $max - $min) != 0 ? $d / (2 - $max - $min) : 0;
887
- else
888
- $s = ($max + $min) != 0 ? $d / ($max + $min) : 0;
889
-
890
- while ($h > 360) $h -= 360;
891
- while ($h < 0) $h += 360;
892
-
893
- $this->hue = $h;
894
- $this->saturation = $s * 100;
895
- $this->lightness = $l * 100;
896
- }
897
-
898
- /**
899
- * Asserts that the colour space is valid.
900
- * Returns the name of the colour space: 'rgb' if red, green, or blue keys given;
901
- * 'hsl' if hue, saturation or lightness keys given; null if a non-associative array
902
- * @param array the colour to test
903
- * @param boolean whether all colour space keys must be given
904
- * @return string name of the colour space
905
- * @throws SassColourException if mixed colour space keys given or not all
906
- * keys for a colour space are required but not given (contructor)
907
- */
908
- public function assertValid($colour, $all = true)
909
- {
910
- if (array_key_exists('red', $colour) || array_key_exists('green', $colour) || array_key_exists('blue', $colour)) {
911
- if (array_key_exists('hue', $colour) || array_key_exists('saturation', $colour) || array_key_exists('lightness', $colour)) {
912
- throw new SassColourException('SassColour can not have HSL and RGB keys specified', SassScriptParser::$context->node);
913
- }
914
- if ($all && (!array_key_exists('red', $colour) || !array_key_exists('green', $colour) || !array_key_exists('blue', $colour))) {
915
- throw new SassColourException('SassColour must have all RGB keys specified', SassScriptParser::$context->node);
916
- }
917
-
918
- return 'rgb';
919
- } elseif (array_key_exists('hue', $colour) || array_key_exists('saturation', $colour) || array_key_exists('lightness', $colour)) {
920
- if ($all && (!array_key_exists('hue', $colour) || !array_key_exists('saturation', $colour) || !array_key_exists('lightness', $colour))) {
921
- throw new SassColourException('SassColour must have all HSL keys specified', SassScriptParser::$context->node);
922
- }
923
-
924
- return 'hsl';
925
- } elseif ($all && sizeof($colour) < 3) {
926
- throw new SassColourException('SassColour array must have at least 3 elements', SassScriptParser::$context->node);
927
- }
928
- }
929
-
930
- /**
931
- * Returns a value indicating if a token of this type can be matched at
932
- * the start of the subject string.
933
- * @param string the subject string
934
- * @return mixed match at the start of the string or false if no match
935
- */
936
- public static function isa($subject)
937
- {
938
- if (empty(self::$regex)) {
939
- self::$regex = str_replace('{CSS_COLOURS}', join('|', array_reverse(array_keys(self::$svgColours))), self::MATCH);
940
- }
941
-
942
- return (preg_match(self::$regex, strtolower($subject), $matches) ?
943
- $matches[0] : false);
944
- }
945
-
946
- public function nth($i)
947
- {
948
- if ($i == 1) return clone $this;
949
- return new SassBoolean(false);
950
- }
951
-
952
- public function length()
953
- {
954
- return 1;
955
- }
956
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/script/literals/SassList.php DELETED
@@ -1,237 +0,0 @@
1
- <?php
2
- /* SVN FILE: $Id$ */
3
- /**
4
- * SassBoolean 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.script.literals
10
- */
11
-
12
- require_once 'SassLiteral.php';
13
-
14
- /**
15
- * SassBoolean class.
16
- * @package PHamlP
17
- * @subpackage Sass.script.literals
18
- */
19
- class SassList extends SassLiteral
20
- {
21
- public $separator = ' ';
22
-
23
- /**
24
- * SassBoolean constructor
25
- * @param string value of the boolean type
26
- * @return SassBoolean
27
- */
28
- public function __construct($value, $separator = 'auto')
29
- {
30
- if (is_array($value)) {
31
- $this->value = $value;
32
- $this->separator = ($separator == 'auto' ? ', ' : $separator);
33
- } elseif ($value == '()') {
34
- $this->value = array();
35
- $this->separator = ($separator == 'auto' ? ', ' : $separator);
36
- } elseif (list($list, $separator) = $this->_parse_list($value, $separator, true, SassScriptParser::$context)) {
37
- $this->value = $list;
38
- $this->separator = ($separator == ',' ? ', ' : ' ');
39
- } else {
40
- throw new SassListException('Invalid SassList', SassScriptParser::$context->node);
41
- }
42
- }
43
-
44
- public function nth($i)
45
- {
46
- $i = $i - 1; # SASS uses 1-offset arrays
47
- if (isset($this->value[$i])) {
48
- return $this->value[$i];
49
- }
50
-
51
- return new SassBoolean(false);
52
- }
53
-
54
- public function length()
55
- {
56
- return count($this->value);
57
- }
58
-
59
- public function append($other, $separator = null)
60
- {
61
- if ($separator) {
62
- $this->separator = $separator;
63
- }
64
- if ($other instanceof SassList) {
65
- $this->value = array_merge($this->value, $other->value);
66
- } elseif ($other instanceof SassLiteral) {
67
- $this->value[] = $other;
68
- } else {
69
- throw new SassListException('Appendation can only occur with literals', SassScriptParser::$context->node);
70
- }
71
- }
72
-
73
- // New function index returns the list index of a value within a list. For example: index(1px solid red, solid) returns 2. When the value is not found false is returned.
74
- public function index($value)
75
- {
76
- for ($i = 0; $i < count($this->value); $i++) {
77
- if (trim((string) $value) == trim((string) $this->value[$i])) {
78
- return new SassNumber($i);
79
- }
80
- }
81
-
82
- return new SassBoolean(false);
83
- }
84
-
85
- /**
86
- * Returns the value of this boolean.
87
- * @return boolean the value of this boolean
88
- */
89
- public function getValue()
90
- {
91
- $result = array();
92
- foreach ($this->value as $k => $v) {
93
- if ($v instanceOf SassString) {
94
- $list = $this->_parse_list($v);
95
- if (count($list[0]) > 1) {
96
- if ($list[1] == $this->separator) {
97
- $result = array_merge($result, $list[0]);
98
- } else {
99
- $result[] = $v;
100
- }
101
- } else {
102
- $result[] = $v;
103
- }
104
- } else {
105
- $result[] = $v;
106
- }
107
- }
108
- $this->value = $result;
109
-
110
- return $this->value;
111
- }
112
-
113
- /**
114
- * Returns a string representation of the value.
115
- * @return string string representation of the value.
116
- */
117
- public function toString()
118
- {
119
- $aliases = array(
120
- 'comma' => ',',
121
- 'space' => '',
122
- );
123
- $this->separator = trim($this->separator);
124
- if (isset($aliases[$this->separator])) {
125
- $this->separator = $aliases[$this->separator];
126
- }
127
-
128
- return implode($this->separator . ' ', $this->getValue());
129
- }
130
-
131
- /**
132
- * Returns a value indicating if a token of this type can be matched at
133
- * the start of the subject string.
134
- * @param string the subject string
135
- * @return mixed match at the start of the string or false if no match
136
- */
137
- public static function isa($subject)
138
- {
139
- list($list, $separator) = self::_parse_list($subject, 'auto', false);
140
-
141
- return count($list) > 1 ? $subject : FALSE;
142
- }
143
-
144
- public static function _parse_list($list, $separator = 'auto', $lex = true, $context = null)
145
- {
146
- if ($lex) {
147
- $context = new SassContext($context);
148
- $list = SassScriptParser::$instance->evaluate($list, $context);
149
- $list = $list->toString();
150
- }
151
- if ($separator == 'auto') {
152
- $separator = ',';
153
- $list = $list = self::_build_list($list, ',');
154
- if (count($list) < 2) {
155
- $separator = ' ';
156
- $list = self::_build_list($list, ' ');
157
- }
158
- } else {
159
- $list = self::_build_list($list, $separator);
160
- }
161
-
162
- if ($lex) {
163
- $context = new SassContext($context);
164
- foreach ($list as $k => $v) {
165
- $list[$k] = SassScriptParser::$instance->evaluate($v, $context);
166
- }
167
- }
168
-
169
- return array($list, $separator);
170
- }
171
-
172
- public static function _build_list($list, $separator = ',')
173
- {
174
- if (is_object($list)) {
175
- $list = $list->value;
176
- }
177
-
178
- if (is_array($list)) {
179
- $newlist = array();
180
- foreach ($list as $listlet) {
181
- list($newlist, $separator) = array_merge($newlist, self::_parse_list($listlet, $separator, false));
182
- }
183
- $list = implode(', ', $newlist);
184
- }
185
-
186
- $out = array();
187
- $size = 0;
188
- $braces = 0;
189
- $quotes = false;
190
- $stack = '';
191
- for ($i = 0; $i < strlen($list); $i++) {
192
- $char = substr($list, $i, 1);
193
- switch ($char) {
194
- case '"':
195
- case "'":
196
- if (!$quotes) {
197
- $quotes = $char;
198
- } elseif ($quotes && $quotes == $char) {
199
- $quotes = false;
200
- }
201
- $stack .= $char;
202
- break;
203
- case '(':
204
- $braces++;
205
- $stack .= $char;
206
- break;
207
- case ')':
208
- $braces--;
209
- $stack .= $char;
210
- break;
211
- case $separator:
212
- if ($braces === 0 && !$quotes) {
213
- $out[] = $stack;
214
- $stack = '';
215
- $size++;
216
- break;
217
- }
218
- default:
219
- $stack .= $char;
220
- }
221
- }
222
- if (strlen($stack)) {
223
- if (($braces || $quotes) && count($out)) {
224
- $out[count($out) - 1] .= $stack;
225
- } else {
226
- $out[] = $stack;
227
- }
228
- }
229
-
230
- foreach ($out as $k => $v) {
231
- $v = trim($v, ', ');
232
- $out[$k] = $v;
233
- }
234
-
235
- return $out;
236
- }
237
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/script/literals/SassLiteral.php DELETED
@@ -1,410 +0,0 @@
1
- <?php
2
- /* SVN FILE: $Id$ */
3
- /**
4
- * SassLiteral 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.script.literals
10
- */
11
-
12
- require_once 'SassLiteralExceptions.php';
13
-
14
- /**
15
- * SassLiteral class.
16
- * Base class for all Sass literals.
17
- * Sass data types are extended from this class and these override the operation
18
- * methods to provide the appropriate semantics.
19
- * @package PHamlP
20
- * @subpackage Sass.script.literals
21
- */
22
- abstract class SassLiteral
23
- {
24
- /**
25
- * @var array maps class names to data types
26
- */
27
- public static $typeOf = array(
28
- 'SassBoolean' => 'bool',
29
- 'SassColour' => 'color',
30
- 'SassNumber' => 'number',
31
- 'SassString' => 'string',
32
- 'SassList' => 'list'
33
- );
34
-
35
- /**
36
- * @var mixed value of the literal type
37
- */
38
- public $value;
39
-
40
- /**
41
- * class constructor
42
- * @param string value of the literal type
43
- * @return SassLiteral
44
- */
45
- public function __construct($value = null, $context)
46
- {
47
- $this->value = $value;
48
- $this->context = $context;
49
- }
50
-
51
- /**
52
- * Getter.
53
- * @param string name of property to get
54
- * @return mixed return value of getter function
55
- */
56
- public function __get($name)
57
- {
58
- $getter = 'get' . ucfirst($name);
59
- if (method_exists($this, $getter)) {
60
- return $this->$getter();
61
- } else {
62
- throw new SassLiteralException('No getter function for ' . $name, SassScriptParser::$context->node);
63
- }
64
- }
65
-
66
- public function __toString()
67
- {
68
- return $this->toString();
69
- }
70
-
71
- /**
72
- * Returns the boolean representation of the value of this
73
- * @return boolean the boolean representation of the value of this
74
- */
75
- public function toBoolean()
76
- {
77
- return (boolean) $this->value || $this->value === null;
78
- }
79
-
80
- /**
81
- * Returns the type of this
82
- * @return string the type of this
83
- */
84
- public function getTypeOf()
85
- {
86
- return self::$typeOf[get_class($this)];
87
- }
88
-
89
- /**
90
- * Returns the value of this
91
- * @return mixed the value of this
92
- */
93
- public function getValue()
94
- {
95
- throw new SassLiteralException('Child classes must override this method', SassScriptParser::$context->node);
96
- }
97
-
98
- public function getChildren()
99
- {
100
- return array();
101
- }
102
-
103
- /**
104
- * Adds a child object to this.
105
- * @param sassLiteral the child object
106
- */
107
- public function addChild($sassLiteral)
108
- {
109
- $this->children[] = $sassLiteral;
110
- }
111
-
112
- /**
113
- * SassScript '+' operation.
114
- * @param sassLiteral value to add
115
- * @return sassString the string values of this and other with no seperation
116
- */
117
- public function op_plus($other)
118
- {
119
- return new SassString($this->toString().$other->toString());
120
- }
121
-
122
- /**
123
- * SassScript '-' operation.
124
- * @param SassLiteral value to subtract
125
- * @return sassString the string values of this and other seperated by '-'
126
- */
127
- public function op_minus($other)
128
- {
129
- return new SassString($this->toString().'-'.$other->toString());
130
- }
131
-
132
- /**
133
- * SassScript '*' operation.
134
- * @param SassLiteral value to multiply by
135
- * @return sassString the string values of this and other seperated by '*'
136
- */
137
- public function op_times($other)
138
- {
139
- return new SassString($this->toString().'*'.$other->toString());
140
- }
141
-
142
- /**
143
- * SassScript '/' operation.
144
- * @param SassLiteral value to divide by
145
- * @return sassString the string values of this and other seperated by '/'
146
- */
147
- public function op_div($other)
148
- {
149
- return new SassString($this->toString().' / '.$other->toString());
150
- }
151
-
152
- /**
153
- * SassScript '%' operation.
154
- * @param SassLiteral value to take the modulus of
155
- * @return SassLiteral result
156
- * @throws Exception if modulo not supported for the data type
157
- */
158
- public function op_modulo($other)
159
- {
160
- throw new SassLiteralException(get_class($this) . ' does not support Modulus', SassScriptParser::$context->node);
161
- }
162
-
163
- /**
164
- * Bitwise AND the value of other and this value
165
- * @param string value to bitwise AND with
166
- * @return string result
167
- * @throws Exception if bitwise AND not supported for the data type
168
- */
169
- public function op_bw_and($other)
170
- {
171
- throw new SassLiteralException(get_class($this) . ' does not support Bitwise AND', SassScriptParser::$context->node);
172
- }
173
-
174
- /**
175
- * Bitwise OR the value of other and this value
176
- * @param SassNumber value to bitwise OR with
177
- * @return string result
178
- * @throws Exception if bitwise OR not supported for the data type
179
- */
180
- public function op_bw_or($other)
181
- {
182
- throw new SassLiteralException(get_class($this) . ' does not support Bitwise OR', SassScriptParser::$context->node);
183
- }
184
-
185
- /**
186
- * Bitwise XOR the value of other and the value of this
187
- * @param SassNumber value to bitwise XOR with
188
- * @return string result
189
- * @throws Exception if bitwise XOR not supported for the data type
190
- */
191
- public function op_bw_xor($other)
192
- {
193
- throw new SassLiteralException(get_class($this) . ' does not support Bitwise XOR', SassScriptParser::$context->node);
194
- }
195
-
196
- /**
197
- * Bitwise NOT the value of other and the value of this
198
- * @param SassNumber value to bitwise NOT with
199
- * @return string result
200
- * @throws Exception if bitwise NOT not supported for the data type
201
- */
202
- public function op_bw_not()
203
- {
204
- throw new SassLiteralException(get_class($this) . ' does not support Bitwise NOT', SassScriptParser::$context->node);
205
- }
206
-
207
- /**
208
- * Shifts the value of this left by the number of bits given in value
209
- * @param SassNumber amount to shift left by
210
- * @return string result
211
- * @throws Exception if bitwise Shift Left not supported for the data type
212
- */
213
- public function op_shiftl($other)
214
- {
215
- throw new SassLiteralException(get_class($this) . ' does not support Bitwise Shift Left', SassScriptParser::$context->node);
216
- }
217
-
218
- /**
219
- * Shifts the value of this right by the number of bits given in value
220
- * @param SassNumber amount to shift right by
221
- * @return string result
222
- * @throws Exception if bitwise Shift Right not supported for the data type
223
- */
224
- public function op_shiftr($other)
225
- {
226
- throw new SassLiteralException(get_class($this) . ' does not support Bitwise Shift Right', SassScriptParser::$context->node);
227
- }
228
-
229
- /**
230
- * The SassScript and operation.
231
- * @param sassLiteral the value to and with this
232
- * @return SassLiteral other if this is boolean true, this if false
233
- */
234
- public function op_and($other)
235
- {
236
- return ($this->toBoolean() ? $other : $this);
237
- }
238
-
239
- /**
240
- * The SassScript or operation.
241
- * @param sassLiteral the value to or with this
242
- * @return SassLiteral this if this is boolean true, other if false
243
- */
244
- public function op_or($other)
245
- {
246
- return ($this->toBoolean() ? $this : $other);
247
- }
248
-
249
- public function op_assign($other)
250
- {
251
- return $other;
252
- }
253
-
254
- /**
255
- * The SassScript xor operation.
256
- * @param sassLiteral the value to xor with this
257
- * @return SassBoolean SassBoolean object with the value true if this or
258
- * other, but not both, are true, false if not
259
- */
260
- public function op_xor($other)
261
- {
262
- return new SassBoolean($this->toBoolean() xor $other->toBoolean());
263
- }
264
-
265
- /**
266
- * The SassScript not operation.
267
- * @return SassBoolean SassBoolean object with the value true if the
268
- * boolean of this is false or false if it is true
269
- */
270
- public function op_not()
271
- {
272
- return new SassBoolean(!$this->toBoolean());
273
- }
274
-
275
- /**
276
- * The SassScript > operation.
277
- * @param sassLiteral the value to compare to this
278
- * @return SassBoolean SassBoolean object with the value true if the values
279
- * of this is greater than the value of other, false if it is not
280
- */
281
- public function op_gt($other)
282
- {
283
- return new SassBoolean($this->value > $other->value);
284
- }
285
-
286
- /**
287
- * The SassScript >= operation.
288
- * @param sassLiteral the value to compare to this
289
- * @return SassBoolean SassBoolean object with the value true if the values
290
- * of this is greater than or equal to the value of other, false if it is not
291
- */
292
- public function op_gte($other)
293
- {
294
- return new SassBoolean($this->value >= $other->value);
295
- }
296
-
297
- /**
298
- * The SassScript < operation.
299
- * @param sassLiteral the value to compare to this
300
- * @return SassBoolean SassBoolean object with the value true if the values
301
- * of this is less than the value of other, false if it is not
302
- */
303
- public function op_lt($other)
304
- {
305
- return new SassBoolean($this->value < $other->value);
306
- }
307
-
308
- /**
309
- * The SassScript <= operation.
310
- * @param sassLiteral the value to compare to this
311
- * @return SassBoolean SassBoolean object with the value true if the values
312
- * of this is less than or equal to the value of other, false if it is not
313
- */
314
- public function op_lte($other)
315
- {
316
- return new SassBoolean($this->value <= $other->value);
317
- }
318
-
319
- /**
320
- * The SassScript == operation.
321
- * @param sassLiteral the value to compare to this
322
- * @return SassBoolean SassBoolean object with the value true if this and
323
- * other are equal, false if they are not
324
- */
325
- public function op_eq($other)
326
- {
327
- return new SassBoolean($this == $other);
328
- }
329
-
330
- /**
331
- * The SassScript != operation.
332
- * @param sassLiteral the value to compare to this
333
- * @return SassBoolean SassBoolean object with the value true if this and
334
- * other are not equal, false if they are
335
- */
336
- public function op_neq($other)
337
- {
338
- return new SassBoolean(!$this->op_eq($other)->toBoolean());
339
- }
340
-
341
- /**
342
- * The SassScript default operation (e.g. $a $b, "foo" "bar").
343
- * @param sassLiteral the value to concatenate with a space to this
344
- * @return sassString the string values of this and other seperated by " "
345
- */
346
- public function op_concat($other)
347
- {
348
- return new SassString($this->toString().' '.$other->toString());
349
- }
350
-
351
- /**
352
- * SassScript ',' operation.
353
- * @param sassLiteral the value to concatenate with a comma to this
354
- * @return sassString the string values of this and other seperated by ","
355
- */
356
- public function op_comma($other)
357
- {
358
- return new SassString($this->toString().', '.$other->toString());
359
- }
360
-
361
- /**
362
- * Asserts that the literal is the expected type
363
- * @param SassLiteral the literal to test
364
- * @param string expected type
365
- * @throws SassScriptFunctionException if value is not the expected type
366
- */
367
- public static function assertType($literal, $type)
368
- {
369
- if (!$literal instanceof $type) {
370
- throw new SassScriptFunctionException(($literal instanceof SassLiteral ? get_class($literal) : 'literal') . ' must be a ' . $type, SassScriptParser::$context->node);
371
- }
372
- }
373
-
374
- /**
375
- * Asserts that the value of a literal is within the expected range
376
- * @param SassLiteral the literal to test
377
- * @param float the minimum value
378
- * @param float the maximum value
379
- * @param string the units.
380
- * @throws SassScriptFunctionException if value is not the expected type
381
- */
382
- public static function assertInRange($literal, $min, $max, $units = '')
383
- {
384
- if ($literal->value < $min || $literal->value > $max) {
385
- throw new SassScriptFunctionException($literal->typeOf . ' must be between ' . $min.$units . ' and ' . $max.$units . ' inclusive', SassScriptParser::$context->node);
386
- }
387
- }
388
-
389
- /**
390
- * Returns a string representation of the value.
391
- * @return string string representation of the value.
392
- */
393
- abstract public function toString();
394
-
395
- public function render()
396
- {
397
- return $this->toString();
398
- }
399
-
400
- /**
401
- * Returns a value indicating if a token of this type can be matched at
402
- * the start of the subject string.
403
- * @param string the subject string
404
- * @return mixed match at the start of the string or false if no match
405
- */
406
- public static function isa($subject)
407
- {
408
- throw new SassLiteralException('Child classes must override this method');
409
- }
410
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/script/literals/SassLiteralExceptions.php DELETED
@@ -1,47 +0,0 @@
1
- <?php
2
- /* SVN FILE: $Id$ */
3
- /**
4
- * Sass literal exception classes.
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.script.literals
10
- */
11
-
12
- require_once(dirname(__FILE__).'/../SassScriptParserExceptions.php');
13
-
14
- /**
15
- * Sass literal exception.
16
- * @package PHamlP
17
- * @subpackage Sass.script.literals
18
- */
19
- class SassLiteralException extends SassScriptParserException {}
20
-
21
- /**
22
- * SassBooleanException class.
23
- * @package PHamlP
24
- * @subpackage Sass.script.literals
25
- */
26
- class SassBooleanException extends SassLiteralException {}
27
-
28
- /**
29
- * SassColourException class.
30
- * @package PHamlP
31
- * @subpackage Sass.script.literals
32
- */
33
- class SassColourException extends SassLiteralException {}
34
-
35
- /**
36
- * SassNumberException class.
37
- * @package PHamlP
38
- * @subpackage Sass.script.literals
39
- */
40
- class SassNumberException extends SassLiteralException {}
41
-
42
- /**
43
- * SassStringException class.
44
- * @package PHamlP
45
- * @subpackage Sass.script.literals
46
- */
47
- class SassStringException extends SassLiteralException {}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/script/literals/SassNumber.php DELETED
@@ -1,597 +0,0 @@
1
- <?php
2
- /* SVN FILE: $Id$ */
3
- /**
4
- * SassNumber 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.script.literals
10
- */
11
-
12
- require_once 'SassLiteral.php';
13
-
14
- /**
15
- * SassNumber class.
16
- * Provides operations and type testing for Sass numbers.
17
- * Units are of the passed value are converted the those of the class value
18
- * if it has units. e.g. 2cm + 20mm = 4cm while 2 + 20mm = 22mm.
19
- * @package PHamlP
20
- * @subpackage Sass.script.literals
21
- */
22
- class SassNumber extends SassLiteral
23
- {
24
- /**
25
- * Regx for matching and extracting numbers
26
- */
27
- const MATCH = '/^((?:-)?(?:\d*\.)?\d+)(([a-z%]+)(\s*[\*\/]\s*[a-z%]+)*)?/i';
28
- // const MATCH = '/^(?!\d+px\/)((?:-)?(?:\d.)?\d+)(([a-z%]+)(\s[*\/]\s[a-z%]+))?/i';
29
- const VALUE = 1;
30
- const UNITS = 2;
31
- /**
32
- * The number of decimal digits to round to.
33
- * If the units are pixels the result is always
34
- * rounded down to the nearest integer.
35
- */
36
- const PRECISION = 3;
37
-
38
- /**
39
- * @var array Conversion factors for units using inches as the base unit
40
- * (only because pt and pc are expressed as fraction of an inch, so makes the
41
- * numbers easy to understand).
42
- * Conversions are based on the following
43
- * in: inches — 1 inch = 2.54 centimeters
44
- * cm: centimeters
45
- * mm: millimeters
46
- * pc: picas — 1 pica = 12 points
47
- * pt: points — 1 point = 1/72nd of an inch
48
- */
49
- private static $unitConversion = array(
50
- 'in' => 1,
51
- 'cm' => 2.54,
52
- 'mm' => 25.4,
53
- 'pc' => 6,
54
- 'pt' => 72,
55
- 'px' => 96
56
- );
57
- private static $validUnits = array(
58
- 'vw', 'vh', 'vmin', 'vmax',
59
- 'in', 'cm', 'mm', 'pc', 'pt', 'em', 'rem', 'ex', 'px', '%', 's', 'deg'
60
- );
61
-
62
- /**
63
- * @var array numerator units of this number
64
- */
65
- private $numeratorUnits = array();
66
-
67
- /**
68
- * @var array denominator units of this number
69
- */
70
- private $denominatorUnits = array();
71
-
72
- /**
73
- * @var boolean whether this number is in an expression or a literal number
74
- * Used to determine whether division should take place
75
- */
76
- public $inExpression = true;
77
-
78
- /**
79
- * class constructor.
80
- * Sets the value and units of the number.
81
- * @param string number
82
- * @return SassNumber
83
- */
84
- public function __construct($value)
85
- {
86
- preg_match(self::MATCH, $value, $matches);
87
-
88
- $matches += array(null,null,'','');
89
-
90
- $this->value = $matches[self::VALUE];
91
- if (!empty($matches[self::UNITS])) {
92
- $units = explode('/', $matches[self::UNITS]);
93
- $numeratorUnits = $denominatorUnits = array();
94
-
95
- foreach (explode('*', $units[0]) as $unit) {
96
- $numeratorUnits[] = trim($unit);
97
- }
98
- if (isset($units[1])) {
99
- foreach (explode('*', $units[1]) as $unit) {
100
- $denominatorUnits[] = trim($unit);
101
- }
102
- }
103
- $units = $this->removeCommonUnits($numeratorUnits, $denominatorUnits);
104
- $this->numeratorUnits = $units[0];
105
- $this->denominatorUnits = $units[1];
106
- }
107
- }
108
-
109
- /**
110
- * Adds the value of other to the value of this
111
- * @param mixed SassNumber|SassColour: value to add
112
- * @return mixed SassNumber if other is a SassNumber or
113
- * SassColour if it is a SassColour
114
- */
115
- public function op_plus($other)
116
- {
117
- if ($other instanceof SassColour) {
118
- return $other->op_plus($this);
119
- } elseif ($other instanceOf SassString) {
120
- $other = clone $other;
121
- $other->value = $this->value . $other->value;
122
-
123
- return $other;
124
- } elseif (!$other instanceof SassNumber) {
125
- throw new SassNumberException('Number must be a number', SassScriptParser::$context->node);
126
- } else {
127
- $other = $this->convert($other);
128
-
129
- return new SassNumber(($this->value + $other->value).$this->units);
130
- }
131
- }
132
-
133
- /**
134
- * Unary + operator
135
- * @return SassNumber the value of this number
136
- */
137
- public function op_unary_plus()
138
- {
139
- return $this;
140
- }
141
-
142
- /**
143
- * Subtracts the value of other from this value
144
- * @param mixed SassNumber|SassColour: value to subtract
145
- * @return mixed SassNumber if other is a SassNumber or
146
- * SassColour if it is a SassColour
147
- */
148
- public function op_minus($other)
149
- {
150
- if ($other instanceof SassColour) {
151
- return $other->op_minus($this);
152
- } elseif (!$other instanceof SassNumber) {
153
- throw new SassNumberException('Number must be a number', SassScriptParser::$context->node);
154
- } else {
155
- $other = $this->convert($other);
156
-
157
- return new SassNumber(($this->value - $other->value) . $this->units);
158
- }
159
- }
160
-
161
- /**
162
- * Unary - operator
163
- * @return SassNumber the negative value of this number
164
- */
165
- public function op_unary_minus()
166
- {
167
- return new SassNumber(($this->value * -1) . $this->units);
168
- }
169
-
170
- public function op_unary_concat()
171
- {
172
- return $this;
173
- }
174
-
175
- /**
176
- * Multiplies this value by the value of other
177
- * @param mixed SassNumber|SassColour: value to multiply by
178
- * @return mixed SassNumber if other is a SassNumber or
179
- * SassColour if it is a SassColour
180
- */
181
- public function op_times($other)
182
- {
183
- if ($other instanceof SassColour) {
184
- return $other->op_times($this);
185
- } elseif (!$other instanceof SassNumber) {
186
- throw new SassNumberException('Number must be a number', SassScriptParser::$context->node);
187
- } else {
188
- return new SassNumber(($this->value * $other->value).$this->unitString(
189
- array_merge($this->numeratorUnits, $other->numeratorUnits),
190
- array_merge($this->denominatorUnits, $other->denominatorUnits)
191
- ));
192
- }
193
- }
194
-
195
- /**
196
- * Divides this value by the value of other
197
- * @param mixed SassNumber|SassColour: value to divide by
198
- * @return mixed SassNumber if other is a SassNumber or
199
- * SassColour if it is a SassColour
200
- */
201
- public function op_div($other)
202
- {
203
- if ($other instanceof SassColour) {
204
- return $other->op_div($this);
205
- } elseif (!$other instanceof SassNumber) {
206
- throw new SassNumberException('Number must be a number', SassScriptParser::$context->node);
207
- } elseif ($this->inExpression || $other->inExpression) {
208
- return new SassNumber(($this->value / $other->value).$this->unitString(
209
- array_merge($this->numeratorUnits, $other->denominatorUnits),
210
- array_merge($this->denominatorUnits, $other->numeratorUnits)
211
- ));
212
- } else {
213
- return new SassNumber(($this->value / $other->value).$this->unitString(
214
- array_merge($this->numeratorUnits, $other->denominatorUnits),
215
- $this->denominatorUnits
216
- ));
217
- }
218
- }
219
-
220
- /**
221
- * The SassScript == operation.
222
- * @return SassBoolean SassBoolean object with the value true if the values
223
- * of this and other are equal, false if they are not
224
- */
225
- public function op_eq($other)
226
- {
227
- if (!$other instanceof SassNumber) {
228
- return new SassBoolean(false);
229
- }
230
- try {
231
- return new SassBoolean($this->value == $this->convert($other)->value);
232
- } catch (Exception $e) {
233
- return new SassBoolean(false);
234
- }
235
- }
236
-
237
- /**
238
- * The SassScript > operation.
239
- * @param sassLiteral the value to compare to this
240
- * @return SassBoolean SassBoolean object with the value true if the values
241
- * of this is greater than the value of other, false if it is not
242
- */
243
- public function op_gt($other)
244
- {
245
- if (!$other instanceof SassNumber) {
246
- throw new SassNumberException('Number must be a number', SassScriptParser::$context->node);
247
- }
248
-
249
- return new SassBoolean($this->value > $this->convert($other)->value);
250
- }
251
-
252
- /**
253
- * The SassScript >= operation.
254
- * @param sassLiteral the value to compare to this
255
- * @return SassBoolean SassBoolean object with the value true if the values
256
- * of this is greater than or equal to the value of other, false if it is not
257
- */
258
- public function op_gte($other)
259
- {
260
- if (!$other instanceof SassNumber) {
261
- throw new SassNumberException('Number must be a number', SassScriptParser::$context->node);
262
- }
263
-
264
- return new SassBoolean($this->value >= $this->convert($other)->value);
265
- }
266
-
267
- /**
268
- * The SassScript < operation.
269
- * @param sassLiteral the value to compare to this
270
- * @return SassBoolean SassBoolean object with the value true if the values
271
- * of this is less than the value of other, false if it is not
272
- */
273
- public function op_lt($other)
274
- {
275
- if (!$other instanceof SassNumber) {
276
- throw new SassNumberException('Number must be a number', SassScriptParser::$context->node);
277
- }
278
-
279
- return new SassBoolean($this->value < $this->convert($other)->value);
280
- }
281
-
282
- /**
283
- * The SassScript <= operation.
284
- * @param sassLiteral the value to compare to this
285
- * @return SassBoolean SassBoolean object with the value true if the values
286
- * of this is less than or equal to the value of other, false if it is not
287
- */
288
- public function op_lte($other)
289
- {
290
- if (!$other instanceof SassNumber) {
291
- throw new SassNumberException('Number must be a number', SassScriptParser::$context->node);
292
- }
293
-
294
- return new SassBoolean($this->value <= $this->convert($other)->value);
295
- }
296
-
297
- /**
298
- * Takes the modulus (remainder) of this value divided by the value of other
299
- * @param string value to divide by
300
- * @return mixed SassNumber if other is a SassNumber or
301
- * SassColour if it is a SassColour
302
- */
303
- public function op_modulo($other)
304
- {
305
- if (!$other instanceof SassNumber || !$other->isUnitless()) {
306
- throw new SassNumberException('Number must be a unitless number', SassScriptParser::$context->node);
307
- }
308
- $this->value %= $this->convert($other)->value;
309
-
310
- return $this;
311
- }
312
-
313
- /**
314
- * Converts values and units.
315
- * If this is a unitless numeber it will take the units of other; if not
316
- * other is coerced to the units of this.
317
- * @param SassNumber the other number
318
- * @return SassNumber the other number with its value and units coerced if neccessary
319
- * @throws SassNumberException if the units are incompatible
320
- */
321
- private function convert($other)
322
- {
323
- if ($this->isUnitless()) {
324
- $this->numeratorUnits = $other->numeratorUnits;
325
- $this->denominatorUnits = $other->denominatorUnits;
326
- } else {
327
- $other = $other->coerce($this->numeratorUnits, $this->denominatorUnits);
328
- }
329
-
330
- return $other;
331
- }
332
-
333
- /**
334
- * Returns the value of this number converted to other units.
335
- * The conversion takes into account the relationship between e.g. mm and cm,
336
- * as well as between e.g. in and cm.
337
- *
338
- * If this number is unitless, it will simply return itself with the given units.
339
- * @param array $numeratorUnits
340
- * @param array $denominatorUnits
341
- * @return SassNumber
342
- */
343
- public function coerce($numeratorUnits, $denominatorUnits)
344
- {
345
- return new SassNumber(($this->isUnitless() ?
346
- $this->value : $this->value *
347
- $this->coercionFactor($this->numeratorUnits, $numeratorUnits) /
348
- $this->coercionFactor($this->denominatorUnits, $denominatorUnits)
349
- ) . join(' * ', $numeratorUnits) . (!empty($denominatorUnits) ? ' / ' . join(' * ', $denominatorUnits) : ''));
350
- }
351
-
352
- /**
353
- * Calculates the corecion factor to apply to the value
354
- * @param array units being converted from
355
- * @param array units being converted to
356
- * @return float the coercion factor to apply
357
- */
358
- private function coercionFactor($fromUnits, $toUnits)
359
- {
360
- $units = $this->removeCommonUnits($fromUnits, $toUnits);
361
- $fromUnits = $units[0];
362
- $toUnits = $units[1];
363
-
364
- while (count($fromUnits) > count($toUnits)) {
365
- $toUnits[] = 'in';
366
- }
367
-
368
- if (sizeof($fromUnits) !== sizeof($toUnits) || !$this->areConvertable(array_merge($fromUnits, $toUnits))) {
369
- throw new SassNumberException("Incompatible units: '" . join(' * ', $fromUnits) . "' and '" . join(' * ', $toUnits) . "'", SassScriptParser::$context->node);
370
- }
371
-
372
- $coercionFactor = 1;
373
- foreach ($fromUnits as $i=>$from) {
374
- if (array_key_exists($i, $toUnits) && array_key_exists($toUnits[$i], self::$unitConversion)) {
375
- $coercionFactor *= self::$unitConversion[$toUnits[$i]] / self::$unitConversion[$from];
376
- } else {
377
- throw new SassNumberException("Incompatible units: '" . join(' * ', $fromUnits) . "' and '" . join(' * ', $toUnits) . "'", SassScriptParser::$context->node);
378
- }
379
- }
380
-
381
- return $coercionFactor;
382
- }
383
-
384
- /**
385
- * Returns a value indicating if all the units are capable of being converted
386
- * @param array units to test
387
- * @return boolean true if all units can be converted, false if not
388
- */
389
- private function areConvertable($units)
390
- {
391
- $convertable = array_keys(self::$unitConversion);
392
- foreach ($units as $unit) {
393
- if (!in_array($unit, $convertable)) {
394
- return false;
395
- }
396
- }
397
-
398
- return true;
399
- }
400
-
401
- /**
402
- * Removes common units from each set.
403
- * We don't use array_diff because we want (for eaxmple) mm*mm/mm*cm to
404
- * end up as mm/cm.
405
- * @param array first set of units
406
- * @param array second set of units
407
- * @return array both sets of units with common units removed
408
- */
409
- private function removeCommonUnits($u1, $u2)
410
- {
411
- $_u1 = array();
412
- while (!empty($u1)) {
413
- $u = array_shift($u1);
414
- $i = array_search($u, $u2);
415
- if ($i !== false) {
416
- unset($u2[$i]);
417
- } else {
418
- $_u1[] = $u;
419
- }
420
- }
421
-
422
- return (array($_u1, $u2));
423
- }
424
-
425
- /**
426
- * Returns a value indicating if this number is unitless.
427
- * @return boolean true if this number is unitless, false if not
428
- */
429
- public function isUnitless()
430
- {
431
- return empty($this->numeratorUnits) && empty($this->denominatorUnits);
432
- }
433
-
434
- /**
435
- * Returns a value indicating if this number has units.
436
- * @return boolean true if this number has, false if not
437
- */
438
- public function hasUnits()
439
- {
440
- return !$this->isUnitless();
441
- }
442
-
443
- /**
444
- * Returns a value indicating if this number has units that can be represented
445
- * in CSS.
446
- * @return boolean true if this number has units that can be represented in
447
- * CSS, false if not
448
- */
449
- public function hasLegalUnits()
450
- {
451
- return (empty($this->numeratorUnits) || count($this->numeratorUnits) === 1) && empty($this->denominatorUnits);
452
- }
453
-
454
- /**
455
- * Returns a string representation of the units.
456
- * @return string the units
457
- */
458
- public function unitString($numeratorUnits, $denominatorUnits)
459
- {
460
- foreach ($numeratorUnits as $i => $unit) {
461
- if (!in_array($unit, self::$validUnits)) {
462
- unset($numeratorUnits[$i]);
463
- }
464
- }
465
- foreach ($denominatorUnits as $i => $unit) {
466
- if (!in_array($unit, self::$validUnits)) {
467
- unset($denominatorUnits[$i]);
468
- }
469
- }
470
-
471
- return join(' * ', $numeratorUnits) . (!empty($denominatorUnits) ? ' / ' . join(' * ', $denominatorUnits) : '');
472
- }
473
-
474
- /**
475
- * Returns the units of this number.
476
- * @return string the units of this number
477
- */
478
- public function getUnits()
479
- {
480
- return $this->unitString($this->numeratorUnits, $this->denominatorUnits);
481
- }
482
-
483
- /**
484
- * Returns the denominator units of this number.
485
- * @return string the denominator units of this number
486
- */
487
- public function getDenominatorUnits()
488
- {
489
- return join(' * ', $this->denominatorUnits);
490
- }
491
-
492
- /**
493
- * Returns the numerator units of this number.
494
- * @return string the numerator units of this number
495
- */
496
- public function getNumeratorUnits()
497
- {
498
- return join(' * ', $this->numeratorUnits);
499
- }
500
-
501
- /**
502
- * Returns a value indicating if this number can be compared to other.
503
- * @return boolean true if this number can be compared to other, false if not
504
- */
505
- public function isComparableTo($other)
506
- {
507
- try {
508
- $this->op_plus($other);
509
-
510
- return true;
511
- } catch (Exception $e) {
512
- return false;
513
- }
514
- }
515
-
516
- /**
517
- * Returns a value indicating if this number is an integer.
518
- * @return boolean true if this number is an integer, false if not
519
- */
520
- public function isInt()
521
- {
522
- return $this->value % 1 === 0;
523
- }
524
-
525
- /**
526
- * Returns the value of this number.
527
- * @return float the value of this number.
528
- */
529
- public function getValue()
530
- {
531
- return $this->value;
532
- }
533
-
534
- /**
535
- * Returns the integer value.
536
- * @return integer the integer value.
537
- * @throws SassNumberException if the number is not an integer
538
- */
539
- public function toInt()
540
- {
541
- if (!$this->isInt()) {
542
- throw new SassNumberException('Not an integer: ' . $this->value, SassScriptParser::$context->node);
543
- }
544
-
545
- return intval($this->value);
546
- }
547
-
548
- /**
549
- * Converts the number to a string with it's units if any.
550
- * If the units are px the result is rounded down to the nearest integer,
551
- * otherwise the result is rounded to the specified precision.
552
- * @return string number as a string with it's units if any
553
- */
554
- public function toString()
555
- {
556
- if (!isset($this->units)) {
557
- $this->units = $this->getUnits();
558
- }
559
-
560
- return ($this->units == 'px' ? floor($this->value) : str_replace(',','.',round($this->value, self::PRECISION))) . $this->units;
561
- }
562
-
563
- /**
564
- * Returns a value indicating if a token of this type can be matched at
565
- * the start of the subject string.
566
- * @param string the subject string
567
- * @return mixed match at the start of the string or false if no match
568
- */
569
- public static function isa($subject)
570
- {
571
- return (preg_match(self::MATCH, $subject, $matches) ? $matches[0] : false);
572
- }
573
-
574
- /**
575
- * Returns the number of values of SassNumber
576
- * @return int
577
- */
578
- public function length()
579
- {
580
- return count($this->value);
581
- }
582
-
583
- /**
584
- * Returns the nth value of the SassNumber
585
- * @param int - the nth position of value
586
- * @return SassBoolean|SassNumber
587
- */
588
- public function nth($i)
589
- {
590
- if ($i == 1 && isset($this->value)) {
591
- return new SassNumber($this->value);
592
- }
593
-
594
- return new SassBoolean(false);
595
- }
596
-
597
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/script/literals/SassString.php DELETED
@@ -1,148 +0,0 @@
1
- <?php
2
- /* SVN FILE: $Id$ */
3
- /**
4
- * SassString 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.script.literals
10
- */
11
-
12
- require_once 'SassLiteral.php';
13
-
14
- /**
15
- * SassString class.
16
- * Provides operations and type testing for Sass strings.
17
- * @package PHamlP
18
- * @subpackage Sass.script.literals
19
- */
20
- class SassString extends SassLiteral
21
- {
22
- const MATCH = '/^(((["\'])(.*?)(\3))|(-[a-zA-Z-]+[^\s]*?))/i';
23
- const _MATCH = '/^(["\'])(.*?)(\1)?$/'; // Used to match strings such as "Times New Roman",serif
24
- const VALUE = 2;
25
- const QUOTE = 3;
26
-
27
- /**
28
- * @var string string quote type; double or single quotes, or unquoted.
29
- */
30
- public $quote;
31
-
32
- /**
33
- * class constructor
34
- * @param string string
35
- * @return SassString
36
- */
37
- public function __construct($value)
38
- {
39
- preg_match(self::_MATCH, $value, $matches);
40
- if ((isset($matches[self::QUOTE]))) {
41
- $this->quote = $matches[self::QUOTE];
42
- $this->value = $matches[self::VALUE];
43
- } else {
44
- $this->quote = '';
45
- $this->value = $value;
46
- }
47
- }
48
-
49
- /**
50
- * String addition.
51
- * Concatenates this and other.
52
- * The resulting string will be quoted in the same way as this.
53
- * @param sassString string to add to this
54
- * @return sassString the string result
55
- */
56
- public function op_plus($other)
57
- {
58
- $this->value .= $other->value;
59
-
60
- return $this;
61
- }
62
-
63
- /**
64
- * String multiplication.
65
- * this is repeated other times
66
- * @param sassNumber the number of times to repeat this
67
- * @return sassString the string result
68
- */
69
- public function op_times($other)
70
- {
71
- if (!($other instanceof SassNumber) || !$other->isUnitless()) {
72
- throw new SassStringException('Value must be a unitless number', SassScriptParser::$context->node);
73
- }
74
- $this->value = str_repeat($this->value, $other->value);
75
-
76
- return $this;
77
- }
78
-
79
- /**
80
- * Equals - works better
81
- */
82
- public function op_eq($other)
83
- {
84
- return new SassBoolean($this->value == $other->value || $this->toString() == $other->toString());
85
- }
86
-
87
- /**
88
- * Evaluates the value as a boolean.
89
- */
90
- public function toBoolean()
91
- {
92
- $value = strtolower(trim($this->value, ' "\''));
93
- if (!$value || in_array($value, array('false', 'null', '0'))) {
94
- return FALSE;
95
- }
96
-
97
- return TRUE;
98
- }
99
-
100
- /**
101
- * Returns the value of this string.
102
- * @return string the string
103
- */
104
- public function getValue()
105
- {
106
- return $this->value;
107
- }
108
-
109
- /**
110
- * Returns a string representation of the value.
111
- * @return string string representation of the value.
112
- */
113
- public function toString()
114
- {
115
- if ($this->quote) {
116
- $value = $this->quote . $this->value . $this->quote;
117
- } else {
118
- $value = strlen(trim($this->value)) ? trim($this->value) : $this->value;
119
- }
120
-
121
- return $value;
122
- }
123
-
124
- public function toVar()
125
- {
126
- return SassScriptParser::$context->getVariable($this->value);
127
- }
128
-
129
- public function getTypeOf()
130
- {
131
- if (SassList::isa($this->toString())) {
132
- return 'list';
133
- }
134
-
135
- return 'string';
136
- }
137
-
138
- /**
139
- * Returns a value indicating if a token of this type can be matched at
140
- * the start of the subject string.
141
- * @param string the subject string
142
- * @return mixed match at the start of the string or false if no match
143
- */
144
- public static function isa($subject)
145
- {
146
- return (preg_match(self::MATCH, $subject, $matches) ? $matches[0] : false);
147
- }
148
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/test-extensions.php DELETED
@@ -1,147 +0,0 @@
1
- <!-- Just load this in a browser and the tests will run! -->
2
- <html>
3
- <head>
4
- <title>PHamlP Test Suite</title>
5
- <link rel="stylesheet" type="text/css" href="test.css">
6
- </head>
7
- <body>
8
- <?php
9
-
10
- /* Testing for Sassy.
11
- * Looks in tests* and compiles any .sass/.scss files
12
- * and compares to them to their twin .css files by
13
- * filename.
14
- *
15
- * That is, if we have three files:
16
- * test.scss
17
- * test.sass
18
- * test.css
19
- *
20
- * The tester will compile test.scss and test.sass seperately
21
- * and compare their outputs both to each other and to test.css
22
- *
23
- * Testing is eased by stripping out all whitespace, which may
24
- * introduce bugs of their own.
25
- */
26
- include 'SassParser.php';
27
-
28
- $test_dir = './tests/extensions';
29
- $extensions_dir = new DirectoryIterator('./Extensions');
30
-
31
- $files = find_files($test_dir);
32
-
33
- $i = 0;
34
-
35
- foreach ($files['by_name'] as $name => $test) {
36
- if (isset($_GET['name']) && $name != $_GET['name']) {
37
- continue;
38
- }
39
- if (isset($_GET['skip']) && $name && preg_match('/(^|,)(' . preg_quote($name) . ')(,|$)/', $_GET['skip'])) {
40
- continue;
41
- }
42
- if (count($test) > 1) {
43
- $result = test_files($test, $test_dir);
44
-
45
- if ($result === TRUE) {
46
- print "\n\t<p class='pass'><em>PASS</em> $name</p>";
47
- }
48
- else {
49
- print "\n\t<p class='fail'><em>FAIL</em> $name</p>";
50
- print "<pre>$result</pre>";
51
- }
52
- flush();
53
-
54
- if ($i++ == 100) {
55
- die;
56
- }
57
- }
58
- }
59
-
60
- function test_files($files, $dir = '.') {
61
- sort($files);
62
- foreach ($files as $i => $file) {
63
- $name = explode('.', $file);
64
- $ext = array_pop($name);
65
-
66
- $fn = 'parse_' . $ext;
67
- if (function_exists($fn)) {
68
- try {
69
- $result = $fn($dir . '/' . $file);
70
- } catch (Exception $e) {
71
- return $e->__toString();
72
- }
73
- file_put_contents('/tmp/scss_test_' . $i, trim($result) . "\n");
74
- }
75
- }
76
-
77
- $diff = exec('diff -ibwB /tmp/scss_test_0 /tmp/scss_test_1', $out);
78
- if (count($out)) {
79
- if (isset($_GET['full'])) {
80
- $out[] = "\n\n\n" . $result;
81
- }
82
- return implode("\n", $out);
83
- } else {
84
- return TRUE;
85
- }
86
- }
87
-
88
-
89
- function parse_scss($file) {
90
- return __parse($file, 'scss');
91
- }
92
- function parse_sass($file) {
93
- return __parse($file, 'sass');
94
- }
95
- function parse_css($file) {
96
- return file_get_contents($file);
97
- }
98
-
99
- function __parse($file, $syntax, $style = 'nested') {
100
- global $extensions_dir;
101
- foreach ($extensions_dir as $item) {
102
- if ($item->isDir() && !$item->isDot()) {
103
- $extensionTest = $item->getRealPath().'/test.php';
104
- if (file_exists($extensionTest)) {
105
- $result = include $extensionTest;
106
- return $result;
107
- }
108
- }
109
- }
110
- }
111
-
112
- function cb_warn($message, $context) {
113
- print "<p class='warn'>WARN : ";
114
- print_r($message);
115
- print "</p>";
116
- }
117
- function cb_debug($message) {
118
- print "<p class='debug'>DEBUG : ";
119
- print_r($message);
120
- print "</p>";
121
- }
122
-
123
- function find_files($dir) {
124
- $op = opendir($dir);
125
- $return = array('by_type' => array(), 'by_name' => array());
126
- if ($op) {
127
- while (false !== ($file = readdir($op))) {
128
- if (substr($file, 0, 1) == '.') {
129
- continue;
130
- }
131
- $name = explode('.', $file);
132
- $ext = array_pop($name);
133
- $return['by_type'][$ext] = $file;
134
- $name = implode('.', $name);
135
- if (!isset($return['by_name'][$name])) {
136
- $return['by_name'][$name] = array();
137
- }
138
- $return['by_name'][$name][] = $name . '.' . $ext;
139
- }
140
- }
141
- asort($return['by_name']);
142
- asort($return['by_type']);
143
- return $return;
144
- }
145
- ?>
146
- </body>
147
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/test.css DELETED
@@ -1,39 +0,0 @@
1
- body {
2
- margin: 41px 0 0;
3
- font-family: Lato, Calibri, "Trebuchet MS", Verdana, sans-serif;
4
- }
5
-
6
- body::before {
7
- content: 'PHPSass Test Suite';
8
- position: fixed;
9
- top: 0;
10
- left: 0;
11
- right: 0;
12
- padding: 5px 10px;
13
- background: #222;
14
- color: #fff;
15
- font-size: 18pt;
16
- }
17
-
18
- p {
19
- font-size: 12pt;
20
- padding: 5px 10px;
21
- margin: 0 0 1px;
22
- background: #eee;
23
- border-left: 10px solid #eee;
24
- }
25
-
26
- .pass {
27
- border-color: #0c0;
28
- color: #888;
29
- font-size: 8pt;
30
- }
31
-
32
- .fail {
33
- border-color:#c00;
34
- font-weight: bold;
35
- }
36
-
37
- .warn, .debug {
38
- border-color: #27a;
39
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/test.php DELETED
@@ -1,149 +0,0 @@
1
- <!-- Just load this in a browser and the tests will run! -->
2
- <html>
3
- <head>
4
- <title>PHamlP Test Suite</title>
5
- <link rel="stylesheet" type="text/css" href="test.css">
6
- </head>
7
- <body>
8
- <?php
9
-
10
- /* Testing for Sassy.
11
- * Looks in tests* and compiles any .sass/.scss files
12
- * and compares to them to their twin .css files by
13
- * filename.
14
- *
15
- * That is, if we have three files:
16
- * test.scss
17
- * test.sass
18
- * test.css
19
- *
20
- * The tester will compile test.scss and test.sass seperately
21
- * and compare their outputs both to each other and to test.css
22
- *
23
- * Testing is eased by stripping out all whitespace, which may
24
- * introduce bugs of their own.
25
- */
26
- include 'SassParser.php';
27
-
28
- $test_dir = './tests';
29
-
30
- $files = find_files($test_dir);
31
-
32
- $i = 0;
33
-
34
- foreach ($files['by_name'] as $name => $test) {
35
- if (isset($_GET['name']) && $name != $_GET['name']) {
36
- continue;
37
- }
38
- if (isset($_GET['skip']) && $name && preg_match('/(^|,)(' . preg_quote($name) . ')(,|$)/', $_GET['skip'])) {
39
- continue;
40
- }
41
- if (count($test) > 1) {
42
- $result = test_files($test, $test_dir);
43
-
44
- if ($result === TRUE) {
45
- print "\n\t<p class='pass'><em>PASS</em> $name</p>";
46
- }
47
- else {
48
- print "\n\t<p class='fail'><em>FAIL</em> $name</p>";
49
- print "<pre>$result</pre>";
50
- }
51
- flush();
52
-
53
- if ($i++ == 100) {
54
- die;
55
- }
56
- }
57
- }
58
-
59
- function test_files($files, $dir = '.') {
60
- sort($files);
61
- foreach ($files as $i => $file) {
62
- $name = explode('.', $file);
63
- $ext = array_pop($name);
64
-
65
- $fn = 'parse_' . $ext;
66
- if (function_exists($fn)) {
67
- try {
68
- $result = $fn($dir . '/' . $file);
69
- } catch (Exception $e) {
70
- return $e->__toString();
71
- }
72
- file_put_contents('/tmp/scss_test_' . $i, trim($result) . "\n");
73
- }
74
- }
75
-
76
- $diff = exec('diff -ibwB /tmp/scss_test_0 /tmp/scss_test_1', $out);
77
- if (count($out)) {
78
- if (isset($_GET['full'])) {
79
- $out[] = "\n\n\n" . $result;
80
- }
81
- return implode("\n", $out);
82
- } else {
83
- return TRUE;
84
- }
85
- }
86
-
87
-
88
- function parse_scss($file) {
89
- return __parse($file, 'scss');
90
- }
91
- function parse_sass($file) {
92
- return __parse($file, 'sass');
93
- }
94
- function parse_css($file) {
95
- return file_get_contents($file);
96
- }
97
-
98
- function __parse($file, $syntax, $style = 'nested') {
99
- $options = array(
100
- 'style' => $style,
101
- 'cache' => FALSE,
102
- 'syntax' => $syntax,
103
- 'debug' => FALSE,
104
- 'callbacks' => array(
105
- 'warn' => 'cb_warn',
106
- 'debug' => 'cb_debug',
107
- ),
108
- );
109
- // Execute the compiler.
110
- $parser = new SassParser($options);
111
- return $parser->toCss($file);
112
- }
113
-
114
- function cb_warn($message, $context) {
115
- print "<p class='warn'>WARN : ";
116
- print_r($message);
117
- print "</p>";
118
- }
119
- function cb_debug($message) {
120
- print "<p class='debug'>DEBUG : ";
121
- print_r($message);
122
- print "</p>";
123
- }
124
-
125
- function find_files($dir) {
126
- $op = opendir($dir);
127
- $return = array('by_type' => array(), 'by_name' => array());
128
- if ($op) {
129
- while (false !== ($file = readdir($op))) {
130
- if (substr($file, 0, 1) == '.') {
131
- continue;
132
- }
133
- $name = explode('.', $file);
134
- $ext = array_pop($name);
135
- $return['by_type'][$ext] = $file;
136
- $name = implode('.', $name);
137
- if (!isset($return['by_name'][$name])) {
138
- $return['by_name'][$name] = array();
139
- }
140
- $return['by_name'][$name][] = $name . '.' . $ext;
141
- }
142
- }
143
- asort($return['by_name']);
144
- asort($return['by_type']);
145
- return $return;
146
- }
147
- ?>
148
- </body>
149
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/_imported_charset_ibm866.sass DELETED
@@ -1,4 +0,0 @@
1
- @charset "IBM866"
2
-
3
- .bar
4
- a: �
 
 
 
 
lib/phpsass/tests/_imported_charset_utf8.sass DELETED
@@ -1,4 +0,0 @@
1
- @charset "UTF-8"
2
-
3
- .bar
4
- a: щ
 
 
 
 
lib/phpsass/tests/_imported_content.sass DELETED
@@ -1,3 +0,0 @@
1
- @mixin foo
2
- a
3
- @content
 
 
 
lib/phpsass/tests/_partial.sass DELETED
@@ -1,2 +0,0 @@
1
- #foo
2
- :background-color #baf
 
 
lib/phpsass/tests/alt.css DELETED
@@ -1,16 +0,0 @@
1
- h1 {
2
- float: left;
3
- width: 274px;
4
- height: 75px;
5
- margin: 0;
6
- background-repeat: no-repeat;
7
- background-image: none; }
8
- h1 a:hover,
9
- h1 a:visited {
10
- color: green; }
11
- h1 b:hover {
12
- color: red;
13
- background-color: green; }
14
- h1 const {
15
- nosp: 3;
16
- sp: 3; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/alt.sass DELETED
@@ -1,16 +0,0 @@
1
- h1
2
- float: left
3
- width: 274px
4
- height: 75px
5
- margin: 0
6
- background:
7
- repeat: no-repeat
8
- image: none
9
- a:hover, a:visited
10
- color: green
11
- b:hover
12
- color: red
13
- background-color: green
14
- const
15
- nosp: 6 / 2
16
- sp : 1 + 2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/alt.scss DELETED
@@ -1,21 +0,0 @@
1
- h1 {
2
- float: left;
3
- width: 274px;
4
- height: 75px;
5
- margin: 0;
6
- background: {
7
- repeat: no-repeat;
8
- image: none;
9
- }
10
- a:hover, a:visited {
11
- color: green;
12
- }
13
- b:hover {
14
- color: red;
15
- background-color: green;
16
- }
17
- const {
18
- nosp: 6 / 2;
19
- sp : 1 + 2;
20
- }
21
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/basic.css DELETED
@@ -1,21 +0,0 @@
1
- body {
2
- font: Arial;
3
- background: blue; }
4
-
5
- #page {
6
- width: 700px;
7
- height: 100;
8
- line-height: 100%; }
9
- #page #header {
10
- height: 300px; }
11
- #page #header h1 {
12
- font-size: 50px;
13
- color: blue; }
14
-
15
- #content.user.show #container.top #column.left {
16
- width: 100px; }
17
- #content.user.show #container.top #column.right {
18
- width: 600px; }
19
- #content.user.show #container.bottom {
20
- background: brown; }
21
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/basic.sass DELETED
@@ -1,22 +0,0 @@
1
- body
2
- font: Arial
3
- background: blue
4
-
5
- #page
6
- :width 700px
7
- :height 100
8
- :line-height 100%
9
- #header
10
- :height 300px
11
- h1
12
- :font-size 50px
13
- :color blue
14
-
15
- #content.user.show
16
- #container.top
17
- #column.left
18
- :width 100px
19
- #column.right
20
- :width 600px
21
- #container.bottom
22
- :background brown
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/bork1.sass DELETED
@@ -1,2 +0,0 @@
1
- bork
2
- :bork $bork
 
 
lib/phpsass/tests/bork2.sass DELETED
@@ -1,2 +0,0 @@
1
- bork
2
- :bork: bork;
 
 
lib/phpsass/tests/bork3.sass DELETED
@@ -1,2 +0,0 @@
1
- bork
2
- bork:
 
 
lib/phpsass/tests/bork4.sass DELETED
@@ -1,2 +0,0 @@
1
-
2
- bork: blah
 
 
lib/phpsass/tests/bork5.sass DELETED
@@ -1,3 +0,0 @@
1
- foo
2
- @function bar($a)
3
- @return $a
 
 
 
lib/phpsass/tests/colour-nth.css DELETED
@@ -1,2 +0,0 @@
1
- #colour-nth {
2
- background: yellow; }
 
 
lib/phpsass/tests/colour-nth.scss DELETED
@@ -1,3 +0,0 @@
1
- #colour-nth {
2
- background: nth(#ff0, 1);
3
- }
 
 
 
lib/phpsass/tests/comments.css DELETED
@@ -1,20 +0,0 @@
1
- body {
2
- font-family: sans-serif;
3
- color: #111111;
4
- font-size: 75%;
5
- line-height: 1.2;
6
- padding: 0;
7
- margin: 0; }
8
-
9
- .invisible,
10
- .element-invisible {
11
- border: 0;
12
- clip: rect(1px 1px 1px 1px);
13
- clip: rect(1px, 1px, 1px, 1px);
14
- height: 1px;
15
- margin: -1px;
16
- overflow: hidden;
17
- padding: 0;
18
- position: absolute !important;
19
- width: 1px; }
20
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/comments.sass DELETED
@@ -1,20 +0,0 @@
1
- body
2
- font-family: sans-serif
3
- color: #111
4
- font-size: 75% // 12px
5
- line-height: 1.2
6
- padding: 0
7
- // Addresses margins handled incorrectly in IE6/7.
8
- margin: 0
9
-
10
- .invisible,
11
- .element-invisible
12
- border: 0
13
- clip: rect(1px 1px 1px 1px) // IE6, IE7
14
- clip: rect(1px, 1px, 1px, 1px)
15
- height: 1px
16
- margin: -1px
17
- overflow: hidden
18
- padding: 0
19
- position: absolute !important
20
- width: 1px
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/compact.css DELETED
@@ -1,13 +0,0 @@
1
- #main {
2
- width: 15em;
3
- color: blue; }
4
- #main p {
5
- border-style: dotted;
6
- border-width: 2px; }
7
- #main .cool {
8
- width: 100px; }
9
-
10
- #left {
11
- font-size: 2em;
12
- font-weight: bold;
13
- float: left; }
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/compact.sass DELETED
@@ -1,15 +0,0 @@
1
- #main
2
- :width 15em
3
- :color #0000ff
4
- p
5
- :border
6
- :style dotted
7
- :width 2px
8
- .cool
9
- :width 100px
10
-
11
- #left
12
- :font
13
- :size 2em
14
- :weight bold
15
- :float left
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/complex.css DELETED
@@ -1,290 +0,0 @@
1
- body {
2
- margin: 0;
3
- font: 0.85em "Lucida Grande", "Trebuchet MS", Verdana, sans-serif;
4
- color: white;
5
- background: url(/images/global_bg.gif); }
6
-
7
- #page {
8
- width: 900px;
9
- margin: 0 auto;
10
- background: #440008;
11
- border-top-width: 5px;
12
- border-top-style: solid;
13
- border-top-color: #ff8500; }
14
-
15
- #header {
16
- height: 75px;
17
- padding: 0; }
18
- #header h1 {
19
- float: left;
20
- width: 274px;
21
- height: 75px;
22
- margin: 0;
23
- background-image: url(/images/global_logo.gif);
24
- /*
25
- * Crazy nested comment
26
- */
27
- background-repeat: no-repeat;
28
- text-indent: -9999px; }
29
- #header .status {
30
- float: right;
31
- padding-top: 0.5em;
32
- padding-left: 0.5em;
33
- padding-right: 0.5em;
34
- padding-bottom: 0; }
35
- #header .status p {
36
- float: left;
37
- margin-top: 0;
38
- margin-right: 0.5em;
39
- margin-bottom: 0;
40
- margin-left: 0; }
41
- #header .status ul {
42
- float: left;
43
- margin: 0;
44
- padding: 0; }
45
- #header .status li {
46
- list-style-type: none;
47
- display: inline;
48
- margin: 0 5px; }
49
- #header .status a:link,
50
- #header .status a:visited {
51
- color: #ff8500;
52
- text-decoration: none; }
53
- #header .status a:hover {
54
- text-decoration: underline; }
55
- #header .search {
56
- float: right;
57
- clear: right;
58
- margin: 12px 0 0 0; }
59
- #header .search form {
60
- margin: 0; }
61
- #header .search input {
62
- margin: 0 3px 0 0;
63
- padding: 2px;
64
- border: none; }
65
-
66
- #menu {
67
- clear: both;
68
- text-align: right;
69
- height: 20px;
70
- border-bottom: 5px solid #006b95;
71
- background: #00a4e4; }
72
- #menu .contests ul {
73
- margin: 0 5px 0 0;
74
- padding: 0; }
75
- #menu .contests ul li {
76
- list-style-type: none;
77
- margin: 0 5px;
78
- padding: 5px 5px 0 5px;
79
- display: inline;
80
- font-size: 1.1em;
81
- color: white;
82
- background: #00a4e4; }
83
- #menu .contests a:link,
84
- #menu .contests a:visited {
85
- color: white;
86
- text-decoration: none;
87
- font-weight: bold; }
88
- #menu .contests a:hover {
89
- text-decoration: underline; }
90
-
91
- #content {
92
- clear: both; }
93
- #content .container {
94
- clear: both; }
95
- #content .container .column {
96
- float: left; }
97
- #content .container .column .right {
98
- float: right; }
99
- #content a:link,
100
- #content a:visited {
101
- color: #93d700;
102
- text-decoration: none; }
103
- #content a:hover {
104
- text-decoration: underline; }
105
-
106
- #content p,
107
- #content div {
108
- width: 40em; }
109
- #content p li,
110
- #content p dt,
111
- #content p dd,
112
- #content div li,
113
- #content div dt,
114
- #content div dd {
115
- color: #ddffdd;
116
- background-color: #4792bb; }
117
- #content .container.video .column.left {
118
- width: 200px; }
119
- #content .container.video .column.left .box {
120
- margin-top: 10px; }
121
- #content .container.video .column.left .box p {
122
- margin: 0 1em auto 1em; }
123
- #content .container.video .column.left .box.participants img {
124
- float: left;
125
- margin: 0 1em auto 1em;
126
- border: 1px solid #6e000d;
127
- border-style: solid; }
128
- #content .container.video .column.left .box.participants h2 {
129
- margin: 0 0 10px 0;
130
- padding: 0.5em;
131
- /*
132
- * The background image is a gif!
133
- */
134
- background: #6e000d url(/images/hdr_participant.gif) 2px 2px no-repeat;
135
- /*
136
- * Okay check this out
137
- * Multiline comments
138
- * Wow dude
139
- * I mean seriously, WOW
140
- */
141
- text-indent: -9999px;
142
- border-top-width: 5px;
143
- border-top-style: solid;
144
- border-top-color: #a20013;
145
- border-right-width: 1px;
146
- border-right-style: dotted; }
147
- #content .container.video .column.middle {
148
- width: 500px; }
149
- #content .container.video .column.right {
150
- width: 200px; }
151
- #content .container.video .column.right .box {
152
- margin-top: 0; }
153
- #content .container.video .column.right .box p {
154
- margin: 0 1em auto 1em; }
155
- #content .container.video .column p {
156
- margin-top: 0; }
157
-
158
- #content.contests .container.information .column.right .box {
159
- margin: 1em 0; }
160
- #content.contests .container.information .column.right .box.videos .thumbnail img {
161
- width: 200px;
162
- height: 150px;
163
- margin-bottom: 5px; }
164
- #content.contests .container.information .column.right .box.videos a:link,
165
- #content.contests .container.information .column.right .box.videos a:visited {
166
- color: #93d700;
167
- text-decoration: none; }
168
- #content.contests .container.information .column.right .box.videos a:hover {
169
- text-decoration: underline; }
170
- #content.contests .container.information .column.right .box.votes a {
171
- display: block;
172
- width: 200px;
173
- height: 60px;
174
- margin: 15px 0;
175
- background: url(/images/btn_votenow.gif) no-repeat;
176
- text-indent: -9999px;
177
- outline: none;
178
- border: none; }
179
- #content.contests .container.information .column.right .box.votes h2 {
180
- margin: 52px 0 10px 0;
181
- padding: 0.5em;
182
- background: #6e000d url(/images/hdr_videostats.gif) 2px 2px no-repeat;
183
- text-indent: -9999px;
184
- border-top: 5px solid #a20013; }
185
-
186
- #content.contests .container.video .box.videos h2 {
187
- margin: 0;
188
- padding: 0.5em;
189
- background: #6e000d url(/images/hdr_newestclips.gif) 2px 2px no-repeat;
190
- text-indent: -9999px;
191
- border-top: 5px solid #a20013; }
192
- #content.contests .container.video .box.videos table {
193
- width: 100; }
194
- #content.contests .container.video .box.videos table td {
195
- padding: 1em;
196
- width: 25;
197
- vertical-align: top; }
198
- #content.contests .container.video .box.videos table td p {
199
- margin: 0 0 5px 0; }
200
- #content.contests .container.video .box.videos table td a:link,
201
- #content.contests .container.video .box.videos table td a:visited {
202
- color: #93d700;
203
- text-decoration: none; }
204
- #content.contests .container.video .box.videos table td a:hover {
205
- text-decoration: underline; }
206
- #content.contests .container.video .box.videos .thumbnail {
207
- float: left; }
208
- #content.contests .container.video .box.videos .thumbnail img {
209
- width: 80px;
210
- height: 60px;
211
- margin: 0 10px 0 0;
212
- border: 1px solid #6e000d; }
213
-
214
- #content .container.comments .column {
215
- margin-top: 15px; }
216
- #content .container.comments .column.left {
217
- width: 600px; }
218
- #content .container.comments .column.left .box ol {
219
- margin: 0;
220
- padding: 0; }
221
- #content .container.comments .column.left .box li {
222
- list-style-type: none;
223
- padding: 10px;
224
- margin: 0 0 1em 0;
225
- background: #6e000d;
226
- border-top: 5px solid #a20013; }
227
- #content .container.comments .column.left .box li div {
228
- margin-bottom: 1em; }
229
- #content .container.comments .column.left .box li ul {
230
- text-align: right; }
231
- #content .container.comments .column.left .box li ul li {
232
- display: inline;
233
- border: none;
234
- padding: 0; }
235
- #content .container.comments .column.right {
236
- width: 290px;
237
- padding-left: 10px; }
238
- #content .container.comments .column.right h2 {
239
- margin: 0;
240
- padding: 0.5em;
241
- background: #6e000d url(/images/hdr_addcomment.gif) 2px 2px no-repeat;
242
- text-indent: -9999px;
243
- border-top: 5px solid #a20013; }
244
- #content .container.comments .column.right .box textarea {
245
- width: 290px;
246
- height: 100px;
247
- border: none; }
248
-
249
- #footer {
250
- margin-top: 10px;
251
- padding: 1.2em 1.5em;
252
- background: #ff8500; }
253
- #footer ul {
254
- margin: 0;
255
- padding: 0;
256
- list-style-type: none; }
257
- #footer ul li {
258
- display: inline;
259
- margin: 0 0.5em;
260
- color: #440008; }
261
- #footer ul.links {
262
- float: left; }
263
- #footer ul.links a:link,
264
- #footer ul.links a:visited {
265
- color: #440008;
266
- text-decoration: none; }
267
- #footer ul.links a:hover {
268
- text-decoration: underline; }
269
- #footer ul.copyright {
270
- float: right; }
271
-
272
- .clear {
273
- clear: both; }
274
-
275
- .centered {
276
- text-align: center; }
277
-
278
- img {
279
- border: none; }
280
-
281
- button.short {
282
- width: 60px;
283
- height: 22px;
284
- padding: 0 0 2px 0;
285
- color: white;
286
- border: none;
287
- background: url(/images/btn_short.gif) no-repeat; }
288
-
289
- table {
290
- border-collapse: collapse; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/complex.sass DELETED
@@ -1,303 +0,0 @@
1
- body
2
- :margin 0
3
- :font 0.85em "Lucida Grande", "Trebuchet MS", Verdana, sans-serif
4
- :color #fff
5
- $path: /images/global_bg.gif
6
- :background url($path)
7
-
8
- #page
9
- :width 900px
10
- :margin 0 auto
11
- :background #440008
12
- :border-top
13
- :width 5px
14
- :style solid
15
- :color #ff8500
16
-
17
- #header
18
- :height 75px
19
- :padding 0
20
- h1
21
- :float left
22
- :width 274px
23
- :height 75px
24
- :margin 0
25
- :background
26
- :image url(/images/global_logo.gif)
27
- /* Crazy nested comment
28
- :repeat no-repeat
29
- :text-indent -9999px
30
- .status
31
- :float right
32
- :padding
33
- :top .5em
34
- :left .5em
35
- :right .5em
36
- :bottom 0
37
- p
38
- :float left
39
- :margin
40
- :top 0
41
- :right 0.5em
42
- :bottom 0
43
- :left 0
44
- ul
45
- :float left
46
- :margin 0
47
- :padding 0
48
- li
49
- :list-style-type none
50
- :display inline
51
- :margin 0 5px
52
- a:link, a:visited
53
- :color #ff8500
54
- :text-decoration none
55
- a:hover
56
- :text-decoration underline
57
- .search
58
- :float right
59
- :clear right
60
- :margin 12px 0 0 0
61
- form
62
- :margin 0
63
- input
64
- :margin 0 3px 0 0
65
- :padding 2px
66
- :border none
67
-
68
- #menu
69
- :clear both
70
- :text-align right
71
- :height 20px
72
- :border-bottom 5px solid #006b95
73
- :background #00a4e4
74
- .contests
75
- ul
76
- :margin 0 5px 0 0
77
- :padding 0
78
- li
79
- :list-style-type none
80
- :margin 0 5px
81
- :padding 5px 5px 0 5px
82
- :display inline
83
- :font-size 1.1em
84
- // This comment is properly indented
85
- :color #fff
86
- :background #00a4e4
87
- a:link, a:visited
88
- :color #fff
89
- :text-decoration none
90
- :font-weight bold
91
- a:hover
92
- :text-decoration underline
93
-
94
- //General content information
95
- #content
96
- :clear both
97
- .container
98
- :clear both
99
- .column
100
- :float left
101
- .right
102
- :float right
103
- a:link, a:visited
104
- :color #93d700
105
- :text-decoration none
106
- a:hover
107
- :text-decoration underline
108
-
109
- #content
110
- p, div
111
- :width 40em
112
- li, dt, dd
113
- :color #ddffdd
114
- :background-color #4792bb
115
- .container.video
116
- .column.left
117
- :width 200px
118
- .box
119
- :margin-top 10px
120
- p
121
- :margin 0 1em auto 1em
122
- .box.participants
123
- img
124
- :float left
125
- :margin 0 1em auto 1em
126
- :border 1px solid #6e000d
127
- :style solid
128
- h2
129
- :margin 0 0 10px 0
130
- :padding 0.5em
131
- /* The background image is a gif!
132
- :background #6e000d url(/images/hdr_participant.gif) 2px 2px no-repeat
133
- /* Okay check this out
134
- Multiline comments
135
- Wow dude
136
- I mean seriously, WOW
137
- :text-indent -9999px
138
- // And also...
139
- Multiline comments that don't output!
140
- Snazzy, no?
141
- :border
142
- :top
143
- :width 5px
144
- :style solid
145
- :color #a20013
146
- :right
147
- :width 1px
148
- :style dotted
149
- .column.middle
150
- :width 500px
151
- .column.right
152
- :width 200px
153
- .box
154
- :margin-top 0
155
- p
156
- :margin 0 1em auto 1em
157
- .column
158
- p
159
- :margin-top 0
160
-
161
- #content.contests
162
- .container.information
163
- .column.right
164
- .box
165
- :margin 1em 0
166
- .box.videos
167
- .thumbnail img
168
- :width 200px
169
- :height 150px
170
- :margin-bottom 5px
171
- a:link, a:visited
172
- :color #93d700
173
- :text-decoration none
174
- a:hover
175
- :text-decoration underline
176
- .box.votes
177
- a
178
- :display block
179
- :width 200px
180
- :height 60px
181
- :margin 15px 0
182
- :background url(/images/btn_votenow.gif) no-repeat
183
- :text-indent -9999px
184
- :outline none
185
- :border none
186
- h2
187
- :margin 52px 0 10px 0
188
- :padding 0.5em
189
- :background #6e000d url(/images/hdr_videostats.gif) 2px 2px no-repeat
190
- :text-indent -9999px
191
- :border-top 5px solid #a20013
192
-
193
- #content.contests
194
- .container.video
195
- .box.videos
196
- h2
197
- :margin 0
198
- :padding 0.5em
199
- :background #6e000d url(/images/hdr_newestclips.gif) 2px 2px no-repeat
200
- :text-indent -9999px
201
- :border-top 5px solid #a20013
202
- table
203
- :width 100
204
- td
205
- :padding 1em
206
- :width 25
207
- :vertical-align top
208
- p
209
- :margin 0 0 5px 0
210
- a:link, a:visited
211
- :color #93d700
212
- :text-decoration none
213
- a:hover
214
- :text-decoration underline
215
- .thumbnail
216
- :float left
217
- img
218
- :width 80px
219
- :height 60px
220
- :margin 0 10px 0 0
221
- :border 1px solid #6e000d
222
-
223
- #content
224
- .container.comments
225
- .column
226
- :margin-top 15px
227
- .column.left
228
- :width 600px
229
- .box
230
- ol
231
- :margin 0
232
- :padding 0
233
- li
234
- :list-style-type none
235
- :padding 10px
236
- :margin 0 0 1em 0
237
- :background #6e000d
238
- :border-top 5px solid #a20013
239
- div
240
- :margin-bottom 1em
241
- ul
242
- :text-align right
243
- li
244
- :display inline
245
- :border none
246
- :padding 0
247
- .column.right
248
- :width 290px
249
- :padding-left 10px
250
- h2
251
- :margin 0
252
- :padding 0.5em
253
- :background #6e000d url(/images/hdr_addcomment.gif) 2px 2px no-repeat
254
- :text-indent -9999px
255
- :border-top 5px solid #a20013
256
- .box
257
- textarea
258
- :width 290px
259
- :height 100px
260
- :border none
261
-
262
- #footer
263
- :margin-top 10px
264
- :padding 1.2em 1.5em
265
- :background #ff8500
266
- ul
267
- :margin 0
268
- :padding 0
269
- :list-style-type none
270
- li
271
- :display inline
272
- :margin 0 0.5em
273
- :color #440008
274
- ul.links
275
- :float left
276
- a:link, a:visited
277
- :color #440008
278
- :text-decoration none
279
- a:hover
280
- :text-decoration underline
281
- ul.copyright
282
- :float right
283
-
284
-
285
- .clear
286
- :clear both
287
-
288
- .centered
289
- :text-align center
290
-
291
- img
292
- :border none
293
-
294
- button.short
295
- :width 60px
296
- :height 22px
297
- :padding 0 0 2px 0
298
- :color #fff
299
- :border none
300
- :background url(/images/btn_short.gif) no-repeat
301
-
302
- table
303
- :border-collapse collapse
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/compressed.css DELETED
@@ -1,12 +0,0 @@
1
- #main {
2
- width:15em;
3
- color:blue; }
4
- #main p {
5
- border-style:dotted;
6
- border-width:2px; }
7
- #main .cool {
8
- width:100px; }
9
- #left {
10
- font-size:2em;
11
- font-weight:bold;
12
- float:left; }
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/compressed.sass DELETED
@@ -1,15 +0,0 @@
1
- #main
2
- :width 15em
3
- :color #0000ff
4
- p
5
- :border
6
- :style dotted
7
- :width 2px
8
- .cool
9
- :width 100px
10
-
11
- #left
12
- :font
13
- :size 2em
14
- :weight bold
15
- :float left
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/content.css DELETED
@@ -1,2 +0,0 @@
1
- div:before {
2
- content: "- "; }
 
 
lib/phpsass/tests/content.scss DELETED
@@ -1,3 +0,0 @@
1
- div:before {
2
- content: "- ";
3
- }
 
 
 
lib/phpsass/tests/css3.css DELETED
@@ -1,7 +0,0 @@
1
- h1 {
2
- opacity: 0.3;
3
- color: red;
4
- -moz-transition: opacity 1s ease 1s;
5
- -webkit-transition: opacity 1s ease 1s;
6
- -o-transition: opacity 1s ease 1s;
7
- transition: opacity 1s ease 1s; }
 
 
 
 
 
 
 
lib/phpsass/tests/css3.scss DELETED
@@ -1,8 +0,0 @@
1
- h1 {
2
- opacity: 0.3;
3
- color:red;
4
- -moz-transition: opacity 1s ease 1s;
5
- -webkit-transition: opacity 1s ease 1s;
6
- -o-transition: opacity 1s ease 1s;
7
- transition: opacity 1s ease 1s;
8
- }
 
 
 
 
 
 
 
 
lib/phpsass/tests/default.css DELETED
@@ -1,4 +0,0 @@
1
- body {
2
- background: blue;
3
- color: blue;
4
- border-color: blue; }
 
 
 
 
lib/phpsass/tests/default.sass DELETED
@@ -1,11 +0,0 @@
1
- $var1: blue
2
- $var1: red !default
3
-
4
- $var2: blue
5
- @import default_imported.sass
6
- $var3: red !default
7
-
8
- body
9
- background: $var1
10
- color: $var2
11
- border-color: $var3
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/default_imported.sass DELETED
@@ -1,2 +0,0 @@
1
- $var2: red !default
2
- $var3: blue
 
 
lib/phpsass/tests/each.css DELETED
@@ -1,14 +0,0 @@
1
- a {
2
- b: 1px;
3
- b: 2px;
4
- b: 3px;
5
- b: 4px; }
6
-
7
- c {
8
- d: foo;
9
- d: bar;
10
- d: baz;
11
- d: bang; }
12
-
13
- e {
14
- f: blue; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/each.scss DELETED
@@ -1,17 +0,0 @@
1
- a {
2
- @each $number in 1px 2px 3px 4px {
3
- b: $number;
4
- }
5
- }
6
-
7
- c {
8
- @each $str in foo, bar, baz, bang {
9
- d: $str;
10
- }
11
- }
12
-
13
- e {
14
- @each $single in blue {
15
- f: $single;
16
- }
17
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/expanded.css DELETED
@@ -1,17 +0,0 @@
1
- #main {
2
- width: 15em;
3
- color: blue; }
4
- #main p {
5
- border-style: dotted;
6
- /*
7
- * Nested comment
8
- * More nested stuff
9
- */
10
- border-width: 2px; }
11
- #main .cool {
12
- width: 100px; }
13
-
14
- #left {
15
- font-size: 2em;
16
- font-weight: bold;
17
- float: left; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/expanded.sass DELETED
@@ -1,17 +0,0 @@
1
- #main
2
- :width 15em
3
- :color #0000ff
4
- p
5
- :border
6
- :style dotted
7
- /* Nested comment
8
- More nested stuff
9
- :width 2px
10
- .cool
11
- :width 100px
12
-
13
- #left
14
- :font
15
- :size 2em
16
- :weight bold
17
- :float left
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/extend.css DELETED
@@ -1,13 +0,0 @@
1
- .error,
2
- .seriousError,
3
- .hoverlink {
4
- border: 1px red;
5
- background-color: #ffdddd; }
6
-
7
- .seriousError,
8
- .hoverlink {
9
- border-width: 3px; }
10
-
11
- .comment a:hover,
12
- .comment .hoverlink {
13
- text-decoration: underline; }
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/extend.sass DELETED
@@ -1,13 +0,0 @@
1
- @import extend_included.scss;
2
-
3
- .seriousError
4
- @extend .error
5
- border-width: 3px
6
-
7
-
8
- .hoverlink
9
- @extend a:hover
10
- @extend .seriousError
11
-
12
- .comment a:hover
13
- text-decoration: underline
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/extend_included.scss DELETED
@@ -1,4 +0,0 @@
1
- .error {
2
- border: 1px #f00;
3
- background-color: #fdd;
4
- }
 
 
 
 
lib/phpsass/tests/extend_placeholders.css DELETED
@@ -1,48 +0,0 @@
1
- /*
2
- * test basic placeholder usage, with multiple extenders
3
- */
4
- .bar,
5
- .baz {
6
- color: blue; }
7
-
8
- /*
9
- * test unused placeholder
10
- */
11
- /*
12
- * test placeholder descendant selector
13
- */
14
- #context .bar a {
15
- color: blue; }
16
-
17
- /*
18
- * test placeholder-descendant with multiple extenders
19
- */
20
- .bar .baz {
21
- color: blue; }
22
- /*
23
- * test placeholder selector as modifier
24
- */
25
- a.bar.baz {
26
- color: blue; }
27
-
28
- /*
29
- * the div should not be rendered as it results in adiv (invalid)
30
- */
31
-
32
- /*
33
- * test placeholder selector modifier again
34
- */
35
- .hello.goodbye {
36
- color: blue; }
37
-
38
- /*
39
- * test placeholder interpolation
40
- */
41
- .inter {
42
- color: blue; }
43
-
44
- /*
45
- * test media in a plaecholder
46
- */
47
- .media {
48
- c: d; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/extend_placeholders.scss DELETED
@@ -1,58 +0,0 @@
1
- /* test basic placeholder usage, with multiple extenders */
2
- %foo { color: blue; }
3
- .bar { @extend %foo; }
4
- .baz { @extend %foo; }
5
-
6
- /* test unused placeholder */
7
- %bar { color: red; }
8
-
9
- /* test placeholder descendant selector */
10
- #context %context a {
11
- color: blue;
12
- }
13
- .bar {
14
- @extend %context;
15
- }
16
-
17
- /* test placeholder-descendant with multiple extenders */
18
- #three %three, .bar .baz {
19
- color: blue;
20
- }
21
-
22
- /* test placeholder selector as modifier */
23
- a%four.baz {
24
- color: blue;
25
- }
26
- .bar { @extend %four; }
27
- /* the div should not be rendered as it results in adiv (invalid) */
28
- div { @extend %four; }
29
-
30
- /* test placeholder selector modifier again */
31
- .hello%hello {
32
- color: blue;
33
- }
34
-
35
- .goodbye {
36
- @extend %hello;
37
- }
38
-
39
- /* test placeholder interpolation */
40
- $in: 'inter';
41
- %#{$in} {
42
- color: blue;
43
- }
44
- .inter {
45
- @extend %inter;
46
- }
47
-
48
- /* test media in a plaecholder */
49
- %medias {
50
- bar {
51
- @media screen {
52
- a: b;
53
- }
54
- }
55
- }
56
- .media {
57
- c: d;
58
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/extensions/linear_gradient_compass.css DELETED
@@ -1,5 +0,0 @@
1
- p {
2
- background-image: -webkit-linear-gradient(bottom, #eff4f8 23%, white 62%);
3
- background-image: -moz-linear-gradient(bottom, #eff4f8 23%, white 62%);
4
- background-image: linear-gradient(bottom, #eff4f8 23%, white 62%);
5
- }
 
 
 
 
 
lib/phpsass/tests/extensions/linear_gradient_compass.scss DELETED
@@ -1,7 +0,0 @@
1
- @import "compass/compass";
2
-
3
- p {
4
- @include background-image(
5
- linear-gradient(bottom, #eff4f8 23%, #fff 62%)
6
- );
7
- }
 
 
 
 
 
 
 
lib/phpsass/tests/filters.css DELETED
@@ -1,6 +0,0 @@
1
- test {
2
- filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#feffff', endColorstr='#ccffffff',GradientType=0 );
3
- foo: bar; }
4
-
5
- other {
6
- hello: goodbye; }
 
 
 
 
 
 
lib/phpsass/tests/filters.scss DELETED
@@ -1,10 +0,0 @@
1
- // https://github.com/richthegeek/phpsass/issues/31
2
-
3
- test {
4
- filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#feffff', endColorstr='#ccffffff',GradientType=0 );
5
- foo: bar;
6
- }
7
-
8
- other {
9
- hello: goodbye;
10
- }
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/functions.css DELETED
@@ -1,9 +0,0 @@
1
- foo,
2
- bar,
3
- foo + bar {
4
- content: 'one two' true;
5
- content: 'foo bar' true;
6
- content: 'foo two' true;
7
- content: 'one foo' true;
8
- content: bar foo true;
9
- adjust-color: #0000f0; }
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/functions.scss DELETED
@@ -1,16 +0,0 @@
1
- @function test() {
2
- @return 'foo, bar, foo + bar';
3
- }
4
-
5
- @function x($one: 'one', $two: 'two') {
6
- @return $one + ' ' + $two;
7
- }
8
-
9
- #{test()} {
10
- content: x() if(x() == 'one two', true, false);
11
- content: x('foo', 'bar') if(x('foo', 'bar') == 'foo bar', true, false);
12
- content: x('foo') if(x('foo') == 'foo two', true, false);
13
- content: x($two: 'foo') if(x($two: 'foo') == 'one foo', true, false);
14
- content: x($two: 'foo', bar) if(x($two: 'foo', bar) == bar foo, true, false);
15
- adjust-color: adjust-color(#00F, $blue: -15);
16
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/holmes.css DELETED
@@ -1,227 +0,0 @@
1
- body.holmes-debug a:not([href]),
2
- body.holmes-debug a[href=""] {
3
- outline: 2px solid red; }
4
- body.holmes-debug a[href="#"],
5
- body.holmes-debug a[href^="javascript"],
6
- body.holmes-debug a:not([title]),
7
- body.holmes-debug a[title=""] {
8
- outline: 2px solid #ffdd00; }
9
- body.holmes-debug img:not([alt]),
10
- body.holmes-debug img[alt=""] {
11
- outline: 2px solid red; }
12
- body.holmes-debug label:not([for]),
13
- body.holmes-debug label[for=""],
14
- body.holmes-debug input:not([name]),
15
- body.holmes-debug input[name=""],
16
- body.holmes-debug select:not([name]),
17
- body.holmes-debug select[name=""],
18
- body.holmes-debug textarea:not([name]),
19
- body.holmes-debug textarea[name=""],
20
- body.holmes-debug abbr:not([title]),
21
- body.holmes-debug abbr[title=""],
22
- body.holmes-debug [class=""],
23
- body.holmes-debug [id=""],
24
- body.holmes-debug table:not([summary]),
25
- body.holmes-debug table[summary=""] {
26
- outline: 2px solid red; }
27
- body.holmes-debug [style],
28
- body.holmes-debug [onclick],
29
- body.holmes-debug [onblur],
30
- body.holmes-debug [onfocus],
31
- body.holmes-debug [onselect],
32
- body.holmes-debug [onload],
33
- body.holmes-debug [onunload] {
34
- outline: 2px solid #ffdd00; }
35
- body.holmes-debug applet,
36
- body.holmes-debug acronym,
37
- body.holmes-debug center,
38
- body.holmes-debug dir,
39
- body.holmes-debug font,
40
- body.holmes-debug strike,
41
- body.holmes-debug u,
42
- body.holmes-debug big,
43
- body.holmes-debug tt,
44
- body.holmes-debug marquee,
45
- body.holmes-debug plaintext,
46
- body.holmes-debug xmp {
47
- border: 2px solid #a9a9a9; }
48
- body.holmes-debug[bgproperties],
49
- body.holmes-debug[topmargin],
50
- body.holmes-debug[rightmargin],
51
- body.holmes-debug[bottommargin],
52
- body.holmes-debug[leftmargin] {
53
- outline: 2px solid #a9a9a9; }
54
- body.holmes-debug *[bordercolor],
55
- body.holmes-debug *[bordercolordark],
56
- body.holmes-debug *[bordercolorlight],
57
- body.holmes-debug table[frame] {
58
- border: 2px solid #a9a9a9; }
59
- body.holmes-debug div:empty,
60
- body.holmes-debug span:empty,
61
- body.holmes-debug li:empty,
62
- body.holmes-debug p:empty,
63
- body.holmes-debug td:empty,
64
- body.holmes-debug th:empty {
65
- border: 2px solid #ff1100; }
66
- body.holmes-debug a[href="#"]:hover::after,
67
- body.holmes-debug a[href^="javascript"]:hover::after,
68
- body.holmes-debug a:not([title]):hover::after,
69
- body.holmes-debug a[title=""]:hover::after,
70
- body.holmes-debug div:empty:hover::after,
71
- body.holmes-debug span:empty:hover::after,
72
- body.holmes-debug li:empty:hover::after,
73
- body.holmes-debug p:empty:hover::after,
74
- body.holmes-debug td:empty:hover::after,
75
- body.holmes-debug th:empty:hover::after,
76
- body.holmes-debug [style]:hover::after {
77
- border-radius: 0.5em;
78
- display: block;
79
- padding: 1em;
80
- margin: 1em;
81
- background: #ffdd00;
82
- position: fixed;
83
- color: black;
84
- left: 0;
85
- top: 0;
86
- z-index: 9999; }
87
- body.holmes-debug a:not([href]):hover::after,
88
- body.holmes-debug a[href=""]:hover::after,
89
- body.holmes-debug img:not([alt]):hover:after,
90
- body.holmes-debug img[alt=""]:hover::after,
91
- body.holmes-debug label:not([for]):hover::after,
92
- body.holmes-debug label[for=""]:hover::after,
93
- body.holmes-debug input:not([name]):hover::after,
94
- body.holmes-debug input[name=""]:hover::after,
95
- body.holmes-debug select:not([name]):hover::after,
96
- body.holmes-debug select[name=""]:hover::after,
97
- body.holmes-debug textarea:not([name]):hover::after,
98
- body.holmes-debug textarea[name=""]:hover::after,
99
- body.holmes-debug abbr:not([title]):hover::after,
100
- body.holmes-debug abbr[title=""]:hover::after,
101
- body.holmes-debug [class=""]:hover::after,
102
- body.holmes-debug [id=""]:hover::after,
103
- body.holmes-debug table:not([summary]):hover::after,
104
- body.holmes-debug table[summary=""]:hover::after {
105
- border-radius: 0.5em;
106
- display: block;
107
- padding: 1em;
108
- margin: 1em;
109
- background: red;
110
- position: fixed;
111
- color: black;
112
- left: 0;
113
- top: 0;
114
- z-index: 9999;
115
- text-decoration: none; }
116
- body.holmes-debug applet:hover::after,
117
- body.holmes-debug acronym:hover::after,
118
- body.holmes-debug center:hover::after,
119
- body.holmes-debug dir:hover::after,
120
- body.holmes-debug font:hover::after,
121
- body.holmes-debug strike:hover::after,
122
- body.holmes-debug big:hover::after,
123
- body.holmes-debug tt:hover::after,
124
- body.holmes-debug marquee:hover::after,
125
- body.holmes-debug plaintext:hover::after,
126
- body.holmes-debug xmp:hover::after,
127
- body.holmes-debug *[bordercolor]:hover::after,
128
- body.holmes-debug *[bordercolordark]:hover::after,
129
- body.holmes-debug *[bordercolorlight]:hover::after,
130
- body.holmes-debug table[frame]:hover::after {
131
- border-radius: 0.5em;
132
- display: block;
133
- padding: 1em;
134
- margin: 1em;
135
- background: red;
136
- position: fixed;
137
- background: #a9a9a9;
138
- color: black;
139
- left: 0;
140
- top: 0;
141
- z-index: 9999; }
142
- body.holmes-debug[bgproperties]:hover::after,
143
- body.holmes-debug[topmargin]:hover::after,
144
- body.holmes-debug[rightmargin]:hover::after,
145
- body.holmes-debug[bottommargin]:hover::after,
146
- body.holmes-debug[leftmargin]:hover::after {
147
- border-radius: 0.5em;
148
- display: block;
149
- padding: 1em;
150
- margin: 1em;
151
- background: red;
152
- position: fixed;
153
- background: #a9a9a9;
154
- color: black;
155
- bottom: 0;
156
- right: 0;
157
- z-index: 9999; }
158
- body.holmes-debug td:empty:hover::after,
159
- body.holmes-debug th:empty:hover::after {
160
- top: 4em; }
161
- body.holmes-debug a:not([href]):hover::after,
162
- body.holmes-debug a[href=""]:hover::after {
163
- content: "Missing href attribute"; }
164
- body.holmes-debug a[href="#"]:hover:after {
165
- content: "href='#'"; }
166
- body.holmes-debug a[href^="javascript"]:hover:after {
167
- content: "href has JavaScript"; }
168
- body.holmes-debug a:not([title]):hover::after,
169
- body.holmes-debug a[title=""]:hover::after {
170
- content: "Missing title attribute"; }
171
- body.holmes-debug img:not([alt]):hover::after,
172
- body.holmes-debug img[alt=""]:hover::after {
173
- content: "Missing alt attribute"; }
174
- body.holmes-debug label:not([for]):hover::after,
175
- body.holmes-debug label[for=""]:hover::after {
176
- content: "Missing for attribute"; }
177
- body.holmes-debug input:not([name]):hover::after,
178
- body.holmes-debug input[name=""]:hover::after,
179
- body.holmes-debug select:not([name]):hover::after,
180
- body.holmes-debug select[name=""]:hover::after,
181
- body.holmes-debug textarea:not([name]):hover::after,
182
- body.holmes-debug textarea[name=""]:hover::after {
183
- content: "Missing name attribute"; }
184
- body.holmes-debug abbr:not([title]):hover::after,
185
- body.holmes-debug abbr[title=""]:hover::after {
186
- content: "Missing title attribute"; }
187
- body.holmes-debug [class=""]:hover::after {
188
- content: "Blank class attribute"; }
189
- body.holmes-debug [id=""]:hover::after {
190
- content: "Blank id attribute"; }
191
- body.holmes-debug table:not([summary]):hover::after,
192
- body.holmes-debug table[summary=""]:hover::after {
193
- content: "Missing summary attribute"; }
194
- body.holmes-debug [style]:hover::after {
195
- content: "Element has inline styles"; }
196
- body.holmes-debug applet:hover::after,
197
- body.holmes-debug acronym:hover::after,
198
- body.holmes-debug center:hover::after,
199
- body.holmes-debug dir:hover::after,
200
- body.holmes-debug font:hover::after,
201
- body.holmes-debug strike:hover::after,
202
- body.holmes-debug big:hover::after,
203
- body.holmes-debug tt:hover::after,
204
- body.holmes-debug marquee:hover::after,
205
- body.holmes-debug plaintext:hover::after,
206
- body.holmes-debug xmp:hover::after {
207
- content: "Deprecated or Non-W3C element"; }
208
- body.holmes-debug[bgproperties]:hover::after {
209
- content: "Deprecated or Non-W3C body attribute bgproperties"; }
210
- body.holmes-debug[topmargin]:hover::after,
211
- body.holmes-debug[rightmargin]:hover::after,
212
- body.holmes-debug[bottommargin]:hover::after,
213
- body.holmes-debug[leftmargin]:hover::after {
214
- content: "Deprecated or Non-W3C body attribute *margin"; }
215
- body.holmes-debug *[bordercolor]:hover::after,
216
- body.holmes-debug *[bordercolordark]:hover::after,
217
- body.holmes-debug *[bordercolorlight]:hover::after {
218
- content: "Deprecated or Non-W3C body attribute bordercolor"; }
219
- body.holmes-debug table[frame]:hover::after {
220
- content: "Deprecated or Non-W3C attribute frame"; }
221
- body.holmes-debug div:empty:hover::after,
222
- body.holmes-debug span:empty:hover::after,
223
- body.holmes-debug li:empty:hover::after,
224
- body.holmes-debug p:empty:hover::after,
225
- body.holmes-debug td:empty:hover::after,
226
- body.holmes-debug th:empty:hover::after {
227
- content: "Empty element!"; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/holmes.sass DELETED
@@ -1,262 +0,0 @@
1
- body.holmes-debug
2
-
3
- a:not([href]),
4
- a[href=""]
5
- outline: 2px solid red
6
-
7
- a[href="#"],
8
- a[href^="javascript"],
9
- a:not([title]),
10
- a[title=""]
11
- outline: 2px solid #fd0
12
-
13
- img:not([alt]),
14
- img[alt=""]
15
- outline: 2px solid red
16
-
17
- label:not([for]),
18
- label[for=""],
19
- input:not([name]),
20
- input[name=""],
21
- select:not([name]),
22
- select[name=""],
23
- textarea:not([name]),
24
- textarea[name=""],
25
- abbr:not([title]),
26
- abbr[title=""],
27
- [class=""],
28
- [id=""],
29
- table:not([summary]),
30
- table[summary=""]
31
- outline: 2px solid red
32
-
33
- [style],
34
- [onclick],
35
- [onblur],
36
- [onfocus],
37
- [onselect],
38
- [onload],
39
- [onunload]
40
- outline: 2px solid #fd0
41
-
42
- applet,
43
- acronym,
44
- center,
45
- dir,
46
- font,
47
- strike,
48
- u,
49
- big,
50
- tt,
51
- marquee,
52
- plaintext,
53
- xmp
54
- border: 2px solid #a9a9a9
55
-
56
- [bgproperties],
57
- [topmargin],
58
- [rightmargin],
59
- [bottommargin],
60
- [leftmargin]
61
- outline: 2px solid #a9a9a9
62
-
63
- *[bordercolor],
64
- *[bordercolordark],
65
- *[bordercolorlight],
66
- table[frame]
67
- border: 2px solid #a9a9a9
68
-
69
- div:empty,
70
- span:empty,
71
- li:empty,
72
- p:empty,
73
- td:empty,
74
- th:empty
75
- border: 2px solid #f10
76
-
77
- a[href="#"]:hover::after,
78
- a[href^="javascript"]:hover::after,
79
- a:not([title]):hover::after,
80
- a[title=""]:hover::after,
81
- div:empty:hover::after,
82
- span:empty:hover::after,
83
- li:empty:hover::after,
84
- p:empty:hover::after,
85
- td:empty:hover::after,
86
- th:empty:hover::after,
87
- [style]:hover::after
88
- border-radius: 0.5em
89
- display: block
90
- padding: 1em
91
- margin: 1em
92
- background: #fd0
93
- position: fixed
94
- color: #000
95
- left: 0
96
- top: 0
97
- z-index: 9999
98
-
99
- a:not([href]):hover::after,
100
- a[href=""]:hover::after,
101
- img:not([alt]):hover:after,
102
- img[alt=""]:hover::after,
103
- label:not([for]):hover::after,
104
- label[for=""]:hover::after,
105
- input:not([name]):hover::after,
106
- input[name=""]:hover::after,
107
- select:not([name]):hover::after,
108
- select[name=""]:hover::after,
109
- textarea:not([name]):hover::after,
110
- textarea[name=""]:hover::after,
111
- abbr:not([title]):hover::after,
112
- abbr[title=""]:hover::after,
113
- [class=""]:hover::after,
114
- [id=""]:hover::after,
115
- table:not([summary]):hover::after,
116
- table[summary=""]:hover::after
117
- border-radius: 0.5em
118
- display: block
119
- padding: 1em
120
- margin: 1em
121
- background: red
122
- position: fixed
123
- color: #000
124
- left: 0
125
- top: 0
126
- z-index: 9999
127
- text-decoration: none
128
-
129
- applet:hover::after,
130
- acronym:hover::after,
131
- center:hover::after,
132
- dir:hover::after,
133
- font:hover::after,
134
- strike:hover::after,
135
- big:hover::after,
136
- tt:hover::after,
137
- marquee:hover::after,
138
- plaintext:hover::after,
139
- xmp:hover::after,
140
- *[bordercolor]:hover::after,
141
- *[bordercolordark]:hover::after,
142
- *[bordercolorlight]:hover::after,
143
- table[frame]:hover::after
144
- border-radius: 0.5em
145
- display: block
146
- padding: 1em
147
- margin: 1em
148
- background: red
149
- position: fixed
150
- background: #a9a9a9
151
- color: #000
152
- left: 0
153
- top: 0
154
- z-index: 9999
155
-
156
- &[bgproperties]:hover::after,
157
- &[topmargin]:hover::after,
158
- &[rightmargin]:hover::after,
159
- &[bottommargin]:hover::after,
160
- &[leftmargin]:hover::after
161
- border-radius: 0.5em
162
- display: block
163
- padding: 1em
164
- margin: 1em
165
- background: red
166
- position: fixed
167
- background: #a9a9a9
168
- color: #000
169
- bottom: 0
170
- right: 0
171
- z-index: 9999
172
-
173
- td:empty:hover::after,
174
- th:empty:hover::after
175
- top: 4em
176
-
177
- a:not([href]):hover::after,
178
- a[href=""]:hover::after
179
- content: "Missing href attribute"
180
-
181
- a[href="#"]:hover:after
182
- content: "href='#'"
183
-
184
- a[href^="javascript"]:hover:after
185
- content: "href has JavaScript"
186
-
187
- a:not([title]):hover::after,
188
- a[title=""]:hover::after
189
- content: "Missing title attribute"
190
-
191
-
192
- img:not([alt]):hover::after,
193
- img[alt=""]:hover::after
194
- content: "Missing alt attribute"
195
-
196
- label:not([for]):hover::after,
197
- label[for=""]:hover::after
198
- content: "Missing for attribute"
199
-
200
- input:not([name]):hover::after,
201
- input[name=""]:hover::after,
202
- select:not([name]):hover::after,
203
- select[name=""]:hover::after,
204
- textarea:not([name]):hover::after,
205
- textarea[name=""]:hover::after
206
- content: "Missing name attribute"
207
-
208
- abbr:not([title]):hover::after,
209
- abbr[title=""]:hover::after
210
- content: "Missing title attribute"
211
-
212
- [class=""]:hover::after
213
- content: "Blank class attribute"
214
-
215
- [id=""]:hover::after
216
- content: "Blank id attribute"
217
-
218
- table:not([summary]):hover::after,
219
- table[summary=""]:hover::after
220
- content: "Missing summary attribute"
221
-
222
- [style]:hover::after
223
- content: "Element has inline styles"
224
-
225
- applet:hover::after,
226
- acronym:hover::after,
227
- center:hover::after,
228
- dir:hover::after,
229
- font:hover::after,
230
- strike:hover::after,
231
- big:hover::after,
232
- tt:hover::after,
233
- marquee:hover::after,
234
- plaintext:hover::after,
235
- xmp:hover::after
236
- content: "Deprecated or Non-W3C element"
237
-
238
- &[bgproperties]:hover::after
239
- content: "Deprecated or Non-W3C body attribute bgproperties"
240
-
241
- &[topmargin]:hover::after,
242
- &[rightmargin]:hover::after,
243
- &[bottommargin]:hover::after,
244
- &[leftmargin]:hover::after
245
- content: "Deprecated or Non-W3C body attribute *margin"
246
-
247
- *[bordercolor]:hover::after,
248
- *[bordercolordark]:hover::after,
249
- *[bordercolorlight]:hover::after
250
- content: "Deprecated or Non-W3C body attribute bordercolor"
251
-
252
- table[frame]:hover::after
253
- content: "Deprecated or Non-W3C attribute frame"
254
-
255
- div:empty:hover::after,
256
- span:empty:hover::after,
257
- li:empty:hover::after,
258
- p:empty:hover::after,
259
- td:empty:hover::after,
260
- th:empty:hover::after
261
- content: "Empty element!"
262
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/hsl-functions.css DELETED
@@ -1,14 +0,0 @@
1
- #hsl {
2
- background: #010101;
3
- background: rgba(1, 1, 1, 0.5);
4
- background: 32.975deg;
5
- background: 100%;
6
- background: 47.451%;
7
- background: #f28500;
8
- background: #f58600;
9
- background: #ef8400;
10
- background: #f28500;
11
- background: #f18501;
12
- background: #797979;
13
- background: #006df2;
14
- background: #0d7aff; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/hsl-functions.scss DELETED
@@ -1,15 +0,0 @@
1
- #hsl {
2
- background: hsl(.09, 1, .47); // #010101
3
- background: hsla(.09, 1, .47, .5); // rgba(1, 1, 1, 0.5)
4
- background: hue(#f28500); // 32.975deg
5
- background: saturation(#f28500); // 100%
6
- background: lightness(#f28500); // 47.451%
7
- background: adjust-hue(#f28500, .01); // #f28500
8
- background: lighten(#f28500, .5); // #f58600
9
- background: darken(#f28500, .5); // #ef8400
10
- background: saturate(#f28500, .5); // #f28500
11
- background: desaturate(#f28500, .5); // #f18501
12
- background: grayscale(#f28500); // #797979
13
- background: complement(#f28500); // #006df2
14
- background: invert(#f28500); // #0d7aff
15
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/if.css DELETED
@@ -1,5 +0,0 @@
1
- a {
2
- branch: if; }
3
-
4
- b {
5
- branch: else; }
 
 
 
 
 
lib/phpsass/tests/if.sass DELETED
@@ -1,11 +0,0 @@
1
- a
2
- @if true
3
- branch: if
4
- @else
5
- branch: else
6
-
7
- b
8
- @if false
9
- branch: if
10
- @else
11
- branch: else
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/if_parentheses.css DELETED
@@ -1,2 +0,0 @@
1
- body {
2
- width: 100px; }
 
 
lib/phpsass/tests/if_parentheses.scss DELETED
@@ -1,6 +0,0 @@
1
- $value: 10px;
2
- body {
3
- @if (unit($value) == px or unit($value) == rem) {
4
- width: 100px;
5
- }
6
- }
 
 
 
 
 
 
lib/phpsass/tests/import.css DELETED
@@ -1,62 +0,0 @@
1
- imported {
2
- otherconst: hello;
3
- myconst: goodbye;
4
- pre-mixin: here; }
5
-
6
- body {
7
- font: Arial;
8
- background: blue; }
9
-
10
- #page {
11
- width: 700px;
12
- height: 100;
13
- line-height: 100%; }
14
- #page #header {
15
- height: 300px; }
16
- #page #header h1 {
17
- font-size: 50px;
18
- color: blue; }
19
-
20
- #content.user.show #container.top #column.left {
21
- width: 100px; }
22
- #content.user.show #container.top #column.right {
23
- width: 600px; }
24
- #content.user.show #container.bottom {
25
- background: brown; }
26
-
27
- midrule {
28
- inthe: middle; }
29
-
30
- scss {
31
- imported: yes; }
32
-
33
- body {
34
- font: Arial;
35
- background: blue; }
36
-
37
- #page {
38
- width: 700px;
39
- height: 100;
40
- line-height: 100%; }
41
- #page #header {
42
- height: 300px; }
43
- #page #header h1 {
44
- font-size: 50px;
45
- color: blue; }
46
-
47
- #content.user.show #container.top #column.left {
48
- width: 100px; }
49
- #content.user.show #container.top #column.right {
50
- width: 600px; }
51
- #content.user.show #container.bottom {
52
- background: brown; }
53
-
54
- @import url('basic.css');
55
- @import url('../results/complex.css');
56
- #foo {
57
- background-color: #bbaaff; }
58
-
59
- nonimported {
60
- myconst: hello;
61
- otherconst: goodbye;
62
- post-mixin: here; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/import.sass DELETED
@@ -1,15 +0,0 @@
1
- $preconst: hello
2
-
3
- =premixin
4
- pre-mixin: here
5
-
6
- @import importee.sass, scss_importee
7
- @import "basic.sass"
8
- @import basic.css
9
- @import ../results/complex.css
10
- @import partial.sass
11
-
12
- nonimported
13
- :myconst $preconst
14
- :otherconst $postconst
15
- +postmixin
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/import_content.css DELETED
@@ -1,2 +0,0 @@
1
- a {
2
- b: c; }
 
 
lib/phpsass/tests/import_content.sass DELETED
@@ -1,4 +0,0 @@
1
- @import imported_content
2
-
3
- @include foo
4
- b: c
 
 
 
 
lib/phpsass/tests/importee.sass DELETED
@@ -1,19 +0,0 @@
1
- $postconst: goodbye
2
-
3
- =postmixin
4
- post-mixin: here
5
-
6
- imported
7
- :otherconst $preconst
8
- :myconst $postconst
9
- +premixin
10
-
11
- @import basic
12
-
13
- midrule
14
- :inthe middle
15
-
16
- =crazymixin
17
- foo: bar
18
- baz
19
- blat: bang
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/interpolation.css DELETED
@@ -1,27 +0,0 @@
1
- foo,
2
- bar {
3
- o: k; }
4
-
5
- outer foo,
6
- outer bar {
7
- o: k; }
8
-
9
- body[content="oh, look"] foo,
10
- body[content="oh, look"] bar {
11
- o: k; }
12
-
13
- .foo-bar {
14
- o: k; }
15
-
16
- .bar {
17
- o: k; }
18
-
19
- foo2bar {
20
- o: k; }
21
-
22
- nex3_is_weird {
23
- flabnabbit: flabnabbit('1foo'); }
24
-
25
- @media screen and (-webkit-min-device-pixel-ratio: 1.5) {
26
- webkit-only {
27
- color: green; } }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/interpolation.scss DELETED
@@ -1,54 +0,0 @@
1
- $foo: 'foo', bar;
2
-
3
- // selector interpolation
4
- #{$foo} {
5
- o: k;
6
- }
7
-
8
- // nested selector interpolation
9
- outer {
10
- #{$foo} {
11
- o: k;
12
- }
13
- }
14
-
15
- // nested again, but with complexity (commas in the body content)
16
- body[content="oh, look"] {
17
- #{$foo} {
18
- o: k;
19
- }
20
- }
21
-
22
- // interpolation quoted
23
- .foo-#{"bar"} {
24
- o: k
25
- }
26
-
27
- // placeholder interpolation
28
- $bar: bar;
29
- %#{$bar} {
30
- o: k
31
- }
32
- .bar {
33
- @extend %bar;
34
- }
35
-
36
- // string interpolation
37
- foo#{1 + 1}bar {
38
- o: k
39
- }
40
-
41
- // interpolation in a function call
42
- nex3_is_weird {
43
- flabnabbit: flabnabbit('#{1 + 'foo'}');
44
- }
45
-
46
- $media: screen;
47
- $feature: -webkit-min-device-pixel-ratio;
48
- $value: 1.5;
49
-
50
- @media #{$media} and ($feature: $value) {
51
- webkit-only {
52
- color: green;
53
- }
54
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/introspection.css DELETED
@@ -1,13 +0,0 @@
1
- #introspection {
2
- append: 'apple', 'banana', 'pear', 2px, 2, 2em, 4px, 'hello';
3
- content: list;
4
- content: string;
5
- content: number;
6
- content: number;
7
- content: px;
8
- content: ;
9
- content: false;
10
- content: true;
11
- content: true;
12
- content: false;
13
- content: true; }
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/introspection.scss DELETED
@@ -1,16 +0,0 @@
1
- #introspection {
2
- $one: 'hello';
3
- $array: 'apple', 'banana', 'pear', 2px, 2, 2em, 4px;
4
- append: append($array, $one);
5
- content: type-of($array);
6
- content: type-of(nth($array, 1));
7
- content: type-of(nth($array, 4));
8
- content: type-of(nth($array, 5));
9
- content: unit(nth($array, 4));
10
- content: unit(nth($array, 5));
11
- content: unitless(nth($array, 4));
12
- content: unitless(nth($array, 5));
13
- content: comparable(nth($array, 4), nth($array, 5));
14
- content: comparable(nth($array, 4), nth($array, 6));
15
- content: comparable(nth($array, 4), nth($array, 7));
16
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/line_numbers.css DELETED
@@ -1,37 +0,0 @@
1
- foo {
2
- bar: baz; }
3
-
4
- imported {
5
- otherconst: 12;
6
- myconst: goodbye; }
7
- imported squggle {
8
- blat: bang; }
9
-
10
- body {
11
- font: Arial;
12
- background: blue; }
13
-
14
- #page {
15
- width: 700px;
16
- height: 100;
17
- line-height: 100%; }
18
- #page #header {
19
- height: 300px; }
20
- #page #header h1 {
21
- font-size: 50px;
22
- color: blue; }
23
-
24
- #content.user.show #container.top #column.left {
25
- width: 100px; }
26
- #content.user.show #container.top #column.right {
27
- width: 600px; }
28
- #content.user.show #container.bottom {
29
- background: brown; }
30
-
31
- midrule {
32
- inthe: middle; }
33
-
34
- umph {
35
- foo: bar; }
36
- umph baz {
37
- blat: bang; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/line_numbers.sass DELETED
@@ -1,13 +0,0 @@
1
- foo
2
- bar: baz
3
-
4
- =premixin
5
- squggle
6
- blat: bang
7
-
8
- $preconst: 12
9
-
10
- @import importee
11
-
12
- umph
13
- +crazymixin
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/list.css DELETED
@@ -1,4 +0,0 @@
1
- #list {
2
- font-size: 3;
3
- content: 'banana';
4
- content: 'pear'; }
 
 
 
 
lib/phpsass/tests/list.scss DELETED
@@ -1,8 +0,0 @@
1
- #list {
2
- $test-list: 'apple', 'banana', 'orange';
3
- $list-join: 'pear';
4
- font-size: length($test-list);
5
- content: nth($test-list, 2);
6
- $test-list: join($test-list, $list-join);
7
- content: nth($test-list, 4);
8
- }
 
 
 
 
 
 
 
 
lib/phpsass/tests/list_empty.css DELETED
@@ -1,2 +0,0 @@
1
- #list {
2
- width: 10px; }
 
 
lib/phpsass/tests/list_empty.scss DELETED
@@ -1,5 +0,0 @@
1
- #list {
2
- $test-list: ();
3
- $test-list: join($test-list, 10px);
4
- width: nth($test-list, 1)
5
- }
 
 
 
 
 
lib/phpsass/tests/list_variable.css DELETED
@@ -1,2 +0,0 @@
1
- body{
2
- width:10px; }
 
 
lib/phpsass/tests/list_variable.scss DELETED
@@ -1,9 +0,0 @@
1
- @function test($columns) {
2
- @each $var in $columns {
3
- @return $var;
4
- }
5
- }
6
-
7
- body {
8
- width: test(10px 20px 30px);
9
- }
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/media.css DELETED
@@ -1,7 +0,0 @@
1
- .sidebar {
2
- width: 300px; }
3
- @media screen and (max-width: 1024px) {
4
- .sidebar {
5
- width: 500 px; } }
6
- @media all and (max-width: 800px) {
7
- color: blue; }
 
 
 
 
 
 
 
lib/phpsass/tests/media.scss DELETED
@@ -1,15 +0,0 @@
1
- $fiver: 500px;
2
- .sidebar {
3
- width: 300px;
4
- @media screen and (max-width: 1024px) {
5
- width: $fiver;
6
- }
7
- }
8
-
9
- @mixin test-mixin() {
10
- color: blue;
11
- }
12
-
13
- @media all and (max-width: 800px) {
14
- @include test-mixin;
15
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/media_in_for.css DELETED
@@ -1,6 +0,0 @@
1
- @media only screen and (min-width: 500px) {
2
- #gallery {
3
- width: 520px; } }
4
- @media only screen and (min-width: 1000px) {
5
- #gallery {
6
- width: 1020px; } }
 
 
 
 
 
 
lib/phpsass/tests/media_in_for.scss DELETED
@@ -1,10 +0,0 @@
1
- $fiver: 500px;
2
- #gallery {
3
- @for $i from 1 through 2 {
4
- $screenWidth: $fiver * $i;
5
- $galleryWidth: ($fiver * $i) + 20px;
6
- @media only screen and (min-width: $screenWidth) {
7
- width: $galleryWidth;
8
- }
9
- }
10
- }
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/media_in_mixin.css DELETED
@@ -1,3 +0,0 @@
1
- @media (min-width: 768px) {
2
- body {
3
- width: 50px; } }
 
 
 
lib/phpsass/tests/media_in_mixin.scss DELETED
@@ -1,9 +0,0 @@
1
- @mixin mediaContent() {
2
- @media (min-width: 768px) {
3
- @content;
4
- }
5
- }
6
-
7
- @include mediaContent() {
8
- body { width: 50px; }
9
- }
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/media_in_mixin_in_mixin.css DELETED
@@ -1,4 +0,0 @@
1
- @media (min-width: 768px) {
2
- body {
3
- height: 50px;
4
- width: 50px; } }
 
 
 
 
lib/phpsass/tests/media_in_mixin_in_mixin.scss DELETED
@@ -1,18 +0,0 @@
1
- @mixin getMediaDimensions() {
2
- @content;
3
- }
4
-
5
- @mixin getDimensions() {
6
- @include getMediaDimensions() {
7
- @media (min-width: 768px) {
8
- body {
9
- height: 50px;
10
- @content;
11
- }
12
- }
13
- }
14
- }
15
-
16
- @include getDimensions() {
17
- width: 50px;
18
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/misc-functions.css DELETED
@@ -1,6 +0,0 @@
1
- #misc-function {
2
- font-size: 12px; }
3
-
4
- .min-max {
5
- min: -42;
6
- max: 42; }
 
 
 
 
 
 
lib/phpsass/tests/misc-functions.scss DELETED
@@ -1,11 +0,0 @@
1
- #misc-function {
2
- $bool: true;
3
-
4
- font-size: if($bool, 12px, 10px);
5
- }
6
-
7
- .min-max {
8
- $list: 34, 42, 29, 3, -42;
9
- min: min($list...);
10
- max: max($list...);
11
- }
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/misc.css DELETED
@@ -1,85 +0,0 @@
1
- /*
2
- * Source: http://code.google.com/p/phamlp/issues/detail?id=117;
3
- */
4
- @import url("http://fonts.googleapis.com/css?family=Actor");
5
-
6
- /*
7
- * Source: http://code.google.com/p/phamlp/issues/detail?id=116;
8
- */
9
- @import url('somefile.css');
10
-
11
- /*
12
- * Source: http://code.google.com/p/phamlp/issues/detail?id=101;
13
- */
14
- .nav-boolean ol li input:checked + label {
15
- color: red; }
16
-
17
- /*
18
- * Source: http://code.google.com/p/phamlp/issues/detail?id=100;
19
- */
20
- .zero {
21
- margin: 0 0;
22
- padding: 0px; }
23
-
24
- /*
25
- * Source: http://code.google.com/p/phamlp/issues/detail?id=99;
26
- */
27
- /*
28
- * Variables
29
- */
30
- .content-navigation {
31
- border-color: #3bbfce;
32
- color: #2ca2af; }
33
-
34
- .border {
35
- padding: 16px;
36
- margin: 8px;
37
- border-color: #3bbfce; }
38
-
39
- /*
40
- * Nesting
41
- */
42
- table.hl {
43
- margin: 2em 0; }
44
- table.hl td.ln {
45
- text-align: right; }
46
-
47
- li {
48
- font-family: serif;
49
- font-weight: bold;
50
- font-size: 1.2em; }
51
-
52
- /*
53
- * Mixins
54
- */
55
- #data {
56
- float: left;
57
- margin-left: 10px; }
58
- #data th {
59
- text-align: center;
60
- font-weight: bold; }
61
- #data td,
62
- #data th {
63
- padding: 2px; }
64
-
65
- /*
66
- * Selector Inheritance
67
- */
68
- .error,
69
- .madError {
70
- border: 1px red;
71
- background: #ffdddd; }
72
-
73
- .error.intrusion,
74
- .madError.intrusion {
75
- font-size: 1.3em;
76
- font-weight: bold; }
77
-
78
- .madError {
79
- border-width: 3px; }
80
-
81
- git20 {
82
- *margin-left: 0.991%; }
83
-
84
- git30 {
85
- width: 30px !important;}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/misc.scss DELETED
@@ -1,103 +0,0 @@
1
- /* Source: http://code.google.com/p/phamlp/issues/detail?id=117; */
2
- @import url("http://fonts.googleapis.com/css?family=Actor");
3
-
4
- /* Source: http://code.google.com/p/phamlp/issues/detail?id=116; */
5
- @import "somefile.css";
6
-
7
- /* Source: http://code.google.com/p/phamlp/issues/detail?id=101; */
8
- @mixin nav-boolean {
9
- ol {
10
- li {
11
- input:checked + label { color: red; }
12
- }
13
- }
14
- }
15
-
16
- .nav-boolean { @include nav-boolean; }
17
-
18
- /* Source: http://code.google.com/p/phamlp/issues/detail?id=100; */
19
- .zero {
20
- margin: 0 0;
21
- padding: 0px;
22
- }
23
-
24
- /* Source: http://code.google.com/p/phamlp/issues/detail?id=99; */
25
- /* Variables */
26
-
27
- $blue: #3bbfce;
28
- $margin: 16px;
29
-
30
- .content-navigation {
31
- border-color: $blue;
32
- color:
33
- darken($blue, 9%);
34
- }
35
-
36
- .border {
37
- padding: $margin;
38
- margin: $margin / 2;
39
- border-color: $blue;
40
- }
41
-
42
- /* Nesting */
43
-
44
- table.hl {
45
- margin: 2em 0;
46
- td.ln {
47
- text-align: right;
48
- }
49
- }
50
-
51
- li {
52
- font: {
53
- family: serif;
54
- weight: bold;
55
- size: 1.2em;
56
- }
57
- }
58
-
59
- /* Mixins */
60
-
61
- @mixin table-base {
62
- th {
63
- text-align: center;
64
- font-weight: bold;
65
- }
66
- td, th {padding: 2px}
67
- }
68
-
69
- @mixin left($dist) {
70
- float: left;
71
- margin-left: $dist;
72
- }
73
-
74
- #data {
75
- @include left(10px);
76
- @include table-base;
77
- }
78
-
79
- /* Selector Inheritance */
80
-
81
- .error {
82
- border: 1px red;
83
- background: #ffdddd;
84
- }
85
- .error.intrusion {
86
- font-size: 1.3em;
87
- font-weight: bold;
88
- }
89
-
90
- .madError {
91
- @extend .error;
92
- border-width: 3px;
93
- }
94
-
95
- git20 {
96
- $fluidGridGutterWidth: 1%;
97
- $gridRowWidth: 60px;
98
- *margin-left: $fluidGridGutterWidth - (0.5 / $gridRowWidth * 100px * 1%);
99
- }
100
-
101
- git30 {
102
- width: 30px!important;
103
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/mixin-content.css DELETED
@@ -1,5 +0,0 @@
1
- #logo {
2
- background-image: url("/images/logo.png"); }
3
- * html #logo {
4
- width: 500px;
5
- background-image: url("/images/logo.gif"); }
 
 
 
 
 
lib/phpsass/tests/mixin-content.sass DELETED
@@ -1,10 +0,0 @@
1
- $fiver: 500px
2
- =ie6
3
- * html &
4
- @content
5
-
6
- #logo
7
- background-image: url("/images/logo.png")
8
- +ie6
9
- width: $fiver
10
- background-image: url("/images/logo.gif")
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/mixin-content.scss DELETED
@@ -1,14 +0,0 @@
1
- $fiver: 500px;
2
- @mixin ie6 {
3
- * html & {
4
- @content
5
- }
6
- }
7
-
8
- #logo {
9
- background-image: url("/images/logo.png");
10
- @include ie6 {
11
- width: $fiver;
12
- background-image: url("/images/logo.gif");
13
- }
14
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/mixin-ja1.css DELETED
@@ -1,8 +0,0 @@
1
- .messages h2 {
2
- display: -moz-inline-box;
3
- -moz-box-orient: vertical;
4
- display: inline-block;
5
- vertical-align: middle;
6
- *vertical-align: auto; }
7
- .messages h2 {
8
- *display: inline; }
 
 
 
 
 
 
 
 
lib/phpsass/tests/mixin-ja1.sass DELETED
@@ -1,14 +0,0 @@
1
- $legacy-support-for-ie: true
2
- =inline-block
3
- @if $legacy-support-for-ie
4
- &
5
- *display: inline
6
- display: -moz-inline-box
7
- -moz-box-orient: vertical
8
- display: inline-block
9
- vertical-align: middle
10
- @if $legacy-support-for-ie
11
- *vertical-align: auto
12
-
13
- .messages h2
14
- +inline-block
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/mixin-list-params.css DELETED
@@ -1,7 +0,0 @@
1
- .box {
2
- background: url('sprite.png') 0 -276px no-repeat, -moz-linear-gradient(320deg, #e2d0ec, #f8f4fb), #ede2f3;
3
- background: url('sprite.png') 0 -276px no-repeat, -webkit-gradient(320deg, #e2d0ec, #f8f4fb), #ede2f3;
4
- background: url('sprite.png') 0 -276px no-repeat, -webkit-linear-gradient(320deg, #e2d0ec, #f8f4fb), #ede2f3;
5
- background: url('sprite.png') 0 -276px no-repeat, -o-linear-gradient(320deg, #e2d0ec, #f8f4fb), #ede2f3;
6
- background: url('sprite.png') 0 -276px no-repeat, -ms-linear-gradient(320deg, #e2d0ec, #f8f4fb), #ede2f3;
7
- background: url('sprite.png') 0 -276px no-repeat, linear-gradient(-230deg, #e2d0ec, #f8f4fb), #ede2f3; }
 
 
 
 
 
 
 
lib/phpsass/tests/mixin-list-params.scss DELETED
@@ -1,17 +0,0 @@
1
- @mixin multi-backgrounds($image, $gradient, $color) {
2
- $angle: nth($gradient, 1);
3
- $colorStart: nth($gradient, 2);
4
- $colorStop: nth($gradient, 3);
5
- $newAngle: (90-$angle) % 360;
6
-
7
- background: #{$image}, -moz-linear-gradient(#{$gradient}), #{$color};
8
- background: #{$image}, -webkit-gradient(#{$gradient}), #{$color};
9
- background: #{$image}, -webkit-linear-gradient(#{$gradient}), #{$color};
10
- background: #{$image}, -o-linear-gradient(#{$gradient}), #{$color};
11
- background: #{$image}, -ms-linear-gradient(#{$gradient}), #{$color};
12
- background: #{$image}, linear-gradient(#{$newAngle}, #{$colorStart}, #{$colorStop}), #{$color};
13
- }
14
-
15
- .box {
16
- @include multi-backgrounds(url('sprite.png') 0 -276px no-repeat, (320deg, #e2d0ec, lighten(#e2d0ec, 10%)), lighten(#e2d0ec, 5%));
17
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/mixin-params.css DELETED
@@ -1,23 +0,0 @@
1
- default {
2
- one: 'foo';
3
- two: 'bar'; }
4
-
5
- one {
6
- one: 'one';
7
- two: 'bar'; }
8
-
9
- two {
10
- one: 'foo';
11
- two: 'two'; }
12
-
13
- both {
14
- one: 'one';
15
- two: 'two'; }
16
-
17
- whitespace {
18
- one: 'one';
19
- two: 'two'; }
20
-
21
- parens {
22
- one: 'one';
23
- two: white; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/mixin-params.scss DELETED
@@ -1,28 +0,0 @@
1
- @mixin test($one: 'foo', $two: 'bar') {
2
- one: $one;
3
- two: $two;
4
- }
5
-
6
- default {
7
- @include test();
8
- }
9
-
10
- one {
11
- @include test('one');
12
- }
13
-
14
- two {
15
- @include test($two: 'two');
16
- }
17
-
18
- both {
19
- @include test('one', 'two');
20
- }
21
-
22
- whitespace {
23
- @include test ('one', 'two');
24
- }
25
-
26
- parens {
27
- @include test('one', rgb(255, 255, 255) );
28
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/mixin-rgba-param.css DELETED
@@ -1,2 +0,0 @@
1
- .box {
2
- box-shadow: 5px 5px 20px rgba(0, 0, 0, 0.8); }
 
 
lib/phpsass/tests/mixin-rgba-param.scss DELETED
@@ -1,7 +0,0 @@
1
- @mixin some-mixin($value) {
2
- box-shadow: $value;
3
- }
4
-
5
- .box {
6
- @include some-mixin(5px 5px 20px rgba(0, 0, 0, .8));
7
- }
 
 
 
 
 
 
 
lib/phpsass/tests/mixin_bork.sass DELETED
@@ -1,5 +0,0 @@
1
- =outer-mixin
2
- +error-mixin
3
-
4
- foo
5
- +outer-mixin
 
 
 
 
 
lib/phpsass/tests/mixin_in_mixin.css DELETED
@@ -1,2 +0,0 @@
1
- body {
2
- width: 50px; }
 
 
lib/phpsass/tests/mixin_in_mixin.scss DELETED
@@ -1,15 +0,0 @@
1
- @mixin mixin1() {
2
- @content;
3
- }
4
-
5
- @mixin mixin2() {
6
- @include mixin1() {
7
- @content;
8
- }
9
- }
10
-
11
- body {
12
- @include mixin2() {
13
- width: 50px;
14
- }
15
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/mixin_setvar.css DELETED
@@ -1,2 +0,0 @@
1
- body {
2
- foo: 4; }
 
 
lib/phpsass/tests/mixin_setvar.scss DELETED
@@ -1,10 +0,0 @@
1
- @mixin layout2($otherFoo) {
2
- $foo : $otherFoo;
3
- @content;
4
- }
5
- $foo : 2;
6
- body {
7
- @include layout2(4) {
8
- foo: $foo;
9
- }
10
- }
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/mixins.css DELETED
@@ -1,87 +0,0 @@
1
- /*
2
- * test that variable context evaluates correctly
3
- */
4
- test {
5
- one: two; }
6
- #main {
7
- width: 15em;
8
- color: blue; }
9
- #main p {
10
- border-top-width: 2px;
11
- border-top-color: #ffcc00;
12
- border-left-width: 1px;
13
- border-left-color: black;
14
- -moz-border-radius: 10px;
15
- border-style: dotted;
16
- border-width: 2px; }
17
- #main .cool {
18
- width: 100px; }
19
-
20
- #left {
21
- border-top-width: 2px;
22
- border-top-color: #ffcc00;
23
- border-left-width: 1px;
24
- border-left-color: black;
25
- -moz-border-radius: 10px;
26
- font-size: 2em;
27
- font-weight: bold;
28
- float: left; }
29
-
30
- #right {
31
- border-top-width: 2px;
32
- border-top-color: #ffcc00;
33
- border-left-width: 1px;
34
- border-left-color: black;
35
- -moz-border-radius: 10px;
36
- color: red;
37
- font-size: 20px;
38
- float: right; }
39
-
40
- .bordered {
41
- border-top-width: 2px;
42
- border-top-color: #ffcc00;
43
- border-left-width: 1px;
44
- border-left-color: black;
45
- -moz-border-radius: 10px; }
46
-
47
- .complex {
48
- color: red;
49
- font-size: 20px;
50
- text-decoration: none; }
51
- .complex:after {
52
- content: ".";
53
- display: block;
54
- height: 0;
55
- clear: both;
56
- visibility: hidden; }
57
- * html .complex {
58
- height: 1px;
59
- color: red;
60
- font-size: 20px; }
61
-
62
- .more-complex {
63
- color: red;
64
- font-size: 20px;
65
- text-decoration: none;
66
- display: inline;
67
- -webkit-nonsense-top-right: 1px;
68
- -webkit-nonsense-bottom-left: 1px; }
69
- .more-complex:after {
70
- content: ".";
71
- display: block;
72
- height: 0;
73
- clear: both;
74
- visibility: hidden; }
75
- * html .more-complex {
76
- height: 1px;
77
- color: red;
78
- font-size: 20px; }
79
- .more-complex a:hover {
80
- text-decoration: underline;
81
- color: red;
82
- font-size: 20px;
83
- border-top-width: 2px;
84
- border-top-color: #ffcc00;
85
- border-left-width: 1px;
86
- border-left-color: black;
87
- -moz-border-radius: 10px; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/mixins.sass DELETED
@@ -1,84 +0,0 @@
1
- $yellow: #fc0
2
-
3
- /* test that variable context evaluates correctly */
4
- =foo($var, $val)
5
- :#{$var} $val
6
- =bar($var)
7
- +foo('one', $var)
8
- test
9
- +bar(two)
10
-
11
- =bordered
12
- :border
13
- :top
14
- :width 2px
15
- :color $yellow
16
- :left
17
- :width 1px
18
- :color #000
19
- -moz-border-radius: 10px
20
-
21
- =header-font
22
- :color #f00
23
- :font
24
- :size 20px
25
-
26
- =compound
27
- +header-font
28
- +bordered
29
-
30
- =complex
31
- +header-font
32
- text:
33
- decoration: none
34
- &:after
35
- content: "."
36
- display: block
37
- height: 0
38
- clear: both
39
- visibility: hidden
40
- * html &
41
- height: 1px
42
- +header-font
43
- =deep
44
- a:hover
45
- :text-decoration underline
46
- +compound
47
-
48
-
49
- #main
50
- :width 15em
51
- :color #0000ff
52
- p
53
- +bordered
54
- :border
55
- :style dotted
56
- :width 2px
57
- .cool
58
- :width 100px
59
-
60
- #left
61
- +bordered
62
- :font
63
- :size 2em
64
- :weight bold
65
- :float left
66
-
67
- #right
68
- +bordered
69
- +header-font
70
- :float right
71
-
72
- .bordered
73
- +bordered
74
-
75
- .complex
76
- +complex
77
-
78
- .more-complex
79
- +complex
80
- +deep
81
- display: inline
82
- -webkit-nonsense:
83
- top-right: 1px
84
- bottom-left: 1px
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/multiline.css DELETED
@@ -1,24 +0,0 @@
1
- #main,
2
- #header {
3
- height: 50px; }
4
- #main div,
5
- #header div {
6
- width: 100px; }
7
- #main div a span,
8
- #main div em span,
9
- #header div a span,
10
- #header div em span {
11
- color: pink; }
12
-
13
- #one div.nested,
14
- #one span.nested,
15
- #one p.nested,
16
- #two div.nested,
17
- #two span.nested,
18
- #two p.nested,
19
- #three div.nested,
20
- #three span.nested,
21
- #three p.nested {
22
- font-weight: bold;
23
- border-color: red;
24
- display: block; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/multiline.sass DELETED
@@ -1,20 +0,0 @@
1
- #main,
2
- #header
3
- height: 50px
4
- div
5
- width: 100px
6
- a,
7
- em
8
- span
9
- color: pink
10
-
11
- #one,
12
- #two,
13
- #three
14
- div.nested,
15
- span.nested,
16
- p.nested
17
- :font
18
- :weight bold
19
- :border-color red
20
- :display block
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/nested-media.css DELETED
@@ -1,14 +0,0 @@
1
- .sidebar {
2
- width: 300px; }
3
- @media screen and (max-width: 1024px) {
4
- .sidebar {
5
- width: 500px; }
6
- .sidebar .subclass {
7
- height: 100px; }
8
- .sidebar .subclass .subsubclass {
9
- height: 200px; } }
10
- @media screen and (max-width:1024px) {
11
- .subclass {
12
- height: 100px; }
13
- .subclass .subsubclass {
14
- height: 200px; } }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/nested-media.scss DELETED
@@ -1,22 +0,0 @@
1
- $fiver: 500px;
2
- .sidebar {
3
- width: 300px;
4
- @media screen and (max-width: 1024px) {
5
- width: $fiver;
6
- .subclass {
7
- height: 100px;
8
- .subsubclass {
9
- height: 200px;
10
- }
11
- }
12
- }
13
- }
14
-
15
- @media screen and (max-width: 1024px) {
16
- .subclass {
17
- height: 100px;
18
- .subsubclass {
19
- height: 200px;
20
- }
21
- }
22
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/nested.css DELETED
@@ -1,24 +0,0 @@
1
- #main {
2
- width: 15em;
3
- color: blue; }
4
- #main p {
5
- border-style: dotted;
6
- border-width: 2px; }
7
- #main .cool {
8
- width: 100px; }
9
-
10
- #left {
11
- font-size: 2em;
12
- font-weight: bold;
13
- float: left; }
14
-
15
- #right .header {
16
- border-style: solid; }
17
- #right .body {
18
- border-style: dotted; }
19
- #right .footer {
20
- border-style: dashed; }
21
-
22
-
23
- body[bgproperties] {
24
- outline: 2px solid blue; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/nested.sass DELETED
@@ -1,28 +0,0 @@
1
- #main
2
- :width 15em
3
- :color #0000ff
4
- p
5
- :border
6
- :style dotted
7
- :width 2px
8
- .cool
9
- :width 100px
10
-
11
- #left
12
- :font
13
- :size 2em
14
- :weight bold
15
- :float left
16
-
17
- #right
18
- .header
19
- :border-style solid
20
- .body
21
- :border-style dotted
22
- .footer
23
- :border-style dashed
24
-
25
-
26
- body
27
- [bgproperties]
28
- outline: 2px solid blue
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/nested_bork1.sass DELETED
@@ -1,2 +0,0 @@
1
-
2
- @import bork1
 
 
lib/phpsass/tests/nested_bork2.sass DELETED
@@ -1,2 +0,0 @@
1
-
2
- @import bork2
 
 
lib/phpsass/tests/nested_bork3.sass DELETED
@@ -1,2 +0,0 @@
1
-
2
- @import bork3
 
 
lib/phpsass/tests/nested_bork4.sass DELETED
@@ -1,2 +0,0 @@
1
-
2
- @import bork4
 
 
lib/phpsass/tests/nested_bork5.sass DELETED
@@ -1,2 +0,0 @@
1
-
2
- @import bork5
 
 
lib/phpsass/tests/nested_import.css DELETED
@@ -1,18 +0,0 @@
1
- .foo body {
2
- font: Arial;
3
- background: blue; }
4
- .foo #page {
5
- width: 700px;
6
- height: 100;
7
- line-height: 100%; }
8
- .foo #page #header {
9
- height: 300px; }
10
- .foo #page #header h1 {
11
- font-size: 50px;
12
- color: blue; }
13
- .foo #content.user.show #container.top #column.left {
14
- width: 100px; }
15
- .foo #content.user.show #container.top #column.right {
16
- width: 600px; }
17
- .foo #content.user.show #container.bottom {
18
- background: brown; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/nested_import.sass DELETED
@@ -1,2 +0,0 @@
1
- .foo
2
- @import basic
 
 
lib/phpsass/tests/nested_media.css DELETED
@@ -1,5 +0,0 @@
1
- @media only screen and (max-width: 480px) {
2
- a b {
3
- one: two; }
4
- a b c {
5
- three: four; } }
 
 
 
 
 
lib/phpsass/tests/nested_media.scss DELETED
@@ -1,10 +0,0 @@
1
- @media only screen and (max-width: 480px) {
2
- a {
3
- b {
4
- one: two;
5
- c {
6
- three: four;
7
- }
8
- }
9
- }
10
- }
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/nested_mixin_bork.sass DELETED
@@ -1,6 +0,0 @@
1
-
2
-
3
- =error-mixin
4
- width: 1px * 1em
5
-
6
- @import mixin_bork
 
 
 
 
 
 
lib/phpsass/tests/nested_pseudo.css DELETED
@@ -1,3 +0,0 @@
1
- div :first-child,
2
- div h1 + * {
3
- border: 0; }
 
 
 
lib/phpsass/tests/nested_pseudo.scss DELETED
@@ -1,7 +0,0 @@
1
- // Covers issue #13
2
- div {
3
- :first-child,
4
- h1 + * {
5
- border: 0;
6
- }
7
- }
 
 
 
 
 
 
 
lib/phpsass/tests/number.css DELETED
@@ -1,9 +0,0 @@
1
- #number {
2
- font-size: 50%;
3
- font-size: 1;
4
- font-size: 0;
5
- font-size: 1;
6
- font-size: 1;
7
- font-size: 0;
8
- font-size: 0.5;
9
- font-size: 0.5; }
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/number.scss DELETED
@@ -1,10 +0,0 @@
1
- #number {
2
- font-size: percentage(.5);
3
- font-size: round(.5);
4
- font-size: round(.4);
5
- font-size: round(.6);
6
- font-size: ceil(.5);
7
- font-size: floor(.5);
8
- font-size: abs(.5);
9
- font-size: abs(-.5);
10
- }
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/opacity.css DELETED
@@ -1,7 +0,0 @@
1
- #opacity {
2
- background: 0.5;
3
- background: 0.5;
4
- background: rgba(242, 133, 0, 0.7);
5
- background: rgba(242, 133, 0, 0.7);
6
- background: rgba(242, 133, 0, 0.5);
7
- background: rgba(242, 133, 0, 0.5); }
 
 
 
 
 
 
 
lib/phpsass/tests/opacity.scss DELETED
@@ -1,8 +0,0 @@
1
- #opacity {
2
- background: alpha(rgba(#f28500, .5));
3
- background: opacity(rgba(#f28500, .5));
4
- background: opacify(rgba(#f28500, .2), .5);
5
- background: fade-in(rgba(#f28500, .2), .5);
6
- background: transparentize(#f28500, .5);
7
- background: fade-out(#f28500, .5);
8
- }
 
 
 
 
 
 
 
 
lib/phpsass/tests/other-color.css DELETED
@@ -1,5 +0,0 @@
1
- #other-color {
2
- background: #f28500;
3
- background: #ff920e;
4
- background: rgba(242, 133, 0, 0.5); }
5
-
 
 
 
 
 
lib/phpsass/tests/other-color.scss DELETED
@@ -1,5 +0,0 @@
1
- #other-color {
2
- background: adjust-color(#f28500, $green: .1, $red: .2, $blue: .3, $alpha: .4);
3
- background: scale-color(#f28500, $lightness: 10%);
4
- background: change-color(#f28500, $alpha: .5);
5
- }
 
 
 
 
 
lib/phpsass/tests/parent_ref.css DELETED
@@ -1,39 +0,0 @@
1
- a {
2
- color: black; }
3
- a:hover {
4
- color: red; }
5
-
6
- p,
7
- div {
8
- width: 100em; }
9
- p foo,
10
- div foo {
11
- width: 10em; }
12
- p bar,
13
- div bar,
14
- p:hover,
15
- div:hover {
16
- height: 20em; }
17
-
18
- #cool {
19
- border-style: solid;
20
- border-width: 2em; }
21
- .ie7 #cool,
22
- .ie6 #cool {
23
- content: string("Totally not cool."); }
24
- .firefox #cool {
25
- content: string("Quite cool."); }
26
-
27
- .wow,
28
- .snazzy {
29
- font-family: fantasy; }
30
- .wow:hover,
31
- .snazzy:hover,
32
- .wow:visited,
33
- .snazzy:visited {
34
- font-weight: bold; }
35
-
36
- input[type="search"] {
37
- -webkit-appearance: textfield; }
38
- input[type="search"]::-webkit-search-decoration {
39
- -webkit-appearance: none; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/parent_ref.sass DELETED
@@ -1,30 +0,0 @@
1
- a
2
- :color #000
3
- &:hover
4
- :color #f00
5
-
6
- p, div
7
- :width 100em
8
- & foo
9
- :width 10em
10
- &:hover, bar
11
- :height 20em
12
-
13
- #cool
14
- :border
15
- :style solid
16
- :width 2em
17
- .ie7 &, .ie6 &
18
- :content string("Totally not cool.")
19
- .firefox &
20
- :content string("Quite cool.")
21
-
22
- .wow, .snazzy
23
- :font-family fantasy
24
- &:hover, &:visited
25
- :font-weight bold
26
-
27
- input[type="search"]
28
- -webkit-appearance: textfield
29
- &::-webkit-search-decoration
30
- -webkit-appearance: none
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/phpSassTest.php DELETED
@@ -1,409 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * PHP Sass tests.
5
- * @group sass
6
- */
7
- class PHPSass_TestCase extends PHPUnit_Framework_TestCase
8
- {
9
- /**
10
- * This is the path to a directory of SASS, SCSS and CSS files used in tests.
11
- */
12
- public $css_tests_path;
13
-
14
- /**
15
- * This is the location of the PHPSass library being used.
16
- */
17
- public $phpsass_library_path;
18
-
19
- protected function setUp()
20
- {
21
- parent::setUp();
22
-
23
- $this->requirePHPSassLibrary();
24
- $this->css_tests_path = dirname(__FILE__);
25
- }
26
-
27
- /**
28
- * Require the PHPSass Library.
29
- *
30
- * We try to include it from the local site if it's around, otherwise we try a
31
- * few known locations, and then failing all of that we fall back to
32
- * downloading it from the web.
33
- */
34
- protected function requirePHPSassLibrary()
35
- {
36
- // Allow people to specify the library before we are called.
37
- if (isset($this->phpsass_library_path)) {
38
-
39
- }
40
- // Try to use libraries first.
41
- elseif (($library_path = dirname(__FILE__) . '/..') && file_exists($library_path . '/SassParser.php')) {
42
- $this->phpsass_library_path = $library_path;
43
- }
44
-
45
- if (isset($this->phpsass_library_path)) {
46
- require_once($this->phpsass_library_path . '/SassParser.php');
47
- } else {
48
- throw new Exception('Could not find PHPSass compiler.');
49
- }
50
- }
51
-
52
- protected function runSassTest($input, $output = FALSE, $settings = array())
53
- {
54
- $name = $input;
55
-
56
- $path = $this->css_tests_path;
57
- $output = $path . '/' . ($output ? $output : preg_replace('/\..+$/', '.css', $input));
58
- $input = $path . '/' . $input;
59
-
60
- if (!file_exists($input)) {
61
- return $this->fail('Input file not found - ' . $input);
62
- }
63
- if (!file_exists($output)) {
64
- return $this->fail('Comparison file not found - ' . $output);
65
- }
66
-
67
- $syntax = explode('.', $input);
68
- $syntax = array_pop($syntax);
69
- $settings = $settings + array(
70
- 'style' => 'nested',
71
- 'cache' => FALSE,
72
- 'syntax' => $syntax,
73
- 'debug' => FALSE,
74
- 'debug_info' => FALSE,
75
- 'callbacks' => array(
76
- 'debug' => array($this, 'sassParserDebug'),
77
- 'warn' => array($this, 'sassParserWarning'),
78
- ),
79
- );
80
- $parser = new SassParser($settings);
81
- $result = $parser->toCss($input);
82
-
83
- $compare = file_get_contents($output);
84
- if ($compare === FALSE) {
85
- $this->fail('Unable to load comparison file - ' . $compare);
86
- }
87
-
88
- $_result = $this->trimResult($result);
89
- $_compare = $this->trimResult($compare);
90
-
91
- $this->assertEquals($_result, $_compare, 'Result for ' . $name . ' did not match comparison file');
92
- }
93
-
94
- /**
95
- * Logging callback for PHPSass debug messages.
96
- */
97
- public function sassParserDebug($message, $context)
98
- {
99
- }
100
-
101
- /**
102
- * Logging callback for PHPSass warning messages.
103
- */
104
- public function sassParserWarning($message, $context)
105
- {
106
- }
107
-
108
- protected function trimResult(&$input)
109
- {
110
- $trim = preg_replace('/[\s;]+/', '', $input);
111
- $trim = preg_replace('/\/\*.+?\*\//m', '', $trim);
112
-
113
- return $trim;
114
- }
115
-
116
- public function testAlt()
117
- {
118
- $this->runSassTest('alt.sass');
119
- $this->runSassTest('alt.scss');
120
- }
121
-
122
- public function testBasic()
123
- {
124
- $this->runSassTest('basic.sass');
125
- }
126
-
127
-
128
- public function testComments()
129
- {
130
- $this->runSassTest('comments.sass');
131
- }
132
-
133
- public function testCompact()
134
- {
135
- $this->runSassTest('compact.sass');
136
- }
137
-
138
- public function testComplex()
139
- {
140
- $this->runSassTest('complex.sass');
141
- }
142
-
143
- public function testCompressed()
144
- {
145
- $this->runSassTest('compressed.sass');
146
- }
147
-
148
- public function testContent()
149
- {
150
- $this->runSassTest('content.scss');
151
- }
152
-
153
- public function testCss3()
154
- {
155
- $this->runSassTest('css3.scss');
156
- }
157
-
158
- public function testDefault()
159
- {
160
- $this->runSassTest('default.sass');
161
- }
162
-
163
- public function testEach()
164
- {
165
- $this->runSassTest('each.scss');
166
- }
167
-
168
- public function testExpanded()
169
- {
170
- $this->runSassTest('expanded.sass');
171
- }
172
-
173
- public function testExtend()
174
- {
175
- $this->runSassTest('extend.sass');
176
- }
177
-
178
- public function testExtendPlaceholders()
179
- {
180
- $this->runSassTest('extend_placeholders.scss');
181
- }
182
-
183
- public function testFilters()
184
- {
185
- $this->runSassTest('filters.scss');
186
- }
187
-
188
- public function testFunctions()
189
- {
190
- $this->runSassTest('functions.scss');
191
- }
192
-
193
- public function testHolmes()
194
- {
195
- $this->runSassTest('holmes.sass');
196
- }
197
-
198
- public function testHSLFunction()
199
- {
200
- $this->runSassTest('hsl-functions.scss');
201
- }
202
-
203
- public function testIf()
204
- {
205
- $this->runSassTest('if.sass');
206
- }
207
-
208
- public function testImportedContent()
209
- {
210
- $this->runSassTest('import_content.sass');
211
- }
212
-
213
- public function testInterpolation()
214
- {
215
- $this->runSassTest('interpolation.scss');
216
- }
217
-
218
- public function testIntrospection()
219
- {
220
- $this->runSassTest('introspection.scss');
221
- }
222
-
223
- public function testImport()
224
- {
225
- $this->runSassTest('import.sass');
226
- }
227
-
228
- public function testLineNumbers()
229
- {
230
- $this->runSassTest('line_numbers.sass');
231
- }
232
-
233
- public function testList()
234
- {
235
- $this->runSassTest('list.scss');
236
- }
237
-
238
- public function testMedia()
239
- {
240
- $this->runSassTest('media.scss');
241
- }
242
-
243
- public function testMiscFunctions()
244
- {
245
- $this->runSassTest('misc-functions.scss');
246
- }
247
-
248
- public function testMisc()
249
- {
250
- $this->runSassTest('misc.scss');
251
- }
252
-
253
- public function testMixinContent()
254
- {
255
- $this->runSassTest('mixin-content.sass');
256
- $this->runSassTest('mixin-content.scss');
257
- }
258
-
259
- public function testMixinJa1()
260
- {
261
- $this->runSassTest('mixin-ja1.sass');
262
- }
263
-
264
- public function testMixinParams()
265
- {
266
- $this->runSassTest('mixin-params.scss');
267
- }
268
-
269
- public function testMixins()
270
- {
271
- $this->runSassTest('mixins.sass');
272
- }
273
-
274
- public function testMixinInMixin()
275
- {
276
- $this->runSassTest('mixin_in_mixin.scss');
277
- }
278
-
279
- public function testMultiline()
280
- {
281
- $this->runSassTest('multiline.sass');
282
- }
283
-
284
- public function testNestedImport()
285
- {
286
- $this->runSassTest('nested_import.sass');
287
- }
288
-
289
- public function testNested()
290
- {
291
- $this->runSassTest('nested.sass');
292
- }
293
-
294
- public function testNestedMedia()
295
- {
296
- $this->runSassTest('nested_media.scss');
297
- }
298
-
299
- public function testNestedPseudo()
300
- {
301
- $this->runSassTest('nested_pseudo.scss');
302
- }
303
-
304
- public function testNumber()
305
- {
306
- $this->runSassTest('number.scss');
307
- }
308
-
309
- public function testOpacity()
310
- {
311
- $this->runSassTest('opacity.scss');
312
- }
313
-
314
- public function testOtherColor()
315
- {
316
- $this->runSassTest('other-color.scss');
317
- }
318
-
319
- public function testParentRef()
320
- {
321
- $this->runSassTest('parent_ref.sass');
322
- }
323
-
324
- public function testProprietarySelector()
325
- {
326
- $this->runSassTest('proprietary-selector.scss');
327
- }
328
-
329
- public function testRGBFunctions()
330
- {
331
- $this->runSassTest('rgb-functions.scss');
332
- }
333
-
334
- public function testScssImportee()
335
- {
336
- $this->runSassTest('scss_importee.scss');
337
- }
338
-
339
- public function testScssImport()
340
- {
341
- $this->runSassTest('scss_import.scss');
342
- }
343
-
344
- public function testSplats()
345
- {
346
- $this->runSassTest('splats.scss');
347
- }
348
-
349
- public function testString()
350
- {
351
- $this->runSassTest('string.scss');
352
- }
353
-
354
- public function testUnits()
355
- {
356
- $this->runSassTest('units.sass');
357
- }
358
-
359
- public function testListVariable()
360
- {
361
- $this->runSassTest('list_variable.scss');
362
- }
363
-
364
- public function testMediaInFor()
365
- {
366
- $this->runSassTest('media_in_for.scss');
367
- }
368
-
369
- public function testMediaInMixin()
370
- {
371
- $this->runSassTest('media_in_mixin.scss');
372
- }
373
-
374
- public function testMediaInTwoMixins()
375
- {
376
- $this->runSassTest('media_in_mixin_in_mixin.scss');
377
- }
378
-
379
- public function testIfParentheses()
380
- {
381
- $this->runSassTest('if_parentheses.scss');
382
- }
383
-
384
- public function testListEmpty()
385
- {
386
- $this->runSassTest('list_empty.scss');
387
- }
388
-
389
- public function testWarnImported()
390
- {
391
- $this->markTestIncomplete('This test has not been implemented yet.');
392
- //$this->runSassTest('warn_imported.sass');
393
- }
394
-
395
- public function testWarn()
396
- {
397
- $this->runSassTest('warn.sass');
398
- }
399
-
400
- public function testColour()
401
- {
402
- $this->runSassTest('colour-nth.scss');
403
- }
404
-
405
- public function testMixinSetvar()
406
- {
407
- $this->runSassTest('mixin_setvar.scss');
408
- }
409
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/phpunit.xml.dist DELETED
@@ -1,14 +0,0 @@
1
- <!-- Copy and rename to phpunit.xml. Customize as needed. -->
2
- <phpunit backupGlobals="false"
3
- backupStaticAttributes="false"
4
- syntaxCheck="false">
5
- <testsuites>
6
- <testsuite name="PHPSass Test Suite">
7
- <directory>.</directory>
8
- </testsuite>
9
- </testsuites>
10
-
11
- <php>
12
- <includePath>.</includePath>
13
- </php>
14
- </phpunit>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/proprietary-selector.css DELETED
@@ -1,4 +0,0 @@
1
- input:-moz-placeholder {
2
- color: #cccccc; }
3
- input::-webkit-input-placeholder {
4
- color: #cccccc; }
 
 
 
 
lib/phpsass/tests/proprietary-selector.scss DELETED
@@ -1,8 +0,0 @@
1
- input {
2
- &:-moz-placeholder {
3
- color: #ccc;
4
- }
5
- &::-webkit-input-placeholder {
6
- color: #ccc;
7
- }
8
- }
 
 
 
 
 
 
 
 
lib/phpsass/tests/rgb-functions.css DELETED
@@ -1,8 +0,0 @@
1
- #rgb {
2
- background-color: #fff36c;
3
- background-color: rgba(255, 243, 108, 0.5);
4
- background-color: rgba(255, 250, 43, 0.5);
5
- background-color: 255;
6
- background-color: 250;
7
- background-color: 43;
8
- background-color: #fff64b; }
 
 
 
 
 
 
 
 
lib/phpsass/tests/rgb-functions.scss DELETED
@@ -1,9 +0,0 @@
1
- #rgb {
2
- background-color: rgb(255, 243, 108);
3
- background-color: rgba(255, 243, 108, .5);
4
- background-color: rgba(#fffa2b, .5);
5
- background-color: red(#fffa2b);
6
- background-color: green(#fffa2b);
7
- background-color: blue(#fffa2b);
8
- background-color: mix(#fffa2b, rgb(255, 243, 108));
9
- }
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/scss_import.css DELETED
@@ -1,62 +0,0 @@
1
- imported {
2
- otherconst: hello;
3
- myconst: goodbye;
4
- pre-mixin: here; }
5
-
6
- body {
7
- font: Arial;
8
- background: blue; }
9
-
10
- #page {
11
- width: 700px;
12
- height: 100;
13
- line-height: 100%; }
14
- #page #header {
15
- height: 300px; }
16
- #page #header h1 {
17
- font-size: 50px;
18
- color: blue; }
19
-
20
- #content.user.show #container.top #column.left {
21
- width: 100px; }
22
- #content.user.show #container.top #column.right {
23
- width: 600px; }
24
- #content.user.show #container.bottom {
25
- background: brown; }
26
-
27
- midrule {
28
- inthe: middle; }
29
-
30
- scss {
31
- imported: yes; }
32
-
33
- body {
34
- font: Arial;
35
- background: blue; }
36
-
37
- #page {
38
- width: 700px;
39
- height: 100;
40
- line-height: 100%; }
41
- #page #header {
42
- height: 300px; }
43
- #page #header h1 {
44
- font-size: 50px;
45
- color: blue; }
46
-
47
- #content.user.show #container.top #column.left {
48
- width: 100px; }
49
- #content.user.show #container.top #column.right {
50
- width: 600px; }
51
- #content.user.show #container.bottom {
52
- background: brown; }
53
-
54
- @import url('basic.css');
55
- @import url('../results/complex.css');
56
- #foo {
57
- background-color: #bbaaff; }
58
-
59
- nonimported {
60
- myconst: hello;
61
- otherconst: goodbye;
62
- post-mixin: here; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/scss_import.scss DELETED
@@ -1,15 +0,0 @@
1
- $preconst: hello;
2
-
3
- @mixin premixin {pre-mixin: here}
4
-
5
- @import "importee.sass";
6
- @import "scss_importee";
7
- @import "basic.sass";
8
- @import "basic.css";
9
- @import "../results/complex.css";
10
- @import "partial.sass";
11
-
12
- nonimported {
13
- myconst: $preconst;
14
- otherconst: $postconst;
15
- @include postmixin; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/scss_importee.css DELETED
@@ -1,2 +0,0 @@
1
- scss {
2
- imported: yes; }
 
 
lib/phpsass/tests/scss_importee.scss DELETED
@@ -1 +0,0 @@
1
- scss {imported: yes}
 
lib/phpsass/tests/splats.css DELETED
@@ -1,5 +0,0 @@
1
- fn {
2
- three: 1, 2, 3;
3
- four: 1, 2, 3, 4; }
4
- box {
5
- box-shadow: 0 0 0 black, inset 5px 30px 10px red; }
 
 
 
 
 
lib/phpsass/tests/splats.scss DELETED
@@ -1,19 +0,0 @@
1
- @function test($in...) {
2
- @return $in;
3
- }
4
-
5
- fn {
6
- three: test(1,2,3);
7
-
8
- $foo: 1, 2, 3, 4;
9
- four: test($foo...);
10
- }
11
-
12
- @mixin box-shadow($shadows...) {
13
- box-shadow: $shadows;
14
- }
15
-
16
- box {
17
- $shadows: 0 0 0 #000, inset 5px 30px 10px red;
18
- @include box-shadow($shadows...);
19
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/string.css DELETED
@@ -1,3 +0,0 @@
1
- #string {
2
- content: banana;
3
- content: "pineapple"; }
 
 
 
lib/phpsass/tests/string.scss DELETED
@@ -1,6 +0,0 @@
1
- #string {
2
- $banana: "banana";
3
- $pineapple: pineapple;
4
- content: unquote($banana);
5
- content: quote($pineapple);
6
- }
 
 
 
 
 
 
lib/phpsass/tests/subdir/nested_subdir/_nested_partial.sass DELETED
@@ -1,2 +0,0 @@
1
- #nested
2
- :relative true
 
 
lib/phpsass/tests/subdir/nested_subdir/nested_subdir.css DELETED
@@ -1 +0,0 @@
1
- #pi { width: 314px; }
 
lib/phpsass/tests/subdir/nested_subdir/nested_subdir.sass DELETED
@@ -1,3 +0,0 @@
1
- #pi
2
- :width 314px
3
-
 
 
 
lib/phpsass/tests/subdir/subdir.css DELETED
@@ -1,3 +0,0 @@
1
- #nested { relative: true; }
2
-
3
- #subdir { font-size: 20px; font-weight: bold; }
 
 
 
lib/phpsass/tests/subdir/subdir.sass DELETED
@@ -1,6 +0,0 @@
1
- @import nested_subdir/nested_partial.sass
2
-
3
- #subdir
4
- :font
5
- :size 20px
6
- :weight bold
 
 
 
 
 
 
lib/phpsass/tests/units.css DELETED
@@ -1,12 +0,0 @@
1
- b {
2
- foo: 5px;
3
- bar: 24px;
4
- baz: 66.667%;
5
- many-units: 32em;
6
- mm: 15mm;
7
- pc: 2pc;
8
- pt: -72pt;
9
- inches: 2in;
10
- more-inches: 3.5in;
11
- mixed: 6px;
12
- rem: 37rem; }
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/units.sass DELETED
@@ -1,12 +0,0 @@
1
- b
2
- :foo 0.5 * 10px
3
- :bar 10zzz * 12px / 5zzz
4
- :baz percentage(12.0px / 18px)
5
- :many-units 10.0zzz / 3yyy * 12px / 5zzz * 3yyy / 3px * 4em
6
- :mm 5mm + 1cm
7
- :pc 1pc + 12pt
8
- :pt 72pt - 2in
9
- :inches 1in + 2.54cm
10
- :more-inches 1in + ((72pt * 2in) + (36pt * 1in)) / 2.54cm
11
- :mixed (1 + (1em * 6px / 3in)) * 4in / 2em
12
- :rem 34rem + 3rem
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tests/warn.css DELETED
@@ -1 +0,0 @@
1
- /* @warn: In the main file *//* @warn: Imported *//* @warn: In an imported mixin */
 
lib/phpsass/tests/warn.sass DELETED
@@ -1,4 +0,0 @@
1
- @debug 1em + 2em
2
- @warn "In the main file"
3
- @import warn_imported.sass
4
- +emits-a-warning
 
 
 
 
lib/phpsass/tests/warn_imported.sass DELETED
@@ -1,4 +0,0 @@
1
- @warn "Imported"
2
-
3
- =emits-a-warning
4
- @warn "In an imported mixin"
 
 
 
 
lib/phpsass/tree/SassCommentNode.php DELETED
@@ -1,70 +0,0 @@
1
- <?php
2
- /* SVN FILE: $Id$ */
3
- /**
4
- * SassCommentNode 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
-
12
- /**
13
- * SassCommentNode class.
14
- * Represents a CSS comment.
15
- * @package PHamlP
16
- * @subpackage Sass.tree
17
- */
18
- class SassCommentNode extends SassNode
19
- {
20
- const NODE_IDENTIFIER = '/';
21
- const MATCH = '%^/\*\s*?(.*?)\s*?(\*/)?$%s';
22
- const COMMENT = 1;
23
-
24
- private $value;
25
-
26
- /**
27
- * SassCommentNode constructor.
28
- * @param object source token
29
- * @return CommentNode
30
- */
31
- public function __construct($token)
32
- {
33
- parent::__construct($token);
34
- preg_match(self::MATCH, $token->source, $matches);
35
- $this->value = $matches[self::COMMENT];
36
- }
37
-
38
- protected function getValue()
39
- {
40
- return $this->value;
41
- }
42
-
43
- /**
44
- * Parse this node.
45
- * @return array the parsed node - an empty array
46
- */
47
- public function parse($context)
48
- {
49
- return array($this);
50
- }
51
-
52
- /**
53
- * Render this node.
54
- * @return string the rendered node
55
- */
56
- public function render()
57
- {
58
- return $this->renderer->renderComment($this);
59
- }
60
-
61
- /**
62
- * Returns a value indicating if the token represents this type of node.
63
- * @param object token
64
- * @return boolean true if the token represents this type of node, false if not
65
- */
66
- public static function isa($token)
67
- {
68
- return $token->source[0] === self::NODE_IDENTIFIER;
69
- }
70
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tree/SassContentNode.php DELETED
@@ -1,75 +0,0 @@
1
- <?php
2
- /* SVN FILE: $Id$ */
3
- /**
4
- * SassContentNode class file.
5
- * @author Richard Lyon
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
-
12
- /**
13
- * SassContentNode class.
14
- * Represents a Content.
15
- * @package PHamlP
16
- * @subpackage Sass.tree
17
- */
18
- class SassContentNode extends SassNode
19
- {
20
- const MATCH = '/^(@content)(.*)$/i';
21
- const IDENTIFIER = 1;
22
-
23
- /**
24
- * @var statement to execute and return
25
- */
26
- private $statement;
27
-
28
- /**
29
- * SassContentNode constructor.
30
- * @param object source token
31
- * @return SassContentNode
32
- */
33
- public function __construct($token)
34
- {
35
- parent::__construct($token);
36
- preg_match(self::MATCH, $token->source, $matches);
37
-
38
- if (empty($matches)) {
39
- return new SassBoolean('false');
40
- }
41
- }
42
-
43
- /**
44
- * Parse this node.
45
- * Set passed arguments and any optional arguments not passed to their
46
- * defaults, then render the children of the return definition.
47
- * @param SassContext the context in which this node is parsed
48
- * @return array the parsed node
49
- */
50
- public function parse($pcontext)
51
- {
52
- $return = $this;
53
- $context = new SassContext($pcontext);
54
-
55
- $children = array();
56
- foreach ($context->getContent() as $child) {
57
- $child->parent = $this->parent;
58
- $ctx = new SassContext($pcontext->parent);
59
- $ctx->variables = $pcontext->variables;
60
- $children = array_merge($children, $child->parse($ctx));
61
- }
62
-
63
- return $children;
64
- }
65
-
66
- /**
67
- * Contents a value indicating if the token represents this type of node.
68
- * @param object token
69
- * @return boolean true if the token represents this type of node, false if not
70
- */
71
- public static function isa($token)
72
- {
73
- return $token->source[0] === self::NODE_IDENTIFIER;
74
- }
75
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tree/SassContext.php DELETED
@@ -1,213 +0,0 @@
1
- <?php
2
- /* SVN FILE: $Id$ */
3
- /**
4
- * SassContext 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
-
12
- /**
13
- * SassContext class.
14
- * Defines the context that the parser is operating in and so allows variables
15
- * to be scoped.
16
- * A new context is created for Mixins and imported files.
17
- * @package PHamlP
18
- * @subpackage Sass.tree
19
- */
20
- class SassContext
21
- {
22
- /**
23
- * @var SassContext enclosing context
24
- */
25
- public $parent;
26
-
27
- /**
28
- * @var array mixins defined in this context
29
- */
30
- public $mixins = array();
31
-
32
- /**
33
- * @var array mixins defined in this context
34
- */
35
- public $functions = array();
36
-
37
- /**
38
- * @var array variables defined in this context
39
- */
40
- public $variables = array();
41
-
42
- /**
43
- * @var tree representing any contextual content.
44
- */
45
- public $content = array();
46
-
47
- /**
48
- * @var SassNode the node being processed
49
- */
50
- public $node;
51
-
52
- /**
53
- * SassContext constructor.
54
- * @param SassContext - the enclosing context
55
- * @return SassContext
56
- */
57
- public function __construct($parent = null)
58
- {
59
- $this->parent = $parent;
60
- }
61
-
62
- /**
63
- *
64
- */
65
- public function getContent()
66
- {
67
- if ($this->content) {
68
- return $this->content;
69
- }
70
- if (!empty($this->parent)) {
71
- return $this->parent->getContent();
72
- }
73
- throw new SassContextException('@content requested but no content passed', $this->node);
74
- }
75
-
76
- /**
77
- * Adds a mixin
78
- * @param string name of mixin
79
- * @return SassMixinDefinitionNode the mixin
80
- */
81
- public function addMixin($name, $mixin)
82
- {
83
- $this->mixins[$name] = $mixin;
84
-
85
- return $this;
86
- }
87
-
88
- /**
89
- * Returns a mixin
90
- * @param string name of mixin to return
91
- * @return SassMixinDefinitionNode the mixin
92
- * @throws SassContextException if mixin not defined in this context
93
- */
94
- public function getMixin($name)
95
- {
96
- if (isset($this->mixins[$name])) {
97
- return $this->mixins[$name];
98
- } elseif (!empty($this->parent)) {
99
- return $this->parent->getMixin($name);
100
- }
101
- throw new SassContextException('Undefined Mixin: ' . $name, $this->node);
102
- }
103
-
104
- /**
105
- * Adds a function
106
- * @param string name of function
107
- * @return SassFunctionDefinitionNode the function
108
- */
109
- public function addFunction($name, $function)
110
- {
111
- $this->functions[$name] = $function;
112
- if (!empty($this->parent)) {
113
- $this->parent->addFunction($name);
114
- }
115
-
116
- return $this;
117
- }
118
-
119
- /**
120
- * Returns a function
121
- * @param string name of function to return
122
- * @return SassFunctionDefinitionNode the mixin
123
- * @throws SassContextException if function not defined in this context
124
- */
125
- public function getFunction($name)
126
- {
127
- if ($fn = $this->hasFunction($name)) {
128
- return $fn;
129
- }
130
- throw new SassContextException('Undefined Function: ' . $name, $this->node);
131
- }
132
-
133
- /**
134
- * Returns a boolean wether this function exists
135
- * @param string name of function to check for
136
- * @return boolean
137
- */
138
- public function hasFunction($name)
139
- {
140
- if (isset($this->functions[$name])) {
141
- return $this->functions[$name];
142
- } elseif (!empty($this->parent)) {
143
- return $this->parent->hasFunction($name);
144
- }
145
-
146
- return FALSE;
147
- }
148
-
149
- /**
150
- * Returns a variable defined in this context
151
- * @param string name of variable to return
152
- * @return string the variable
153
- * @throws SassContextException if variable not defined in this context
154
- */
155
- public function getVariable($name)
156
- {
157
- $name = str_replace('-', '_', $name);
158
- if ($this->hasVariable($name)) {
159
- return $this->variables[$name];
160
- } elseif (!empty($this->parent)) {
161
- return $this->parent->getVariable($name);
162
- } else {
163
- // Return false instead of throwing an exception.
164
- // throw new SassContextException('Undefined Variable: ' . $name, $this->node);
165
- return new SassBoolean('false');
166
- }
167
- }
168
-
169
- /**
170
- * Returns a value indicating if the variable exists in this context
171
- * @param string name of variable to test
172
- * @return boolean true if the variable exists in this context, false if not
173
- */
174
- public function hasVariable($name)
175
- {
176
- $name = str_replace('-', '_', $name);
177
-
178
- return isset($this->variables[$name]);
179
- }
180
-
181
- /**
182
- * Sets a variable to the given value
183
- * @param string name of variable
184
- * @param sassLiteral value of variable
185
- */
186
- public function setVariable($name, $value)
187
- {
188
- $name = str_replace('-', '_', $name);
189
- $this->variables[$name] = $value;
190
-
191
- return $this;
192
- }
193
-
194
- public function setVariables($vars)
195
- {
196
- foreach ($vars as $key => $value) {
197
- if ($value !== NULL) {
198
- $this->setVariable($key, $value);
199
- }
200
- }
201
- }
202
-
203
- /**
204
- * Makes variables and mixins from this context available in the parent context.
205
- * Note that if there are variables or mixins with the same name in the two
206
- * contexts they will be set to that defined in this context.
207
- */
208
- public function merge()
209
- {
210
- $this->parent->variables = array_merge($this->parent->variables, $this->variables);
211
- $this->parent->mixins = array_merge($this->parent->mixins, $this->mixins);
212
- }
213
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tree/SassDebugNode.php DELETED
@@ -1,93 +0,0 @@
1
- <?php
2
- /* SVN FILE: $Id: SassDebugNode.php 49 2010-04-04 10:51:24Z chris.l.yates $ */
3
- /**
4
- * SassDebugNode 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
-
12
- /**
13
- * SassDebugNode class.
14
- * Represents a Sass @debug or @warn directive.
15
- * @package PHamlP
16
- * @subpackage Sass.tree
17
- */
18
- class SassDebugNode extends SassNode
19
- {
20
- const IDENTIFIER = '@';
21
- const MATCH = '/^@(?:debug|warn)\s+(.+?)\s*;?$/';
22
- const MESSAGE = 1;
23
-
24
- /**
25
- * @var string the debug/warning message
26
- */
27
- private $message;
28
- /**
29
- * @var array parameters for the message;
30
- * only used by internal warning messages
31
- */
32
- private $params;
33
- /**
34
- * @var boolean true if this is a warning
35
- */
36
- private $warning;
37
-
38
- /**
39
- * SassDebugNode.
40
- * @param object source token
41
- * @param mixed string: an internally generated warning message about the
42
- * source
43
- * boolean: the source token is a @debug or @warn directive containing the
44
- * message; True if this is a @warn directive
45
- * @param array parameters for the message
46
- * @return SassDebugNode
47
- */
48
- public function __construct($token, $message = false)
49
- {
50
- parent::__construct($token);
51
- if (is_string($message)) {
52
- $this->message = $message;
53
- $this->warning = true;
54
- } else {
55
- preg_match(self::MATCH, $token->source, $matches);
56
- $this->message = $matches[self::MESSAGE];
57
- $this->warning = $message;
58
- }
59
- }
60
-
61
- /**
62
- * Parse this node.
63
- * This raises an error.
64
- * @return array An empty array
65
- */
66
- public function parse($context)
67
- {
68
- if (!$this->warning) {
69
- $result = $this->evaluate($this->message, $context)->toString();
70
-
71
- $cb = SassParser::$instance->options['callbacks']['debug'];
72
- if ($cb) {
73
- call_user_func($cb, $result, $context);
74
- } else {
75
- set_error_handler(array($this, 'errorHandler'));
76
- trigger_error($result);
77
- restore_error_handler();
78
- }
79
- }
80
-
81
- return array();
82
- }
83
-
84
- /**
85
- * Error handler for degug and warning statements.
86
- * @param int Error number
87
- * @param string Message
88
- */
89
- public function errorHandler($errno, $message)
90
- {
91
- echo '<div style="background-color:#ce4dd6;border-bottom:1px dashed #88338d;color:white;font:10pt verdana;margin:0;padding:0.5em 2%;width:96%;"><p style="height:auto;margin:0.25em 0;padding:0;width:100%;"><span style="font-weight:bold;">SASS '.($this->warning ? 'WARNING' : 'DEBUG').":</span> $message</p><p style=\"margin:0.1em;padding:0;padding-left:0.5em;width:100%;\">{$this->filename}::{$this->line}</p><p style=\"margin:0.1em;padding:0;padding-left:0.5em;width:100%;\">Source: {$this->source}</p></div>";
92
- }
93
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tree/SassDirectiveNode.php DELETED
@@ -1,124 +0,0 @@
1
- <?php
2
- /* SVN FILE: $Id$ */
3
- /**
4
- * SassDirectiveNode 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
-
12
- /**
13
- * SassDirectiveNode class.
14
- * Represents a CSS directive.
15
- * @package PHamlP
16
- * @subpackage Sass.tree
17
- */
18
- class SassDirectiveNode extends SassNode
19
- {
20
- const NODE_IDENTIFIER = '@';
21
- const MATCH = '/^(@[\w-]+)/';
22
-
23
- const INTERPOLATION_MATCH = '/\$([\w-]+)/';
24
-
25
- /**
26
- * SassDirectiveNode.
27
- * @param object source token
28
- * @return SassDirectiveNode
29
- */
30
- public function __construct($token)
31
- {
32
- parent::__construct($token);
33
- }
34
-
35
- protected function getDirective()
36
- {
37
- return $this->token->source;
38
- preg_match('/^(@[\w-]+)(?:\s*(\w+))*/', $this->token->source, $matches);
39
- array_shift($matches);
40
- $parts = implode(' ', $matches);
41
-
42
- return strtolower($parts);
43
- }
44
-
45
- /**
46
- * Parse this node.
47
- * @param SassContext the context in which this node is parsed
48
- * @return array the parsed node
49
- */
50
- public function parse($context)
51
- {
52
- $this->token->source = self::interpolate_nonstrict($this->token->source, $context);
53
-
54
- $this->children = $this->parseChildren($context);
55
-
56
- return array($this);
57
- }
58
-
59
- /**
60
- * Render this node.
61
- * @return string the rendered node
62
- */
63
- public function render()
64
- {
65
- $properties = array();
66
- foreach ($this->children as $child) {
67
- $properties[] = $child->render();
68
- } // foreach
69
-
70
- return $this->renderer->renderDirective($this, $properties);
71
- }
72
-
73
- /**
74
- * Returns a value indicating if the token represents this type of node.
75
- * @param object token
76
- * @return boolean true if the token represents this type of node, false if not
77
- */
78
- public static function isa($token)
79
- {
80
- return $token->source[0] === self::NODE_IDENTIFIER;
81
- }
82
-
83
- /**
84
- * Returns the directive
85
- * @param object token
86
- * @return string the directive
87
- */
88
- public static function extractDirective($token)
89
- {
90
- preg_match(self::MATCH, $token->source, $matches);
91
-
92
- return strtolower($matches[1]);
93
- }
94
-
95
- public static function interpolate_nonstrict($string, $context)
96
- {
97
- for ($i = 0, $n = preg_match_all(self::INTERPOLATION_MATCH, $string, $matches); $i < $n; $i++) {
98
- $var = SassScriptParser::$instance->evaluate($matches[0][$i], $context);
99
-
100
- if ($var instanceOf SassString) {
101
- $var = $var->value;
102
- } else {
103
- $var = $var->toString();
104
- }
105
-
106
- if (preg_match('/^unquote\((["\'])(.*)\1\)$/', $var, $match)) {
107
- $val = $match[2];
108
- } elseif ($var == '""') {
109
- $val = "";
110
- } elseif (preg_match('/^(["\'])(.*)\1$/', $var, $match)) {
111
- $val = $match[2];
112
- } else {
113
- $val = $var;
114
- }
115
- $matches[1][$i] = $val;
116
- }
117
- $matches[0][] = '#{';
118
- $matches[0][] = '}';
119
- $matches[1][] = '';
120
- $matches[1][] = '';
121
-
122
- return str_replace($matches[0], $matches[1], $string);
123
- }
124
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tree/SassEachNode.php DELETED
@@ -1,79 +0,0 @@
1
- <?php
2
- /* SVN FILE: $Id$ */
3
- /**
4
- * SassEachNode class file.
5
- * The syntax is:
6
- * <pre>@each <var> in <list><pre>.
7
- *
8
- * <list> is comma+space separated
9
- * <var> is available to the rest of the script following evaluation
10
- * and has the value that terminated the loop.
11
- *
12
- * @author Pavol (Lopo) Hluchy <lopo@losys.eu>
13
- * @copyright Copyright (c) 2011 Lopo
14
- * @license http://www.gnu.org/licenses/gpl.html GNU General Public License Version 3
15
- * @package PHamlP
16
- * @subpackage Sass.tree
17
- */
18
-
19
- /**
20
- * SassEachNode class.
21
- * Represents a Sass @each loop.
22
- * @package PHamlP
23
- * @subpackage Sass.tree
24
- */
25
- class SassEachNode extends SassNode
26
- {
27
- const MATCH = '/@each\s+[!\$](.+?)in\s+(.+)$/i';
28
-
29
- const VARIABLE = 1;
30
- const IN = 2;
31
-
32
- /**
33
- * @var string variable name for the loop
34
- */
35
- private $variable;
36
- /**
37
- * @var string expression that provides the loop values
38
- */
39
- private $in;
40
-
41
- /**
42
- * SassEachNode constructor.
43
- * @param object source token
44
- * @return SassEachNode
45
- */
46
- public function __construct($token)
47
- {
48
- parent::__construct($token);
49
- if (!preg_match(self::MATCH, $token->source, $matches)) {
50
- throw new SassEachNodeException('Invalid @each directive', $this);
51
- } else {
52
- $this->variable = trim($matches[self::VARIABLE]);
53
- $this->in = $matches[self::IN];
54
- }
55
- }
56
-
57
- /**
58
- * Parse this node.
59
- * @param SassContext the context in which this node is parsed
60
- * @return array parsed child nodes
61
- */
62
- public function parse($context)
63
- {
64
- $children = array();
65
-
66
- if ($this->variable && $this->in) {
67
- $context = new SassContext($context);
68
-
69
- list($in, $sep) = SassList::_parse_list($this->in, 'auto', true, $context);
70
- foreach ($in as $var) {
71
- $context->setVariable($this->variable, $var);
72
- $children = array_merge($children, $this->parseChildren($context));
73
- }
74
- }
75
- $context->merge();
76
-
77
- return $children;
78
- }
79
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tree/SassElseNode.php DELETED
@@ -1,30 +0,0 @@
1
- <?php
2
- /* SVN FILE: $Id: SassIfNode.php 49 2010-04-04 10:51:24Z chris.l.yates $ */
3
- /**
4
- * SassElseNode 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
-
12
- /**
13
- * SassElseNode class.
14
- * Represents Sass Else If and Else statements.
15
- * Else If and Else statement nodes are chained below the If statement node.
16
- * @package PHamlP
17
- * @subpackage Sass.tree
18
- */
19
- class SassElseNode extends SassIfNode
20
- {
21
- /**
22
- * SassElseNode constructor.
23
- * @param object source token
24
- * @return SassElseNode
25
- */
26
- public function __construct($token)
27
- {
28
- parent::__construct($token, false);
29
- }
30
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tree/SassExtendNode.php DELETED
@@ -1,53 +0,0 @@
1
- <?php
2
- /* SVN FILE: $Id: SassExtendNode.php 49 2010-04-04 10:51:24Z chris.l.yates $ */
3
- /**
4
- * SassExtendNode 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
-
12
- /**
13
- * SassExtendNode class.
14
- * Represents a Sass @debug or @warn directive.
15
- * @package PHamlP
16
- * @subpackage Sass.tree
17
- */
18
- class SassExtendNode extends SassNode
19
- {
20
- const IDENTIFIER = '@';
21
- const MATCH = '/^@extend\s+(.+)/i';
22
- const VALUE = 1;
23
-
24
- /**
25
- * @var string the directive
26
- */
27
- private $value;
28
-
29
- /**
30
- * SassExtendNode.
31
- * @param object source token
32
- * @return SassExtendNode
33
- */
34
- public function __construct($token)
35
- {
36
- parent::__construct($token);
37
- preg_match(self::MATCH, $token->source, $matches);
38
- $this->value = $matches[self::VALUE];
39
- }
40
-
41
- /**
42
- * Parse this node.
43
- * @return array An empty array
44
- */
45
- public function parse($context)
46
- {
47
- # resolve selectors in relation to variables
48
- # allows extend inside nested loops.
49
- $this->root->extend($this->value, $this->parent->resolveSelectors($context));
50
-
51
- return array();
52
- }
53
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tree/SassForNode.php DELETED
@@ -1,103 +0,0 @@
1
- <?php
2
- /* SVN FILE: $Id$ */
3
- /**
4
- * SassForNode class file.
5
- * This is an enhanced version of the standard SassScript @for loop that adds
6
- * an optional step clause. Step must evaluate to a positive integer.
7
- * The syntax is:
8
- * <pre>@for <var> from <start> to|through <end>[ step <step>]</pre>.
9
- *
10
- * <start> can be less or greater than <end>.
11
- * If the step clause is ommitted the <step> = 1.
12
- * <var> is available to the rest of the script following evaluation
13
- * and has the value that terminated the loop.
14
- *
15
- * @author Chris Yates <chris.l.yates@gmail.com>
16
- * @copyright Copyright (c) 2010 PBM Web Development
17
- * @license http://phamlp.googlecode.com/files/license.txt
18
- * @package PHamlP
19
- * @subpackage Sass.tree
20
- */
21
-
22
- /**
23
- * SassForNode class.
24
- * Represents a Sass @for loop.
25
- * @package PHamlP
26
- * @subpackage Sass.tree
27
- */
28
- class SassForNode extends SassNode
29
- {
30
- const MATCH = '/@for\s+[!\$](\w+)\s+from\s+(.+?)\s+(through|to)\s+(.+?)(?:\s+step\s+(.+))?$/i';
31
-
32
- const VARIABLE = 1;
33
- const FROM = 2;
34
- const INCLUSIVE = 3;
35
- const TO = 4;
36
- const STEP = 5;
37
- const IS_INCLUSIVE = 'through';
38
-
39
- /**
40
- * @var string variable name for the loop
41
- */
42
- private $variable;
43
- /**
44
- * @var string expression that provides the loop start value
45
- */
46
- private $from;
47
- /**
48
- * @var string expression that provides the loop end value
49
- */
50
- private $to;
51
- /**
52
- * @var boolean whether the loop end value is inclusive
53
- */
54
- private $inclusive;
55
- /**
56
- * @var string expression that provides the amount by which the loop variable
57
- * changes on each iteration
58
- */
59
- private $step;
60
-
61
- /**
62
- * SassForNode constructor.
63
- * @param object source token
64
- * @return SassForNode
65
- */
66
- public function __construct($token)
67
- {
68
- parent::__construct($token);
69
- if (!preg_match(self::MATCH, $token->source, $matches)) {
70
- throw new SassForNodeException('Invalid @for directive', $this);
71
- }
72
- $this->variable = $matches[self::VARIABLE];
73
- $this->from = $matches[self::FROM];
74
- $this->to = $matches[self::TO];
75
- $this->inclusive = ($matches[self::INCLUSIVE] === SassForNode::IS_INCLUSIVE);
76
- $this->step = (empty($matches[self::STEP]) ? 1 : $matches[self::STEP]);
77
- }
78
-
79
- /**
80
- * Parse this node.
81
- * @param SassContext the context in which this node is parsed
82
- * @return array parsed child nodes
83
- */
84
- public function parse($context)
85
- {
86
- $children = array();
87
- $from = (float) $this->evaluate($this->from, $context)->value;
88
- $to = (float) $this->evaluate($this->to, $context)->value;
89
- $step = (float) $this->evaluate($this->step, $context)->value * ($to > $from ? 1 : -1);
90
-
91
- if ($this->inclusive) {
92
- $to += ($from < $to ? 1 : -1);
93
- }
94
-
95
- $context = new SassContext($context);
96
- for ($i = $from; ($from < $to ? $i < $to : $i > $to); $i = $i + $step) {
97
- $context->setVariable($this->variable, new SassNumber($i));
98
- $children = array_merge($children, $this->parseChildren($context));
99
- }
100
-
101
- return $children;
102
- }
103
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tree/SassFunctionDefinitionNode.php DELETED
@@ -1,123 +0,0 @@
1
- <?php
2
- /* SVN FILE: $Id$ */
3
- /**
4
- * SassFunctionDefinitionNode 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
-
12
- /**
13
- * SassFunctionDefinitionNode class.
14
- * Represents a Function definition.
15
- * @package PHamlP
16
- * @subpackage Sass.tree
17
- */
18
- class SassFunctionDefinitionNode extends SassNode
19
- {
20
- const NODE_IDENTIFIER = FALSE;
21
- const MATCH = '/^@function\s+([_-\w]+)\s*(?:\((.*?)\))?\s*$/im';
22
- const IDENTIFIER = 1;
23
- const NAME = 1;
24
- const ARGUMENTS = 2;
25
-
26
- /**
27
- * @var string name of the function
28
- */
29
- private $name;
30
- /**
31
- * @var array arguments for the function as name=>value pairs were value is the
32
- * default value or null for required arguments
33
- */
34
- private $args = array();
35
-
36
- public $parent;
37
-
38
- /**
39
- * SassFunctionDefinitionNode constructor.
40
- * @param object source token
41
- * @return SassFunctionDefinitionNode
42
- */
43
- public function __construct($token)
44
- {
45
- // if ($token->level !== 0) {
46
- // throw new SassFunctionDefinitionNodeException('Functions can only be defined at root level', $token);
47
- // }
48
- parent::__construct($token);
49
- preg_match(self::MATCH, $token->source, $matches);
50
- if (empty($matches)) {
51
- throw new SassFunctionDefinitionNodeException('Invalid Function', $token);
52
- }
53
- $this->name = $matches[self::NAME];
54
- $this->name = preg_replace('/[^a-z0-9_]/', '_', strtolower($this->name));
55
- if (isset($matches[self::ARGUMENTS])) {
56
- if (strlen(trim($matches[self::ARGUMENTS]))) {
57
- foreach (explode(',', $matches[self::ARGUMENTS]) as $arg) {
58
- $arg = explode(($matches[self::IDENTIFIER] === self::NODE_IDENTIFIER ? '=' : ':'), trim($arg));
59
- $this->args[substr(trim($arg[0]), 1)] = (count($arg) == 2 ? trim($arg[1]) : null);
60
- } // foreach
61
- }
62
- }
63
- }
64
-
65
- /**
66
- * Parse this node.
67
- * Add this function to the current context.
68
- * @param SassContext the context in which this node is parsed
69
- * @return array the parsed node - an empty array
70
- */
71
- public function parse($context)
72
- {
73
- $context->addFunction($this->name, $this);
74
-
75
- return array();
76
- }
77
-
78
- /**
79
- * Returns the arguments with default values for this function
80
- * @return array the arguments with default values for this function
81
- */
82
- public function getArgs()
83
- {
84
- return $this->args;
85
- }
86
-
87
- /**
88
- * Returns a value indicating if the token represents this type of node.
89
- * @param object token
90
- * @return boolean true if the token represents this type of node, false if not
91
- */
92
- public static function isa($token)
93
- {
94
- return $token->source[0] === self::NODE_IDENTIFIER;
95
- }
96
-
97
- /**
98
- * Evalutes the function in the given context, with the provided arguments
99
- * @param SassContext - the parent context
100
- * @param array - the list of provided variables
101
- * @throws SassReturn - if the @return is fired then this is thrown to break early
102
- * @return SassBoolean(false) - if no @return was fired, return false
103
- */
104
- public function execute($pcontext, $provided)
105
- {
106
- list($arguments, $context) = SassScriptFunction::fill_parameters($this->args, $provided, $pcontext, $this);
107
- $context->setVariables($arguments);
108
-
109
- $parser = $this->parent->parser;
110
-
111
- $children = array();
112
- try {
113
- foreach ($this->children as $child) {
114
- $child->parent = $this;
115
- $children = array_merge($children, $child->parse($context));
116
- }
117
- } catch (SassReturn $e) {
118
- return $e->value;
119
- }
120
-
121
- return new SassBoolean('false');
122
- }
123
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tree/SassIfNode.php DELETED
@@ -1,98 +0,0 @@
1
- <?php
2
- /* SVN FILE: $Id$ */
3
- /**
4
- * SassIfNode 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
-
12
- /**
13
- * SassIfNode class.
14
- * Represents Sass If, Else If and Else statements.
15
- * Else If and Else statement nodes are chained below the If statement node.
16
- * @package PHamlP
17
- * @subpackage Sass.tree
18
- */
19
- class SassIfNode extends SassNode
20
- {
21
- const MATCH_IF = '/^@if\s*(.+)$/i';
22
- const MATCH_ELSE = '/@else(\s*if\s*(.+))?/i';
23
- const IF_EXPRESSION = 1;
24
- const ELSE_IF = 1;
25
- const ELSE_EXPRESSION = 2;
26
- /**
27
- * @var SassIfNode the next else node.
28
- */
29
- private $else;
30
- /**
31
- * @var string expression to evaluate
32
- */
33
- private $expression;
34
-
35
- /**
36
- * SassIfNode constructor.
37
- * @param object source token
38
- * @param boolean true for an "if" node, false for an "else if | else" node
39
- * @return SassIfNode
40
- */
41
- public function __construct($token, $if=true)
42
- {
43
- parent::__construct($token);
44
- if ($if) {
45
- preg_match(self::MATCH_IF, $token->source, $matches);
46
- $this->expression = $matches[SassIfNode::IF_EXPRESSION];
47
- } else {
48
- preg_match(self::MATCH_ELSE, $token->source, $matches);
49
- $this->expression = (sizeof($matches)==1 ? null : $matches[SassIfNode::ELSE_EXPRESSION]);
50
- }
51
- }
52
-
53
- /**
54
- * Adds an "else" statement to this node.
55
- * @param SassIfNode "else" statement node to add
56
- * @return SassIfNode this node
57
- */
58
- public function addElse($node)
59
- {
60
- if (is_null($this->else)) {
61
- $node->parent = $this;
62
- $node->root = $this->root;
63
- $this->else = $node;
64
- } else {
65
- $this->else->addElse($node);
66
- }
67
-
68
- return $this;
69
- }
70
-
71
- /**
72
- * Parse this node.
73
- * @param SassContext the context in which this node is parsed
74
- * @return array parsed child nodes
75
- */
76
- public function parse($context)
77
- {
78
- if ($this->isElse() || $this->evaluate($this->expression, $context)->toBoolean()) {
79
- $children = $this->parseChildren($context);
80
- } elseif (!empty($this->else)) {
81
- $children = $this->else->parse($context);
82
- } else {
83
- $children = array();
84
- }
85
-
86
- return $children;
87
- }
88
-
89
- /**
90
- * Returns a value indicating if this node is an "else" node.
91
- * @return true if this node is an "else" node, false if this node is an "if"
92
- * or "else if" node
93
- */
94
- private function isElse()
95
- {
96
- return ($this->expression=='');
97
- }
98
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tree/SassImportNode.php DELETED
@@ -1,109 +0,0 @@
1
- <?php
2
- /* SVN FILE: $Id$ */
3
- /**
4
- * SassImportNode 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
-
12
- /**
13
- * SassImportNode class.
14
- * Represents a CSS Import.
15
- * @package PHamlP
16
- * @subpackage Sass.tree
17
- */
18
- class SassImportNode extends SassNode
19
- {
20
- const IDENTIFIER = '@';
21
- const MATCH = '/^@import\s+(.+)/i';
22
- const MATCH_CSS = '/^((url)\((.+)\)|.+" \w+|http|.+\.css$)/im';
23
- const FILES = 1;
24
-
25
- /**
26
- * @var array files to import
27
- */
28
- private $files = array();
29
-
30
- /**
31
- * SassImportNode.
32
- * @param object source token
33
- * @return SassImportNode
34
- */
35
- public function __construct($token, $parent)
36
- {
37
- parent::__construct($token);
38
- $this->parent = $parent;
39
- preg_match(self::MATCH, $token->source, $matches);
40
-
41
- foreach (SassList::_build_list($matches[self::FILES]) as $file) {
42
- $this->files[] = trim($file, '"\'; ');
43
- }
44
- }
45
-
46
- /**
47
- * Parse this node.
48
- * If the node is a CSS import return the CSS import rule.
49
- * Else returns the rendered tree for the file.
50
- * @param SassContext the context in which this node is parsed
51
- * @return array the parsed node
52
- */
53
- public function parse($context)
54
- {
55
- $imported = array();
56
- foreach ($this->files as $file) {
57
- if (preg_match(self::MATCH_CSS, $file, $matches)) {
58
- if (isset($matches[2]) && $matches[2] == 'url') {
59
- $file = $matches[1];
60
- } else {
61
- $file = "url('$file')";
62
- }
63
-
64
- return array(new SassString("@import $file;"), new SassString("\n"));
65
- }
66
- $file = trim($file, '\'"');
67
- $files = SassFile::get_file($file, $this->parser);
68
- $tree = array();
69
- if ($files) {
70
- if ($this->token->level > 0) {
71
- $tree = $this->parent;
72
- while (get_class($tree) != 'SassRuleNode' && get_class($tree) != 'SassRootNode' && isset($tree->parent)) {
73
- $tree = $tree->parent;
74
- }
75
- $tree = clone $tree;
76
- $tree->children = array();
77
- } else {
78
- $tree = new SassRootNode($this->parser);
79
- $tree->extend_parent = $this->parent;
80
- }
81
-
82
- foreach ($files as $subfile) {
83
- if (preg_match(self::MATCH_CSS, $subfile)) {
84
- $tree->addChild(new SassString("@import url('$subfile');"));
85
- } else {
86
- $this->parser->filename = $subfile;
87
- $subtree = SassFile::get_tree($subfile, $this->parser);
88
- foreach ($subtree->getChildren() as $child) {
89
- $tree->addChild($child);
90
- }
91
- }
92
- }
93
- }
94
- if (!empty($tree)) {
95
- # parent may be either SassRootNode (returns an object) or SassRuleNode (returns an array of nodes)
96
- # so we parse then try get the children.
97
- $parsed = $tree->parse($context);
98
- if (!is_array($parsed) && isset($parsed->children)) {
99
- $parsed = $parsed->children;
100
- }
101
- if (is_array($parsed)) {
102
- $imported = array_merge($imported, $parsed);
103
- }
104
- }
105
- }
106
-
107
- return $imported;
108
- }
109
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tree/SassMediaNode.php DELETED
@@ -1,99 +0,0 @@
1
- <?php
2
- /* SVN FILE: $Id: SassMediaNode.php 49 2010-04-04 10:51:24Z chris.l.yates $ */
3
- /**
4
- * SassMediaNode class file.
5
- * @author Richard Lyon
6
- * @copyright none
7
- * @license http://phamlp.googlecode.com/files/license.txt
8
- * @package PHamlP
9
- * @subpackage Sass.tree
10
- */
11
-
12
- /**
13
- * SassMediaNode class.
14
- * Represents a CSS @media directive
15
- * @package PHamlP
16
- * @subpackage Sass.tree
17
- */
18
- class SassMediaNode extends SassNode
19
- {
20
- const IDENTIFIER = '@';
21
- const MATCH = '/^@(media)\s+(.+?)\s*;?$/';
22
- const MEDIA = 1;
23
-
24
- public $token;
25
-
26
- /**
27
- * @var string
28
- */
29
- private $media;
30
- /**
31
- * @var array parameters for the message;
32
- * only used by internal warning messages
33
- */
34
- private $params;
35
- /**
36
- * @var boolean true if this is a warning
37
- */
38
- private $warning;
39
-
40
- /**
41
- * SassMediaNode.
42
- * @param object source token
43
- * @param mixed string: an internally generated warning message about the
44
- * source
45
- * boolean: the source token is a @Media or @warn directive containing the
46
- * message; True if this is a @warn directive
47
- * @param array parameters for the message
48
- * @return SassMediaNode
49
- */
50
- public function __construct($token)
51
- {
52
- parent::__construct($token);
53
-
54
- preg_match(self::MATCH, $token->source, $matches);
55
- $this->token = $token;
56
- $this->media = $matches[self::MEDIA];
57
- }
58
-
59
- /**
60
- * Parse this node.
61
- * This raises an error.
62
- * @return array An empty array
63
- */
64
- public function parse($context)
65
- {
66
- // If we are in a loop, function or mixin then the parent isn't what should
67
- // go inside the media node. Walk up the parent tree to find the rule node
68
- // to put inside the media node or the root node if the media node should be
69
- // at the root.
70
- $parent = $this->parent;
71
- while (!($parent instanceOf SassRuleNode) && !($parent instanceOf SassRootNode)) {
72
- $parent = $parent->parent;
73
- }
74
-
75
- // Make a copy of the token before parsing in case we are in a loop and it contains variables
76
- $token = clone $this->token;
77
- $token->source = SassDirectiveNode::interpolate_nonstrict($token->source, $context);
78
-
79
- $node = new SassRuleNode($token, $context);
80
- $node->root = $parent->root;
81
-
82
- $rule = clone $parent;
83
- $rule->root = $node->root;
84
- $rule->children = $this->children;
85
-
86
- $try = $rule->parse($context);
87
- if (is_array($try)) {
88
- $rule->children = $try;
89
- }
90
- // Tests were failing with this, but I'm not sure if we cover every case.
91
- //else if (is_object($try) && method_exists($try, 'render')) {
92
- // $rule = $try;
93
- //}
94
-
95
- $node->children = array(new SassString($rule->render($context)));
96
-
97
- return array($node);
98
- }
99
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tree/SassMixinDefinitionNode.php DELETED
@@ -1,85 +0,0 @@
1
- <?php
2
- /* SVN FILE: $Id$ */
3
- /**
4
- * SassMixinDefinitionNode 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
-
12
- /**
13
- * SassMixinDefinitionNode class.
14
- * Represents a Mixin definition.
15
- * @package PHamlP
16
- * @subpackage Sass.tree
17
- */
18
- class SassMixinDefinitionNode extends SassNode
19
- {
20
- const NODE_IDENTIFIER = '=';
21
- const MATCH = '/^(=|@mixin\s+)([-\w]+)\s*(?:\((.*?)\))?\s*$/im';
22
- const IDENTIFIER = 1;
23
- const NAME = 2;
24
- const ARGUMENTS = 3;
25
-
26
- /**
27
- * @var string name of the mixin
28
- */
29
- private $name;
30
- /**
31
- * @var array arguments for the mixin as name=>value pairs were value is the
32
- * default value or null for required arguments
33
- */
34
- private $args = array();
35
-
36
- /**
37
- * SassMixinDefinitionNode constructor.
38
- * @param object source token
39
- * @return SassMixinDefinitionNode
40
- */
41
- public function __construct($token)
42
- {
43
- preg_match(self::MATCH, $token->source, $matches);
44
- parent::__construct($token);
45
- if (empty($matches)) {
46
- throw new SassMixinDefinitionNodeException('Invalid Mixin', $this);
47
- }
48
- $this->name = $matches[self::NAME];
49
- if (isset($matches[self::ARGUMENTS])) {
50
- $this->args = SassScriptFunction::extractArgs($matches[self::ARGUMENTS], true, new SassContext);
51
- }
52
- }
53
-
54
- /**
55
- * Parse this node.
56
- * Add this mixin to the current context.
57
- * @param SassContext the context in which this node is parsed
58
- * @return array the parsed node - an empty array
59
- */
60
- public function parse($context)
61
- {
62
- $context->addMixin($this->name, $this);
63
-
64
- return array();
65
- }
66
-
67
- /**
68
- * Returns the arguments with default values for this mixin
69
- * @return array the arguments with default values for this mixin
70
- */
71
- public function getArgs()
72
- {
73
- return $this->args;
74
- }
75
-
76
- /**
77
- * Returns a value indicating if the token represents this type of node.
78
- * @param object token
79
- * @return boolean true if the token represents this type of node, false if not
80
- */
81
- public static function isa($token)
82
- {
83
- return $token->source[0] === self::NODE_IDENTIFIER;
84
- }
85
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tree/SassMixinNode.php DELETED
@@ -1,93 +0,0 @@
1
- <?php
2
- /* SVN FILE: $Id$ */
3
- /**
4
- * SassMixinNode 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
-
12
- /**
13
- * SassMixinNode class.
14
- * Represents a Mixin.
15
- * @package PHamlP
16
- * @subpackage Sass.tree
17
- */
18
- class SassMixinNode extends SassNode
19
- {
20
- const NODE_IDENTIFIER = '+';
21
- const MATCH = '/^(\+|@include\s+)([a-z0-9_-]+)\s*(?:\((.*?)\))?\s*$/i';
22
- const IDENTIFIER = 1;
23
- const NAME = 2;
24
- const ARGS = 3;
25
-
26
- /**
27
- * @var string name of the mixin
28
- */
29
- private $name;
30
- /**
31
- * @var array arguments for the mixin
32
- */
33
- private $args = '';
34
-
35
- /**
36
- * SassMixinDefinitionNode constructor.
37
- * @param object source token
38
- * @return SassMixinNode
39
- */
40
- public function __construct($token)
41
- {
42
- parent::__construct($token);
43
- preg_match(self::MATCH, $token->source, $matches);
44
-
45
- if (!isset($matches[self::NAME])) {
46
- throw new SassMixinNodeException('Invalid mixin invocation: ($token->source)', $this);
47
- }
48
- $this->name = $matches[self::NAME];
49
- if (isset($matches[self::ARGS]) && strlen($matches[self::ARGS])) {
50
- $this->args = $matches[self::ARGS];
51
- }
52
- }
53
-
54
- /**
55
- * Parse this node.
56
- * Set passed arguments and any optional arguments not passed to their
57
- * defaults, then render the children of the mixin definition.
58
- * @param SassContext the context in which this node is parsed
59
- * @return array the parsed node
60
- */
61
- public function parse($pcontext)
62
- {
63
- $mixin = $pcontext->getMixin($this->name);
64
- $context = new SassContext($pcontext);
65
- $context->content = $this->children;
66
- $argc = count($this->args);
67
- $count = 0;
68
-
69
- $args = SassScriptFunction::extractArgs($this->args, false, $context);
70
-
71
- list($arguments) = SassScriptFunction::fill_parameters($mixin->args, $args, $context, $this);
72
- $context->setVariables($arguments);
73
-
74
- $children = array();
75
- foreach ($mixin->children as $child) {
76
- $child->parent = $this;
77
- $children = array_merge($children, $child->parse($context));
78
- }
79
-
80
- // $context->merge();
81
- return $children;
82
- }
83
-
84
- /**
85
- * Returns a value indicating if the token represents this type of node.
86
- * @param object token
87
- * @return boolean true if the token represents this type of node, false if not
88
- */
89
- public static function isa($token)
90
- {
91
- return $token->source[0] === self::NODE_IDENTIFIER;
92
- }
93
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tree/SassNode.php DELETED
@@ -1,392 +0,0 @@
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
-
12
- require_once 'SassContext.php';
13
- require_once 'SassCommentNode.php';
14
- require_once 'SassDebugNode.php';
15
- require_once 'SassDirectiveNode.php';
16
- require_once 'SassImportNode.php';
17
- require_once 'SassMixinNode.php';
18
- require_once 'SassMixinDefinitionNode.php';
19
- require_once 'SassPropertyNode.php';
20
- require_once 'SassRootNode.php';
21
- require_once 'SassRuleNode.php';
22
- require_once 'SassVariableNode.php';
23
- require_once 'SassExtendNode.php';
24
- require_once 'SassEachNode.php';
25
- require_once 'SassForNode.php';
26
- require_once 'SassIfNode.php';
27
- require_once 'SassElseNode.php';
28
- require_once 'SassWhileNode.php';
29
- require_once 'SassNodeExceptions.php';
30
-
31
- require_once 'SassFunctionDefinitionNode.php';
32
- require_once 'SassReturnNode.php';
33
- require_once 'SassContentNode.php';
34
- require_once 'SassWarnNode.php';
35
- require_once 'SassMediaNode.php';
36
-
37
- /**
38
- * SassNode class.
39
- * Base class for all Sass nodes.
40
- * @package PHamlP
41
- * @subpackage Sass.tree
42
- */
43
- class SassNode
44
- {
45
- /**
46
- * @var SassNode parent of this node
47
- */
48
- public $parent;
49
- /**
50
- * @var SassNode root node
51
- */
52
- public $root;
53
- /**
54
- * @var array children of this node
55
- */
56
- public $children = array();
57
- /**
58
- * @var object source token
59
- */
60
- public $token;
61
-
62
- /**
63
- * Constructor.
64
- * @param object source token
65
- * @return SassNode
66
- */
67
- public function __construct($token)
68
- {
69
- $this->token = $token;
70
- }
71
-
72
- /**
73
- * Getter.
74
- * @param string name of property to get
75
- * @return mixed return value of getter function
76
- */
77
- public function __get($name)
78
- {
79
- $getter = 'get' . ucfirst($name);
80
- if (method_exists($this, $getter)) {
81
- return $this->$getter();
82
- }
83
- throw new SassNodeException('No getter function for ' . $name, $this);
84
- }
85
-
86
- /**
87
- * Setter.
88
- * @param string name of property to set
89
- * @return mixed value of property
90
- * @return SassNode this node
91
- */
92
- public function __set($name, $value)
93
- {
94
- $setter = 'set' . ucfirst($name);
95
- if (method_exists($this, $setter)) {
96
- $this->$setter($value);
97
-
98
- return $this;
99
- }
100
- throw new SassNodeException('No setter function for ' . $name, $this);
101
- }
102
-
103
- /**
104
- * Resets children when cloned
105
- * @see parse
106
- */
107
- public function __clone()
108
- {
109
- $this->children = array();
110
- }
111
-
112
- /**
113
- * Return a value indicating if this node has a parent
114
- * @return array the node's parent
115
- */
116
- public function hasParent()
117
- {
118
- return !empty($this->parent);
119
- }
120
-
121
- /**
122
- * Returns the node's parent
123
- * @return array the node's parent
124
- */
125
- public function getParent()
126
- {
127
- return $this->parent;
128
- }
129
-
130
- /**
131
- * Adds a child to this node.
132
- * @return SassNode the child to add
133
- */
134
- public function addChild($child)
135
- {
136
- if ($child instanceof SassElseNode) {
137
- if (!$this->lastChild instanceof SassIfNode) {
138
- throw new SassException('@else(if) directive must come after @(else)if', $child);
139
- }
140
- $this->lastChild->addElse($child);
141
- } else {
142
- $this->children[] = $child;
143
- $child->parent = $this;
144
- $child->root = $this->root;
145
- }
146
- // The child will have children if a debug node has been added
147
- foreach ($child->children as $grandchild) {
148
- $grandchild->root = $this->root;
149
- }
150
- }
151
-
152
- /**
153
- * Returns a value indicating if this node has children
154
- * @return boolean true if the node has children, false if not
155
- */
156
- public function hasChildren()
157
- {
158
- return !empty($this->children);
159
- }
160
-
161
- /**
162
- * Returns the node's children
163
- * @return array the node's children
164
- */
165
- public function getChildren()
166
- {
167
- return $this->children;
168
- }
169
-
170
- /**
171
- * Returns a value indicating if this node is a child of the passed node.
172
- * This just checks the levels of the nodes. If this node is at a greater
173
- * level than the passed node if is a child of it.
174
- * @return boolean true if the node is a child of the passed node, false if not
175
- */
176
- public function isChildOf($node)
177
- {
178
- return $this->level > $node->level;
179
- }
180
-
181
- /**
182
- * Returns the last child node of this node.
183
- * @return SassNode the last child node of this node
184
- */
185
- public function getLastChild()
186
- {
187
- return $this->children[count($this->children) - 1];
188
- }
189
-
190
- /**
191
- * Returns the level of this node.
192
- * @return integer the level of this node
193
- */
194
- public function getLevel()
195
- {
196
- return $this->token->level;
197
- }
198
-
199
- /**
200
- * Returns the source for this node
201
- * @return string the source for this node
202
- */
203
- public function getSource()
204
- {
205
- return $this->token->source;
206
- }
207
-
208
- /**
209
- * Returns the debug_info option setting for this node
210
- * @return boolean the debug_info option setting for this node
211
- */
212
- public function getDebug_info()
213
- {
214
- return $this->parser->debug_info;
215
- }
216
-
217
- /**
218
- * Returns the line number for this node
219
- * @return string the line number for this node
220
- */
221
- public function getLine()
222
- {
223
- return $this->token->line;
224
- }
225
-
226
- /**
227
- * Returns the line_numbers option setting for this node
228
- * @return boolean the line_numbers option setting for this node
229
- */
230
- public function getLine_numbers()
231
- {
232
- return $this->parser->line_numbers;
233
- }
234
-
235
- /**
236
- * Returns the filename for this node
237
- * @return string the filename for this node
238
- */
239
- public function getFilename()
240
- {
241
- return $this->token->filename;
242
- }
243
-
244
- /**
245
- * Returns the Sass parser.
246
- * @return SassParser the Sass parser
247
- */
248
- public function getParser()
249
- {
250
- return $this->root->parser;
251
- }
252
-
253
- /**
254
- * Returns the property syntax being used.
255
- * @return string the property syntax being used
256
- */
257
- public function getPropertySyntax()
258
- {
259
- return $this->root->parser->propertySyntax;
260
- }
261
-
262
- /**
263
- * Returns the SassScript parser.
264
- * @return SassScriptParser the SassScript parser
265
- */
266
- public function getScript()
267
- {
268
- return $this->root->script;
269
- }
270
-
271
- /**
272
- * Returns the renderer.
273
- * @return SassRenderer the renderer
274
- */
275
- public function getRenderer()
276
- {
277
- return $this->root->renderer;
278
- }
279
-
280
- /**
281
- * Returns the render style of the document tree.
282
- * @return string the render style of the document tree
283
- */
284
- public function getStyle()
285
- {
286
- return $this->root->parser->style;
287
- }
288
-
289
- /**
290
- * Returns a value indicating whether this node is in a directive
291
- * @param boolean true if the node is in a directive, false if not
292
- */
293
- public function inDirective()
294
- {
295
- return $this->parent instanceof SassDirectiveNode ||
296
- $this->parent instanceof SassDirectiveNode;
297
- }
298
-
299
- /**
300
- * Returns a value indicating whether this node is in a SassScript directive
301
- * @param boolean true if this node is in a SassScript directive, false if not
302
- */
303
- public function inSassScriptDirective()
304
- {
305
- return $this->parent instanceof SassEachNode ||
306
- $this->parent->parent instanceof SassEachNode ||
307
- $this->parent instanceof SassForNode ||
308
- $this->parent->parent instanceof SassForNode ||
309
- $this->parent instanceof SassIfNode ||
310
- $this->parent->parent instanceof SassIfNode ||
311
- $this->parent instanceof SassWhileNode ||
312
- $this->parent->parent instanceof SassWhileNode;
313
- }
314
-
315
- /**
316
- * Evaluates a SassScript expression.
317
- * @param string expression to evaluate
318
- * @param SassContext the context in which the expression is evaluated
319
- * @return SassLiteral value of parsed expression
320
- */
321
- public function evaluate($expression, $context, $x=null)
322
- {
323
- $context->node = $this;
324
-
325
- return $this->script->evaluate($expression, $context, $x);
326
- }
327
-
328
- /**
329
- * Replace interpolated SassScript contained in '#{}' with the parsed value.
330
- * @param string the text to interpolate
331
- * @param SassContext the context in which the string is interpolated
332
- * @return string the interpolated text
333
- */
334
- public function interpolate($expression, $context)
335
- {
336
- $context->node = $this;
337
-
338
- return $this->script->interpolate($expression, $context);
339
- }
340
-
341
- /**
342
- * Adds a warning to the node.
343
- * @param string warning message
344
- * @param array line
345
- */
346
- public function addWarning($message)
347
- {
348
- $warning = new SassDebugNode($this->token, $message);
349
- $this->addChild($warning);
350
- }
351
-
352
- /**
353
- * Parse the children of the node.
354
- * @param SassContext the context in which the children are parsed
355
- * @return array the parsed child nodes
356
- */
357
- public function parseChildren($context)
358
- {
359
- $children = array();
360
- foreach ($this->children as $child) {
361
- # child could be a SassLiteral /or/ SassNode
362
- if (method_exists($child, 'parse')) {
363
- $kid = $child->parse($context);
364
- } else {
365
- $kid = array($child);
366
- }
367
- $children = array_merge($children, $kid);
368
- }
369
-
370
- return $children;
371
- }
372
-
373
- /**
374
- * Returns a value indicating if the token represents this type of node.
375
- * @param object token
376
- * @return boolean true if the token represents this type of node, false if not
377
- */
378
- public static function isa($token)
379
- {
380
- throw new SassNodeException('Child classes must override this method');
381
- }
382
-
383
- public function printDebugTree($i = 0)
384
- {
385
- echo str_repeat(' ', $i*2).get_class($this)." ".$this->getSource()."\n";
386
- $p = $this->getParent();
387
- if ($p) echo str_repeat(' ', $i*2)." parent: ".get_class($p)."\n";
388
- foreach ($this->getChildren() as $c) {
389
- $c->printDebugTree($i+1);
390
- }
391
- }
392
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tree/SassNodeExceptions.php DELETED
@@ -1,131 +0,0 @@
1
- <?php
2
- /* SVN FILE: $Id$ */
3
- /**
4
- * SassNode exception classes.
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
-
12
- require_once(dirname(__FILE__).'/../SassException.php');
13
-
14
- /**
15
- * SassNodeException class.
16
- * @package PHamlP
17
- * @subpackage Sass.tree
18
- */
19
- class SassNodeException extends SassException {}
20
-
21
- /**
22
- * SassContextException class.
23
- * @package PHamlP
24
- * @subpackage Sass.tree
25
- */
26
- class SassContextException extends SassNodeException {}
27
-
28
- /**
29
- * SassCommentNodeException class.
30
- * @package PHamlP
31
- * @subpackage Sass.tree
32
- */
33
- class SassCommentNodeException extends SassNodeException {}
34
-
35
- /**
36
- * SassDebugNodeException class.
37
- * @package PHamlP
38
- * @subpackage Sass.tree
39
- */
40
- class SassDebugNodeException extends SassNodeException {}
41
-
42
- /**
43
- * SassDirectiveNodeException class.
44
- * @package PHamlP
45
- * @subpackage Sass.tree
46
- */
47
- class SassDirectiveNodeException extends SassNodeException {}
48
-
49
- /**
50
- * SassEachNodeException class.
51
- * @package PHamlP
52
- * @subpackage Sass.tree
53
- */
54
- class SassEachNodeException extends SassNodeException {}
55
-
56
- /**
57
- * SassExtendNodeException class.
58
- * @package PHamlP
59
- * @subpackage Sass.tree
60
- */
61
- class SassExtendNodeException extends SassNodeException {}
62
-
63
- /**
64
- * SassForNodeException class.
65
- * @package PHamlP
66
- * @subpackage Sass.tree
67
- */
68
- class SassForNodeException extends SassNodeException {}
69
-
70
- /**
71
- * SassFunctionDefinitionNodeException class.
72
- * @package PHamlP
73
- * @subpackage Sass.tree
74
- */
75
- class SassFunctionDefinitionNodeException extends SassNodeException {}
76
-
77
- /**
78
- * SassIfNodeException class.
79
- * @package PHamlP
80
- * @subpackage Sass.tree
81
- */
82
- class SassIfNodeException extends SassNodeException {}
83
-
84
- /**
85
- * SassImportNodeException class.
86
- * @package PHamlP
87
- * @subpackage Sass.tree
88
- */
89
- class SassImportNodeException extends SassNodeException {}
90
-
91
- /**
92
- * SassMixinDefinitionNodeException class.
93
- * @package PHamlP
94
- * @subpackage Sass.tree
95
- */
96
- class SassMixinDefinitionNodeException extends SassNodeException {}
97
-
98
- /**
99
- * SassMixinNodeException class.
100
- * @package PHamlP
101
- * @subpackage Sass.tree
102
- */
103
- class SassMixinNodeException extends SassNodeException {}
104
-
105
- /**
106
- * SassPropertyNodeException class.
107
- * @package PHamlP
108
- * @subpackage Sass.tree
109
- */
110
- class SassPropertyNodeException extends SassNodeException {}
111
-
112
- /**
113
- * SassRuleNodeException class.
114
- * @package PHamlP
115
- * @subpackage Sass.tree
116
- */
117
- class SassRuleNodeException extends SassNodeException {}
118
-
119
- /**
120
- * SassVariableNodeException class.
121
- * @package PHamlP
122
- * @subpackage Sass.tree
123
- */
124
- class SassVariableNodeException extends SassNodeException {}
125
-
126
- /**
127
- * SassWhileNodeException class.
128
- * @package PHamlP
129
- * @subpackage Sass.tree
130
- */
131
- class SassWhileNodeException extends SassNodeException {}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tree/SassPropertyNode.php DELETED
@@ -1,276 +0,0 @@
1
- <?php
2
- /* SVN FILE: $Id: SassPropertyNode.php 118 2010-09-21 09:45:11Z chris.l.yates@gmail.com $ */
3
- /**
4
- * SassPropertyNode 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
-
12
- /**
13
- * SassPropertyNode class.
14
- * Represents a CSS property.
15
- * @package PHamlP
16
- * @subpackage Sass.tree
17
- */
18
- class SassPropertyNode extends SassNode
19
- {
20
- const MATCH_PROPERTY_SCSS = '/^([^\s=:"(\\\\:)]*)\s*(?:(= )|:)([^\:].*?)?(\s*!important[^;]*)?;*$/';
21
- const MATCH_PROPERTY_NEW = '/^([^\s=:"]+)\s*(?:(= )|:)([^\:].*?)?(\s*!important[^;]*)?;*$/';
22
- const MATCH_PROPERTY_OLD = '/^:([^\s=:]+)(?:\s*(=)\s*|\s+|$)(.*)(\s*!important.*)?/';
23
- const MATCH_PSUEDO_SELECTOR = '/^:*\w[-\w]+\(?/i';
24
- const MATCH_INTERPOLATION = '/^#\{(.*?)\}/i';
25
- const MATCH_PROPRIETARY_SELECTOR = '/^:?-(moz|webkit|o|ms)-/';
26
- const NAME = 1;
27
- const SCRIPT = 2;
28
- const VALUE = 3;
29
- const IS_SCRIPT = '= ';
30
-
31
- public static $psuedoSelectors = array(
32
- 'root',
33
- 'nth-child(',
34
- 'nth-last-child(',
35
- 'nth-of-type(',
36
- 'nth-last-of-type(',
37
- 'first-child',
38
- 'last-child',
39
- 'first-of-type',
40
- 'last-of-type',
41
- 'only-child',
42
- 'only-of-type',
43
- 'empty',
44
- 'link',
45
- 'visited',
46
- 'active',
47
- 'hover',
48
- 'focus',
49
- 'target',
50
- 'lang(',
51
- 'enabled',
52
- 'disabled',
53
- 'checked',
54
- ':first-line',
55
- ':first-letter',
56
- ':before',
57
- ':after',
58
- // CSS 2.1
59
- 'first-line',
60
- 'first-letter',
61
- 'before',
62
- 'after',
63
- // CSS 3
64
- 'not(',
65
- );
66
-
67
- /**
68
- * @var string property name
69
- */
70
- public $name;
71
- /**
72
- * @var string property value or expression to evaluate
73
- */
74
- public $value;
75
-
76
- /**
77
- * @var boolean, wether the property is important
78
- */
79
- public $important;
80
-
81
- /**
82
- * SassPropertyNode constructor.
83
- * @param object source token
84
- * @param string property syntax
85
- * @return SassPropertyNode
86
- */
87
- public function __construct($token, $syntax = 'new')
88
- {
89
- parent::__construct($token);
90
- $matches = self::match($token, $syntax);
91
- $this->name = @$matches[self::NAME];
92
- if (!isset($matches[self::VALUE])) {
93
- $this->value = '';
94
- } else {
95
- $this->value = $matches[self::VALUE];
96
- if ($matches[self::SCRIPT] === self::IS_SCRIPT) {
97
- $this->addWarning('Setting CSS properties with "=" is deprecated; use "{name}: {value};"',
98
- array('{name}'=>$this->name, '{value}'=>$this->value)
99
- );
100
- }
101
- }
102
- $this->important = trim(array_pop($matches)) == '!important';
103
- }
104
-
105
- /**
106
- * Parse this node.
107
- * If the node is a property namespace return all parsed child nodes. If not
108
- * return the parsed version of this node.
109
- * @param SassContext the context in which this node is parsed
110
- * @return array the parsed node
111
- */
112
- public function parse($context)
113
- {
114
- $return = array();
115
- if ($this->value !== "") {
116
- $node = clone $this;
117
- $node->name = ($this->inNamespace() ? "{$this->namespace}-" : '') . $this->interpolate($this->name, $context);
118
-
119
- $result = $this->evaluate($this->interpolate($this->value, $context), $context, SassScriptParser::CSS_PROPERTY);
120
-
121
- $node->value = $result && is_object($result) ? $result->toString() : $this->value;
122
- $return[] = $node;
123
- }
124
- if ($this->children) {
125
- $return = array_merge($return, $this->parseChildren($context));
126
- }
127
-
128
- return $return;
129
- }
130
-
131
- /**
132
- * Render this node.
133
- * @return string the rendered node
134
- */
135
- public function render()
136
- {
137
- return $this->renderer->renderProperty($this);
138
- }
139
-
140
- /**
141
- * Returns a value indicating if this node is in a namespace
142
- * @return boolean true if this node is in a property namespace, false if not
143
- */
144
- public function inNamespace()
145
- {
146
- $parent = $this->parent;
147
- do {
148
- if ($parent instanceof SassPropertyNode) {
149
- return true;
150
- }
151
- $parent = $parent->parent;
152
- } while (is_object($parent));
153
-
154
- return false;
155
- }
156
-
157
- /**
158
- * Returns the namespace for this node
159
- * @return string the namespace for this node
160
- */
161
- public function getNamespace()
162
- {
163
- $namespace = array();
164
- $parent = $this->parent;
165
- do {
166
- if ($parent instanceof SassPropertyNode) {
167
- $namespace[] = $parent->name;
168
- }
169
- $parent = $parent->parent;
170
- } while (is_object($parent));
171
-
172
- return join('-', array_reverse($namespace));
173
- }
174
-
175
- /**
176
- * Returns the name of this property.
177
- * If the property is in a namespace the namespace is prepended
178
- * @return string the name of this property
179
- */
180
- public function getName()
181
- {
182
- return $this->name;
183
- }
184
-
185
- /**
186
- * Returns the parsed value of this property.
187
- * @return string the parsed value of this property
188
- */
189
- public function getValue()
190
- {
191
- return $this->value;
192
- }
193
-
194
- /**
195
- * Returns a value indicating if the token represents this type of node.
196
- * @param object token
197
- * @param string the property syntax being used
198
- * @return boolean true if the token represents this type of node, false if not
199
- */
200
- public static function isa($token)
201
- {
202
- if (!is_array($token)) {
203
- $syntax = 'old';
204
- } else {
205
- $syntax = $token['syntax'];
206
- $token = $token['token'];
207
- }
208
-
209
- $matches = self::match($token, $syntax);
210
-
211
- if (!empty($matches)) {
212
- if (isset($matches[self::VALUE]) && self::isPseudoSelector($matches[self::VALUE])) {
213
- return false;
214
- }
215
- if ($token->level === 0) {
216
- # RL - if it's on the first level it's probably a false positive, not an error.
217
- # even if it is a genuine error, no need to kill the compiler about it.
218
-
219
- return false;
220
- // throw new SassPropertyNodeException('Properties can not be assigned at root level', $token);
221
- } else {
222
- return true;
223
- }
224
- } else {
225
- return false;
226
- }
227
- }
228
-
229
- /**
230
- * Returns the matches for this type of node.
231
- * @param array the line to match
232
- * @param string the property syntax being used
233
- * @return array matches
234
- */
235
- public static function match($token, $syntax)
236
- {
237
- switch ($syntax) {
238
- case 'scss':
239
- preg_match(self::MATCH_PROPERTY_SCSS, $token->source, $matches);
240
- break;
241
- case 'new':
242
- preg_match(self::MATCH_PROPERTY_NEW, $token->source, $matches);
243
- break;
244
- case 'old':
245
- preg_match(self::MATCH_PROPERTY_OLD, $token->source, $matches);
246
- break;
247
- default:
248
- if (preg_match(self::MATCH_PROPERTY_NEW, $token->source, $matches) == 0) {
249
- preg_match(self::MATCH_PROPERTY_OLD, $token->source, $matches);
250
- }
251
- break;
252
- }
253
-
254
- return $matches;
255
- }
256
-
257
- /**
258
- * Returns a value indicating if the string starts with a pseudo selector.
259
- * This is used to reject pseudo selectors as property values as, for example,
260
- * "a:hover" and "text-decoration:underline" look the same to the property
261
- * match regex.
262
- * It will also match interpolation to allow for constructs such as
263
- * content:#{$pos}
264
- * @see isa()
265
- * @param string the string to test
266
- * @return bool true if the string starts with a pseudo selector, false if not
267
- */
268
- public static function isPseudoSelector($string)
269
- {
270
- preg_match(self::MATCH_PSUEDO_SELECTOR, $string, $matches);
271
-
272
- return (isset($matches[0]) && in_array($matches[0], self::$psuedoSelectors)) ||
273
- preg_match(self::MATCH_INTERPOLATION, $string) ||
274
- preg_match(self::MATCH_PROPRIETARY_SELECTOR, $string);
275
- }
276
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tree/SassReturnNode.php DELETED
@@ -1,86 +0,0 @@
1
- <?php
2
- /* SVN FILE: $Id$ */
3
- /**
4
- * SassReturnNode 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
-
12
- /**
13
- * SassReturnNode class.
14
- * Represents a Return.
15
- * @package PHamlP
16
- * @subpackage Sass.tree
17
- */
18
- class SassReturnNode extends SassNode
19
- {
20
- const NODE_IDENTIFIER = '+';
21
- const MATCH = '/^(@return\s+)(.*)$/i';
22
- const IDENTIFIER = 1;
23
- const STATEMENT = 2;
24
-
25
- /**
26
- * @var statement to execute and return
27
- */
28
- private $statement;
29
-
30
- /**
31
- * SassReturnNode constructor.
32
- * @param object source token
33
- * @return SassReturnNode
34
- */
35
- public function __construct($token)
36
- {
37
- parent::__construct($token);
38
- preg_match(self::MATCH, $token->source, $matches);
39
-
40
- if (empty($matches)) {
41
- return new SassBoolean('false');
42
- }
43
-
44
- $this->statement = $matches[self::STATEMENT];
45
- }
46
-
47
- /**
48
- * Parse this node.
49
- * Set passed arguments and any optional arguments not passed to their
50
- * defaults, then render the children of the return definition.
51
- * @param SassContext the context in which this node is parsed
52
- * @return array the parsed node
53
- */
54
- public function parse($pcontext)
55
- {
56
- $return = $this;
57
- $context = new SassContext($pcontext);
58
- $statement = $this->statement;
59
-
60
- $parent = $this->parent->parent->parser;
61
- $script = $this->parent->parent->script;
62
- $lexer = $script->lexer;
63
-
64
- $result = $script->evaluate($statement, $context);
65
-
66
- throw new SassReturn($result);
67
- }
68
-
69
- /**
70
- * Returns a value indicating if the token represents this type of node.
71
- * @param object token
72
- * @return boolean true if the token represents this type of node, false if not
73
- */
74
- public static function isa($token)
75
- {
76
- return $token->source[0] === self::NODE_IDENTIFIER;
77
- }
78
- }
79
-
80
- class SassReturn extends Exception
81
- {
82
- public function __construct($value)
83
- {
84
- $this->value = $value;
85
- }
86
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tree/SassRootNode.php DELETED
@@ -1,122 +0,0 @@
1
- <?php
2
- /* SVN FILE: $Id$ */
3
- /**
4
- * SassRootNode 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
-
12
- require_once(dirname(__FILE__).'/../script/SassScriptParser.php');
13
- require_once(dirname(__FILE__).'/../renderers/SassRenderer.php');
14
-
15
- /**
16
- * SassRootNode class.
17
- * Also the root node of a document.
18
- * @package PHamlP
19
- * @subpackage Sass.tree
20
- */
21
- class SassRootNode extends SassNode
22
- {
23
- /**
24
- * @var SassScriptParser SassScript parser
25
- */
26
- public $script;
27
- /**
28
- * @var SassRenderer the renderer for this node
29
- */
30
- public $renderer;
31
- /**
32
- * @var SassParser
33
- */
34
- public $parser;
35
- /**
36
- * @var array extenders for this tree in the form extendee=>extender
37
- */
38
- public $extenders = array();
39
-
40
- /**
41
- * Extend_parent - for resolving extends across imported files.
42
- */
43
- public $extend_parent = null;
44
-
45
- /**
46
- * Root SassNode constructor.
47
- * @param SassParser Sass parser
48
- * @return SassNode
49
- */
50
- public function __construct($parser)
51
- {
52
- parent::__construct((object) array(
53
- 'source' => '',
54
- 'level' => -1,
55
- 'filename' => $parser->filename,
56
- 'line' => 0,
57
- ));
58
- $this->parser = $parser;
59
- $this->script = new SassScriptParser();
60
- $this->renderer = SassRenderer::getRenderer($parser->style);
61
- $this->root = $this;
62
- }
63
-
64
- /**
65
- * Parses this node and its children into the render tree.
66
- * Dynamic nodes are evaluated, files imported, etc.
67
- * Only static nodes for rendering are in the resulting tree.
68
- * @param SassContext the context in which this node is parsed
69
- * @return SassNode root node of the render tree
70
- */
71
- public function parse($context)
72
- {
73
- $node = clone $this;
74
- $node->children = $this->parseChildren($context);
75
-
76
- return $node;
77
- }
78
-
79
- /**
80
- * Render this node.
81
- * @return string the rendered node
82
- */
83
- public function render($context = null)
84
- {
85
- $context = new SassContext($context);
86
- $node = $this->parse($context);
87
- $output = '';
88
- foreach ($node->children as $child) {
89
- $output .= $child->render();
90
- } // foreach
91
-
92
- return $output;
93
- }
94
-
95
- public function extend($extendee, $selectors)
96
- {
97
- if ($this->extend_parent && method_exists($this->extend_parent, 'extend')) {
98
- return $this->extend_parent->extend($extendee, $selectors);
99
- }
100
- $this->extenders[$extendee] = (isset($this->extenders[$extendee])
101
- ? array_merge($this->extenders[$extendee], $selectors) : $selectors);
102
- }
103
-
104
- public function getExtenders()
105
- {
106
- if ($this->extend_parent && method_exists($this->extend_parent, 'getExtenders')) {
107
- return $this->extend_parent->getExtenders();
108
- }
109
-
110
- return $this->extenders;
111
- }
112
-
113
- /**
114
- * Returns a value indicating if the line represents this type of node.
115
- * Child classes must override this method.
116
- * @throws SassNodeException if not overriden
117
- */
118
- public static function isa($line)
119
- {
120
- throw new SassNodeException('Child classes must override this method');
121
- }
122
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tree/SassRuleNode.php DELETED
@@ -1,392 +0,0 @@
1
- <?php
2
- /* SVN FILE: $Id$ */
3
- /**
4
- * SassRuleNode 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
-
12
- /**
13
- * SassRuleNode class.
14
- * Represents a CSS rule.
15
- * @package PHamlP
16
- * @subpackage Sass.tree
17
- */
18
- class SassRuleNode extends SassNode
19
- {
20
- const MATCH = '/^(.+?)(?:\s*\{)?$/';
21
- const SELECTOR = 1;
22
- const CONTINUED = ',';
23
-
24
- /**
25
- * @const string that is replaced with the parent node selector
26
- */
27
- const PARENT_REFERENCE = '&';
28
-
29
- /**
30
- * @var array selector(s)
31
- */
32
- private $selectors = array();
33
-
34
- /**
35
- * @var array parent selectors
36
- */
37
- private $parentSelectors = array();
38
-
39
- /**
40
- * @var array resolved selectors
41
- */
42
- private $resolvedSelectors = array();
43
-
44
- /**
45
- * @var boolean whether the node expects more selectors
46
- */
47
- private $isContinued;
48
-
49
- /**
50
- * SassRuleNode constructor.
51
- * @param object source token
52
- * @param string rule selector
53
- * @return SassRuleNode
54
- */
55
- public function __construct($token)
56
- {
57
- parent::__construct($token);
58
- preg_match(self::MATCH, $token->source, $matches);
59
- $this->addSelectors($matches[SassRuleNode::SELECTOR]);
60
- }
61
-
62
- /**
63
- * Adds selector(s) to the rule.
64
- * If the selectors are to continue for the rule the selector must end in a comma
65
- * @param string selector
66
- */
67
- public function addSelectors($selectors, $explode = true)
68
- {
69
- $this->isContinued = substr($selectors, -1) === self::CONTINUED;
70
- $this->selectors = array_merge($this->selectors, $explode ? $this->explode($selectors) : $selectors);
71
- }
72
-
73
- /**
74
- * Returns a value indicating if the selectors for this rule are to be continued.
75
- * @param boolean true if the selectors for this rule are to be continued,
76
- * false if not
77
- */
78
- public function getIsContinued()
79
- {
80
- return $this->isContinued;
81
- }
82
-
83
- /**
84
- * Parse this node and its children into static nodes.
85
- * @param SassContext the context in which this node is parsed
86
- * @return array the parsed node and its children
87
- */
88
- public function parse($context)
89
- {
90
- $node = clone $this;
91
- $node->selectors = $this->resolveSelectors($context);
92
- $node->children = $this->parseChildren($context);
93
-
94
- return array($node);
95
- }
96
-
97
- /**
98
- * Render this node and its children to CSS.
99
- * @return string the rendered node
100
- */
101
- public function render()
102
- {
103
- $this->extend();
104
- $rules = '';
105
- $properties = array();
106
-
107
- foreach ($this->children as $child) {
108
- $child->parent = $this;
109
- if ($child instanceof SassRuleNode) {
110
- $rules .= $child->render();
111
- } else {
112
- $properties[] = $child->render();
113
- }
114
- }
115
-
116
- return $this->renderer->renderRule($this, $properties, $rules);
117
- }
118
-
119
- /**
120
- * Extend this nodes selectors
121
- * $extendee is the subject of the @extend directive
122
- * $extender is the selector that contains the @extend directive
123
- * $selector a selector or selector sequence that is to be extended
124
- */
125
- public function extend()
126
- {
127
- foreach ($this->root->getExtenders() as $extendee => $extenders) {
128
- if ($this->isPsuedo($extendee)) {
129
- $extendee = explode(':', $extendee);
130
- $pattern = preg_quote($extendee[0]).'((\.[-\w]+)*):'.preg_quote($extendee[1]);
131
- } else {
132
- $pattern = preg_quote($extendee);
133
- }
134
-
135
- foreach (preg_grep('/'.$pattern.'/', $this->selectors) as $selector) {
136
- foreach ($extenders as $extender) {
137
- # first if establishes that we are using a placeholder and the extendee begins with a tag
138
- if ($extendee{0} == '%' && $selector{0} != '%' && preg_match('/(^| )[a-zA-Z][^%]*' . preg_quote($extendee) . '([^a-z0-9_-]|$)/', $selector)) {
139
- # the second if establishes that the extender is a tag rather than a class/id
140
- $zero = ord(strtolower(substr($extender, 0, 1))); // cheaper than regex
141
- if ($zero >= 97 && $zero <= 122) {
142
- continue;
143
- }
144
- }
145
- if (is_array($extendee)) {
146
- $this->selectors[] = preg_replace('/(.*?)'.$pattern.'([^a-zA-Z0-9_-]|$)/', '$1' . $extender . '$2', $selector);
147
- } elseif ($this->isSequence($extender) || $this->isSequence($selector)) {
148
- $this->selectors = array_merge($this->selectors, $this->mergeSequence($extender, $extendee, $selector));
149
- } else {
150
- $this->selectors[] = str_replace($extendee, $extender, $selector);
151
- }
152
- }
153
- }
154
- $this->selectors = array_unique($this->selectors);
155
- }
156
- }
157
-
158
- /**
159
- * Tests whether the selector is a psuedo selector
160
- * @param string selector to test
161
- * @return boolean true if the selector is a psuedo selector, false if not
162
- */
163
- private function isPsuedo($selector)
164
- {
165
- return strpos($selector, ':') !== false;
166
- }
167
-
168
- /**
169
- * Tests whether the selector is a sequence selector
170
- * @param string selector to test
171
- * @return boolean true if the selector is a sequence selector, false if not
172
- */
173
- private function isSequence($selector)
174
- {
175
- return strpos($selector, ' ') !== false;
176
- }
177
-
178
- public function isPlaceholder($selector)
179
- {
180
- return strpos($selector, '%') !== false;
181
- }
182
-
183
- /**
184
- * Merges selector sequences
185
- * @param string the extender selector
186
- * @param string selector to extend
187
- * @return array the merged sequences
188
- */
189
- private function mergeSequence($extender, $extendee, $selector)
190
- {
191
- // if it's a placeholder, be lazy. Needs tests.
192
- if ($extendee[0] == '%') {
193
- // need to stop things like a%foo accepting div { @extend %foo }
194
- return array(str_replace($extendee, $extender, $selector));
195
- }
196
-
197
- $extender = explode(' ', $extender);
198
- $end = array_pop($extender);
199
- $selector = explode(' ', $selector);
200
- array_pop($selector);
201
-
202
- $common = array();
203
- if (count($extender) && count($selector)) {
204
- while (trim($extender[0]) === trim($selector[0])) {
205
- $common[] = array_shift($selector);
206
- array_shift($extender);
207
- if (!count($extender)) {
208
- break;
209
- }
210
- }
211
- }
212
-
213
- $beginning = (!empty($common) ? join(' ', $common) . ' ' : '');
214
-
215
- # Richard Lyon - 2011-10-25 - removes duplicates by uniquing and trimming.
216
- # regex removes whitespace from start and and end of string as well as removing
217
- # whitespace following whitespace. slightly quicker than a trim and simpler replace
218
-
219
- return array_unique(array(
220
- preg_replace('/(^\s+|(\s)\s+|\s+$)/', '$2', $beginning.join(' ', $selector).' '.join(' ', $extender). ' ' . $end),
221
- preg_replace('/(^\s+|(\s)\s+|\s+$)/', '$2', $beginning.join(' ', $extender).' '.join(' ', $selector). ' ' . $end)
222
- ));
223
- }
224
-
225
- /**
226
- * Returns the selectors
227
- * @return array selectors
228
- */
229
- public function getSelectors()
230
- {
231
- return $this->selectors;
232
- }
233
-
234
- /**
235
- * Resolves selectors.
236
- * Interpolates SassScript in selectors and resolves any parent references or
237
- * appends the parent selectors.
238
- * @param SassContext the context in which this node is parsed
239
- *
240
- * Change: 7/Dec/11 - change to make selector ordering conform to Ruby compiler.
241
- */
242
- public function resolveSelectors($context)
243
- {
244
- $resolvedSelectors = $normalSelectors = array();
245
- $this->parentSelectors = $this->getParentSelectors($context);
246
-
247
- foreach ($this->selectors as $key=>$selector) {
248
- $selector = $this->interpolate($selector, $context);
249
- $selectors = SassList::_build_list($selector);
250
-
251
- foreach ($selectors as $selector) {
252
- $selector = trim($selector, ' \'"'); // strip whitespace and quotes, just-in-case.
253
- if ($this->hasParentReference($selector)) {
254
- $resolvedSelectors = array_merge($resolvedSelectors, $this->resolveParentReferences($selector, $context));
255
- } else {
256
- $normalSelectors[] = $selector;
257
- }
258
- }
259
- } // foreach
260
-
261
- // merge with parent selectors
262
- if ($this->parentSelectors) {
263
- $return = array();
264
- foreach ($this->parentSelectors as $parent) {
265
- foreach ($normalSelectors as $selector) {
266
- $spacer = (substr($selector, 0, 1) == '[') ? '' : ' ';
267
-
268
- $return[] = $parent . $spacer . $selector;
269
- }
270
- }
271
- $normalSelectors = $return;
272
- }
273
-
274
- return array_merge($normalSelectors, $resolvedSelectors);
275
- }
276
-
277
- /**
278
- * Returns the parent selector(s) for this node.
279
- * This in an empty array if there is no parent selector.
280
- * @return array the parent selector for this node
281
- */
282
- protected function getParentSelectors($context)
283
- {
284
- $ancestor = $this->parent;
285
- while (!$ancestor instanceof SassRuleNode && $ancestor->hasParent()) {
286
- $ancestor = $ancestor->parent;
287
- }
288
-
289
- if ($ancestor instanceof SassRuleNode) {
290
- return $ancestor->resolveSelectors($context);
291
- }
292
-
293
- return array();
294
- }
295
-
296
- /**
297
- * Returns the position of the first parent reference in the selector.
298
- * If there is no parent reference in the selector this function returns
299
- * boolean FALSE.
300
- * Note that the return value may be non-Boolean that evaluates to FALSE,
301
- * i.e. 0. The return value should be tested using the === operator.
302
- * @param string selector to test
303
- * @return mixed integer: position of the the first parent reference,
304
- * boolean: false if there is no parent reference.
305
- */
306
- private function parentReferencePos($selector)
307
- {
308
- $inString = '';
309
- for ($i = 0, $l = strlen($selector); $i < $l; $i++) {
310
- $c = $selector[$i];
311
- if ($c === self::PARENT_REFERENCE && empty($inString)) {
312
- return $i;
313
- } elseif (empty($inString) && ($c === '"' || $c === "'")) {
314
- $inString = $c;
315
- } elseif ($c === $inString) {
316
- $inString = '';
317
- }
318
- }
319
-
320
- return false;
321
- }
322
-
323
- /**
324
- * Determines if there is a parent reference in the selector
325
- * @param string selector
326
- * @return boolean true if there is a parent reference in the selector
327
- */
328
- private function hasParentReference($selector)
329
- {
330
- return $this->parentReferencePos($selector) !== false;
331
- }
332
-
333
- /**
334
- * Resolves parent references in the selector
335
- * @param string selector
336
- * @return string selector with parent references resolved
337
- */
338
- private function resolveParentReferences($selector, $context)
339
- {
340
- $resolvedReferences = array();
341
- if (!count($this->parentSelectors)) {
342
- throw new SassRuleNodeException('Can not use parent selector (' . self::PARENT_REFERENCE . ') when no parent selectors', $this);
343
- }
344
- foreach ($this->getParentSelectors($context) as $parentSelector) {
345
- $resolvedReferences[] = str_replace(self::PARENT_REFERENCE, $parentSelector, $selector);
346
- }
347
-
348
- return $resolvedReferences;
349
- }
350
-
351
- /**
352
- * Explodes a string of selectors into an array.
353
- * We can't use PHP::explode as this will potentially explode attribute
354
- * matches in the selector, e.g. div[title="some,value"] and interpolations.
355
- * @param string selectors
356
- * @return array selectors
357
- */
358
- private function explode($string)
359
- {
360
- $selectors = array();
361
- $inString = false;
362
- $interpolate = false;
363
- $selector = '';
364
-
365
- for ($i = 0, $l = strlen($string); $i < $l; $i++) {
366
- $c = $string[$i];
367
- if ($c === self::CONTINUED && !$inString && !$interpolate) {
368
- $selectors[] = trim($selector);
369
- $selector = '';
370
- } else {
371
- $selector .= $c;
372
- if ($c === '"' || $c === "'") {
373
- do {
374
- $_c = $string[++$i];
375
- $selector .= $_c;
376
- } while ($_c !== $c && isset($string[$i+1]));
377
- } elseif ($c === '#' && $string[$i+1] === '{') {
378
- do {
379
- $c = $string[++$i];
380
- $selector .= $c;
381
- } while ($c !== '}');
382
- }
383
- }
384
- }
385
-
386
- if (!empty($selector)) {
387
- $selectors[] = trim($selector);
388
- }
389
-
390
- return $selectors;
391
- }
392
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tree/SassVariableNode.php DELETED
@@ -1,96 +0,0 @@
1
- <?php
2
- /* SVN FILE: $Id$ */
3
- /**
4
- * SassVariableNode 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
-
12
- /**
13
- * SassVariableNode class.
14
- * Represents a variable.
15
- * @package PHamlP
16
- * @subpackage Sass.tree
17
- */
18
- class SassVariableNode extends SassNode
19
- {
20
- const MATCH = '/^([!$])([\w-]+)\s*:?\s*((\|\|)?=)?\s*(.+?)\s*(!default)?;?$/i';
21
- const IDENTIFIER = 1;
22
- const NAME = 2;
23
- const SASS_ASSIGNMENT = 3;
24
- const SASS_DEFAULT = 4;
25
- const VALUE = 5;
26
- const SCSS_DEFAULT = 6;
27
- const SASS_IDENTIFIER = '!';
28
- const SCSS_IDENTIFIER = '$';
29
-
30
- /**
31
- * @var string name of the variable
32
- */
33
- private $name;
34
- /**
35
- * @var string value of the variable or expression to evaluate
36
- */
37
- private $value;
38
- /**
39
- * @var boolean whether the variable is optionally assigned
40
- */
41
- private $isDefault;
42
-
43
- /**
44
- * SassVariableNode constructor.
45
- * @param object source token
46
- * @return SassVariableNode
47
- */
48
- public function __construct($token)
49
- {
50
- parent::__construct($token);
51
- preg_match(self::MATCH, $token->source, $matches);
52
- if (empty($matches[self::NAME]) || ($matches[self::VALUE] === '')) {
53
- throw new SassVariableNodeException('Invalid variable definition; name and expression required', $this);
54
- }
55
-
56
- $this->name = $matches[self::NAME];
57
- $this->value = $matches[self::VALUE];
58
- $this->isDefault = (!empty($matches[self::SASS_DEFAULT]) || !empty($matches[self::SCSS_DEFAULT]));
59
-
60
- // Warn about deprecated features
61
- if ($matches[self::IDENTIFIER] === self::SASS_IDENTIFIER) {
62
- $this->addWarning('Variables prefixed with "!" is deprecated; use "' . $this->name . '"');
63
- }
64
- if (!empty($matches[SassVariableNode::SASS_ASSIGNMENT])) {
65
- $this->addWarning('Setting variables with "' . (!empty($matches[SassVariableNode::SASS_DEFAULT])?'||':'') . '=" is deprecated; use "$' . $this->name . ': ' . $this->value . (!empty($matches[SassVariableNode::SASS_DEFAULT]) ? ' !default' : ''));
66
- }
67
- }
68
-
69
- /**
70
- * Parse this node.
71
- * Sets the variable in the current context.
72
- * @param SassContext the context in which this node is parsed
73
- * @return array the parsed node - an empty array
74
- */
75
- public function parse($context)
76
- {
77
- if (!$this->isDefault || !$context->hasVariable($this->name)) {
78
- $context->setVariable(
79
- $this->name, $this->evaluate($this->value, $context)
80
- );
81
- }
82
- $this->parseChildren($context); // Parse any warnings
83
-
84
- return array();
85
- }
86
-
87
- /**
88
- * Returns a value indicating if the token represents this type of node.
89
- * @param object token
90
- * @return boolean true if the token represents this type of node, false if not
91
- */
92
- public static function isa($token)
93
- {
94
- return $token->source[0] === self::SASS_IDENTIFIER || $token->source[0] === self::SCSS_IDENTIFIER;
95
- }
96
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tree/SassWarnNode.php DELETED
@@ -1,83 +0,0 @@
1
- <?php
2
- /* SVN FILE: $Id$ */
3
- /**
4
- * SassReturnNode class file.
5
- * @author Richard Lyon <richthegeek@gmail.com>
6
- * @copyright none
7
- * @license http://phamlp.googlecode.com/files/license.txt
8
- * @package PHamlP
9
- * @subpackage Sass.tree
10
- */
11
-
12
- /**
13
- * SassReturnNode class.
14
- * Represents a Return.
15
- * @package PHamlP
16
- * @subpackage Sass.tree
17
- */
18
- class SassWarnNode extends SassNode
19
- {
20
- const NODE_IDENTIFIER = '+';
21
- const MATCH = '/^(@warn\s+)(["\']?)(.*?)(["\']?)$/i';
22
- const IDENTIFIER = 1;
23
- const STATEMENT = 3;
24
-
25
- /**
26
- * @var statement to execute and return
27
- */
28
- private $statement;
29
-
30
- /**
31
- * SassReturnNode constructor.
32
- * @param object source token
33
- * @return SassReturnNode
34
- */
35
- public function __construct($token)
36
- {
37
- parent::__construct($token);
38
- preg_match(self::MATCH, $token->source, $matches);
39
-
40
- if (empty($matches)) {
41
- return new SassBoolean('false');
42
- }
43
-
44
- $this->statement = $matches[self::STATEMENT];
45
- }
46
-
47
- /**
48
- * Parse this node.
49
- * Set passed arguments and any optional arguments not passed to their
50
- * defaults, then render the children of the return definition.
51
- * @param SassContext the context in which this node is parsed
52
- * @return array the parsed node
53
- */
54
- public function parse($pcontext)
55
- {
56
- $context = new SassContext($pcontext);
57
- $statement = $this->statement;
58
-
59
- try {
60
- $statement = $this->evaluate($this->statement, $context)->toString();
61
- } catch (Exception $e) {}
62
-
63
- if (SassParser::$instance->options['callbacks']['warn']) {
64
- call_user_func(SassParser::$instance->options['callbacks']['warn'], $statement, $context);
65
- }
66
-
67
- if (SassParser::$instance->getQuiet()) {
68
- return array(new SassString(''));
69
- } else {
70
- return array(new SassString('/* @warn: ' . str_replace('*/', '', $statement) . ' */'));
71
- }
72
- }
73
-
74
- /**
75
- * Returns a value indicating if the token represents this type of node.
76
- * @param object token
77
- * @return boolean true if the token represents this type of node, false if not
78
- */
79
- public static function isa($token)
80
- {
81
- return $token->source[0] === self::NODE_IDENTIFIER;
82
- }
83
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/phpsass/tree/SassWhileNode.php DELETED
@@ -1,67 +0,0 @@
1
- <?php
2
- /* SVN FILE: $Id$ */
3
- /**
4
- * SassWhileNode 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
-
12
- /**
13
- * SassWhileNode class.
14
- * Represents a Sass @while loop and a Sass @do loop.
15
- * @package PHamlP
16
- * @subpackage Sass.tree
17
- */
18
- class SassWhileNode extends SassNode
19
- {
20
- const MATCH = '/^@(do|while)\s+(.+)$/i';
21
- const LOOP = 1;
22
- const EXPRESSION = 2;
23
- const IS_DO = 'do';
24
- /**
25
- * @var boolean whether this is a do/while.
26
- * A do/while loop is guarenteed to run at least once.
27
- */
28
- private $isDo;
29
- /**
30
- * @var string expression to evaluate
31
- */
32
- private $expression;
33
-
34
- /**
35
- * SassWhileNode constructor.
36
- * @param object source token
37
- * @return SassWhileNode
38
- */
39
- public function __construct($token)
40
- {
41
- parent::__construct($token);
42
- preg_match(self::MATCH, $token->source, $matches);
43
- $this->expression = $matches[self::EXPRESSION];
44
- $this->isDo = ($matches[self::LOOP] === SassWhileNode::IS_DO);
45
- }
46
-
47
- /**
48
- * Parse this node.
49
- * @param SassContext the context in which this node is parsed
50
- * @return array the parsed child nodes
51
- */
52
- public function parse($context)
53
- {
54
- $children = array();
55
- if ($this->isDo) {
56
- do {
57
- $children = array_merge($children, $this->parseChildren($context));
58
- } while ($this->evaluate($this->expression, $context)->toBoolean());
59
- } else {
60
- while ($this->evaluate($this->expression, $context)->toBoolean()) {
61
- $children = array_merge($children, $this->parseChildren($context));
62
- }
63
- }
64
-
65
- return $children;
66
- }
67
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
lib/scssphp/.travis.yml ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ language: php
2
+
3
+ php:
4
+ - 5.3
5
+ - 5.4
6
+ - 5.5
7
+ # - hhvm
8
+
9
+ script:
10
+ - phpunit tests
lib/scssphp/LICENSE.md ADDED
@@ -0,0 +1,660 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ For ease of distribution, scssphp is available under a dual license.
2
+ You are free to pick which one suits your needs.
3
+
4
+ * * *
5
+
6
+
7
+ MIT LICENSE
8
+
9
+
10
+
11
+
12
+ Copyright (c) 2012 Leaf Corcoran, http://leafo.net/scssphp
13
+
14
+ Permission is hereby granted, free of charge, to any person obtaining
15
+ a copy of this software and associated documentation files (the
16
+ "Software"), to deal in the Software without restriction, including
17
+ without limitation the rights to use, copy, modify, merge, publish,
18
+ distribute, sublicense, and/or sell copies of the Software, and to
19
+ permit persons to whom the Software is furnished to do so, subject to
20
+ the following conditions:
21
+
22
+ The above copyright notice and this permission notice shall be
23
+ included in all copies or substantial portions of the Software.
24
+
25
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32
+
33
+ * * *
34
+
35
+
36
+ GPL VERSION 3
37
+
38
+
39
+
40
+
41
+ GNU GENERAL PUBLIC LICENSE
42
+ Version 3, 29 June 2007
43
+
44
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
45
+ Everyone is permitted to copy and distribute verbatim copies
46
+ of this license document, but changing it is not allowed.
47
+
48
+ Preamble
49
+
50
+ The GNU General Public License is a free, copyleft license for
51
+ software and other kinds of works.
52
+
53
+ The licenses for most software and other practical works are designed
54
+ to take away your freedom to share and change the works. By contrast,
55
+ the GNU General Public License is intended to guarantee your freedom to
56
+ share and change all versions of a program--to make sure it remains free
57
+ software for all its users. We, the Free Software Foundation, use the
58
+ GNU General Public License for most of our software; it applies also to
59
+ any other work released this way by its authors. You can apply it to
60
+ your programs, too.
61
+
62
+ When we speak of free software, we are referring to freedom, not
63
+ price. Our General Public Licenses are designed to make sure that you
64
+ have the freedom to distribute copies of free software (and charge for
65
+ them if you wish), that you receive source code or can get it if you
66
+ want it, that you can change the software or use pieces of it in new
67
+ free programs, and that you know you can do these things.
68
+
69
+ To protect your rights, we need to prevent others from denying you
70
+ these rights or asking you to surrender the rights. Therefore, you have
71
+ certain responsibilities if you distribute copies of the software, or if
72
+ you modify it: responsibilities to respect the freedom of others.
73
+
74
+ For example, if you distribute copies of such a program, whether
75
+ gratis or for a fee, you must pass on to the recipients the same
76
+ freedoms that you received. You must make sure that they, too, receive
77
+ or can get the source code. And you must show them these terms so they
78
+ know their rights.
79
+
80
+ Developers that use the GNU GPL protect your rights with two steps:
81
+ (1) assert copyright on the software, and (2) offer you this License
82
+ giving you legal permission to copy, distribute and/or modify it.
83
+
84
+ For the developers' and authors' protection, the GPL clearly explains
85
+ that there is no warranty for this free software. For both users' and
86
+ authors' sake, the GPL requires that modified versions be marked as
87
+ changed, so that their problems will not be attributed erroneously to
88
+ authors of previous versions.
89
+
90
+ Some devices are designed to deny users access to install or run
91
+ modified versions of the software inside them, although the manufacturer
92
+ can do so. This is fundamentally incompatible with the aim of
93
+ protecting users' freedom to change the software. The systematic
94
+ pattern of such abuse occurs in the area of products for individuals to
95
+ use, which is precisely where it is most unacceptable. Therefore, we
96
+ have designed this version of the GPL to prohibit the practice for those
97
+ products. If such problems arise substantially in other domains, we
98
+ stand ready to extend this provision to those domains in future versions
99
+ of the GPL, as needed to protect the freedom of users.
100
+
101
+ Finally, every program is threatened constantly by software patents.
102
+ States should not allow patents to restrict development and use of
103
+ software on general-purpose computers, but in those that do, we wish to
104
+ avoid the special danger that patents applied to a free program could
105
+ make it effectively proprietary. To prevent this, the GPL assures that
106
+ patents cannot be used to render the program non-free.
107
+
108
+ The precise terms and conditions for copying, distribution and
109
+ modification follow.
110
+
111
+ TERMS AND CONDITIONS
112
+
113
+ 0. Definitions.
114
+
115
+ "This License" refers to version 3 of the GNU General Public License.
116
+
117
+ "Copyright" also means copyright-like laws that apply to other kinds of
118
+ works, such as semiconductor masks.
119
+
120
+ "The Program" refers to any copyrightable work licensed under this
121
+ License. Each licensee is addressed as "you". "Licensees" and
122
+ "recipients" may be individuals or organizations.
123
+
124
+ To "modify" a work means to copy from or adapt all or part of the work
125
+ in a fashion requiring copyright permission, other than the making of an
126
+ exact copy. The resulting work is called a "modified version" of the
127
+ earlier work or a work "based on" the earlier work.
128
+
129
+ A "covered work" means either the unmodified Program or a work based
130
+ on the Program.
131
+
132
+ To "propagate" a work means to do anything with it that, without
133
+ permission, would make you directly or secondarily liable for
134
+ infringement under applicable copyright law, except executing it on a
135
+ computer or modifying a private copy. Propagation includes copying,
136
+ distribution (with or without modification), making available to the
137
+ public, and in some countries other activities as well.
138
+
139
+ To "convey" a work means any kind of propagation that enables other
140
+ parties to make or receive copies. Mere interaction with a user through
141
+ a computer network, with no transfer of a copy, is not conveying.
142
+
143
+ An interactive user interface displays "Appropriate Legal Notices"
144
+ to the extent that it includes a convenient and prominently visible
145
+ feature that (1) displays an appropriate copyright notice, and (2)
146
+ tells the user that there is no warranty for the work (except to the
147
+ extent that warranties are provided), that licensees may convey the
148
+ work under this License, and how to view a copy of this License. If
149
+ the interface presents a list of user commands or options, such as a
150
+ menu, a prominent item in the list meets this criterion.
151
+
152
+ 1. Source Code.
153
+
154
+ The "source code" for a work means the preferred form of the work
155
+ for making modifications to it. "Object code" means any non-source
156
+ form of a work.
157
+
158
+ A "Standard Interface" means an interface that either is an official
159
+ standard defined by a recognized standards body, or, in the case of
160
+ interfaces specified for a particular programming language, one that
161
+ is widely used among developers working in that language.
162
+
163
+ The "System Libraries" of an executable work include anything, other
164
+ than the work as a whole, that (a) is included in the normal form of
165
+ packaging a Major Component, but which is not part of that Major
166
+ Component, and (b) serves only to enable use of the work with that
167
+ Major Component, or to implement a Standard Interface for which an
168
+ implementation is available to the public in source code form. A
169
+ "Major Component", in this context, means a major essential component
170
+ (kernel, window system, and so on) of the specific operating system
171
+ (if any) on which the executable work runs, or a compiler used to
172
+ produce the work, or an object code interpreter used to run it.
173
+
174
+ The "Corresponding Source" for a work in object code form means all
175
+ the source code needed to generate, install, and (for an executable
176
+ work) run the object code and to modify the work, including scripts to
177
+ control those activities. However, it does not include the work's
178
+ System Libraries, or general-purpose tools or generally available free
179
+ programs which are used unmodified in performing those activities but
180
+ which are not part of the work. For example, Corresponding Source
181
+ includes interface definition files associated with source files for
182
+ the work, and the source code for shared libraries and dynamically
183
+ linked subprograms that the work is specifically designed to require,
184
+ such as by intimate data communication or control flow between those
185
+ subprograms and other parts of the work.
186
+
187
+ The Corresponding Source need not include anything that users
188
+ can regenerate automatically from other parts of the Corresponding
189
+ Source.
190
+
191
+ The Corresponding Source for a work in source code form is that
192
+ same work.
193
+
194
+ 2. Basic Permissions.
195
+
196
+ All rights granted under this License are granted for the term of
197
+ copyright on the Program, and are irrevocable provided the stated
198
+ conditions are met. This License explicitly affirms your unlimited
199
+ permission to run the unmodified Program. The output from running a
200
+ covered work is covered by this License only if the output, given its
201
+ content, constitutes a covered work. This License acknowledges your
202
+ rights of fair use or other equivalent, as provided by copyright law.
203
+
204
+ You may make, run and propagate covered works that you do not
205
+ convey, without conditions so long as your license otherwise remains
206
+ in force. You may convey covered works to others for the sole purpose
207
+ of having them make modifications exclusively for you, or provide you
208
+ with facilities for running those works, provided that you comply with
209
+ the terms of this License in conveying all material for which you do
210
+ not control copyright. Those thus making or running the covered works
211
+ for you must do so exclusively on your behalf, under your direction
212
+ and control, on terms that prohibit them from making any copies of
213
+ your copyrighted material outside their relationship with you.
214
+
215
+ Conveying under any other circumstances is permitted solely under
216
+ the conditions stated below. Sublicensing is not allowed; section 10
217
+ makes it unnecessary.
218
+
219
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
220
+
221
+ No covered work shall be deemed part of an effective technological
222
+ measure under any applicable law fulfilling obligations under article
223
+ 11 of the WIPO copyright treaty adopted on 20 December 1996, or
224
+ similar laws prohibiting or restricting circumvention of such
225
+ measures.
226
+
227
+ When you convey a covered work, you waive any legal power to forbid
228
+ circumvention of technological measures to the extent such circumvention
229
+ is effected by exercising rights under this License with respect to
230
+ the covered work, and you disclaim any intention to limit operation or
231
+ modification of the work as a means of enforcing, against the work's
232
+ users, your or third parties' legal rights to forbid circumvention of
233
+ technological measures.
234
+
235
+ 4. Conveying Verbatim Copies.
236
+
237
+ You may convey verbatim copies of the Program's source code as you
238
+ receive it, in any medium, provided that you conspicuously and
239
+ appropriately publish on each copy an appropriate copyright notice;
240
+ keep intact all notices stating that this License and any
241
+ non-permissive terms added in accord with section 7 apply to the code;
242
+ keep intact all notices of the absence of any warranty; and give all
243
+ recipients a copy of this License along with the Program.
244
+
245
+ You may charge any price or no price for each copy that you convey,
246
+ and you may offer support or warranty protection for a fee.
247
+
248
+ 5. Conveying Modified Source Versions.
249
+
250
+ You may convey a work based on the Program, or the modifications to
251
+ produce it from the Program, in the form of source code under the
252
+ terms of section 4, provided that you also meet all of these conditions:
253
+
254
+ a) The work must carry prominent notices stating that you modified
255
+ it, and giving a relevant date.
256
+
257
+ b) The work must carry prominent notices stating that it is
258
+ released under this License and any conditions added under section
259
+ 7. This requirement modifies the requirement in section 4 to
260
+ "keep intact all notices".
261
+
262
+ c) You must license the entire work, as a whole, under this
263
+ License to anyone who comes into possession of a copy. This
264
+ License will therefore apply, along with any applicable section 7
265
+ additional terms, to the whole of the work, and all its parts,
266
+ regardless of how they are packaged. This License gives no
267
+ permission to license the work in any other way, but it does not
268
+ invalidate such permission if you have separately received it.
269
+
270
+ d) If the work has interactive user interfaces, each must display
271
+ Appropriate Legal Notices; however, if the Program has interactive
272
+ interfaces that do not display Appropriate Legal Notices, your
273
+ work need not make them do so.
274
+
275
+ A compilation of a covered work with other separate and independent
276
+ works, which are not by their nature extensions of the covered work,
277
+ and which are not combined with it such as to form a larger program,
278
+ in or on a volume of a storage or distribution medium, is called an
279
+ "aggregate" if the compilation and its resulting copyright are not
280
+ used to limit the access or legal rights of the compilation's users
281
+ beyond what the individual works permit. Inclusion of a covered work
282
+ in an aggregate does not cause this License to apply to the other
283
+ parts of the aggregate.
284
+
285
+ 6. Conveying Non-Source Forms.
286
+
287
+ You may convey a covered work in object code form under the terms
288
+ of sections 4 and 5, provided that you also convey the
289
+ machine-readable Corresponding Source under the terms of this License,
290
+ in one of these ways:
291
+
292
+ a) Convey the object code in, or embodied in, a physical product
293
+ (including a physical distribution medium), accompanied by the
294
+ Corresponding Source fixed on a durable physical medium
295
+ customarily used for software interchange.
296
+
297
+ b) Convey the object code in, or embodied in, a physical product
298
+ (including a physical distribution medium), accompanied by a
299
+ written offer, valid for at least three years and valid for as
300
+ long as you offer spare parts or customer support for that product
301
+ model, to give anyone who possesses the object code either (1) a
302
+ copy of the Corresponding Source for all the software in the
303
+ product that is covered by this License, on a durable physical
304
+ medium customarily used for software interchange, for a price no
305
+ more than your reasonable cost of physically performing this
306
+ conveying of source, or (2) access to copy the
307
+ Corresponding Source from a network server at no charge.
308
+
309
+ c) Convey individual copies of the object code with a copy of the
310
+ written offer to provide the Corresponding Source. This
311
+ alternative is allowed only occasionally and noncommercially, and
312
+ only if you received the object code with such an offer, in accord
313
+ with subsection 6b.
314
+
315
+ d) Convey the object code by offering access from a designated
316
+ place (gratis or for a charge), and offer equivalent access to the
317
+ Corresponding Source in the same way through the same place at no
318
+ further charge. You need not require recipients to copy the
319
+ Corresponding Source along with the object code. If the place to
320
+ copy the object code is a network server, the Corresponding Source
321
+ may be on a different server (operated by you or a third party)
322
+ that supports equivalent copying facilities, provided you maintain
323
+ clear directions next to the object code saying where to find the
324
+ Corresponding Source. Regardless of what server hosts the
325
+ Corresponding Source, you remain obligated to ensure that it is
326
+ available for as long as needed to satisfy these requirements.
327
+
328
+ e) Convey the object code using peer-to-peer transmission, provided
329
+ you inform other peers where the object code and Corresponding
330
+ Source of the work are being offered to the general public at no
331
+ charge under subsection 6d.
332
+
333
+ A separable portion of the object code, whose source code is excluded
334
+ from the Corresponding Source as a System Library, need not be
335
+ included in conveying the object code work.
336
+
337
+ A "User Product" is either (1) a "consumer product", which means any
338
+ tangible personal property which is normally used for personal, family,
339
+ or household purposes, or (2) anything designed or sold for incorporation
340
+ into a dwelling. In determining whether a product is a consumer product,
341
+ doubtful cases shall be resolved in favor of coverage. For a particular
342
+ product received by a particular user, "normally used" refers to a
343
+ typical or common use of that class of product, regardless of the status
344
+ of the particular user or of the way in which the particular user
345
+ actually uses, or expects or is expected to use, the product. A product
346
+ is a consumer product regardless of whether the product has substantial
347
+ commercial, industrial or non-consumer uses, unless such uses represent
348
+ the only significant mode of use of the product.
349
+
350
+ "Installation Information" for a User Product means any methods,
351
+ procedures, authorization keys, or other information required to install
352
+ and execute modified versions of a covered work in that User Product from
353
+ a modified version of its Corresponding Source. The information must
354
+ suffice to ensure that the continued functioning of the modified object
355
+ code is in no case prevented or interfered with solely because
356
+ modification has been made.
357
+
358
+ If you convey an object code work under this section in, or with, or
359
+ specifically for use in, a User Product, and the conveying occurs as
360
+ part of a transaction in which the right of possession and use of the
361
+ User Product is transferred to the recipient in perpetuity or for a
362
+ fixed term (regardless of how the transaction is characterized), the
363
+ Corresponding Source conveyed under this section must be accompanied
364
+ by the Installation Information. But this requirement does not apply
365
+ if neither you nor any third party retains the ability to install
366
+ modified object code on the User Product (for example, the work has
367
+ been installed in ROM).
368
+
369
+ The requirement to provide Installation Information does not include a
370
+ requirement to continue to provide support service, warranty, or updates
371
+ for a work that has been modified or installed by the recipient, or for
372
+ the User Product in which it has been modified or installed. Access to a
373
+ network may be denied when the modification itself materially and
374
+ adversely affects the operation of the network or violates the rules and
375
+ protocols for communication across the network.
376
+
377
+ Corresponding Source conveyed, and Installation Information provided,
378
+ in accord with this section must be in a format that is publicly
379
+ documented (and with an implementation available to the public in
380
+ source code form), and must require no special password or key for
381
+ unpacking, reading or copying.
382
+
383
+ 7. Additional Terms.
384
+
385
+ "Additional permissions" are terms that supplement the terms of this
386
+ License by making exceptions from one or more of its conditions.
387
+ Additional permissions that are applicable to the entire Program shall
388
+ be treated as though they were included in this License, to the extent
389
+ that they are valid under applicable law. If additional permissions
390
+ apply only to part of the Program, that part may be used separately
391
+ under those permissions, but the entire Program remains governed by
392
+ this License without regard to the additional permissions.
393
+
394
+ When you convey a copy of a covered work, you may at your option
395
+ remove any additional permissions from that copy, or from any part of
396
+ it. (Additional permissions may be written to require their own
397
+ removal in certain cases when you modify the work.) You may place
398
+ additional permissions on material, added by you to a covered work,
399
+ for which you have or can give appropriate copyright permission.
400
+
401
+ Notwithstanding any other provision of this License, for material you
402
+ add to a covered work, you may (if authorized by the copyright holders of
403
+ that material) supplement the terms of this License with terms:
404
+
405
+ a) Disclaiming warranty or limiting liability differently from the
406
+ terms of sections 15 and 16 of this License; or
407
+
408
+ b) Requiring preservation of specified reasonable legal notices or
409
+ author attributions in that material or in the Appropriate Legal
410
+ Notices displayed by works containing it; or
411
+
412
+ c) Prohibiting misrepresentation of the origin of that material, or
413
+ requiring that modified versions of such material be marked in
414
+ reasonable ways as different from the original version; or
415
+
416
+ d) Limiting the use for publicity purposes of names of licensors or
417
+ authors of the material; or
418
+
419
+ e) Declining to grant rights under trademark law for use of some
420
+ trade names, trademarks, or service marks; or
421
+
422
+ f) Requiring indemnification of licensors and authors of that
423
+ material by anyone who conveys the material (or modified versions of
424
+ it) with contractual assumptions of liability to the recipient, for
425
+ any liability that these contractual assumptions directly impose on
426
+ those licensors and authors.
427
+
428
+ All other non-permissive additional terms are considered "further
429
+ restrictions" within the meaning of section 10. If the Program as you
430
+ received it, or any part of it, contains a notice stating that it is
431
+ governed by this License along with a term that is a further
432
+ restriction, you may remove that term. If a license document contains
433
+ a further restriction but permits relicensing or conveying under this
434
+ License, you may add to a covered work material governed by the terms
435
+ of that license document, provided that the further restriction does
436
+ not survive such relicensing or conveying.
437
+
438
+ If you add terms to a covered work in accord with this section, you
439
+ must place, in the relevant source files, a statement of the
440
+ additional terms that apply to those files, or a notice indicating
441
+ where to find the applicable terms.
442
+
443
+ Additional terms, permissive or non-permissive, may be stated in the
444
+ form of a separately written license, or stated as exceptions;
445
+ the above requirements apply either way.
446
+
447
+ 8. Termination.
448
+
449
+ You may not propagate or modify a covered work except as expressly
450
+ provided under this License. Any attempt otherwise to propagate or
451
+ modify it is void, and will automatically terminate your rights under
452
+ this License (including any patent licenses granted under the third
453
+ paragraph of section 11).
454
+
455
+ However, if you cease all violation of this License, then your
456
+ license from a particular copyright holder is reinstated (a)
457
+ provisionally, unless and until the copyright holder explicitly and
458
+ finally terminates your license, and (b) permanently, if the copyright
459
+ holder fails to notify you of the violation by some reasonable means
460
+ prior to 60 days after the cessation.
461
+
462
+ Moreover, your license from a particular copyright holder is
463
+ reinstated permanently if the copyright holder notifies you of the
464
+ violation by some reasonable means, this is the first time you have
465
+ received notice of violation of this License (for any work) from that
466
+ copyright holder, and you cure the violation prior to 30 days after
467
+ your receipt of the notice.
468
+
469
+ Termination of your rights under this section does not terminate the
470
+ licenses of parties who have received copies or rights from you under
471
+ this License. If your rights have been terminated and not permanently
472
+ reinstated, you do not qualify to receive new licenses for the same
473
+ material under section 10.
474
+
475
+ 9. Acceptance Not Required for Having Copies.
476
+
477
+ You are not required to accept this License in order to receive or
478
+ run a copy of the Program. Ancillary propagation of a covered work
479
+ occurring solely as a consequence of using peer-to-peer transmission
480
+ to receive a copy likewise does not require acceptance. However,
481
+ nothing other than this License grants you permission to propagate or
482
+ modify any covered work. These actions infringe copyright if you do
483
+ not accept this License. Therefore, by modifying or propagating a
484
+ covered work, you indicate your acceptance of this License to do so.
485
+
486
+ 10. Automatic Licensing of Downstream Recipients.
487
+
488
+ Each time you convey a covered work, the recipient automatically
489
+ receives a license from the original licensors, to run, modify and
490
+ propagate that work, subject to this License. You are not responsible
491
+ for enforcing compliance by third parties with this License.
492
+
493
+ An "entity transaction" is a transaction transferring control of an
494
+ organization, or substantially all assets of one, or subdividing an
495
+ organization, or merging organizations. If propagation of a covered
496
+ work results from an entity transaction, each party to that
497
+ transaction who receives a copy of the work also receives whatever
498
+ licenses to the work the party's predecessor in interest had or could
499
+ give under the previous paragraph, plus a right to possession of the
500
+ Corresponding Source of the work from the predecessor in interest, if
501
+ the predecessor has it or can get it with reasonable efforts.
502
+
503
+ You may not impose any further restrictions on the exercise of the
504
+ rights granted or affirmed under this License. For example, you may
505
+ not impose a license fee, royalty, or other charge for exercise of
506
+ rights granted under this License, and you may not initiate litigation
507
+ (including a cross-claim or counterclaim in a lawsuit) alleging that
508
+ any patent claim is infringed by making, using, selling, offering for
509
+ sale, or importing the Program or any portion of it.
510
+
511
+ 11. Patents.
512
+
513
+ A "contributor" is a copyright holder who authorizes use under this
514
+ License of the Program or a work on which the Program is based. The
515
+ work thus licensed is called the contributor's "contributor version".
516
+
517
+ A contributor's "essential patent claims" are all patent claims
518
+ owned or controlled by the contributor, whether already acquired or
519
+ hereafter acquired, that would be infringed by some manner, permitted
520
+ by this License, of making, using, or selling its contributor version,
521
+ but do not include claims that would be infringed only as a
522
+ consequence of further modification of the contributor version. For
523
+ purposes of this definition, "control" includes the right to grant
524
+ patent sublicenses in a manner consistent with the requirements of
525
+ this License.
526
+
527
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
528
+ patent license under the contributor's essential patent claims, to
529
+ make, use, sell, offer for sale, import and otherwise run, modify and
530
+ propagate the contents of its contributor version.
531
+
532
+ In the following three paragraphs, a "patent license" is any express
533
+ agreement or commitment, however denominated, not to enforce a patent
534
+ (such as an express permission to practice a patent or covenant not to
535
+ sue for patent infringement). To "grant" such a patent license to a
536
+ party means to make such an agreement or commitment not to enforce a
537
+ patent against the party.
538
+
539
+ If you convey a covered work, knowingly relying on a patent license,
540
+ and the Corresponding Source of the work is not available for anyone
541
+ to copy, free of charge and under the terms of this License, through a
542
+ publicly available network server or other readily accessible means,
543
+ then you must either (1) cause the Corresponding Source to be so
544
+ available, or (2) arrange to deprive yourself of the benefit of the
545
+ patent license for this particular work, or (3) arrange, in a manner
546
+ consistent with the requirements of this License, to extend the patent
547
+ license to downstream recipients. "Knowingly relying" means you have
548
+ actual knowledge that, but for the patent license, your conveying the
549
+ covered work in a country, or your recipient's use of the covered work
550
+ in a country, would infringe one or more identifiable patents in that
551
+ country that you have reason to believe are valid.
552
+
553
+ If, pursuant to or in connection with a single transaction or
554
+ arrangement, you convey, or propagate by procuring conveyance of, a
555
+ covered work, and grant a patent license to some of the parties
556
+ receiving the covered work authorizing them to use, propagate, modify
557
+ or convey a specific copy of the covered work, then the patent license
558
+ you grant is automatically extended to all recipients of the covered
559
+ work and works based on it.
560
+
561
+ A patent license is "discriminatory" if it does not include within
562
+ the scope of its coverage, prohibits the exercise of, or is
563
+ conditioned on the non-exercise of one or more of the rights that are
564
+ specifically granted under this License. You may not convey a covered
565
+ work if you are a party to an arrangement with a third party that is
566
+ in the business of distributing software, under which you make payment
567
+ to the third party based on the extent of your activity of conveying
568
+ the work, and under which the third party grants, to any of the
569
+ parties who would receive the covered work from you, a discriminatory
570
+ patent license (a) in connection with copies of the covered work
571
+ conveyed by you (or copies made from those copies), or (b) primarily
572
+ for and in connection with specific products or compilations that
573
+ contain the covered work, unless you entered into that arrangement,
574
+ or that patent license was granted, prior to 28 March 2007.
575
+
576
+ Nothing in this License shall be construed as excluding or limiting
577
+ any implied license or other defenses to infringement that may
578
+ otherwise be available to you under applicable patent law.
579
+
580
+ 12. No Surrender of Others' Freedom.
581
+
582
+ If conditions are imposed on you (whether by court order, agreement or
583
+ otherwise) that contradict the conditions of this License, they do not
584
+ excuse you from the conditions of this License. If you cannot convey a
585
+ covered work so as to satisfy simultaneously your obligations under this
586
+ License and any other pertinent obligations, then as a consequence you may
587
+ not convey it at all. For example, if you agree to terms that obligate you
588
+ to collect a royalty for further conveying from those to whom you convey
589
+ the Program, the only way you could satisfy both those terms and this
590
+ License would be to refrain entirely from conveying the Program.
591
+
592
+ 13. Use with the GNU Affero General Public License.
593
+
594
+ Notwithstanding any other provision of this License, you have
595
+ permission to link or combine any covered work with a work licensed
596
+ under version 3 of the GNU Affero General Public License into a single
597
+ combined work, and to convey the resulting work. The terms of this
598
+ License will continue to apply to the part which is the covered work,
599
+ but the special requirements of the GNU Affero General Public License,
600
+ section 13, concerning interaction through a network will apply to the
601
+ combination as such.
602
+
603
+ 14. Revised Versions of this License.
604
+
605
+ The Free Software Foundation may publish revised and/or new versions of
606
+ the GNU General Public License from time to time. Such new versions will
607
+ be similar in spirit to the present version, but may differ in detail to
608
+ address new problems or concerns.
609
+
610
+ Each version is given a distinguishing version number. If the
611
+ Program specifies that a certain numbered version of the GNU General
612
+ Public License "or any later version" applies to it, you have the
613
+ option of following the terms and conditions either of that numbered
614
+ version or of any later version published by the Free Software
615
+ Foundation. If the Program does not specify a version number of the
616
+ GNU General Public License, you may choose any version ever published
617
+ by the Free Software Foundation.
618
+
619
+ If the Program specifies that a proxy can decide which future
620
+ versions of the GNU General Public License can be used, that proxy's
621
+ public statement of acceptance of a version permanently authorizes you
622
+ to choose that version for the Program.
623
+
624
+ Later license versions may give you additional or different
625
+ permissions. However, no additional obligations are imposed on any
626
+ author or copyright holder as a result of your choosing to follow a
627
+ later version.
628
+
629
+ 15. Disclaimer of Warranty.
630
+
631
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
632
+ APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
633
+ HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
634
+ OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
635
+ THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
636
+ PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
637
+ IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
638
+ ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
639
+
640
+ 16. Limitation of Liability.
641
+
642
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
643
+ WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
644
+ THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
645
+ GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
646
+ USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
647
+ DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
648
+ PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
649
+ EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
650
+ SUCH DAMAGES.
651
+
652
+ 17. Interpretation of Sections 15 and 16.
653
+
654
+ If the disclaimer of warranty and limitation of liability provided
655
+ above cannot be given local legal effect according to their terms,
656
+ reviewing courts shall apply local law that most closely approximates
657
+ an absolute waiver of all civil liability in connection with the
658
+ Program, unless a warranty or assumption of liability accompanies a
659
+ copy of the Program in return for a fee.
660
+
lib/scssphp/Makefile ADDED
@@ -0,0 +1,2 @@
 
 
1
+ test:
2
+ vendor/bin/phpunit --colors tests
lib/scssphp/README.md ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # scssphp v0.1.1
2
+ ### <http://leafo.net/scssphp>
3
+
4
+ [![Build Status](https://secure.travis-ci.org/leafo/scssphp.png)](http://travis-ci.org/leafo/scssphp)
5
+
6
+ `scssphp` is a compiler for SCSS written in PHP.
7
+
8
+ It implements SCSS 3.2.12. It does not implement the SASS syntax, only the SCSS
9
+ syntax.
10
+
11
+ Checkout the homepage, <http://leafo.net/scssphp>, for directions on how to use.
12
+
13
+ ## Running Tests
14
+
15
+ `scssphp` uses [PHPUnit](https://github.com/sebastianbergmann/phpunit) for testing.
16
+
17
+ Run the following command from the root directory to run every test:
18
+
19
+ phpunit tests
20
+
21
+ There are two kinds of tests in the `tests/` directory:
22
+
23
+ * `ApiTest.php` contains various unit tests that test the PHP interface.
24
+ * `ExceptionTest.php` contains unit tests that test for exceptions thrown by the parser and compiler.
25
+ * `InputTest.php` compiles every `.scss` file in the `tests/inputs` directory
26
+ then compares to the respective `.css` file in the `tests/outputs` directory.
27
+
28
+ When changing any of the tests in `tests/inputs`, the tests will most likely
29
+ fail because the output has changed. Once you verify that the output is correct
30
+ you can run the following command to rebuild all the tests:
31
+
32
+ BUILD=true phpunit tests
33
+
34
+ This will compile all the tests, and save results into `tests/outputs`.
lib/scssphp/bin/pscss ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env php
2
+ <?php
3
+
4
+ error_reporting(E_ALL);
5
+
6
+ include __DIR__.'/../scss.inc.php';
7
+
8
+ use Leafo\ScssPhp\Compiler;
9
+ use Leafo\ScssPhp\Parser;
10
+
11
+ $opts = getopt('hvTi:f:', array('help', 'version'));
12
+
13
+ function has() {
14
+ global $opts;
15
+
16
+ foreach (func_get_args() as $arg) {
17
+ if (isset($opts[$arg])) {
18
+ return true;
19
+ }
20
+ }
21
+
22
+ return false;
23
+ }
24
+
25
+ if (has("h", "help")) {
26
+ $exe = array_shift($argv);
27
+
28
+ $HELP = <<<EOT
29
+ Usage: $exe [options] < input-file
30
+
31
+ Options include:
32
+
33
+ -h, --help Show this message
34
+ -v, --version Print the version
35
+ -f=format Set the output format (compressed, crunched, expanded, or nested)
36
+ -T Dump formatted parse tree
37
+ -i=path Set import path
38
+
39
+ EOT;
40
+ exit($HELP);
41
+ }
42
+
43
+ if (has("v", "version")) {
44
+ exit(Compiler::$VERSION . "\n");
45
+ }
46
+
47
+ $data = "";
48
+
49
+ while (!feof(STDIN)) {
50
+ $data .= fread(STDIN, 8192);
51
+ }
52
+
53
+ if (has("T")) {
54
+ $parser = new Parser("STDIN");
55
+
56
+ print_r($parser->parse($data));
57
+
58
+ exit();
59
+ }
60
+
61
+ $scss = new Compiler();
62
+
63
+ if (has("i")) {
64
+ $scss->addImportPath($opts["i"]);
65
+ }
66
+
67
+ if (has("f")) {
68
+ $scss->setFormatter('Leafo\\ScssPhp\\Formatter\\' . ucfirst($opts["f"]));
69
+ }
70
+
71
+ echo $scss->compile($data, "STDIN");
lib/scssphp/classmap.php ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * SCSSPHP
4
+ *
5
+ * Stub classes for backward compatibility
6
+ *
7
+ * @copyright 2012-2014 Leaf Corcoran
8
+ *
9
+ * @license http://opensource.org/licenses/gpl-license GPL-3.0
10
+ * @license http://opensource.org/licenses/MIT MIT
11
+ *
12
+ * @link http://leafo.net/scssphp
13
+ */
14
+
15
+ /**
16
+ * @deprecated since 0.1.0
17
+ */
18
+ class scssc extends \Leafo\ScssPhp\Compiler
19
+ {
20
+ }
21
+
22
+ /**
23
+ * @deprecated since 0.1.0
24
+ */
25
+ class scss_parser extends \Leafo\ScssPhp\Parser
26
+ {
27
+ }
28
+
29
+ /**
30
+ * @deprecated since 0.1.0
31
+ */
32
+ class scss_formatter extends \Leafo\ScssPhp\Formatter\Expanded
33
+ {
34
+ }
35
+
36
+ /**
37
+ * @deprecated since 0.1.0
38
+ */
39
+ class scss_formatter_nested extends \Leafo\ScssPhp\Formatter\Nested
40
+ {
41
+ }
42
+
43
+ /**
44
+ * @deprecated since 0.1.0
45
+ */
46
+ class scss_formatter_compressed extends \Leafo\ScssPhp\Formatter\Compressed
47
+ {
48
+ }
49
+
50
+ /**
51
+ * @deprecated since 0.1.0
52
+ */
53
+ class scss_formatter_crunched extends \Leafo\ScssPhp\Formatter\Crunched
54
+ {
55
+ }
56
+
57
+ /**
58
+ * @deprecated since 0.1.0
59
+ */
60
+ class scss_server extends \Leafo\ScssPhp\Server
61
+ {
62
+ }
lib/scssphp/composer.json ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "leafo/scssphp",
3
+ "type": "library",
4
+ "description": "scssphp is a compiler for SCSS written in PHP.",
5
+ "keywords": ["css", "stylesheet", "scss", "sass", "less"],
6
+ "homepage": "http://leafo.net/scssphp/",
7
+ "license": [
8
+ "MIT",
9
+ "GPL-3.0"
10
+ ],
11
+ "authors": [
12
+ {
13
+ "name": "Leaf Corcoran",
14
+ "email": "leafot@gmail.com",
15
+ "homepage": "http://leafo.net"
16
+ }
17
+ ],
18
+ "autoload": {
19
+ "classmap": ["classmap.php"],
20
+ "psr-4": { "Leafo\\ScssPhp\\": "src/" }
21
+ },
22
+ "autoload-dev": {
23
+ "psr-4": { "Leafo\\ScssPhp\\Test\\": "tests/" }
24
+ },
25
+ "require": {
26
+ "php": ">=5.3.0"
27
+ },
28
+ "require-dev": {
29
+ "phpunit/phpunit": "3.7.*"
30
+ },
31
+ "bin": ["bin/pscss"]
32
+ }
lib/scssphp/package.sh ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/sh
2
+
3
+ # creates tar.gz for current version
4
+
5
+ TARGET_DIR="site/www/src"
6
+
7
+ VERSION=`./pscss -v | sed -n 's/^v\(.*\)$/\1/p'`
8
+ OUT_DIR="tmp/scssphp"
9
+ TMP=`dirname $OUT_DIR`
10
+
11
+ mkdir -p $OUT_DIR
12
+ tar -c `git ls-files` | tar -C $OUT_DIR -x
13
+
14
+ rm $OUT_DIR/.gitignore
15
+ rm $OUT_DIR/package.sh
16
+ rm $OUT_DIR/todo
17
+ rm -r $OUT_DIR/site
18
+
19
+ OUT_PATH="$TARGET_DIR/scssphp-$VERSION.tar.gz"
20
+ tar -czf "$OUT_PATH" -C $TMP scssphp/
21
+ echo "Wrote $OUT_PATH"
22
+
23
+ rm -r $TMP
24
+
lib/scssphp/phpunit.xml.dist ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+
3
+ <!-- http://www.phpunit.de/manual/current/en/appendixes.configuration.html -->
4
+ <phpunit
5
+ backupGlobals = "false"
6
+ backupStaticAttributes = "false"
7
+ strict = "false"
8
+ colors = "true"
9
+ convertErrorsToExceptions = "true"
10
+ convertNoticesToExceptions = "true"
11
+ convertWarningsToExceptions = "true"
12
+ processIsolation = "false"
13
+ stopOnFailure = "false"
14
+ syntaxCheck = "false"
15
+ bootstrap = "scss.inc.php">
16
+
17
+ <testsuites>
18
+ <testsuite name="Project Test Suite">
19
+ <directory>tests</directory>
20
+ </testsuite>
21
+ </testsuites>
22
+
23
+ <filter>
24
+ <whitelist>
25
+ <directory>src</directory>
26
+ </whitelist>
27
+ </filter>
28
+
29
+ </phpunit>
lib/scssphp/scss.inc.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ include __DIR__ . '/src/Colors.php';
3
+ include __DIR__ . '/src/Compiler.php';
4
+ include __DIR__ . '/src/Formatter.php';
5
+ include __DIR__ . '/src/Formatter/Compressed.php';
6
+ include __DIR__ . '/src/Formatter/Crunched.php';
7
+ include __DIR__ . '/src/Formatter/Expanded.php';
8
+ include __DIR__ . '/src/Formatter/Nested.php';
9
+ include __DIR__ . '/src/Parser.php';
10
+ include __DIR__ . '/src/Server.php';
11
+ include __DIR__ . '/classmap.php';
lib/scssphp/site/composer.html ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
1
+ <pre class="highlight lang_json"><code><span class="p">{</span>
2
+ <span class="nt">&quot;require&quot;</span><span class="p">:</span> <span class="p">{</span>
3
+ <span class="nt">&quot;leafo/scssphp&quot;</span><span class="p">:</span> <span class="s2">&quot;$current_version&quot;</span>
4
+ <span class="p">}</span>
5
+ <span class="p">}</span></code>
6
+ </pre>
lib/scssphp/site/docs/index.md ADDED
@@ -0,0 +1,325 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ title: Documentation
2
+ --
3
+
4
+ <h1 skip="true">scssphp $current_version Documentation</h1>
5
+
6
+ <div class="index">$index</div>
7
+
8
+ ## PHP Interface
9
+
10
+ ### Including
11
+
12
+ The project can be loaded through a `composer` generated auto-loader.
13
+
14
+ Alternatively, the entire project can be loaded through a utility file.
15
+ Just include it somewhere to start using it:
16
+
17
+ ```php
18
+ <?php
19
+ require "scssphp/scss.inc.php";
20
+ ```
21
+
22
+ ### Compiling
23
+
24
+ In order to manually compile code from PHP you must create an instance of the
25
+ `Compiler` class. The typical flow is to create the instance, set any compile time
26
+ options, then run the compiler with the `compile` method.
27
+
28
+ ```php
29
+ <?php
30
+ require "scssphp/scss.inc.php";
31
+
32
+ use Leafo\ScssPhp\Compiler;
33
+
34
+ $scss = new Compiler();
35
+
36
+ echo $scss->compile('
37
+ $color: #abc;
38
+ div { color: lighten($color, 20%); }
39
+ ');
40
+ ```
41
+
42
+ * <p>`compile($scssCode)` will attempt to compile a string of SCSS code. If it
43
+ succeeds then the CSS will be returned as a string. If there is any error, an
44
+ exception is thrown with an appropriate error message.
45
+ </p>
46
+
47
+ ### Import Paths
48
+
49
+ When you import a file using the `@import` directive, the current path of your
50
+ PHP script is used as the search path by default. This is often not what
51
+ you want, so there are two methods for manipulating the import path:
52
+ `addImportPath`, and `setImportPaths`.
53
+
54
+ * `addImportPath($path)` will append `$path` to the list of the import
55
+ paths that are searched.
56
+
57
+ * `setImportPaths($pathArray)` will replace the entire import path with
58
+ `$pathArray`. The value of `$pathArray` will be converted to an array if it
59
+ isn't one already.
60
+
61
+ If the import path is set to `array()` then importing is effectively disabled.
62
+ The default import path is `array("")`, which means the current directory.
63
+
64
+ ```php
65
+ <?php
66
+ require "scssphp/scss.inc.php";
67
+
68
+ use Leafo\ScssPhp\Compiler;
69
+
70
+ $scss = new Compiler();
71
+ $scss->setImportPaths("assets/stylesheets/");
72
+
73
+ // will search for `assets/stylesheets/mixins.scss'
74
+ echo $scss->compile('@import "mixins.scss"');
75
+ ```
76
+
77
+ Besides adding static import paths, it's also possible to add custom import
78
+ functions. This allows you to load paths from a database, or HTTP, or using
79
+ files that SCSS would otherwise not process (such as vanilla CSS imports).
80
+
81
+ ```php
82
+ <?php
83
+ require "scssphp/scss.inc.php";
84
+
85
+ use Leafo\ScssPhp\Compiler;
86
+
87
+ $scss = new Compiler();
88
+ $scss->addImportPath(function($path) {
89
+ if (!file_exists('stylesheets/'.$path)) return null;
90
+ return 'stylesheets/'.$path;
91
+ });
92
+
93
+ // will import `stylesheets/vanilla.css'
94
+ echo $scss->compile('@import "vanilla.css"');
95
+ ```
96
+
97
+ ### Output Formatting
98
+
99
+ It's possible to customize the formatting of the output CSS by changing the
100
+ default formatter.
101
+
102
+ Three formatters are included:
103
+
104
+ * `Leafo\ScssPhp\Formatter\Expanded`
105
+ * `Leafo\ScssPhp\Formatter\Nested` *(default)*
106
+ * `Leafo\ScssPhp\Formatter\Compressed`
107
+
108
+ We can change the formatting using the `setFormatter` method.
109
+
110
+ * <p>`setFormatter($formatterName)` sets the current formatter to `$formatterName`,
111
+ the name of a class as a string that implements the formatting interface. See
112
+ the source for `Leafo\ScssPhp\Formatter\Expanded` for an example.
113
+ </p>
114
+
115
+ Given the following SCSS:
116
+
117
+ ```scss
118
+ .navigation {
119
+ ul {
120
+ line-height: 20px;
121
+ color: blue;
122
+ a {
123
+ color: red;
124
+ }
125
+ }
126
+ }
127
+
128
+ .footer {
129
+ .copyright {
130
+ color: silver;
131
+ }
132
+ }
133
+ ```
134
+
135
+ The formatters will output,
136
+
137
+ `Leafo\ScssPhp\Formatter\Expanded`:
138
+
139
+ ```css
140
+ .navigation ul {
141
+ line-height: 20px;
142
+ color: blue;
143
+ }
144
+ .navigation ul a {
145
+ color: red;
146
+ }
147
+ .footer .copyright {
148
+ color: silver;
149
+ }
150
+ ```
151
+
152
+ `Leafo\ScssPhp\Formatter\Nested`:
153
+
154
+ ```css
155
+ .navigation ul {
156
+ line-height: 20px;
157
+ color: blue; }
158
+ .navigation ul a {
159
+ color: red; }
160
+
161
+ .footer .copyright {
162
+ color: silver; }
163
+ ```
164
+
165
+ `Leafo\ScssPhp\Formatter\Compressed`:
166
+
167
+ ```css
168
+ .navigation ul{line-height:20px;color:blue;}.navigation ul a{color:red;}.footer .copyright{color:silver;}
169
+ ```
170
+
171
+ ### Custom Functions
172
+
173
+ It's possible to register custom functions written in PHP that can be called
174
+ from SCSS. Some possible applications include appending your assets directory
175
+ to a URL with an `asset-url` function, or converting image URLs to an embedded
176
+ data URI to reduce the number of requests on a page with a `data-uri` function.
177
+
178
+ We can add and remove functions using the methods `registerFunction` and
179
+ `unregisterFunction`.
180
+
181
+ * `registerFunction($functionName, $callable)` assigns the callable value to
182
+ the name `$functionName`. The name is normalized using the rules of SCSS.
183
+ Meaning underscores and dashes are interchangeable. If a function with the
184
+ same name already exists then it is replaced.
185
+
186
+ * `unregisterFunction($functionName)` removes `$functionName` from the list of
187
+ available functions.
188
+
189
+
190
+ The `$callable` can be anything that PHP knows how to call using
191
+ `call_user_func`. The function receives two arguments when invoked. The first
192
+ is an array of SCSS typed arguments that the function was sent. The second is a
193
+ reference to the current `scss` instance.
194
+
195
+ The *SCSS typed arguments* are actually just arrays that represent SCSS values.
196
+ SCSS has different types than PHP, and this is how **scssphp** represents them
197
+ internally.
198
+
199
+ For example, the value `10px` in PHP would be `array("number", 1, "px")`. There
200
+ is a large variety of types. Experiment with a debugging function like `print_r`
201
+ to examine the possible inputs.
202
+
203
+ The return value of the custom function can either be a SCSS type or a basic
204
+ PHP type. (such as a string or a number) If it's a PHP type, it will be converted
205
+ automatically to the corresponding SCSS type.
206
+
207
+ As an example, a function called `add-two` is registered, which adds two numbers
208
+ together. PHP's anonymous function syntax is used to define the function.
209
+
210
+ ```php
211
+ <?php
212
+ use Leafo\ScssPhp\Compiler;
213
+
214
+ $scss = new Compiler();
215
+
216
+ $scss->registerFunction("add-two", function($args) {
217
+ list($a, $b) = $args;
218
+ return $a[1] + $b[1];
219
+ });
220
+
221
+ $scss->compile('.ex1 { result: add-two(10, 10); }');
222
+ ```
223
+
224
+ It's worth noting that in this example we lose the units of the number, and we
225
+ also don't do any type checking. This will have undefined results if we give it
226
+ anything other than two numbers.
227
+
228
+
229
+ ## SCSS Server
230
+
231
+ The SCSS server is a small class that helps with automatically compiling SCSS.
232
+
233
+ It's an endpoint for your web application that searches for SCSS files in a
234
+ directory then compiles and serves them as CSS. It will only compile
235
+ files if they've been modified (or one of the imports has been modified).
236
+
237
+ ### Using `serveFrom`
238
+
239
+ `Server::serveFrom` is a simple to use function that should handle most cases.
240
+
241
+ For example, create a file `style.php`:
242
+
243
+ ```php
244
+ <?php
245
+ $directory = "stylesheets";
246
+
247
+ require "scssphp/scss.inc.php";
248
+
249
+ use Leafo\ScssPhp\Server;
250
+
251
+ Server::serveFrom($directory);
252
+ ```
253
+
254
+ Going to the URL `example.com/style.php/style.scss` will attempt to compile
255
+ `style.scss` from the `stylesheets` directory, and serve it as CSS.
256
+
257
+ * <p>`Server::serveFrom($directory)` will serve SCSS files out of
258
+ `$directory`. It will attempt to get the path to the file out of
259
+ `$_SERVER["PATH_INFO"]`. (It also looks at the GET parameter `p`)
260
+ </p>
261
+
262
+ If it can not find the file it will return an HTTP 404 page:
263
+
264
+ ```text
265
+ /* INPUT NOT FOUND scss v0.0.1 */
266
+ ```
267
+
268
+ If the file can't be compiled due to an error, then an HTTP 500 page is
269
+ returned. Similar to the following:
270
+
271
+ ```text
272
+ Parse error: parse error: failed at `height: ;` stylesheets/test.scss on line 8
273
+ ```
274
+
275
+ By default , the SCSS server must have write access to the style sheet
276
+ directory. It writes its cache in a special directory called `scss_cache`.
277
+
278
+ Also, because SCSS server writes headers, make sure no output is written before
279
+ it runs.
280
+
281
+ ### Using `Leafo\ScssPhp\Server`
282
+
283
+ Creating an instance of `Server` is just another way of accomplishing what
284
+ `serveFrom` does. It lets us customize the cache directory and the instance
285
+ of the `Compiler` that is used to compile
286
+
287
+
288
+ * <p>`new Server($sourceDir, $cacheDir, $scss)` creates a new server that
289
+ serves files from `$sourceDir`. The cache dir is where the cached compiled
290
+ files are placed. When `null`, `$sourceDir . "/scss_cache"` is used. `$scss`
291
+ is the instance of `scss` that is used to compile.
292
+ </p>
293
+
294
+ Just call the `serve` method to let it render its output.
295
+
296
+ Here's an example of creating a SCSS server that outputs compressed CSS:
297
+
298
+ ```php
299
+ <?php
300
+ require "scssphp/scss.inc.php";
301
+
302
+ use Leafo\ScssPhp\Compiler;
303
+ use Leafo\ScssPhp\Server;
304
+
305
+ $scss = new Compiler();
306
+ $scss->setFormatter("scss_formatter_compressed");
307
+
308
+ $server = new Server("stylesheets", null, $scss);
309
+ $server->serve();
310
+ ```
311
+
312
+
313
+ ## Command Line Tool
314
+
315
+ A really basic command line tool is included for integration with scripts. It
316
+ is called `pscss`. It reads a SCSS file from standard out and returns the CSS.
317
+
318
+ If passed the flag `-v`, input is ignored and the current version if returned.
319
+
320
+ The flag `-f` can be used to set the [formatter](#Output_formatting):
321
+
322
+ ```bash
323
+ $ bin/pscss -f scss_formatter_compressed < styles.scss
324
+ ```
325
+
lib/scssphp/site/index.md ADDED
@@ -0,0 +1,233 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ **scssphp** is a compiler for [SCSS][0] written in PHP.
2
+
3
+ SCSS is a CSS preprocessor that adds many features like variables, mixins,
4
+ imports, color manipulation, functions, and tons of other powerful features.
5
+
6
+ The entire compiler comes in a single class file ready for including in any
7
+ kind of project in addition to a command line tool for running the compiler
8
+ from the terminal.
9
+
10
+ **scssphp** implements SCSS (3.2.12). It does not implement the SASS syntax,
11
+ only the SCSS syntax.
12
+
13
+ Follow the author on twitter: [@moonscript](http://twitter.com/moonscript).
14
+
15
+ <div class="github-buttons">
16
+ <iframe src="http://ghbtns.com/github-btn.html?user=leafo&repo=scssphp&type=watch&count=true" allowtransparency="true" frameborder="0" scrolling="0" width="110px" height="20px"></iframe>
17
+ <iframe src="http://ghbtns.com/github-btn.html?user=leafo&repo=scssphp&type=fork&count=true" allowtransparency="true" frameborder="0" scrolling="0" width="95px" height="20px"></iframe>
18
+ </div>
19
+
20
+ <a name="installing"></a>
21
+ ## Installing
22
+
23
+ You can always download the latest version here:
24
+ <a href="$root/src/scssphp-$current_version.tar.gz" id="download-link">scssphp-$current_version.tar.gz</a>
25
+
26
+ You can also find the latest source online:
27
+ <https://github.com/leafo/scssphp/>
28
+
29
+ If you use [Packagist][2] for installing packages, then you can update your `composer.json` like so:
30
+
31
+ $render{[[composer]]}
32
+
33
+ <a name="quickstart"></a>
34
+ ## Language Reference
35
+
36
+ For a complete guide to the syntax of SCSS, consult the [official documentation][1].
37
+
38
+ ## PHP Reference
39
+
40
+ Complete documentation for **scssphp** is located at <a href="$root/docs/">http://leafo.net/scssphp/docs/</a>.
41
+
42
+ ### Quickstart
43
+
44
+ If you just want to start serving compiled `scss` files as quick as possible
45
+ then start here.
46
+
47
+ **scssphp** comes with a easy to use class that automatically compiles modified
48
+ `scss` files and serves them from a directory you specify.
49
+
50
+ Create a file, like `style.php`:
51
+
52
+ ```php
53
+ <?php
54
+ $directory = "stylesheets";
55
+
56
+ require "scssphp/scss.inc.php";
57
+
58
+ use Leafo\ScssPhp\Server;
59
+
60
+ Server::serveFrom($directory);
61
+
62
+ ```
63
+
64
+ Create the directory set in the script alongside the script, then add your
65
+ `scss` files to it.
66
+
67
+ If we've got a file in there called `style.scss`, then we just need to hit the
68
+ url: `example.com/style.php/style.scss` to get the compiled css.
69
+
70
+ If there is an error compiling, the url will result in a `500` error with the
71
+ error message. If the file can't be found, then a friendly `404` is returned.
72
+
73
+ **scssphp** will automatically create a `scss_cache` directory inside the
74
+ stylesheets directory where it will cache the compiled output. This way it can
75
+ quickly serve the files if no modifications have been made. Your PHP script
76
+ must have permission to write in `scss_cache`.
77
+
78
+ ### Compiler Interface
79
+
80
+ If you're interested in directly using the compiler, then all you need to either
81
+ require `scss.inc.php` or use your `composer` generated auto-laoder, and then
82
+ invoke the `Compiler` class:
83
+
84
+ ```php
85
+ <?php
86
+ require "scssphp/scss.inc.php";
87
+
88
+ use Leafo\ScssPhp\Compiler;
89
+
90
+ $scss = new Compiler();
91
+
92
+ echo $scss->compile('
93
+ $color: #abc;
94
+ div { color: lighten($color, 20%); }
95
+ ');
96
+
97
+ ```
98
+
99
+ The `compile` method takes `SCSS` as a string, and returns the `CSS`. If there
100
+ is an error when compiling then an exception is thrown with an appropriate
101
+ message.
102
+
103
+
104
+ For a more detailed guide consult <a href="$root/docs/">http://leafo.net/scssphp/docs/</a>.
105
+
106
+ <a name="issues"></a>
107
+ ## Issues
108
+
109
+ Find any issues? I'd love to fix them for you, post about them on [the issues tracker][3].
110
+
111
+ <div id="changelog"></div>
112
+ ## Changelog
113
+
114
+ * **0.1.1** -- Aug 12, 2014
115
+ * add stub classes -- a backward compatibility layer (vladimmi)
116
+ * **0.1.0** -- Aug 9, 2014
117
+ * raise PHP requirement (5.3+)
118
+ * reformat/reorganize source files to be PSR-2 compliant
119
+ * **0.0.15** -- Aug 6, 2014
120
+ * fix regression with default values in functions (torkiljohnsen)
121
+ * **0.0.14** -- Aug 5, 2014
122
+ * @keyframes $name - didn't work inside mixin (sergeylukin)
123
+ * Bourbon transform(translateX()) didn't work (dovy and greynor)
124
+ * **0.0.13** -- Aug 4, 2014
125
+ * handle If-None-Match in client request, and send ETag in response (NSmithUK)
126
+ * normalize quotation marks (NoxNebula)
127
+ * improve handling of escape sequence in selectors (matt3224)
128
+ * add "scss_formatter_crunched" which strips comments
129
+ * internal: generate more accurate parse tree
130
+ * **0.0.12** -- July 6, 2014
131
+ * revert erroneous import-partials-fix (smuuf)
132
+ * handle If-Modified-Since in client request, and send Last-Modified in response (braver)
133
+ * add hhvm to travis-ci testing
134
+ * **0.0.11** -- July 5, 2014
135
+ * support multi-line continuation character (backslash)per CSS2.1 and CSS3 spec (caiosm1005)
136
+ * imported partials should not be compiled (squarestar)
137
+ * add setVariables() and unsetVariable() to interface (leafo/lessphp)
138
+ * micro-optimizing is_null() (Yahasana)
139
+ * **0.0.10** -- April 14, 2014
140
+ * fix media query merging (timonbaetz)
141
+ * inline if should treat null as false (wonderslug)
142
+ * optimizing toHSL() (jfsullivan)
143
+ * **0.0.9** -- December 23, 2013
144
+ * fix @for/@while inside @content block (sergeylukin)
145
+ * fix functions in mixin_content (timonbaetz)
146
+ * fix infinite loop when target extends itself (oscherler)
147
+ * fix function arguments are lost inside of @content block
148
+ * allow setting number precision (kasperisager)
149
+ * add public function helpers (toBool, get, findImport, assertList, assertColor, assertNumber, throwError) (Burgov, atdt)
150
+ * add optional cache buster prefix to serve() method (iMoses)
151
+ * **0.0.8** -- September 16, 2013
152
+ * Avoid IE7 content: counter bug
153
+ * Support transparent as color name
154
+ * Recursively create cache dir (turksheadsw)
155
+ * Fix for INPUT NOT FOUND (morgen32)
156
+ * **0.0.7** -- May 24, 2013
157
+ * Port various fixes from leafo/lessphp.
158
+ * Improve filter precision.
159
+ * Parsing large image data-urls does not work.
160
+ * Add == and != ops for colors.
161
+ * @if and @while directives should treat null like false.
162
+ * Add pscss as bin in composer.json (Christian Lück).
163
+ * Fix !default bug (James Shannon, Alberto Aldegheri).
164
+ * Fix mixin content includes (James Shannon, Christian Brandt).
165
+ * Fix passing of varargs to another mixin.
166
+ * Fix interpolation bug in expToString() (Matti Jarvinen).
167
+ * **0.0.5** -- March 11, 2013
168
+ * Better compile time errors
169
+ * Fix top level properties inside of a nested `@media` (Anthon Pang)
170
+ * Fix some issues with `@extends` (Anthon Pang)
171
+ * Enhanced handling of `null` (Anthon Pang)
172
+ * Helper functions shouldn't mix with css builtins (Anthon Pang)
173
+ * Enhance selector parsing (Guilherme Blanco, Anthon Pang)
174
+ * Add Placeholder selector support (Martin Hasoň)
175
+ * Add variable argument support (Martin Hasoň)
176
+ * Add zip, index, comparable functions (Martin Hasoň)
177
+ * A bunch of parser and bug fixes
178
+ * **0.0.4** -- Nov 3nd, 2012
179
+ * [Import path can be a function](docs/#import_paths) (Christian Lück).
180
+ * Correctly parse media queries with more than one item (Christian Lück).
181
+ * Add `ie_hex_str`, `abs`, `min`, `max` functions (Martin Hasoň)
182
+ * Ignore expressions inside of `calc()` (Martin Hasoň)
183
+ * Improve operator evaluation (Martin Hasoň)
184
+ * Add [`@content`](http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#mixin-content) support.
185
+ * Misc bug fixes.
186
+ * **0.0.3** -- August 2nd, 2012
187
+ * Add missing and/or/not operators.
188
+ * Expression evaluation happens correctly.
189
+ * Import file caching and _partial filename support.
190
+ * Misc bug fixes.
191
+ * **0.0.2** -- July 30th, 2012
192
+ * SCSS server is aware of imports
193
+ * added custom function interface
194
+ * compressed formatter
195
+ * wrote <a href="http://leafo.net/scssphp/docs/">documentation</a>
196
+ * Initial Release v0.0.1 -- July 29th, 2012
197
+
198
+ <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
199
+ <script type="text/javascript">
200
+ (function() {
201
+ var changelog = jQuery("#changelog").nextAll("ul:first");
202
+ var hidden = changelog.children("li").slice(1).hide();
203
+ if (hidden.length) {
204
+ var show_all = jQuery("<a href=''>Show All</a>").insertAfter(changelog).on("click", function() {
205
+ hidden.show();
206
+ show_all.remove();
207
+ return false;
208
+ });
209
+ }
210
+ })();
211
+ </script>
212
+
213
+ <a name="comments"></a>
214
+ ## Comments
215
+
216
+ <div class="comments" id="disqus_thread"></div>
217
+ <script type="text/javascript">
218
+ var disqus_shortname = 'leafo';
219
+ var disqus_url = 'http://leafo.net/scssphp/';
220
+
221
+ (function() {
222
+ var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
223
+ dsq.src = 'http://' + disqus_shortname + '.disqus.com/embed.js';
224
+ (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
225
+ })();
226
+ </script>
227
+
228
+
229
+ [0]: http://sass-lang.com/
230
+ [1]: http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#css_extensions
231
+ [2]: http://packagist.org/
232
+ [3]: https://github.com/leafo/scssphp/issues
233
+ [4]: https://github.com/leafo/scssphp/
lib/scssphp/site/site.moon ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ require "sitegen"
2
+
3
+ tools = require "sitegen.tools"
4
+
5
+ sitegen.create_site =>
6
+ @current_version = "0.1.1"
7
+ @title = "SCSS Compiler in PHP"
8
+
9
+ scssphp = tools.system_command "bin/pscss < %s > %s", "css"
10
+ build scssphp, "style.scss", "style/style.css"
11
+
12
+ deploy_to "leaf@leafo.net", "www/scssphp/"
13
+
14
+ add "docs/index.md"
15
+
lib/scssphp/site/style.scss ADDED
@@ -0,0 +1,303 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ $site_width: 640px;
3
+
4
+ $light_teal: #7FC7AF;
5
+ $teal: desaturate(#3FB8AF, 10%);
6
+ $brown: #DAD8A7;
7
+ $pink: darken(#FF9E9D, 10%);
8
+ $btn_color: desaturate(#FF3D7F, 10%);
9
+
10
+ ::selection {
11
+ background: red;
12
+ color: white;
13
+ }
14
+
15
+ @mixin unselectable {
16
+ -moz-user-select: none;
17
+ -webkit-user-select: none;
18
+ user-select: none;
19
+ }
20
+
21
+ @mixin grad($top, $bottom) {
22
+ background-color: mix($top, $bottom);
23
+ background-image: linear-gradient(bottom, $bottom 0%, $top 100%);
24
+ background-image: -webkit-linear-gradient(bottom, $bottom 0%, $top 100%);
25
+ background-image: -moz-linear-gradient(bottom, $bottom 0%, $top 100%);
26
+ background-image: -o-linear-gradient(bottom, $bottom 0%, $top 100%);
27
+ background-image: -ms-linear-gradient(bottom, $bottom 0%, $top 100%);
28
+ }
29
+
30
+ @mixin autograd($color, $amount: 10%) {
31
+ @include grad($color, darken($color, $amount));
32
+ }
33
+
34
+ body {
35
+ background: $pink;
36
+ font-family: Lato, sans-serif;
37
+ }
38
+
39
+ .header, .footer, .body {
40
+ .inner {
41
+ width: $site_width;
42
+ margin: 0 auto;
43
+ }
44
+ }
45
+
46
+ .header {
47
+ text-shadow: 0px -1px 0px darken($teal, 15%);
48
+
49
+ .color {
50
+ background: $teal url(../img/tile.png);
51
+ border-top: 4px solid $light_teal;
52
+ box-shadow: inset 0px 1px 0px rgba(255,255,255, 0.5), inset 0px 8px 8px -8px #37505A, inset 0px -1px 0px rgba(255,255,255, 0.3);
53
+ }
54
+
55
+ h1 {
56
+ font-family: 'Quicksand', sans-serif;
57
+ font-size: 40px;
58
+ line-height: 100px;
59
+ font-weight: normal;
60
+ margin: 0;
61
+
62
+ a {
63
+ text-decoration: none;
64
+ color: #EDFFF9;
65
+
66
+ &:active {
67
+ position: relative;
68
+ top: 1px;
69
+ }
70
+ }
71
+ }
72
+
73
+ .nav {
74
+ padding: 8px 0;
75
+ font-size: 17px;
76
+ text-shadow: none;
77
+ background: darken($teal, 30%);
78
+ color: $teal;
79
+ box-shadow: inset 0px 4px 8px -4px rgba(0,0,0,0.9), inset 0px -1px 0px rgba(255,255,255, 0.8);
80
+
81
+ a {
82
+ color: lighten($teal, 40%);
83
+ text-decoration: none;
84
+
85
+ &:hover {
86
+ text-decoration: underline;
87
+ }
88
+ }
89
+
90
+ .social {
91
+ float: right;
92
+ margin-top: -2px;
93
+ }
94
+ }
95
+
96
+ .download-area {
97
+ float: right;
98
+ margin-top: 25px;
99
+ background: rgba(255,255,255, 0.3);
100
+ border-radius: 8px;
101
+ padding: 5px;
102
+
103
+ a {
104
+ text-decoration: none;
105
+ }
106
+
107
+ .download-button {
108
+ $height: 8px;
109
+ $depress: 4px;
110
+
111
+ @include unselectable;
112
+
113
+ color: white;
114
+ text-align: center;
115
+
116
+ @include autograd($btn_color);
117
+
118
+ position: relative;
119
+ top: -1 * $height;
120
+
121
+ padding: 8px 20px;
122
+ border-radius: 8px;
123
+ text-shadow: none;
124
+
125
+ box-shadow: 0px $height 0px darken($btn_color, 30%), inset 0px -1px 0px rgba(255,255,255, 0.2), inset 0px 1px 0px rgba(0,0,0, 0.2);
126
+ text-shadow: 0px 1px 2px darken($btn_color, 40%);
127
+
128
+ cursor: pointer;
129
+
130
+ -webkit-transition: all 0.05s ease-in-out;
131
+ -moz-transition: all 0.05s ease-in-out;
132
+ transition: all 0.05s ease-in-out;
133
+
134
+ &:hover {
135
+ @include autograd(lighten($btn_color, 3%));
136
+ }
137
+
138
+ &:active {
139
+ box-shadow: 0px $height - $depress 0px darken($btn_color, 30%), inset 0px -1px 0px rgba(255,255,255, 0.2), inset 0px 1px 0px rgba(0,0,0, 0.2);
140
+ top: -1 * ($height - $depress);
141
+ }
142
+
143
+ .top {
144
+ font-weight: bold;
145
+ font-size: 16px;
146
+ }
147
+
148
+ .sub {
149
+ font-size: 14px;
150
+ }
151
+ }
152
+ }
153
+
154
+ }
155
+
156
+ .body {
157
+ $bg_color: #FEFFED;
158
+ $text_color: darken($brown, 60%);
159
+ box-shadow: inset 0px 4px 8px -4px rgba(0,0,0,0.7), inset 0px -4px 8px -4px rgba(0,0,0,0.4);
160
+ background: $bg_color;
161
+ overflow: hidden;
162
+ color: $text_color;
163
+ font-size: 18px;
164
+ padding-bottom: 20px;
165
+
166
+ .inner {
167
+ background: white;
168
+ margin-top: 20px;
169
+ padding: 30px 50px;
170
+ border: 1px solid lightGrey;
171
+ box-shadow: 0px 4px 20px rgba(0, 0, 0, 0.19);
172
+
173
+ h1, h2, h3 {
174
+ margin: 0 0 20px 0;
175
+ }
176
+ }
177
+
178
+ h1, h2, h3 {
179
+ text-shadow: 1px 1px 0px $bg_color, 2px 2px 0px rgba($text_color, 0.3);
180
+ letter-spacing: -1px;
181
+ }
182
+
183
+ h3 {
184
+ color: #4D4C3D;
185
+ }
186
+
187
+ p {
188
+ margin: 0 0 15px 0;
189
+ }
190
+
191
+ a {
192
+ color: #DB1C4A;
193
+ &:hover {
194
+ color: lighten(#DB1C4A, 10%);
195
+ }
196
+ }
197
+
198
+ pre {
199
+ margin: 20px 0;
200
+ }
201
+ }
202
+
203
+ .footer {
204
+ font-size: 16px;
205
+ color: lighten($pink, 20%);
206
+ text-shadow: 0px 1px 0px darken($pink, 20%);
207
+
208
+ border-top: 1px dashed darken($pink, 50%);
209
+ box-shadow: inset 0px 1px 0px rgba(255,255,255, 0.5);
210
+ padding: 8px 0 20px 0;
211
+
212
+ line-height: 150%;
213
+
214
+ a {
215
+ color: white;
216
+ font-weight: bold;
217
+ text-decoration: none;
218
+ padding: 0 4px;
219
+ border-radius: 4px;
220
+ border: 1px solid lighten($pink, 4%);
221
+
222
+ &:hover {
223
+ background: darken($pink, 3%);
224
+ border: 1px solid lighten($pink, 4%);
225
+ }
226
+ }
227
+ }
228
+
229
+
230
+ p {
231
+ line-height: 150%;
232
+ code {
233
+ background: rgba(0,0,0, 0.1);
234
+ border-radius: 4px;
235
+ padding: 1px 4px;
236
+ }
237
+ }
238
+
239
+ .comments {
240
+ font-size: 12px;
241
+ }
242
+
243
+ .index {
244
+ line-height: 150%;
245
+ margin-bottom: 20px;
246
+
247
+ ul {
248
+ margin: 0;
249
+ }
250
+ }
251
+
252
+ .highlight {
253
+ background: #333;
254
+ color: white;
255
+ font-size: 14px;
256
+ padding: 10px;
257
+ box-shadow: 0px 1px 3px rgba(0,0,0, 0.7), inset 0px 0px 0px 1px rgba(255,255,255,0.3);
258
+ border-radius: 2px;
259
+ border: 1px solid #222;
260
+
261
+
262
+ // builtins
263
+ .nb {
264
+ color: #FFA67C;
265
+ }
266
+
267
+ // strings
268
+ .s, .s1, .s2, .se, .nt {
269
+ color: #ffe898;
270
+ }
271
+
272
+ // proper names
273
+ .nc, .vc, .bp {
274
+ color: #98d9ff;
275
+ }
276
+
277
+ // true, false, nil
278
+ .kc {
279
+ color: #acfff0;
280
+ }
281
+
282
+ // function lit, braces, parens
283
+ .nf, .kt {
284
+ color: #9fff98;
285
+ }
286
+
287
+ .nv {
288
+ color: #ff9898;
289
+ }
290
+
291
+ // keywords
292
+ .k, .kd, .na {
293
+ color: #cb98ff;
294
+ }
295
+
296
+ .c1, .c2 {
297
+ color: #929292;
298
+ }
299
+
300
+ .m, .mi, .mf, .mh, .o {
301
+ color: #9495ff;
302
+ }
303
+ }
lib/scssphp/site/templates/index.html ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE HTML>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <title>$if{"title"}[[$title - ]]scssphp</title>
6
+ <link href='http://fonts.googleapis.com/css?family=Lato:400,900|Quicksand' rel='stylesheet' type='text/css'>
7
+ <link rel="stylesheet" href="$root/style/normalize.css" />
8
+ <link rel="stylesheet" href="$root/style/style.css?$generate_date" />
9
+ $analytics{"UA-136625-1"}
10
+ </head>
11
+ <body>
12
+ <div class="header">
13
+ <div class="color">
14
+ <div class="inner">
15
+ <div class="download-area">
16
+ <a href="$root/src/scssphp-$current_version.tar.gz">
17
+ <div class="download-button" id="download-button">
18
+ <div class="top">Download</div>
19
+ <div class="sub">scssphp-$current_version.tar.gz</div>
20
+ </div>
21
+ </a>
22
+ </div>
23
+
24
+ <h1><a href="$root">scssphp</a></h1>
25
+ </div>
26
+ </div>
27
+
28
+ <div class="nav">
29
+ <div class="inner">
30
+ <div class="social">
31
+ <a href="https://twitter.com/share" class="twitter-share-button" data-url="http://leafo.net/scssphp/" data-text="scssphp v$current_version - SCSS compiler for PHP" data-count="horizontal" data-via="moonscript">Tweet</a><script type="text/javascript" src="//platform.twitter.com/widgets.js"></script>
32
+ <a href="https://twitter.com/moonscript" class="twitter-follow-button" data-width="70px" data-show-count="false" data-show-screen-name="false">Follow @moonscript</a>
33
+ </div>
34
+
35
+ <a href="$root/#installing">Install</a>
36
+ &middot;
37
+ <a href="$root/#quickstart">Quickstart</a>
38
+ &middot;
39
+ <a href="$root/docs/">Docs</a>
40
+ &middot;
41
+ <a href="$root/#comments">Comments</a>
42
+ </div>
43
+ </div>
44
+
45
+ </div>
46
+
47
+ <div class="body">
48
+ <div class="inner">
49
+ $body
50
+ </div>
51
+ </div>
52
+
53
+ <div class="footer">
54
+ <div class="inner">
55
+ <div>
56
+ created by <a href="http://leafo.net">leaf corcoran</a> &middot; scssphp is licensed under GPL3/MIT
57
+ </div>
58
+ <div>
59
+ generated by <a href="http://github.com/leafo/sitegen">sitegen</a> on $generate_date
60
+ </div>
61
+ </div>
62
+ </div>
63
+
64
+ <script type="text/javascript">
65
+ (function() {
66
+ document.getElementById("download-button").onclick = function() {
67
+ _gaq.push(['_trackEvent', 'scssphp', 'click', 'download-button']);
68
+ }
69
+ var link = document.getElementById("download-link");
70
+ if (link) link.onclick = function() {
71
+ _gaq.push(['_trackEvent', 'scssphp', 'click', 'download-link']);
72
+ }
73
+ })();
74
+ </script>
75
+
76
+ <script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="https://platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script>
77
+
78
+
79
+ <a href="https://github.com/leafo/scssphp"><img style="position: fixed; top: 0; right: 0; border: 0;" src="https://s3.amazonaws.com/github/ribbons/forkme_right_red_aa0000.png" alt="Fork me on GitHub"></a>
80
+ </body>
81
+ </html>
lib/scssphp/site/www/img/tile.png ADDED
Binary file
lib/scssphp/site/www/style/normalize.css ADDED
@@ -0,0 +1,500 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*! normalize.css 2012-07-07T09:50 UTC - http://github.com/necolas/normalize.css */
2
+
3
+ /* ==========================================================================
4
+ HTML5 display definitions
5
+ ========================================================================== */
6
+
7
+ /*
8
+ * Corrects `block` display not defined in IE6/7/8/9 & FF3.
9
+ */
10
+
11
+ article,
12
+ aside,
13
+ details,
14
+ figcaption,
15
+ figure,
16
+ footer,
17
+ header,
18
+ hgroup,
19
+ nav,
20
+ section,
21
+ summary {
22
+ display: block;
23
+ }
24
+
25
+ /*
26
+ * Corrects `inline-block` display not defined in IE6/7/8/9 & FF3.
27
+ */
28
+
29
+ audio,
30
+ canvas,
31
+ video {
32
+ display: inline-block;
33
+ *display: inline;
34
+ *zoom: 1;
35
+ }
36
+
37
+ /*
38
+ * Prevents modern browsers from displaying `audio` without controls.
39
+ * Remove excess height in iOS5 devices.
40
+ */
41
+
42
+ audio:not([controls]) {
43
+ display: none;
44
+ height: 0;
45
+ }
46
+
47
+ /*
48
+ * Addresses styling for `hidden` attribute not present in IE7/8/9, FF3, S4.
49
+ * Known issue: no IE6 support.
50
+ */
51
+
52
+ [hidden] {
53
+ display: none;
54
+ }
55
+
56
+ /* ==========================================================================
57
+ Base
58
+ ========================================================================== */
59
+
60
+ /*
61
+ * 1. Corrects text resizing oddly in IE6/7 when body `font-size` is set using
62
+ * `em` units.
63
+ * 2. Prevents iOS text size adjust after orientation change, without disabling
64
+ * user zoom.
65
+ */
66
+
67
+ html {
68
+ font-size: 100%; /* 1 */
69
+ -webkit-text-size-adjust: 100%; /* 2 */
70
+ -ms-text-size-adjust: 100%; /* 2 */
71
+ }
72
+
73
+ /*
74
+ * Addresses `font-family` inconsistency between `textarea` and other form
75
+ * elements.
76
+ */
77
+
78
+ html,
79
+ button,
80
+ input,
81
+ select,
82
+ textarea {
83
+ font-family: sans-serif;
84
+ }
85
+
86
+ /*
87
+ * Addresses margins handled incorrectly in IE6/7.
88
+ */
89
+
90
+ body {
91
+ margin: 0;
92
+ }
93
+
94
+ /* ==========================================================================
95
+ Links
96
+ ========================================================================== */
97
+
98
+ /*
99
+ * Addresses `outline` inconsistency between Chrome and other browsers.
100
+ */
101
+
102
+ a:focus {
103
+ outline: thin dotted;
104
+ }
105
+
106
+ /*
107
+ * Improves readability when focused and also mouse hovered in all browsers.
108
+ * people.opera.com/patrickl/experiments/keyboard/test
109
+ */
110
+
111
+ a:active,
112
+ a:hover {
113
+ outline: 0;
114
+ }
115
+
116
+ /* ==========================================================================
117
+ Typography
118
+ ========================================================================== */
119
+
120
+ /*
121
+ * Addresses font sizes and margins set differently in IE6/7.
122
+ * Addresses font sizes within `section` and `article` in FF4+, Chrome, S5.
123
+ */
124
+
125
+ h1 {
126
+ font-size: 2em;
127
+ margin: 0.67em 0;
128
+ }
129
+
130
+ h2 {
131
+ font-size: 1.5em;
132
+ margin: 0.83em 0;
133
+ }
134
+
135
+ h3 {
136
+ font-size: 1.17em;
137
+ margin: 1em 0;
138
+ }
139
+
140
+ h4 {
141
+ font-size: 1em;
142
+ margin: 1.33em 0;
143
+ }
144
+
145
+ h5 {
146
+ font-size: 0.83em;
147
+ margin: 1.67em 0;
148
+ }
149
+
150
+ h6 {
151
+ font-size: 0.75em;
152
+ margin: 2.33em 0;
153
+ }
154
+
155
+ /*
156
+ * Addresses styling not present in IE7/8/9, S5, Chrome.
157
+ */
158
+
159
+ abbr[title] {
160
+ border-bottom: 1px dotted;
161
+ }
162
+
163
+ /*
164
+ * Addresses style set to `bolder` in FF3+, S4/5, Chrome.
165
+ */
166
+
167
+ b,
168
+ strong {
169
+ font-weight: bold;
170
+ }
171
+
172
+ blockquote {
173
+ margin: 1em 40px;
174
+ }
175
+
176
+ /*
177
+ * Addresses styling not present in S5, Chrome.
178
+ */
179
+
180
+ dfn {
181
+ font-style: italic;
182
+ }
183
+
184
+ /*
185
+ * Addresses styling not present in IE6/7/8/9.
186
+ */
187
+
188
+ mark {
189
+ background: #ff0;
190
+ color: #000;
191
+ }
192
+
193
+ /*
194
+ * Addresses margins set differently in IE6/7.
195
+ */
196
+
197
+ p,
198
+ pre {
199
+ margin: 1em 0;
200
+ }
201
+
202
+ /*
203
+ * Corrects font family set oddly in IE6, S4/5, Chrome.
204
+ * en.wikipedia.org/wiki/User:Davidgothberg/Test59
205
+ */
206
+
207
+ code,
208
+ kbd,
209
+ pre,
210
+ samp {
211
+ font-family: monospace, serif;
212
+ _font-family: 'courier new', monospace;
213
+ font-size: 1em;
214
+ }
215
+
216
+ /*
217
+ * Improves readability of pre-formatted text in all browsers.
218
+ */
219
+
220
+ pre {
221
+ white-space: pre;
222
+ white-space: pre-wrap;
223
+ word-wrap: break-word;
224
+ }
225
+
226
+ /*
227
+ * Addresses CSS quotes not supported in IE6/7.
228
+ */
229
+
230
+ q {
231
+ quotes: none;
232
+ }
233
+
234
+ /*
235
+ * Addresses `quotes` property not supported in S4.
236
+ */
237
+
238
+ q:before,
239
+ q:after {
240
+ content: '';
241
+ content: none;
242
+ }
243
+
244
+ small {
245
+ font-size: 75%;
246
+ }
247
+
248
+ /*
249
+ * Prevents `sub` and `sup` affecting `line-height` in all browsers.
250
+ * gist.github.com/413930
251
+ */
252
+
253
+ sub,
254
+ sup {
255
+ font-size: 75%;
256
+ line-height: 0;
257
+ position: relative;
258
+ vertical-align: baseline;
259
+ }
260
+
261
+ sup {
262
+ top: -0.5em;
263
+ }
264
+
265
+ sub {
266
+ bottom: -0.25em;
267
+ }
268
+
269
+ /* ==========================================================================
270
+ Lists
271
+ ========================================================================== */
272
+
273
+ /*
274
+ * Addresses margins set differently in IE6/7.
275
+ */
276
+
277
+ dl,
278
+ menu,
279
+ ol,
280
+ ul {
281
+ margin: 1em 0;
282
+ }
283
+
284
+ dd {
285
+ margin: 0 0 0 40px;
286
+ }
287
+
288
+ /*
289
+ * Addresses paddings set differently in IE6/7.
290
+ */
291
+
292
+ menu,
293
+ ol,
294
+ ul {
295
+ padding: 0 0 0 40px;
296
+ }
297
+
298
+ /*
299
+ * Corrects list images handled incorrectly in IE7.
300
+ */
301
+
302
+ nav ul,
303
+ nav ol {
304
+ list-style: none;
305
+ list-style-image: none;
306
+ }
307
+
308
+ /* ==========================================================================
309
+ Embedded content
310
+ ========================================================================== */
311
+
312
+ /*
313
+ * 1. Removes border when inside `a` element in IE6/7/8/9, FF3.
314
+ * 2. Improves image quality when scaled in IE7.
315
+ * code.flickr.com/blog/2008/11/12/on-ui-quality-the-little-things-client-side-image-resizing/
316
+ */
317
+
318
+ img {
319
+ border: 0; /* 1 */
320
+ -ms-interpolation-mode: bicubic; /* 2 */
321
+ }
322
+
323
+ /*
324
+ * Corrects overflow displayed oddly in IE9.
325
+ */
326
+
327
+ svg:not(:root) {
328
+ overflow: hidden;
329
+ }
330
+
331
+ /* ==========================================================================
332
+ Figures
333
+ ========================================================================== */
334
+
335
+ /*
336
+ * Addresses margin not present in IE6/7/8/9, S5, O11.
337
+ */
338
+
339
+ figure {
340
+ margin: 0;
341
+ }
342
+
343
+ /* ==========================================================================
344
+ Forms
345
+ ========================================================================== */
346
+
347
+ /*
348
+ * Corrects margin displayed oddly in IE6/7.
349
+ */
350
+
351
+ form {
352
+ margin: 0;
353
+ }
354
+
355
+ /*
356
+ * Define consistent border, margin, and padding.
357
+ */
358
+
359
+ fieldset {
360
+ border: 1px solid #c0c0c0;
361
+ margin: 0 2px;
362
+ padding: 0.35em 0.625em 0.75em;
363
+ }
364
+
365
+ /*
366
+ * 1. Corrects color not being inherited in IE6/7/8/9.
367
+ * 2. Corrects text not wrapping in FF3.
368
+ * 3. Corrects alignment displayed oddly in IE6/7.
369
+ */
370
+
371
+ legend {
372
+ border: 0; /* 1 */
373
+ padding: 0;
374
+ white-space: normal; /* 2 */
375
+ *margin-left: -7px; /* 3 */
376
+ }
377
+
378
+ /*
379
+ * 1. Corrects font size not being inherited in all browsers.
380
+ * 2. Addresses margins set differently in IE6/7, FF3+, S5, Chrome.
381
+ * 3. Improves appearance and consistency in all browsers.
382
+ */
383
+
384
+ button,
385
+ input,
386
+ select,
387
+ textarea {
388
+ font-size: 100%; /* 1 */
389
+ margin: 0; /* 2 */
390
+ vertical-align: baseline; /* 3 */
391
+ *vertical-align: middle; /* 3 */
392
+ }
393
+
394
+ /*
395
+ * Addresses FF3/4 setting `line-height` on `input` using `!important` in the
396
+ * UA stylesheet.
397
+ */
398
+
399
+ button,
400
+ input {
401
+ line-height: normal;
402
+ }
403
+
404
+ /*
405
+ * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
406
+ * and `video` controls.
407
+ * 2. Corrects inability to style clickable `input` types in iOS.
408
+ * 3. Improves usability and consistency of cursor style between image-type
409
+ * `input` and others.
410
+ * 4. Removes inner spacing in IE7 without affecting normal text inputs.
411
+ * Known issue: inner spacing remains in IE6.
412
+ */
413
+
414
+ button,
415
+ html input[type="button"], /* 1 */
416
+ input[type="reset"],
417
+ input[type="submit"] {
418
+ -webkit-appearance: button; /* 2 */
419
+ cursor: pointer; /* 3 */
420
+ *overflow: visible; /* 4 */
421
+ }
422
+
423
+ /*
424
+ * Re-set default cursor for disabled elements.
425
+ */
426
+
427
+ button[disabled],
428
+ input[disabled] {
429
+ cursor: default;
430
+ }
431
+
432
+ /*
433
+ * 1. Addresses box sizing set to content-box in IE8/9.
434
+ * 2. Removes excess padding in IE8/9.
435
+ * 3. Removes excess padding in IE7.
436
+ * Known issue: excess padding remains in IE6.
437
+ */
438
+
439
+ input[type="checkbox"],
440
+ input[type="radio"] {
441
+ box-sizing: border-box; /* 1 */
442
+ padding: 0; /* 2 */
443
+ *height: 13px; /* 3 */
444
+ *width: 13px; /* 3 */
445
+ }
446
+
447
+ /*
448
+ * 1. Addresses `appearance` set to `searchfield` in S5, Chrome.
449
+ * 2. Addresses `box-sizing` set to `border-box` in S5, Chrome (include `-moz`
450
+ * to future-proof).
451
+ */
452
+
453
+ input[type="search"] {
454
+ -webkit-appearance: textfield; /* 1 */
455
+ -moz-box-sizing: content-box;
456
+ -webkit-box-sizing: content-box; /* 2 */
457
+ box-sizing: content-box;
458
+ }
459
+
460
+ /*
461
+ * Removes inner padding and search cancel button in S5, Chrome on OS X.
462
+ */
463
+
464
+ input[type="search"]::-webkit-search-cancel-button,
465
+ input[type="search"]::-webkit-search-decoration {
466
+ -webkit-appearance: none;
467
+ }
468
+
469
+ /*
470
+ * Removes inner padding and border in FF3+.
471
+ */
472
+
473
+ button::-moz-focus-inner,
474
+ input::-moz-focus-inner {
475
+ border: 0;
476
+ padding: 0;
477
+ }
478
+
479
+ /*
480
+ * 1. Removes default vertical scrollbar in IE6/7/8/9.
481
+ * 2. Improves readability and alignment in all browsers.
482
+ */
483
+
484
+ textarea {
485
+ overflow: auto; /* 1 */
486
+ vertical-align: top; /* 2 */
487
+ }
488
+
489
+ /* ==========================================================================
490
+ Tables
491
+ ========================================================================== */
492
+
493
+ /*
494
+ * Remove most spacing between table cells.
495
+ */
496
+
497
+ table {
498
+ border-collapse: collapse;
499
+ border-spacing: 0;
500
+ }
lib/scssphp/src/Colors.php ADDED
@@ -0,0 +1,179 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * SCSSPHP
4
+ *
5
+ * @copyright 2012-2014 Leaf Corcoran
6
+ *
7
+ * @license http://opensource.org/licenses/gpl-license GPL-3.0
8
+ * @license http://opensource.org/licenses/MIT MIT
9
+ *
10
+ * @link http://leafo.net/scssphp
11
+ */
12
+
13
+ namespace Leafo\ScssPhp;
14
+
15
+ use Leafo\ScssPhp\Parser;
16
+
17
+ /**
18
+ * CSS Colors
19
+ *
20
+ * @author Leaf Corcoran <leafot@gmail.com>
21
+ */
22
+ class Colors
23
+ {
24
+ /**
25
+ * CSS Colors
26
+ *
27
+ * @see http://www.w3.org/TR/css3-color
28
+ */
29
+ public static $cssColors = array(
30
+ 'aliceblue' => '240,248,255',
31
+ 'antiquewhite' => '250,235,215',
32
+ 'aqua' => '0,255,255',
33
+ 'aquamarine' => '127,255,212',
34
+ 'azure' => '240,255,255',
35
+ 'beige' => '245,245,220',
36
+ 'bisque' => '255,228,196',
37
+ 'black' => '0,0,0',
38
+ 'blanchedalmond' => '255,235,205',
39
+ 'blue' => '0,0,255',
40
+ 'blueviolet' => '138,43,226',
41
+ 'brown' => '165,42,42',
42
+ 'burlywood' => '222,184,135',
43
+ 'cadetblue' => '95,158,160',
44
+ 'chartreuse' => '127,255,0',
45
+ 'chocolate' => '210,105,30',
46
+ 'coral' => '255,127,80',
47
+ 'cornflowerblue' => '100,149,237',
48
+ 'cornsilk' => '255,248,220',
49
+ 'crimson' => '220,20,60',
50
+ 'cyan' => '0,255,255',
51
+ 'darkblue' => '0,0,139',
52
+ 'darkcyan' => '0,139,139',
53
+ 'darkgoldenrod' => '184,134,11',
54
+ 'darkgray' => '169,169,169',
55
+ 'darkgreen' => '0,100,0',
56
+ 'darkgrey' => '169,169,169',
57
+ 'darkkhaki' => '189,183,107',
58
+ 'darkmagenta' => '139,0,139',
59
+ 'darkolivegreen' => '85,107,47',
60
+ 'darkorange' => '255,140,0',
61
+ 'darkorchid' => '153,50,204',
62
+ 'darkred' => '139,0,0',
63
+ 'darksalmon' => '233,150,122',
64
+ 'darkseagreen' => '143,188,143',
65
+ 'darkslateblue' => '72,61,139',
66
+ 'darkslategray' => '47,79,79',
67
+ 'darkslategrey' => '47,79,79',
68
+ 'darkturquoise' => '0,206,209',
69
+ 'darkviolet' => '148,0,211',
70
+ 'deeppink' => '255,20,147',
71
+ 'deepskyblue' => '0,191,255',
72
+ 'dimgray' => '105,105,105',
73
+ 'dimgrey' => '105,105,105',
74
+ 'dodgerblue' => '30,144,255',
75
+ 'firebrick' => '178,34,34',
76
+ 'floralwhite' => '255,250,240',
77
+ 'forestgreen' => '34,139,34',
78
+ 'fuchsia' => '255,0,255',
79
+ 'gainsboro' => '220,220,220',
80
+ 'ghostwhite' => '248,248,255',
81
+ 'gold' => '255,215,0',
82
+ 'goldenrod' => '218,165,32',
83
+ 'gray' => '128,128,128',
84
+ 'green' => '0,128,0',
85
+ 'greenyellow' => '173,255,47',
86
+ 'grey' => '128,128,128',
87
+ 'honeydew' => '240,255,240',
88
+ 'hotpink' => '255,105,180',
89
+ 'indianred' => '205,92,92',
90
+ 'indigo' => '75,0,130',
91
+ 'ivory' => '255,255,240',
92
+ 'khaki' => '240,230,140',
93
+ 'lavender' => '230,230,250',
94
+ 'lavenderblush' => '255,240,245',
95
+ 'lawngreen' => '124,252,0',
96
+ 'lemonchiffon' => '255,250,205',
97
+ 'lightblue' => '173,216,230',
98
+ 'lightcoral' => '240,128,128',
99
+ 'lightcyan' => '224,255,255',
100
+ 'lightgoldenrodyellow' => '250,250,210',
101
+ 'lightgray' => '211,211,211',
102
+ 'lightgreen' => '144,238,144',
103
+ 'lightgrey' => '211,211,211',
104
+ 'lightpink' => '255,182,193',
105
+ 'lightsalmon' => '255,160,122',
106
+ 'lightseagreen' => '32,178,170',
107
+ 'lightskyblue' => '135,206,250',
108
+ 'lightslategray' => '119,136,153',
109
+ 'lightslategrey' => '119,136,153',
110
+ 'lightsteelblue' => '176,196,222',
111
+ 'lightyellow' => '255,255,224',
112
+ 'lime' => '0,255,0',
113
+ 'limegreen' => '50,205,50',
114
+ 'linen' => '250,240,230',
115
+ 'magenta' => '255,0,255',
116
+ 'maroon' => '128,0,0',
117
+ 'mediumaquamarine' => '102,205,170',
118
+ 'mediumblue' => '0,0,205',
119
+ 'mediumorchid' => '186,85,211',
120
+ 'mediumpurple' => '147,112,219',
121
+ 'mediumseagreen' => '60,179,113',
122
+ 'mediumslateblue' => '123,104,238',
123
+ 'mediumspringgreen' => '0,250,154',
124
+ 'mediumturquoise' => '72,209,204',
125
+ 'mediumvioletred' => '199,21,133',
126
+ 'midnightblue' => '25,25,112',
127
+ 'mintcream' => '245,255,250',
128
+ 'mistyrose' => '255,228,225',
129
+ 'moccasin' => '255,228,181',
130
+ 'navajowhite' => '255,222,173',
131
+ 'navy' => '0,0,128',
132
+ 'oldlace' => '253,245,230',
133
+ 'olive' => '128,128,0',
134
+ 'olivedrab' => '107,142,35',
135
+ 'orange' => '255,165,0',
136
+ 'orangered' => '255,69,0',
137
+ 'orchid' => '218,112,214',
138
+ 'palegoldenrod' => '238,232,170',
139
+ 'palegreen' => '152,251,152',
140
+ 'paleturquoise' => '175,238,238',
141
+ 'palevioletred' => '219,112,147',
142
+ 'papayawhip' => '255,239,213',
143
+ 'peachpuff' => '255,218,185',
144
+ 'peru' => '205,133,63',
145
+ 'pink' => '255,192,203',
146
+ 'plum' => '221,160,221',
147
+ 'powderblue' => '176,224,230',
148
+ 'purple' => '128,0,128',
149
+ 'red' => '255,0,0',
150
+ 'rosybrown' => '188,143,143',
151
+ 'royalblue' => '65,105,225',
152
+ 'saddlebrown' => '139,69,19',
153
+ 'salmon' => '250,128,114',
154
+ 'sandybrown' => '244,164,96',
155
+ 'seagreen' => '46,139,87',
156
+ 'seashell' => '255,245,238',
157
+ 'sienna' => '160,82,45',
158
+ 'silver' => '192,192,192',
159
+ 'skyblue' => '135,206,235',
160
+ 'slateblue' => '106,90,205',
161
+ 'slategray' => '112,128,144',
162
+ 'slategrey' => '112,128,144',
163
+ 'snow' => '255,250,250',
164
+ 'springgreen' => '0,255,127',
165
+ 'steelblue' => '70,130,180',
166
+ 'tan' => '210,180,140',
167
+ 'teal' => '0,128,128',
168
+ 'thistle' => '216,191,216',
169
+ 'tomato' => '255,99,71',
170
+ 'transparent' => '0,0,0,0',
171
+ 'turquoise' => '64,224,208',
172
+ 'violet' => '238,130,238',
173
+ 'wheat' => '245,222,179',
174
+ 'white' => '255,255,255',
175
+ 'whitesmoke' => '245,245,245',
176
+ 'yellow' => '255,255,0',
177
+ 'yellowgreen' => '154,205,50'
178
+ );
179
+ }
lib/scssphp/src/Compiler.php ADDED
@@ -0,0 +1,3006 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * SCSSPHP
4
+ *
5
+ * @copyright 2012-2014 Leaf Corcoran
6
+ *
7
+ * @license http://opensource.org/licenses/gpl-license GPL-3.0
8
+ * @license http://opensource.org/licenses/MIT MIT
9
+ *
10
+ * @link http://leafo.net/scssphp
11
+ */
12
+
13
+ namespace Leafo\ScssPhp;
14
+
15
+ use Leafo\ScssPhp\Colors;
16
+ use Leafo\ScssPhp\Parser;
17
+
18
+ /**
19
+ * The scss compiler and parser.
20
+ *
21
+ * Converting SCSS to CSS is a three stage process. The incoming file is parsed
22
+ * by `Parser` into a syntax tree, then it is compiled into another tree
23
+ * representing the CSS structure by `Compiler`. The CSS tree is fed into a
24
+ * formatter, like `Formatter` which then outputs CSS as a string.
25
+ *
26
+ * During the first compile, all values are *reduced*, which means that their
27
+ * types are brought to the lowest form before being dump as strings. This
28
+ * handles math equations, variable dereferences, and the like.
29
+ *
30
+ * The `parse` function of `Compiler` is the entry point.
31
+ *
32
+ * In summary:
33
+ *
34
+ * The `Compiler` class creates an instance of the parser, feeds it SCSS code,
35
+ * then transforms the resulting tree to a CSS tree. This class also holds the
36
+ * evaluation context, such as all available mixins and variables at any given
37
+ * time.
38
+ *
39
+ * The `Parser` class is only concerned with parsing its input.
40
+ *
41
+ * The `Formatter` takes a CSS tree, and dumps it to a formatted string,
42
+ * handling things like indentation.
43
+ */
44
+
45
+ /**
46
+ * SCSS compiler
47
+ *
48
+ * @author Leaf Corcoran <leafot@gmail.com>
49
+ */
50
+ class Compiler
51
+ {
52
+ static public $VERSION = 'v0.1.1';
53
+
54
+ static protected $operatorNames = array(
55
+ '+' => 'add',
56
+ '-' => 'sub',
57
+ '*' => 'mul',
58
+ '/' => 'div',
59
+ '%' => 'mod',
60
+
61
+ '==' => 'eq',
62
+ '!=' => 'neq',
63
+ '<' => 'lt',
64
+ '>' => 'gt',
65
+
66
+ '<=' => 'lte',
67
+ '>=' => 'gte',
68
+ );
69
+
70
+ static protected $namespaces = array(
71
+ 'special' => '%',
72
+ 'mixin' => '@',
73
+ 'function' => '^',
74
+ );
75
+
76
+ static protected $unitTable = array(
77
+ 'in' => array(
78
+ 'in' => 1,
79
+ 'pt' => 72,
80
+ 'pc' => 6,
81
+ 'cm' => 2.54,
82
+ 'mm' => 25.4,
83
+ 'px' => 96,
84
+ )
85
+ );
86
+
87
+ static public $true = array('keyword', 'true');
88
+ static public $false = array('keyword', 'false');
89
+ static public $null = array('null');
90
+
91
+ static public $defaultValue = array('keyword', '');
92
+ static public $selfSelector = array('self');
93
+
94
+ protected $importPaths = array('');
95
+ protected $importCache = array();
96
+
97
+ protected $userFunctions = array();
98
+ protected $registeredVars = array();
99
+
100
+ protected $numberPrecision = 5;
101
+
102
+ protected $formatter = 'Leafo\ScssPhp\Formatter\Nested';
103
+
104
+ /**
105
+ * Compile scss
106
+ *
107
+ * @param string $code
108
+ * @param string $name
109
+ *
110
+ * @return string
111
+ */
112
+ public function compile($code, $name = null)
113
+ {
114
+ $this->indentLevel = -1;
115
+ $this->commentsSeen = array();
116
+ $this->extends = array();
117
+ $this->extendsMap = array();
118
+ $this->parsedFiles = array();
119
+ $this->env = null;
120
+ $this->scope = null;
121
+
122
+ $locale = setlocale(LC_NUMERIC, 0);
123
+ setlocale(LC_NUMERIC, 'C');
124
+
125
+ $this->parser = new Parser($name);
126
+
127
+ $tree = $this->parser->parse($code);
128
+
129
+ $this->formatter = new $this->formatter();
130
+
131
+ $this->pushEnv($tree);
132
+ $this->injectVariables($this->registeredVars);
133
+ $this->compileRoot($tree);
134
+ $this->popEnv();
135
+
136
+ $out = $this->formatter->format($this->scope);
137
+
138
+ setlocale(LC_NUMERIC, $locale);
139
+
140
+ return $out;
141
+ }
142
+
143
+ protected function isSelfExtend($target, $origin)
144
+ {
145
+ foreach ($origin as $sel) {
146
+ if (in_array($target, $sel)) {
147
+ return true;
148
+ }
149
+ }
150
+
151
+ return false;
152
+ }
153
+
154
+ protected function pushExtends($target, $origin)
155
+ {
156
+ if ($this->isSelfExtend($target, $origin)) {
157
+ return;
158
+ }
159
+
160
+ $i = count($this->extends);
161
+ $this->extends[] = array($target, $origin);
162
+
163
+ foreach ($target as $part) {
164
+ if (isset($this->extendsMap[$part])) {
165
+ $this->extendsMap[$part][] = $i;
166
+ } else {
167
+ $this->extendsMap[$part] = array($i);
168
+ }
169
+ }
170
+ }
171
+
172
+ protected function makeOutputBlock($type, $selectors = null)
173
+ {
174
+ $out = new \stdClass;
175
+ $out->type = $type;
176
+ $out->lines = array();
177
+ $out->children = array();
178
+ $out->parent = $this->scope;
179
+ $out->selectors = $selectors;
180
+ $out->depth = $this->env->depth;
181
+
182
+ return $out;
183
+ }
184
+
185
+ protected function matchExtendsSingle($single, &$outOrigin)
186
+ {
187
+ $counts = array();
188
+ foreach ($single as $part) {
189
+ if (!is_string($part)) {
190
+ return false; // hmm
191
+ }
192
+
193
+ if (isset($this->extendsMap[$part])) {
194
+ foreach ($this->extendsMap[$part] as $idx) {
195
+ $counts[$idx] =
196
+ isset($counts[$idx]) ? $counts[$idx] + 1 : 1;
197
+ }
198
+ }
199
+ }
200
+
201
+ $outOrigin = array();
202
+ $found = false;
203
+
204
+ foreach ($counts as $idx => $count) {
205
+ list($target, $origin) = $this->extends[$idx];
206
+
207
+ // check count
208
+ if ($count != count($target)) {
209
+ continue;
210
+ }
211
+
212
+ // check if target is subset of single
213
+ if (array_diff(array_intersect($single, $target), $target)) {
214
+ continue;
215
+ }
216
+
217
+ $rem = array_diff($single, $target);
218
+
219
+ foreach ($origin as $j => $new) {
220
+ // prevent infinite loop when target extends itself
221
+ foreach ($new as $new_selector) {
222
+ if (!array_diff($single, $new_selector)) {
223
+ continue 2;
224
+ }
225
+ }
226
+
227
+ $origin[$j][count($origin[$j]) - 1] = $this->combineSelectorSingle(end($new), $rem);
228
+ }
229
+
230
+ $outOrigin = array_merge($outOrigin, $origin);
231
+
232
+ $found = true;
233
+ }
234
+
235
+ return $found;
236
+ }
237
+
238
+ protected function combineSelectorSingle($base, $other)
239
+ {
240
+ $tag = null;
241
+ $out = array();
242
+
243
+ foreach (array($base, $other) as $single) {
244
+ foreach ($single as $part) {
245
+ if (preg_match('/^[^\[.#:]/', $part)) {
246
+ $tag = $part;
247
+ } else {
248
+ $out[] = $part;
249
+ }
250
+ }
251
+ }
252
+
253
+ if ($tag) {
254
+ array_unshift($out, $tag);
255
+ }
256
+
257
+ return $out;
258
+ }
259
+
260
+ protected function matchExtends($selector, &$out, $from = 0, $initial = true)
261
+ {
262
+ foreach ($selector as $i => $part) {
263
+ if ($i < $from) {
264
+ continue;
265
+ }
266
+
267
+ if ($this->matchExtendsSingle($part, $origin)) {
268
+ $before = array_slice($selector, 0, $i);
269
+ $after = array_slice($selector, $i + 1);
270
+
271
+ foreach ($origin as $new) {
272
+ $k = 0;
273
+
274
+ // remove shared parts
275
+ if ($initial) {
276
+ foreach ($before as $k => $val) {
277
+ if (!isset($new[$k]) || $val != $new[$k]) {
278
+ break;
279
+ }
280
+ }
281
+ }
282
+
283
+ $result = array_merge(
284
+ $before,
285
+ $k > 0 ? array_slice($new, $k) : $new,
286
+ $after
287
+ );
288
+
289
+ if ($result == $selector) {
290
+ continue;
291
+ }
292
+
293
+ $out[] = $result;
294
+
295
+ // recursively check for more matches
296
+ $this->matchExtends($result, $out, $i, false);
297
+
298
+ // selector sequence merging
299
+ if (!empty($before) && count($new) > 1) {
300
+ $result2 = array_merge(
301
+ array_slice($new, 0, -1),
302
+ $k > 0 ? array_slice($before, $k) : $before,
303
+ array_slice($new, -1),
304
+ $after
305
+ );
306
+
307
+ $out[] = $result2;
308
+ }
309
+ }
310
+ }
311
+ }
312
+ }
313
+
314
+ protected function flattenSelectors($block, $parentKey = null)
315
+ {
316
+ if ($block->selectors) {
317
+ $selectors = array();
318
+
319
+ foreach ($block->selectors as $s) {
320
+ $selectors[] = $s;
321
+
322
+ if (!is_array($s)) {
323
+ continue;
324
+ }
325
+
326
+ // check extends
327
+ if (!empty($this->extendsMap)) {
328
+ $this->matchExtends($s, $selectors);
329
+ }
330
+ }
331
+
332
+ $block->selectors = array();
333
+ $placeholderSelector = false;
334
+
335
+ foreach ($selectors as $selector) {
336
+ if ($this->hasSelectorPlaceholder($selector)) {
337
+ $placeholderSelector = true;
338
+ continue;
339
+ }
340
+
341
+ $block->selectors[] = $this->compileSelector($selector);
342
+ }
343
+
344
+ if ($placeholderSelector && 0 == count($block->selectors) && null !== $parentKey) {
345
+ unset($block->parent->children[$parentKey]);
346
+
347
+ return;
348
+ }
349
+ }
350
+
351
+ foreach ($block->children as $key => $child) {
352
+ $this->flattenSelectors($child, $key);
353
+ }
354
+ }
355
+
356
+ protected function compileRoot($rootBlock)
357
+ {
358
+ $this->scope = $this->makeOutputBlock('root');
359
+
360
+ $this->compileChildren($rootBlock->children, $this->scope);
361
+ $this->flattenSelectors($this->scope);
362
+ }
363
+
364
+ protected function compileMedia($media)
365
+ {
366
+ $this->pushEnv($media);
367
+
368
+ $mediaQuery = $this->compileMediaQuery($this->multiplyMedia($this->env));
369
+
370
+ if (!empty($mediaQuery)) {
371
+ $this->scope = $this->makeOutputBlock('media', array($mediaQuery));
372
+
373
+ $parentScope = $this->mediaParent($this->scope);
374
+ $parentScope->children[] = $this->scope;
375
+
376
+ // top level properties in a media cause it to be wrapped
377
+ $needsWrap = false;
378
+
379
+ foreach ($media->children as $child) {
380
+ $type = $child[0];
381
+ if ($type !== 'block' && $type !== 'media' && $type !== 'directive') {
382
+ $needsWrap = true;
383
+ break;
384
+ }
385
+ }
386
+
387
+ if ($needsWrap) {
388
+ $wrapped = (object)array(
389
+ 'selectors' => array(),
390
+ 'children' => $media->children
391
+ );
392
+ $media->children = array(array('block', $wrapped));
393
+ }
394
+
395
+ $this->compileChildren($media->children, $this->scope);
396
+
397
+ $this->scope = $this->scope->parent;
398
+ }
399
+
400
+ $this->popEnv();
401
+ }
402
+
403
+ protected function mediaParent($scope)
404
+ {
405
+ while (!empty($scope->parent)) {
406
+ if (!empty($scope->type) && $scope->type != 'media') {
407
+ break;
408
+ }
409
+ $scope = $scope->parent;
410
+ }
411
+
412
+ return $scope;
413
+ }
414
+
415
+ // TODO refactor compileNestedBlock and compileMedia into same thing
416
+ protected function compileNestedBlock($block, $selectors)
417
+ {
418
+ $this->pushEnv($block);
419
+
420
+ $this->scope = $this->makeOutputBlock($block->type, $selectors);
421
+ $this->scope->parent->children[] = $this->scope;
422
+ $this->compileChildren($block->children, $this->scope);
423
+
424
+ $this->scope = $this->scope->parent;
425
+ $this->popEnv();
426
+ }
427
+
428
+ /**
429
+ * Recursively compiles a block.
430
+ *
431
+ * A block is analogous to a CSS block in most cases. A single SCSS document
432
+ * is encapsulated in a block when parsed, but it does not have parent tags
433
+ * so all of its children appear on the root level when compiled.
434
+ *
435
+ * Blocks are made up of selectors and children.
436
+ *
437
+ * The children of a block are just all the blocks that are defined within.
438
+ *
439
+ * Compiling the block involves pushing a fresh environment on the stack,
440
+ * and iterating through the props, compiling each one.
441
+ *
442
+ * @see Compiler::compileChild()
443
+ *
444
+ * @param \StdClass $block
445
+ */
446
+ protected function compileBlock($block)
447
+ {
448
+ $env = $this->pushEnv($block);
449
+
450
+ $env->selectors =
451
+ array_map(array($this, 'evalSelector'), $block->selectors);
452
+
453
+ $out = $this->makeOutputBlock(null, $this->multiplySelectors($env));
454
+ $this->scope->children[] = $out;
455
+ $this->compileChildren($block->children, $out);
456
+
457
+ $this->popEnv();
458
+ }
459
+
460
+ // root level comment
461
+ protected function compileComment($block)
462
+ {
463
+ $out = $this->makeOutputBlock('comment');
464
+ $out->lines[] = $block[1];
465
+ $this->scope->children[] = $out;
466
+ }
467
+
468
+ // joins together .classes and #ids
469
+ protected function flattenSelectorSingle($single)
470
+ {
471
+ $joined = array();
472
+ foreach ($single as $part) {
473
+ if (empty($joined) ||
474
+ !is_string($part) ||
475
+ preg_match('/[\[.:#%]/', $part)
476
+ ) {
477
+ $joined[] = $part;
478
+ continue;
479
+ }
480
+
481
+ if (is_array(end($joined))) {
482
+ $joined[] = $part;
483
+ } else {
484
+ $joined[count($joined) - 1] .= $part;
485
+ }
486
+ }
487
+
488
+ return $joined;
489
+ }
490
+
491
+ // replaces all the interpolates
492
+ protected function evalSelector($selector)
493
+ {
494
+ return array_map(array($this, 'evalSelectorPart'), $selector);
495
+ }
496
+
497
+ protected function evalSelectorPart($piece)
498
+ {
499
+ foreach ($piece as &$p) {
500
+ if (!is_array($p)) {
501
+ continue;
502
+ }
503
+
504
+ switch ($p[0]) {
505
+ case 'interpolate':
506
+ $p = $this->compileValue($p);
507
+ break;
508
+ case 'string':
509
+ $p = $this->compileValue($p);
510
+ break;
511
+ }
512
+ }
513
+
514
+ return $this->flattenSelectorSingle($piece);
515
+ }
516
+
517
+ // compiles to string
518
+ // self(&) should have been replaced by now
519
+ protected function compileSelector($selector)
520
+ {
521
+ if (!is_array($selector)) {
522
+ return $selector; // media and the like
523
+ }
524
+
525
+ return implode(
526
+ ' ',
527
+ array_map(
528
+ array($this, 'compileSelectorPart'),
529
+ $selector
530
+ )
531
+ );
532
+ }
533
+
534
+ protected function compileSelectorPart($piece)
535
+ {
536
+ foreach ($piece as &$p) {
537
+ if (!is_array($p)) {
538
+ continue;
539
+ }
540
+
541
+ switch ($p[0]) {
542
+ case 'self':
543
+ $p = '&';
544
+ break;
545
+ default:
546
+ $p = $this->compileValue($p);
547
+ break;
548
+ }
549
+ }
550
+
551
+ return implode($piece);
552
+ }
553
+
554
+ protected function hasSelectorPlaceholder($selector)
555
+ {
556
+ if (!is_array($selector)) {
557
+ return false;
558
+ }
559
+
560
+ foreach ($selector as $parts) {
561
+ foreach ($parts as $part) {
562
+ if ('%' == $part[0]) {
563
+ return true;
564
+ }
565
+ }
566
+ }
567
+
568
+ return false;
569
+ }
570
+
571
+ protected function compileChildren($stms, $out)
572
+ {
573
+ foreach ($stms as $stm) {
574
+ $ret = $this->compileChild($stm, $out);
575
+
576
+ if (isset($ret)) {
577
+ return $ret;
578
+ }
579
+ }
580
+ }
581
+
582
+ protected function compileMediaQuery($queryList)
583
+ {
584
+ $out = '@media';
585
+ $first = true;
586
+
587
+ foreach ($queryList as $query) {
588
+ $type = null;
589
+ $parts = array();
590
+
591
+ foreach ($query as $q) {
592
+ switch ($q[0]) {
593
+ case 'mediaType':
594
+ if ($type) {
595
+ $type = $this->mergeMediaTypes(
596
+ $type,
597
+ array_map(array($this, 'compileValue'), array_slice($q, 1))
598
+ );
599
+
600
+ if (empty($type)) { // merge failed
601
+ return null;
602
+ }
603
+ } else {
604
+ $type = array_map(array($this, 'compileValue'), array_slice($q, 1));
605
+ }
606
+ break;
607
+ case 'mediaExp':
608
+ if (isset($q[2])) {
609
+ $parts[] = '('
610
+ . $this->compileValue($q[1])
611
+ . $this->formatter->assignSeparator
612
+ . $this->compileValue($q[2])
613
+ . ')';
614
+ } else {
615
+ $parts[] = '('
616
+ . $this->compileValue($q[1])
617
+ . ')';
618
+ }
619
+ break;
620
+ }
621
+ }
622
+
623
+ if ($type) {
624
+ array_unshift($parts, implode(' ', array_filter($type)));
625
+ }
626
+
627
+ if (!empty($parts)) {
628
+ if ($first) {
629
+ $first = false;
630
+ $out .= ' ';
631
+ } else {
632
+ $out .= $this->formatter->tagSeparator;
633
+ }
634
+
635
+ $out .= implode(' and ', $parts);
636
+ }
637
+ }
638
+
639
+ return $out;
640
+ }
641
+
642
+ protected function mergeMediaTypes($type1, $type2)
643
+ {
644
+ if (empty($type1)) {
645
+ return $type2;
646
+ }
647
+
648
+ if (empty($type2)) {
649
+ return $type1;
650
+ }
651
+
652
+ $m1 = '';
653
+ $t1 = '';
654
+
655
+ if (count($type1) > 1) {
656
+ $m1= strtolower($type1[0]);
657
+ $t1= strtolower($type1[1]);
658
+ } else {
659
+ $t1 = strtolower($type1[0]);
660
+ }
661
+
662
+ $m2 = '';
663
+ $t2 = '';
664
+
665
+ if (count($type2) > 1) {
666
+ $m2 = strtolower($type2[0]);
667
+ $t2 = strtolower($type2[1]);
668
+ } else {
669
+ $t2 = strtolower($type2[0]);
670
+ }
671
+
672
+ if (($m1 == 'not') ^ ($m2 == 'not')) {
673
+ if ($t1 == $t2) {
674
+ return null;
675
+ }
676
+
677
+ return array(
678
+ $m1 == 'not' ? $m2 : $m1,
679
+ $m1 == 'not' ? $t2 : $t1
680
+ );
681
+ }
682
+
683
+ if ($m1 == 'not' && $m2 == 'not') {
684
+ # CSS has no way of representing "neither screen nor print"
685
+ if ($t1 != $t2) {
686
+ return null;
687
+ }
688
+
689
+ return array('not', $t1);
690
+ }
691
+
692
+ if ($t1 != $t2) {
693
+ return null;
694
+ }
695
+
696
+ // t1 == t2, neither m1 nor m2 are "not"
697
+ return array(empty($m1)? $m2 : $m1, $t1);
698
+ }
699
+
700
+ // returns true if the value was something that could be imported
701
+ protected function compileImport($rawPath, $out)
702
+ {
703
+ if ($rawPath[0] == 'string') {
704
+ $path = $this->compileStringContent($rawPath);
705
+
706
+ if ($path = $this->findImport($path)) {
707
+ $this->importFile($path, $out);
708
+
709
+ return true;
710
+ }
711
+
712
+ return false;
713
+ }
714
+ if ($rawPath[0] == 'list') {
715
+ // handle a list of strings
716
+ if (count($rawPath[2]) == 0) {
717
+ return false;
718
+ }
719
+
720
+ foreach ($rawPath[2] as $path) {
721
+ if ($path[0] != 'string') {
722
+ return false;
723
+ }
724
+ }
725
+
726
+ foreach ($rawPath[2] as $path) {
727
+ $this->compileImport($path, $out);
728
+ }
729
+
730
+ return true;
731
+ }
732
+
733
+ return false;
734
+ }
735
+
736
+ // return a value to halt execution
737
+ protected function compileChild($child, $out)
738
+ {
739
+ $this->sourcePos = isset($child[-1]) ? $child[-1] : -1;
740
+ $this->sourceParser = isset($child[-2]) ? $child[-2] : $this->parser;
741
+
742
+ switch ($child[0]) {
743
+ case 'import':
744
+ list(,$rawPath) = $child;
745
+
746
+ $rawPath = $this->reduce($rawPath);
747
+ if (!$this->compileImport($rawPath, $out)) {
748
+ $out->lines[] = '@import ' . $this->compileValue($rawPath) . ';';
749
+ }
750
+ break;
751
+ case 'directive':
752
+ list(, $directive) = $child;
753
+
754
+ $s = '@' . $directive->name;
755
+ if (!empty($directive->value)) {
756
+ $s .= ' ' . $this->compileValue($directive->value);
757
+ }
758
+ $this->compileNestedBlock($directive, array($s));
759
+ break;
760
+ case 'media':
761
+ $this->compileMedia($child[1]);
762
+ break;
763
+ case 'block':
764
+ $this->compileBlock($child[1]);
765
+ break;
766
+ case 'charset':
767
+ $out->lines[] = '@charset '.$this->compileValue($child[1]).';';
768
+ break;
769
+ case 'assign':
770
+ list(,$name, $value) = $child;
771
+
772
+ if ($name[0] == 'var') {
773
+ $isDefault = !empty($child[3]);
774
+
775
+ if ($isDefault) {
776
+ $existingValue = $this->get($name[1], true);
777
+ $shouldSet = $existingValue === true || $existingValue == self::$null;
778
+ }
779
+
780
+ if (! $isDefault || $shouldSet) {
781
+ $this->set($name[1], $this->reduce($value));
782
+ }
783
+ break;
784
+ }
785
+
786
+ // if the value reduces to null from something else then
787
+ // the property should be discarded
788
+ if ($value[0] != 'null') {
789
+ $value = $this->reduce($value);
790
+ if ($value[0] == 'null') {
791
+ break;
792
+ }
793
+ }
794
+
795
+ $compiledValue = $this->compileValue($value);
796
+ $out->lines[] = $this->formatter->property(
797
+ $this->compileValue($name),
798
+ $compiledValue
799
+ );
800
+ break;
801
+ case 'comment':
802
+ if ($out->type == 'root') {
803
+ $this->compileComment($child);
804
+ break;
805
+ }
806
+
807
+ $out->lines[] = $child[1];
808
+ break;
809
+ case 'mixin':
810
+ case 'function':
811
+ list(,$block) = $child;
812
+
813
+ $this->set(self::$namespaces[$block->type] . $block->name, $block);
814
+ break;
815
+ case 'extend':
816
+ list(, $selectors) = $child;
817
+
818
+ foreach ($selectors as $sel) {
819
+ // only use the first one
820
+ $sel = current($this->evalSelector($sel));
821
+ $this->pushExtends($sel, $out->selectors);
822
+ }
823
+ break;
824
+ case 'if':
825
+ list(, $if) = $child;
826
+
827
+ if ($this->isTruthy($this->reduce($if->cond, true))) {
828
+ return $this->compileChildren($if->children, $out);
829
+ } else {
830
+ foreach ($if->cases as $case) {
831
+ if ($case->type == 'else' ||
832
+ $case->type == 'elseif' && $this->isTruthy($this->reduce($case->cond))
833
+ ) {
834
+ return $this->compileChildren($case->children, $out);
835
+ }
836
+ }
837
+ }
838
+ break;
839
+ case 'return':
840
+ return $this->reduce($child[1], true);
841
+ case 'each':
842
+ list(,$each) = $child;
843
+
844
+ $list = $this->coerceList($this->reduce($each->list));
845
+ foreach ($list[2] as $item) {
846
+ $this->pushEnv();
847
+ $this->set($each->var, $item);
848
+ // TODO: allow return from here
849
+ $this->compileChildren($each->children, $out);
850
+ $this->popEnv();
851
+ }
852
+ break;
853
+ case 'while':
854
+ list(,$while) = $child;
855
+
856
+ while ($this->isTruthy($this->reduce($while->cond, true))) {
857
+ $ret = $this->compileChildren($while->children, $out);
858
+ if ($ret) {
859
+ return $ret;
860
+ }
861
+ }
862
+ break;
863
+ case 'for':
864
+ list(,$for) = $child;
865
+
866
+ $start = $this->reduce($for->start, true);
867
+ $start = $start[1];
868
+ $end = $this->reduce($for->end, true);
869
+ $end = $end[1];
870
+ $d = $start < $end ? 1 : -1;
871
+
872
+ while (true) {
873
+ if ((! $for->until && $start - $d == $end) ||
874
+ ($for->until && $start == $end)
875
+ ) {
876
+ break;
877
+ }
878
+
879
+ $this->set($for->var, array('number', $start, ''));
880
+ $start += $d;
881
+
882
+ $ret = $this->compileChildren($for->children, $out);
883
+
884
+ if ($ret) {
885
+ return $ret;
886
+ }
887
+ }
888
+
889
+ break;
890
+ case 'nestedprop':
891
+ list(,$prop) = $child;
892
+
893
+ $prefixed = array();
894
+ $prefix = $this->compileValue($prop->prefix) . '-';
895
+
896
+ foreach ($prop->children as $child) {
897
+ if ($child[0] == 'assign') {
898
+ array_unshift($child[1][2], $prefix);
899
+ }
900
+
901
+ if ($child[0] == 'nestedprop') {
902
+ array_unshift($child[1]->prefix[2], $prefix);
903
+ }
904
+
905
+ $prefixed[] = $child;
906
+ }
907
+
908
+ $this->compileChildren($prefixed, $out);
909
+ break;
910
+ case 'include': // including a mixin
911
+ list(,$name, $argValues, $content) = $child;
912
+
913
+ $mixin = $this->get(self::$namespaces['mixin'] . $name, false);
914
+
915
+ if (! $mixin) {
916
+ $this->throwError("Undefined mixin $name");
917
+ }
918
+
919
+ $callingScope = $this->env;
920
+
921
+ // push scope, apply args
922
+ $this->pushEnv();
923
+
924
+ if ($this->env->depth > 0) {
925
+ $this->env->depth--;
926
+ }
927
+
928
+ if (isset($content)) {
929
+ $content->scope = $callingScope;
930
+ $this->setRaw(self::$namespaces['special'] . 'content', $content);
931
+ }
932
+
933
+ if (isset($mixin->args)) {
934
+ $this->applyArguments($mixin->args, $argValues);
935
+ }
936
+
937
+ foreach ($mixin->children as $child) {
938
+ $this->compileChild($child, $out);
939
+ }
940
+
941
+ $this->popEnv();
942
+ break;
943
+ case 'mixin_content':
944
+ $content = $this->get(self::$namespaces['special'] . 'content');
945
+
946
+ if (!isset($content)) {
947
+ $this->throwError('Expected @content inside of mixin');
948
+ }
949
+
950
+ $strongTypes = array('include', 'block', 'for', 'while');
951
+
952
+ foreach ($content->children as $child) {
953
+ $this->storeEnv = (in_array($child[0], $strongTypes))
954
+ ? null
955
+ : $content->scope;
956
+
957
+ $this->compileChild($child, $out);
958
+ }
959
+
960
+ unset($this->storeEnv);
961
+ break;
962
+ case 'debug':
963
+ list(,$value, $pos) = $child;
964
+
965
+ $line = $this->parser->getLineNo($pos);
966
+ $value = $this->compileValue($this->reduce($value, true));
967
+ fwrite(STDERR, "Line $line DEBUG: $value\n");
968
+ break;
969
+ default:
970
+ $this->throwError("unknown child type: $child[0]");
971
+ }
972
+ }
973
+
974
+ protected function expToString($exp)
975
+ {
976
+ list(, $op, $left, $right, $inParens, $whiteLeft, $whiteRight) = $exp;
977
+
978
+ $content = array($this->reduce($left));
979
+
980
+ if ($whiteLeft) {
981
+ $content[] = ' ';
982
+ }
983
+
984
+ $content[] = $op;
985
+
986
+ if ($whiteRight) {
987
+ $content[] = ' ';
988
+ }
989
+
990
+ $content[] = $this->reduce($right);
991
+
992
+ return array('string', '', $content);
993
+ }
994
+
995
+ protected function isTruthy($value)
996
+ {
997
+ return $value != self::$false && $value != self::$null;
998
+ }
999
+
1000
+ // should $value cause its operand to eval
1001
+ protected function shouldEval($value)
1002
+ {
1003
+ switch ($value[0]) {
1004
+ case 'exp':
1005
+ if ($value[1] == '/') {
1006
+ return $this->shouldEval($value[2], $value[3]);
1007
+ }
1008
+
1009
+ // fall-thru
1010
+ case 'var':
1011
+ case 'fncall':
1012
+ return true;
1013
+ }
1014
+ return false;
1015
+ }
1016
+
1017
+ protected function reduce($value, $inExp = false)
1018
+ {
1019
+ list($type) = $value;
1020
+ switch ($type) {
1021
+ case 'exp':
1022
+ list(, $op, $left, $right, $inParens) = $value;
1023
+
1024
+ $opName = isset(self::$operatorNames[$op]) ? self::$operatorNames[$op] : $op;
1025
+ $inExp = $inExp || $this->shouldEval($left) || $this->shouldEval($right);
1026
+
1027
+ $left = $this->reduce($left, true);
1028
+ $right = $this->reduce($right, true);
1029
+
1030
+ // only do division in special cases
1031
+ if ($opName == 'div' && !$inParens && !$inExp) {
1032
+ if ($left[0] != 'color' && $right[0] != 'color') {
1033
+ return $this->expToString($value);
1034
+ }
1035
+ }
1036
+
1037
+ $left = $this->coerceForExpression($left);
1038
+ $right = $this->coerceForExpression($right);
1039
+
1040
+ $ltype = $left[0];
1041
+ $rtype = $right[0];
1042
+
1043
+ $ucOpName = ucfirst($opName);
1044
+ $ucLType = ucfirst($ltype);
1045
+ $ucRType = ucfirst($rtype);
1046
+
1047
+ // this tries:
1048
+ // 1. op[op name][left type][right type]
1049
+ // 2. op[left type][right type] (passing the op as first arg
1050
+ // 3. op[op name]
1051
+ $fn = "op${ucOpName}${ucLType}${ucRType}";
1052
+ if (is_callable(array($this, $fn)) ||
1053
+ (($fn = "op${ucLType}${ucRType}") &&
1054
+ is_callable(array($this, $fn)) &&
1055
+ $passOp = true) ||
1056
+ (($fn = "op${ucOpName}") &&
1057
+ is_callable(array($this, $fn)) &&
1058
+ $genOp = true)
1059
+ ) {
1060
+ $unitChange = false;
1061
+
1062
+ if (!isset($genOp) &&
1063
+ $left[0] == 'number' && $right[0] == 'number'
1064
+ ) {
1065
+ if ($opName == 'mod' && $right[2] != '') {
1066
+ $this->throwError("Cannot modulo by a number with units: $right[1]$right[2].");
1067
+ }
1068
+
1069
+ $unitChange = true;
1070
+ $emptyUnit = $left[2] == '' || $right[2] == '';
1071
+ $targetUnit = '' != $left[2] ? $left[2] : $right[2];
1072
+
1073
+ if ($opName != 'mul') {
1074
+ $left[2] = '' != $left[2] ? $left[2] : $targetUnit;
1075
+ $right[2] = '' != $right[2] ? $right[2] : $targetUnit;
1076
+ }
1077
+
1078
+ if ($opName != 'mod') {
1079
+ $left = $this->normalizeNumber($left);
1080
+ $right = $this->normalizeNumber($right);
1081
+ }
1082
+
1083
+ if ($opName == 'div' && !$emptyUnit && $left[2] == $right[2]) {
1084
+ $targetUnit = '';
1085
+ }
1086
+
1087
+ if ($opName == 'mul') {
1088
+ $left[2] = '' != $left[2] ? $left[2] : $right[2];
1089
+ $right[2] = '' != $right[2] ? $right[2] : $left[2];
1090
+ } elseif ($opName == 'div' && $left[2] == $right[2]) {
1091
+ $left[2] = '';
1092
+ $right[2] = '';
1093
+ }
1094
+ }
1095
+
1096
+ $shouldEval = $inParens || $inExp;
1097
+
1098
+ if (isset($passOp)) {
1099
+ $out = $this->$fn($op, $left, $right, $shouldEval);
1100
+ } else {
1101
+ $out = $this->$fn($left, $right, $shouldEval);
1102
+ }
1103
+
1104
+ if (isset($out)) {
1105
+ if ($unitChange && $out[0] == 'number') {
1106
+ $out = $this->coerceUnit($out, $targetUnit);
1107
+ }
1108
+
1109
+ return $out;
1110
+ }
1111
+ }
1112
+
1113
+ return $this->expToString($value);
1114
+ case 'unary':
1115
+ list(, $op, $exp, $inParens) = $value;
1116
+
1117
+ $inExp = $inExp || $this->shouldEval($exp);
1118
+ $exp = $this->reduce($exp);
1119
+
1120
+ if ($exp[0] == 'number') {
1121
+ switch ($op) {
1122
+ case '+':
1123
+ return $exp;
1124
+ case '-':
1125
+ $exp[1] *= -1;
1126
+
1127
+ return $exp;
1128
+ }
1129
+ }
1130
+
1131
+ if ($op == 'not') {
1132
+ if ($inExp || $inParens) {
1133
+ if ($exp == self::$false) {
1134
+ return self::$true;
1135
+ }
1136
+
1137
+ return self::$false;
1138
+ } else {
1139
+ $op = $op . ' ';
1140
+ }
1141
+ }
1142
+
1143
+ return array('string', '', array($op, $exp));
1144
+ case 'var':
1145
+ list(, $name) = $value;
1146
+
1147
+ return $this->reduce($this->get($name));
1148
+ case 'list':
1149
+ foreach ($value[2] as &$item) {
1150
+ $item = $this->reduce($item);
1151
+ }
1152
+
1153
+ return $value;
1154
+ case 'string':
1155
+ foreach ($value[2] as &$item) {
1156
+ if (is_array($item)) {
1157
+ $item = $this->reduce($item);
1158
+ }
1159
+ }
1160
+ return $value;
1161
+ case 'interpolate':
1162
+ $value[1] = $this->reduce($value[1]);
1163
+
1164
+ return $value;
1165
+ case 'fncall':
1166
+ list(,$name, $argValues) = $value;
1167
+
1168
+ // user defined function?
1169
+ $func = $this->get(self::$namespaces['function'] . $name, false);
1170
+
1171
+ if ($func) {
1172
+ $this->pushEnv();
1173
+
1174
+ // set the args
1175
+ if (isset($func->args)) {
1176
+ $this->applyArguments($func->args, $argValues);
1177
+ }
1178
+
1179
+ // throw away lines and children
1180
+ $tmp = (object)array(
1181
+ 'lines' => array(),
1182
+ 'children' => array()
1183
+ );
1184
+
1185
+ $ret = $this->compileChildren($func->children, $tmp);
1186
+
1187
+ $this->popEnv();
1188
+
1189
+ return !isset($ret) ? self::$defaultValue : $ret;
1190
+ }
1191
+
1192
+ // built in function
1193
+ if ($this->callBuiltin($name, $argValues, $returnValue)) {
1194
+ return $returnValue;
1195
+ }
1196
+
1197
+ // need to flatten the arguments into a list
1198
+ $listArgs = array();
1199
+
1200
+ foreach ((array)$argValues as $arg) {
1201
+ if (empty($arg[0])) {
1202
+ $listArgs[] = $this->reduce($arg[1]);
1203
+ }
1204
+ }
1205
+
1206
+ return array('function', $name, array('list', ',', $listArgs));
1207
+ default:
1208
+ return $value;
1209
+ }
1210
+ }
1211
+
1212
+ public function normalizeValue($value)
1213
+ {
1214
+ $value = $this->coerceForExpression($this->reduce($value));
1215
+ list($type) = $value;
1216
+
1217
+ switch ($type) {
1218
+ case 'list':
1219
+ $value = $this->extractInterpolation($value);
1220
+
1221
+ if ($value[0] != 'list') {
1222
+ return array('keyword', $this->compileValue($value));
1223
+ }
1224
+
1225
+ foreach ($value[2] as $key => $item) {
1226
+ $value[2][$key] = $this->normalizeValue($item);
1227
+ }
1228
+
1229
+ return $value;
1230
+
1231
+ case 'number':
1232
+ return $this->normalizeNumber($value);
1233
+
1234
+ default:
1235
+ return $value;
1236
+ }
1237
+ }
1238
+
1239
+ // just does physical lengths for now
1240
+ protected function normalizeNumber($number)
1241
+ {
1242
+ list(, $value, $unit) = $number;
1243
+
1244
+ if (isset(self::$unitTable['in'][$unit])) {
1245
+ $conv = self::$unitTable['in'][$unit];
1246
+
1247
+ return array('number', $value / $conv, 'in');
1248
+ }
1249
+
1250
+ return $number;
1251
+ }
1252
+
1253
+ // $number should be normalized
1254
+ protected function coerceUnit($number, $unit)
1255
+ {
1256
+ list(, $value, $baseUnit) = $number;
1257
+
1258
+ if (isset(self::$unitTable[$baseUnit][$unit])) {
1259
+ $value = $value * self::$unitTable[$baseUnit][$unit];
1260
+ }
1261
+
1262
+ return array('number', $value, $unit);
1263
+ }
1264
+
1265
+ protected function opAddNumberNumber($left, $right)
1266
+ {
1267
+ return array('number', $left[1] + $right[1], $left[2]);
1268
+ }
1269
+
1270
+ protected function opMulNumberNumber($left, $right)
1271
+ {
1272
+ return array('number', $left[1] * $right[1], $left[2]);
1273
+ }
1274
+
1275
+ protected function opSubNumberNumber($left, $right)
1276
+ {
1277
+ return array('number', $left[1] - $right[1], $left[2]);
1278
+ }
1279
+
1280
+ protected function opDivNumberNumber($left, $right)
1281
+ {
1282
+ return array('number', $left[1] / $right[1], $left[2]);
1283
+ }
1284
+
1285
+ protected function opModNumberNumber($left, $right)
1286
+ {
1287
+ return array('number', $left[1] % $right[1], $left[2]);
1288
+ }
1289
+
1290
+ // adding strings
1291
+ protected function opAdd($left, $right)
1292
+ {
1293
+ if ($strLeft = $this->coerceString($left)) {
1294
+ if ($right[0] == 'string') {
1295
+ $right[1] = '';
1296
+ }
1297
+
1298
+ $strLeft[2][] = $right;
1299
+
1300
+ return $strLeft;
1301
+ }
1302
+
1303
+ if ($strRight = $this->coerceString($right)) {
1304
+ if ($left[0] == 'string') {
1305
+ $left[1] = '';
1306
+ }
1307
+
1308
+ array_unshift($strRight[2], $left);
1309
+
1310
+ return $strRight;
1311
+ }
1312
+ }
1313
+
1314
+ protected function opAnd($left, $right, $shouldEval)
1315
+ {
1316
+ if (!$shouldEval) {
1317
+ return;
1318
+ }
1319
+
1320
+ if ($left != self::$false) {
1321
+ return $right;
1322
+ }
1323
+
1324
+ return $left;
1325
+ }
1326
+
1327
+ protected function opOr($left, $right, $shouldEval)
1328
+ {
1329
+ if (!$shouldEval) {
1330
+ return;
1331
+ }
1332
+
1333
+ if ($left != self::$false) {
1334
+ return $left;
1335
+ }
1336
+
1337
+ return $right;
1338
+ }
1339
+
1340
+ protected function opColorColor($op, $left, $right)
1341
+ {
1342
+ $out = array('color');
1343
+
1344
+ foreach (range(1, 3) as $i) {
1345
+ $lval = isset($left[$i]) ? $left[$i] : 0;
1346
+ $rval = isset($right[$i]) ? $right[$i] : 0;
1347
+
1348
+ switch ($op) {
1349
+ case '+':
1350
+ $out[] = $lval + $rval;
1351
+ break;
1352
+ case '-':
1353
+ $out[] = $lval - $rval;
1354
+ break;
1355
+ case '*':
1356
+ $out[] = $lval * $rval;
1357
+ break;
1358
+ case '%':
1359
+ $out[] = $lval % $rval;
1360
+ break;
1361
+ case '/':
1362
+ if ($rval == 0) {
1363
+ $this->throwError("color: Can't divide by zero");
1364
+ }
1365
+ $out[] = $lval / $rval;
1366
+ break;
1367
+ case '==':
1368
+ return $this->opEq($left, $right);
1369
+ case '!=':
1370
+ return $this->opNeq($left, $right);
1371
+ default:
1372
+ $this->throwError("color: unknown op $op");
1373
+ }
1374
+ }
1375
+
1376
+ if (isset($left[4])) {
1377
+ $out[4] = $left[4];
1378
+ } elseif (isset($right[4])) {
1379
+ $out[4] = $right[4];
1380
+ }
1381
+
1382
+ return $this->fixColor($out);
1383
+ }
1384
+
1385
+ protected function opColorNumber($op, $left, $right)
1386
+ {
1387
+ $value = $right[1];
1388
+
1389
+ return $this->opColorColor(
1390
+ $op,
1391
+ $left,
1392
+ array('color', $value, $value, $value)
1393
+ );
1394
+ }
1395
+
1396
+ protected function opNumberColor($op, $left, $right)
1397
+ {
1398
+ $value = $left[1];
1399
+
1400
+ return $this->opColorColor(
1401
+ $op,
1402
+ array('color', $value, $value, $value),
1403
+ $right
1404
+ );
1405
+ }
1406
+
1407
+ protected function opEq($left, $right)
1408
+ {
1409
+ if (($lStr = $this->coerceString($left)) && ($rStr = $this->coerceString($right))) {
1410
+ $lStr[1] = '';
1411
+ $rStr[1] = '';
1412
+
1413
+ return $this->toBool($this->compileValue($lStr) == $this->compileValue($rStr));
1414
+ }
1415
+
1416
+ return $this->toBool($left == $right);
1417
+ }
1418
+
1419
+ protected function opNeq($left, $right)
1420
+ {
1421
+ return $this->toBool($left != $right);
1422
+ }
1423
+
1424
+ protected function opGteNumberNumber($left, $right)
1425
+ {
1426
+ return $this->toBool($left[1] >= $right[1]);
1427
+ }
1428
+
1429
+ protected function opGtNumberNumber($left, $right)
1430
+ {
1431
+ return $this->toBool($left[1] > $right[1]);
1432
+ }
1433
+
1434
+ protected function opLteNumberNumber($left, $right)
1435
+ {
1436
+ return $this->toBool($left[1] <= $right[1]);
1437
+ }
1438
+
1439
+ protected function opLtNumberNumber($left, $right)
1440
+ {
1441
+ return $this->toBool($left[1] < $right[1]);
1442
+ }
1443
+
1444
+ public function toBool($thing)
1445
+ {
1446
+ return $thing ? self::$true : self::$false;
1447
+ }
1448
+
1449
+ /**
1450
+ * Compiles a primitive value into a CSS property value.
1451
+ *
1452
+ * Values in scssphp are typed by being wrapped in arrays, their format is
1453
+ * typically:
1454
+ *
1455
+ * array(type, contents [, additional_contents]*)
1456
+ *
1457
+ * The input is expected to be reduced. This function will not work on
1458
+ * things like expressions and variables.
1459
+ *
1460
+ * @param array $value
1461
+ */
1462
+ protected function compileValue($value)
1463
+ {
1464
+ $value = $this->reduce($value);
1465
+
1466
+ list($type) = $value;
1467
+
1468
+ switch ($type) {
1469
+ case 'keyword':
1470
+ return $value[1];
1471
+ case 'color':
1472
+ // [1] - red component (either number for a %)
1473
+ // [2] - green component
1474
+ // [3] - blue component
1475
+ // [4] - optional alpha component
1476
+ list(, $r, $g, $b) = $value;
1477
+
1478
+ $r = round($r);
1479
+ $g = round($g);
1480
+ $b = round($b);
1481
+
1482
+ if (count($value) == 5 && $value[4] != 1) { // rgba
1483
+ return 'rgba('.$r.', '.$g.', '.$b.', '.$value[4].')';
1484
+ }
1485
+
1486
+ $h = sprintf('#%02x%02x%02x', $r, $g, $b);
1487
+
1488
+ // Converting hex color to short notation (e.g. #003399 to #039)
1489
+ if ($h[1] === $h[2] && $h[3] === $h[4] && $h[5] === $h[6]) {
1490
+ $h = '#' . $h[1] . $h[3] . $h[5];
1491
+ }
1492
+
1493
+ return $h;
1494
+ case 'number':
1495
+ return round($value[1], $this->numberPrecision) . $value[2];
1496
+ case 'string':
1497
+ return $value[1] . $this->compileStringContent($value) . $value[1];
1498
+ case 'function':
1499
+ $args = !empty($value[2]) ? $this->compileValue($value[2]) : '';
1500
+ return "$value[1]($args)";
1501
+ case 'list':
1502
+ $value = $this->extractInterpolation($value);
1503
+
1504
+ if ($value[0] != 'list') {
1505
+ return $this->compileValue($value);
1506
+ }
1507
+
1508
+ list(, $delim, $items) = $value;
1509
+
1510
+ $filtered = array();
1511
+ foreach ($items as $item) {
1512
+ if ($item[0] == 'null') {
1513
+ continue;
1514
+ }
1515
+
1516
+ $filtered[] = $this->compileValue($item);
1517
+ }
1518
+
1519
+ return implode("$delim ", $filtered);
1520
+ case 'interpolated': # node created by extractInterpolation
1521
+ list(, $interpolate, $left, $right) = $value;
1522
+ list(,, $whiteLeft, $whiteRight) = $interpolate;
1523
+
1524
+ $left = count($left[2]) > 0 ?
1525
+ $this->compileValue($left).$whiteLeft : '';
1526
+
1527
+ $right = count($right[2]) > 0 ?
1528
+ $whiteRight.$this->compileValue($right) : '';
1529
+
1530
+ return $left.$this->compileValue($interpolate).$right;
1531
+
1532
+ case 'interpolate': # raw parse node
1533
+ list(, $exp) = $value;
1534
+
1535
+ // strip quotes if it's a string
1536
+ $reduced = $this->reduce($exp);
1537
+ switch ($reduced[0]) {
1538
+ case 'string':
1539
+ $reduced = array('keyword',
1540
+ $this->compileStringContent($reduced));
1541
+ break;
1542
+ case 'null':
1543
+ $reduced = array('keyword', '');
1544
+ }
1545
+
1546
+ return $this->compileValue($reduced);
1547
+ case 'null':
1548
+ return 'null';
1549
+ default:
1550
+ $this->throwError("unknown value type: $type");
1551
+ }
1552
+ }
1553
+
1554
+ protected function compileStringContent($string)
1555
+ {
1556
+ $parts = array();
1557
+
1558
+ foreach ($string[2] as $part) {
1559
+ if (is_array($part)) {
1560
+ $parts[] = $this->compileValue($part);
1561
+ } else {
1562
+ $parts[] = $part;
1563
+ }
1564
+ }
1565
+
1566
+ return implode($parts);
1567
+ }
1568
+
1569
+ // doesn't need to be recursive, compileValue will handle that
1570
+ protected function extractInterpolation($list)
1571
+ {
1572
+ $items = $list[2];
1573
+
1574
+ foreach ($items as $i => $item) {
1575
+ if ($item[0] == 'interpolate') {
1576
+ $before = array('list', $list[1], array_slice($items, 0, $i));
1577
+ $after = array('list', $list[1], array_slice($items, $i + 1));
1578
+
1579
+ return array('interpolated', $item, $before, $after);
1580
+ }
1581
+ }
1582
+
1583
+ return $list;
1584
+ }
1585
+
1586
+ // find the final set of selectors
1587
+ protected function multiplySelectors($env)
1588
+ {
1589
+ $envs = array();
1590
+
1591
+ while (null !== $env) {
1592
+ if (!empty($env->selectors)) {
1593
+ $envs[] = $env;
1594
+ }
1595
+
1596
+ $env = $env->parent;
1597
+ };
1598
+
1599
+ $selectors = array();
1600
+ $parentSelectors = array(array());
1601
+
1602
+ while ($env = array_pop($envs)) {
1603
+ $selectors = array();
1604
+
1605
+ foreach ($env->selectors as $selector) {
1606
+ foreach ($parentSelectors as $parent) {
1607
+ $selectors[] = $this->joinSelectors($parent, $selector);
1608
+ }
1609
+ }
1610
+
1611
+ $parentSelectors = $selectors;
1612
+ }
1613
+
1614
+ return $selectors;
1615
+ }
1616
+
1617
+ // looks for & to replace, or append parent before child
1618
+ protected function joinSelectors($parent, $child)
1619
+ {
1620
+ $setSelf = false;
1621
+ $out = array();
1622
+
1623
+ foreach ($child as $part) {
1624
+ $newPart = array();
1625
+
1626
+ foreach ($part as $p) {
1627
+ if ($p == self::$selfSelector) {
1628
+ $setSelf = true;
1629
+
1630
+ foreach ($parent as $i => $parentPart) {
1631
+ if ($i > 0) {
1632
+ $out[] = $newPart;
1633
+ $newPart = array();
1634
+ }
1635
+
1636
+ foreach ($parentPart as $pp) {
1637
+ $newPart[] = $pp;
1638
+ }
1639
+ }
1640
+ } else {
1641
+ $newPart[] = $p;
1642
+ }
1643
+ }
1644
+
1645
+ $out[] = $newPart;
1646
+ }
1647
+
1648
+ return $setSelf ? $out : array_merge($parent, $child);
1649
+ }
1650
+
1651
+ protected function multiplyMedia($env, $childQueries = null)
1652
+ {
1653
+ if (!isset($env) ||
1654
+ !empty($env->block->type) && $env->block->type != 'media'
1655
+ ) {
1656
+ return $childQueries;
1657
+ }
1658
+
1659
+ // plain old block, skip
1660
+ if (empty($env->block->type)) {
1661
+ return $this->multiplyMedia($env->parent, $childQueries);
1662
+ }
1663
+
1664
+ $parentQueries = $env->block->queryList;
1665
+ if ($childQueries == null) {
1666
+ $childQueries = $parentQueries;
1667
+ } else {
1668
+ $originalQueries = $childQueries;
1669
+ $childQueries = array();
1670
+
1671
+ foreach ($parentQueries as $parentQuery) {
1672
+ foreach ($originalQueries as $childQuery) {
1673
+ $childQueries []= array_merge($parentQuery, $childQuery);
1674
+ }
1675
+ }
1676
+ }
1677
+
1678
+ return $this->multiplyMedia($env->parent, $childQueries);
1679
+ }
1680
+
1681
+ // convert something to list
1682
+ protected function coerceList($item, $delim = ',')
1683
+ {
1684
+ if (isset($item) && $item[0] == 'list') {
1685
+ return $item;
1686
+ }
1687
+
1688
+ return array('list', $delim, !isset($item) ? array(): array($item));
1689
+ }
1690
+
1691
+ protected function applyArguments($argDef, $argValues)
1692
+ {
1693
+ $storeEnv = $this->getStoreEnv();
1694
+
1695
+ $env = new \stdClass;
1696
+ $env->store = $storeEnv->store;
1697
+
1698
+ $hasVariable = false;
1699
+ $args = array();
1700
+
1701
+ foreach ($argDef as $i => $arg) {
1702
+ list($name, $default, $isVariable) = $argDef[$i];
1703
+
1704
+ $args[$name] = array($i, $name, $default, $isVariable);
1705
+ $hasVariable |= $isVariable;
1706
+ }
1707
+
1708
+ $keywordArgs = array();
1709
+ $deferredKeywordArgs = array();
1710
+ $remaining = array();
1711
+
1712
+ // assign the keyword args
1713
+ foreach ((array) $argValues as $arg) {
1714
+ if (!empty($arg[0])) {
1715
+ if (!isset($args[$arg[0][1]])) {
1716
+ if ($hasVariable) {
1717
+ $deferredKeywordArgs[$arg[0][1]] = $arg[1];
1718
+ } else {
1719
+ $this->throwError("Mixin or function doesn't have an argument named $%s.", $arg[0][1]);
1720
+ }
1721
+ } elseif ($args[$arg[0][1]][0] < count($remaining)) {
1722
+ $this->throwError("The argument $%s was passed both by position and by name.", $arg[0][1]);
1723
+ } else {
1724
+ $keywordArgs[$arg[0][1]] = $arg[1];
1725
+ }
1726
+ } elseif (count($keywordArgs)) {
1727
+ $this->throwError('Positional arguments must come before keyword arguments.');
1728
+ } elseif ($arg[2] == true) {
1729
+ $val = $this->reduce($arg[1], true);
1730
+
1731
+ if ($val[0] == 'list') {
1732
+ foreach ($val[2] as $name => $item) {
1733
+ if (!is_numeric($name)) {
1734
+ $keywordArgs[$name] = $item;
1735
+ } else {
1736
+ $remaining[] = $item;
1737
+ }
1738
+ }
1739
+ } else {
1740
+ $remaining[] = $val;
1741
+ }
1742
+ } else {
1743
+ $remaining[] = $arg[1];
1744
+ }
1745
+ }
1746
+
1747
+ foreach ($args as $arg) {
1748
+ list($i, $name, $default, $isVariable) = $arg;
1749
+
1750
+ if ($isVariable) {
1751
+ $val = array('list', ',', array());
1752
+ for ($count = count($remaining); $i < $count; $i++) {
1753
+ $val[2][] = $remaining[$i];
1754
+ }
1755
+ foreach ($deferredKeywordArgs as $itemName => $item) {
1756
+ $val[2][$itemName] = $item;
1757
+ }
1758
+ } elseif (isset($remaining[$i])) {
1759
+ $val = $remaining[$i];
1760
+ } elseif (isset($keywordArgs[$name])) {
1761
+ $val = $keywordArgs[$name];
1762
+ } elseif (!empty($default)) {
1763
+ continue;
1764
+ } else {
1765
+ $this->throwError("Missing argument $name");
1766
+ }
1767
+
1768
+ $this->set($name, $this->reduce($val, true), true, $env);
1769
+ }
1770
+
1771
+ $storeEnv->store = $env->store;
1772
+
1773
+ foreach ($args as $arg) {
1774
+ list($i, $name, $default, $isVariable) = $arg;
1775
+
1776
+ if ($isVariable || isset($remaining[$i]) || isset($keywordArgs[$name]) || empty($default)) {
1777
+ continue;
1778
+ }
1779
+
1780
+ $this->set($name, $this->reduce($default, true), true);
1781
+ }
1782
+ }
1783
+
1784
+ protected function pushEnv($block = null)
1785
+ {
1786
+ $env = new \stdClass;
1787
+ $env->parent = $this->env;
1788
+ $env->store = array();
1789
+ $env->block = $block;
1790
+ $env->depth = isset($this->env->depth) ? $this->env->depth + 1 : 0;
1791
+
1792
+ $this->env = $env;
1793
+
1794
+ return $env;
1795
+ }
1796
+
1797
+ protected function normalizeName($name)
1798
+ {
1799
+ return str_replace('-', '_', $name);
1800
+ }
1801
+
1802
+ protected function getStoreEnv()
1803
+ {
1804
+ return isset($this->storeEnv) ? $this->storeEnv : $this->env;
1805
+ }
1806
+
1807
+ protected function set($name, $value, $shadow = false, $env = null)
1808
+ {
1809
+ $name = $this->normalizeName($name);
1810
+
1811
+ if ($shadow) {
1812
+ $this->setRaw($name, $value, $env);
1813
+ } else {
1814
+ $this->setExisting($name, $value, $env);
1815
+ }
1816
+ }
1817
+
1818
+ protected function setExisting($name, $value, $env = null)
1819
+ {
1820
+ if (!isset($env)) {
1821
+ $env = $this->getStoreEnv();
1822
+ }
1823
+
1824
+ if (isset($env->store[$name]) || !isset($env->parent)) {
1825
+ $env->store[$name] = $value;
1826
+ } else {
1827
+ $this->setExisting($name, $value, $env->parent);
1828
+ }
1829
+ }
1830
+
1831
+ protected function setRaw($name, $value, $env = null)
1832
+ {
1833
+ if (!isset($env)) {
1834
+ $env = $this->getStoreEnv();
1835
+ }
1836
+
1837
+ $env->store[$name] = $value;
1838
+ }
1839
+
1840
+ public function get($name, $defaultValue = null, $env = null)
1841
+ {
1842
+ $name = $this->normalizeName($name);
1843
+
1844
+ if (!isset($env)) {
1845
+ $env = $this->getStoreEnv();
1846
+ }
1847
+
1848
+ if (! isset($defaultValue)) {
1849
+ $defaultValue = self::$defaultValue;
1850
+ }
1851
+
1852
+ if (isset($env->store[$name])) {
1853
+ return $env->store[$name];
1854
+ }
1855
+
1856
+ if (isset($env->parent)) {
1857
+ return $this->get($name, $defaultValue, $env->parent);
1858
+ }
1859
+
1860
+ return $defaultValue; // found nothing
1861
+ }
1862
+
1863
+ protected function injectVariables(array $args)
1864
+ {
1865
+ if (empty($args)) {
1866
+ return;
1867
+ }
1868
+
1869
+ $parser = new Parser(__METHOD__, false);
1870
+
1871
+ foreach ($args as $name => $strValue) {
1872
+ if ($name[0] === '$') {
1873
+ $name = substr($name, 1);
1874
+ }
1875
+
1876
+ $parser->env = null;
1877
+ $parser->count = 0;
1878
+ $parser->buffer = (string) $strValue;
1879
+ $parser->inParens = false;
1880
+ $parser->eatWhiteDefault = true;
1881
+ $parser->insertComments = true;
1882
+
1883
+ if (! $parser->valueList($value)) {
1884
+ throw new \Exception("failed to parse passed in variable $name: $strValue");
1885
+ }
1886
+
1887
+ $this->set($name, $value);
1888
+ }
1889
+ }
1890
+
1891
+ /**
1892
+ * Set variables
1893
+ *
1894
+ * @param array $variables
1895
+ */
1896
+ public function setVariables(array $variables)
1897
+ {
1898
+ $this->registeredVars = array_merge($this->registeredVars, $variables);
1899
+ }
1900
+
1901
+ /**
1902
+ * Unset variable
1903
+ *
1904
+ * @param string $name
1905
+ */
1906
+ public function unsetVariable($name)
1907
+ {
1908
+ unset($this->registeredVars[$name]);
1909
+ }
1910
+
1911
+ protected function popEnv()
1912
+ {
1913
+ $env = $this->env;
1914
+ $this->env = $this->env->parent;
1915
+
1916
+ return $env;
1917
+ }
1918
+
1919
+ public function getParsedFiles()
1920
+ {
1921
+ return $this->parsedFiles;
1922
+ }
1923
+
1924
+ public function addImportPath($path)
1925
+ {
1926
+ $this->importPaths[] = $path;
1927
+ }
1928
+
1929
+ public function setImportPaths($path)
1930
+ {
1931
+ $this->importPaths = (array)$path;
1932
+ }
1933
+
1934
+ public function setNumberPrecision($numberPrecision)
1935
+ {
1936
+ $this->numberPrecision = $numberPrecision;
1937
+ }
1938
+
1939
+ public function setFormatter($formatterName)
1940
+ {
1941
+ $this->formatter = $formatterName;
1942
+ }
1943
+
1944
+ public function registerFunction($name, $func)
1945
+ {
1946
+ $this->userFunctions[$this->normalizeName($name)] = $func;
1947
+ }
1948
+
1949
+ public function unregisterFunction($name)
1950
+ {
1951
+ unset($this->userFunctions[$this->normalizeName($name)]);
1952
+ }
1953
+
1954
+ protected function importFile($path, $out)
1955
+ {
1956
+ // see if tree is cached
1957
+ $realPath = realpath($path);
1958
+ if (isset($this->importCache[$realPath])) {
1959
+ $tree = $this->importCache[$realPath];
1960
+ } else {
1961
+ $code = file_get_contents($path);
1962
+ $parser = new Parser($path, false);
1963
+ $tree = $parser->parse($code);
1964
+ $this->parsedFiles[] = $path;
1965
+
1966
+ $this->importCache[$realPath] = $tree;
1967
+ }
1968
+
1969
+ $pi = pathinfo($path);
1970
+ array_unshift($this->importPaths, $pi['dirname']);
1971
+ $this->compileChildren($tree->children, $out);
1972
+ array_shift($this->importPaths);
1973
+ }
1974
+
1975
+ // results the file path for an import url if it exists
1976
+ public function findImport($url)
1977
+ {
1978
+ $urls = array();
1979
+
1980
+ // for "normal" scss imports (ignore vanilla css and external requests)
1981
+ if (!preg_match('/\.css|^http:\/\/$/', $url)) {
1982
+ // try both normal and the _partial filename
1983
+ $urls = array($url, preg_replace('/[^\/]+$/', '_\0', $url));
1984
+ }
1985
+
1986
+ foreach ($this->importPaths as $dir) {
1987
+ if (is_string($dir)) {
1988
+ // check urls for normal import paths
1989
+ foreach ($urls as $full) {
1990
+ $full = $dir .
1991
+ (!empty($dir) && substr($dir, -1) != '/' ? '/' : '') .
1992
+ $full;
1993
+
1994
+ if ($this->fileExists($file = $full.'.scss') ||
1995
+ $this->fileExists($file = $full)
1996
+ ) {
1997
+ return $file;
1998
+ }
1999
+ }
2000
+ } elseif (is_callable($dir)) {
2001
+ // check custom callback for import path
2002
+ $file = call_user_func($dir, $url, $this);
2003
+
2004
+ if ($file !== null) {
2005
+ return $file;
2006
+ }
2007
+ }
2008
+ }
2009
+
2010
+ return null;
2011
+ }
2012
+
2013
+ protected function fileExists($name)
2014
+ {
2015
+ return is_file($name);
2016
+ }
2017
+
2018
+ protected function callBuiltin($name, $args, &$returnValue)
2019
+ {
2020
+ // try a lib function
2021
+ $name = $this->normalizeName($name);
2022
+ $libName = 'lib' . preg_replace_callback(
2023
+ '/_(.)/',
2024
+ function ($m) {
2025
+ return ucfirst($m[1]);
2026
+ },
2027
+ ucfirst($name)
2028
+ );
2029
+
2030
+ $f = array($this, $libName);
2031
+
2032
+ if (is_callable($f)) {
2033
+ $prototype = isset(self::$$libName) ? self::$$libName : null;
2034
+ $sorted = $this->sortArgs($prototype, $args);
2035
+
2036
+ foreach ($sorted as &$val) {
2037
+ $val = $this->reduce($val, true);
2038
+ }
2039
+
2040
+ $returnValue = call_user_func($f, $sorted, $this);
2041
+ } elseif (isset($this->userFunctions[$name])) {
2042
+ // see if we can find a user function
2043
+ $fn = $this->userFunctions[$name];
2044
+
2045
+ foreach ($args as &$val) {
2046
+ $val = $this->reduce($val[1], true);
2047
+ }
2048
+
2049
+ $returnValue = call_user_func($fn, $args, $this);
2050
+ }
2051
+
2052
+ if (isset($returnValue)) {
2053
+ // coerce a php value into a scss one
2054
+ if (is_numeric($returnValue)) {
2055
+ $returnValue = array('number', $returnValue, '');
2056
+ } elseif (is_bool($returnValue)) {
2057
+ $returnValue = $returnValue ? self::$true : self::$false;
2058
+ } elseif (!is_array($returnValue)) {
2059
+ $returnValue = array('keyword', $returnValue);
2060
+ }
2061
+
2062
+ return true;
2063
+ }
2064
+
2065
+ return false;
2066
+ }
2067
+
2068
+ // sorts any keyword arguments
2069
+ // TODO: merge with apply arguments
2070
+ protected function sortArgs($prototype, $args)
2071
+ {
2072
+ $keyArgs = array();
2073
+ $posArgs = array();
2074
+
2075
+ foreach ($args as $arg) {
2076
+ list($key, $value) = $arg;
2077
+ $key = $key[1];
2078
+ if (empty($key)) {
2079
+ $posArgs[] = $value;
2080
+ } else {
2081
+ $keyArgs[$key] = $value;
2082
+ }
2083
+ }
2084
+
2085
+ if (!isset($prototype)) {
2086
+ return $posArgs;
2087
+ }
2088
+
2089
+ $finalArgs = array();
2090
+
2091
+ foreach ($prototype as $i => $names) {
2092
+ if (isset($posArgs[$i])) {
2093
+ $finalArgs[] = $posArgs[$i];
2094
+ continue;
2095
+ }
2096
+
2097
+ $set = false;
2098
+ foreach ((array)$names as $name) {
2099
+ if (isset($keyArgs[$name])) {
2100
+ $finalArgs[] = $keyArgs[$name];
2101
+ $set = true;
2102
+ break;
2103
+ }
2104
+ }
2105
+
2106
+ if (!$set) {
2107
+ $finalArgs[] = null;
2108
+ }
2109
+ }
2110
+
2111
+ return $finalArgs;
2112
+ }
2113
+
2114
+ protected function coerceForExpression($value)
2115
+ {
2116
+ if ($color = $this->coerceColor($value)) {
2117
+ return $color;
2118
+ }
2119
+
2120
+ return $value;
2121
+ }
2122
+
2123
+ protected function coerceColor($value)
2124
+ {
2125
+ switch ($value[0]) {
2126
+ case 'color':
2127
+ return $value;
2128
+
2129
+ case 'keyword':
2130
+ $name = $value[1];
2131
+
2132
+ if (isset(Colors::$cssColors[$name])) {
2133
+ $rgba = explode(',', Colors::$cssColors[$name]);
2134
+
2135
+ return isset($rgba[3])
2136
+ ? array('color', (int) $rgba[0], (int) $rgba[1], (int) $rgba[2], (int) $rgba[3])
2137
+ : array('color', (int) $rgba[0], (int) $rgba[1], (int) $rgba[2]);
2138
+ }
2139
+
2140
+ return null;
2141
+ }
2142
+
2143
+ return null;
2144
+ }
2145
+
2146
+ protected function coerceString($value)
2147
+ {
2148
+ switch ($value[0]) {
2149
+ case 'string':
2150
+ return $value;
2151
+ case 'keyword':
2152
+ return array('string', '', array($value[1]));
2153
+ }
2154
+ return null;
2155
+ }
2156
+
2157
+ public function assertList($value)
2158
+ {
2159
+ if ($value[0] != 'list') {
2160
+ $this->throwError('expecting list');
2161
+ }
2162
+
2163
+ return $value;
2164
+ }
2165
+
2166
+ public function assertColor($value)
2167
+ {
2168
+ if ($color = $this->coerceColor($value)) {
2169
+ return $color;
2170
+ }
2171
+
2172
+ $this->throwError('expecting color');
2173
+ }
2174
+
2175
+ public function assertNumber($value)
2176
+ {
2177
+ if ($value[0] != 'number') {
2178
+ $this->throwError('expecting number');
2179
+ }
2180
+
2181
+ return $value[1];
2182
+ }
2183
+
2184
+ protected function coercePercent($value)
2185
+ {
2186
+ if ($value[0] == 'number') {
2187
+ if ($value[2] == '%') {
2188
+ return $value[1] / 100;
2189
+ }
2190
+
2191
+ return $value[1];
2192
+ }
2193
+
2194
+ return 0;
2195
+ }
2196
+
2197
+ // make sure a color's components don't go out of bounds
2198
+ protected function fixColor($c)
2199
+ {
2200
+ foreach (range(1, 3) as $i) {
2201
+ if ($c[$i] < 0) {
2202
+ $c[$i] = 0;
2203
+ }
2204
+
2205
+ if ($c[$i] > 255) {
2206
+ $c[$i] = 255;
2207
+ }
2208
+ }
2209
+
2210
+ return $c;
2211
+ }
2212
+
2213
+ public function toHSL($red, $green, $blue)
2214
+ {
2215
+ $min = min($red, $green, $blue);
2216
+ $max = max($red, $green, $blue);
2217
+
2218
+ $l = $min + $max;
2219
+
2220
+ if ($min == $max) {
2221
+ $s = $h = 0;
2222
+ } else {
2223
+ $d = $max - $min;
2224
+
2225
+ if ($l < 255) {
2226
+ $s = $d / $l;
2227
+ } else {
2228
+ $s = $d / (510 - $l);
2229
+ }
2230
+
2231
+ if ($red == $max) {
2232
+ $h = 60 * ($green - $blue) / $d;
2233
+ } elseif ($green == $max) {
2234
+ $h = 60 * ($blue - $red) / $d + 120;
2235
+ } elseif ($blue == $max) {
2236
+ $h = 60 * ($red - $green) / $d + 240;
2237
+ }
2238
+ }
2239
+
2240
+ return array('hsl', fmod($h, 360), $s * 100, $l / 5.1);
2241
+ }
2242
+
2243
+ public function hueToRGB($m1, $m2, $h)
2244
+ {
2245
+ if ($h < 0) {
2246
+ $h += 1;
2247
+ } elseif ($h > 1) {
2248
+ $h -= 1;
2249
+ }
2250
+
2251
+ if ($h * 6 < 1) {
2252
+ return $m1 + ($m2 - $m1) * $h * 6;
2253
+ }
2254
+
2255
+ if ($h * 2 < 1) {
2256
+ return $m2;
2257
+ }
2258
+
2259
+ if ($h * 3 < 2) {
2260
+ return $m1 + ($m2 - $m1) * (2/3 - $h) * 6;
2261
+ }
2262
+
2263
+ return $m1;
2264
+ }
2265
+
2266
+ // H from 0 to 360, S and L from 0 to 100
2267
+ public function toRGB($hue, $saturation, $lightness)
2268
+ {
2269
+ if ($hue < 0) {
2270
+ $hue += 360;
2271
+ }
2272
+
2273
+ $h = $hue / 360;
2274
+ $s = min(100, max(0, $saturation)) / 100;
2275
+ $l = min(100, max(0, $lightness)) / 100;
2276
+
2277
+ $m2 = $l <= 0.5 ? $l * ($s + 1) : $l + $s - $l * $s;
2278
+ $m1 = $l * 2 - $m2;
2279
+
2280
+ $r = $this->hueToRGB($m1, $m2, $h + 1/3) * 255;
2281
+ $g = $this->hueToRGB($m1, $m2, $h) * 255;
2282
+ $b = $this->hueToRGB($m1, $m2, $h - 1/3) * 255;
2283
+
2284
+ $out = array('color', $r, $g, $b);
2285
+
2286
+ return $out;
2287
+ }
2288
+
2289
+ // Built in functions
2290
+
2291
+ protected static $libIf = array('condition', 'if-true', 'if-false');
2292
+ protected function libIf($args)
2293
+ {
2294
+ list($cond,$t, $f) = $args;
2295
+
2296
+ if (!$this->isTruthy($cond)) {
2297
+ return $f;
2298
+ }
2299
+
2300
+ return $t;
2301
+ }
2302
+
2303
+ protected static $libIndex = array('list', 'value');
2304
+ protected function libIndex($args)
2305
+ {
2306
+ list($list, $value) = $args;
2307
+
2308
+ $list = $this->assertList($list);
2309
+
2310
+ $values = array();
2311
+
2312
+ foreach ($list[2] as $item) {
2313
+ $values[] = $this->normalizeValue($item);
2314
+ }
2315
+
2316
+ $key = array_search($this->normalizeValue($value), $values);
2317
+
2318
+ return false === $key ? false : $key + 1;
2319
+ }
2320
+
2321
+ protected static $libRgb = array('red', 'green', 'blue');
2322
+ protected function libRgb($args)
2323
+ {
2324
+ list($r,$g,$b) = $args;
2325
+
2326
+ return array('color', $r[1], $g[1], $b[1]);
2327
+ }
2328
+
2329
+ protected static $libRgba = array(
2330
+ array('red', 'color'),
2331
+ 'green', 'blue', 'alpha');
2332
+ protected function libRgba($args)
2333
+ {
2334
+ if ($color = $this->coerceColor($args[0])) {
2335
+ $num = !isset($args[1]) ? $args[3] : $args[1];
2336
+ $alpha = $this->assertNumber($num);
2337
+ $color[4] = $alpha;
2338
+
2339
+ return $color;
2340
+ }
2341
+
2342
+ list($r,$g,$b, $a) = $args;
2343
+
2344
+ return array('color', $r[1], $g[1], $b[1], $a[1]);
2345
+ }
2346
+
2347
+ // helper function for adjust_color, change_color, and scale_color
2348
+ protected function alterColor($args, $fn)
2349
+ {
2350
+ $color = $this->assertColor($args[0]);
2351
+
2352
+ foreach (array(1,2,3,7) as $i) {
2353
+ if (isset($args[$i])) {
2354
+ $val = $this->assertNumber($args[$i]);
2355
+ $ii = $i == 7 ? 4 : $i; // alpha
2356
+ $color[$ii] =
2357
+ $this->$fn(isset($color[$ii]) ? $color[$ii] : 0, $val, $i);
2358
+ }
2359
+ }
2360
+
2361
+ if (isset($args[4]) || isset($args[5]) || isset($args[6])) {
2362
+ $hsl = $this->toHSL($color[1], $color[2], $color[3]);
2363
+
2364
+ foreach (array(4,5,6) as $i) {
2365
+ if (isset($args[$i])) {
2366
+ $val = $this->assertNumber($args[$i]);
2367
+ $hsl[$i - 3] = $this->$fn($hsl[$i - 3], $val, $i);
2368
+ }
2369
+ }
2370
+
2371
+ $rgb = $this->toRGB($hsl[1], $hsl[2], $hsl[3]);
2372
+
2373
+ if (isset($color[4])) {
2374
+ $rgb[4] = $color[4];
2375
+ }
2376
+
2377
+ $color = $rgb;
2378
+ }
2379
+
2380
+ return $color;
2381
+ }
2382
+
2383
+ protected static $libAdjustColor = array(
2384
+ 'color', 'red', 'green', 'blue',
2385
+ 'hue', 'saturation', 'lightness', 'alpha'
2386
+ );
2387
+ protected function adjustColorHelper($base, $alter, $i)
2388
+ {
2389
+ return $base += $alter;
2390
+ }
2391
+ protected function libAdjustColor($args)
2392
+ {
2393
+ return $this->alterColor($args, 'adjustColorHelper');
2394
+ }
2395
+
2396
+ protected static $libChangeColor = array(
2397
+ 'color', 'red', 'green', 'blue',
2398
+ 'hue', 'saturation', 'lightness', 'alpha'
2399
+ );
2400
+ protected function changeColorHelper($base, $alter, $i)
2401
+ {
2402
+ return $alter;
2403
+ }
2404
+ protected function libChangeColor($args)
2405
+ {
2406
+ return $this->alterColor($args, 'changeColorHelper');
2407
+ }
2408
+
2409
+ protected static $libScaleColor = array(
2410
+ 'color', 'red', 'green', 'blue',
2411
+ 'hue', 'saturation', 'lightness', 'alpha'
2412
+ );
2413
+ protected function scaleColorHelper($base, $scale, $i)
2414
+ {
2415
+ // 1,2,3 - rgb
2416
+ // 4, 5, 6 - hsl
2417
+ // 7 - a
2418
+ switch ($i) {
2419
+ case 1:
2420
+ case 2:
2421
+ case 3:
2422
+ $max = 255;
2423
+ break;
2424
+ case 4:
2425
+ $max = 360;
2426
+ break;
2427
+ case 7:
2428
+ $max = 1;
2429
+ break;
2430
+ default:
2431
+ $max = 100;
2432
+ }
2433
+
2434
+ $scale = $scale / 100;
2435
+
2436
+ if ($scale < 0) {
2437
+ return $base * $scale + $base;
2438
+ }
2439
+
2440
+ return ($max - $base) * $scale + $base;
2441
+ }
2442
+ protected function libScaleColor($args)
2443
+ {
2444
+ return $this->alterColor($args, 'scaleColorHelper');
2445
+ }
2446
+
2447
+ protected static $libIeHexStr = array('color');
2448
+ protected function libIeHexStr($args)
2449
+ {
2450
+ $color = $this->coerceColor($args[0]);
2451
+ $color[4] = isset($color[4]) ? round(255*$color[4]) : 255;
2452
+
2453
+ return sprintf('#%02X%02X%02X%02X', $color[4], $color[1], $color[2], $color[3]);
2454
+ }
2455
+
2456
+ protected static $libRed = array('color');
2457
+ protected function libRed($args)
2458
+ {
2459
+ $color = $this->coerceColor($args[0]);
2460
+
2461
+ return $color[1];
2462
+ }
2463
+
2464
+ protected static $libGreen = array('color');
2465
+ protected function libGreen($args)
2466
+ {
2467
+ $color = $this->coerceColor($args[0]);
2468
+
2469
+ return $color[2];
2470
+ }
2471
+
2472
+ protected static $libBlue = array('color');
2473
+ protected function libBlue($args)
2474
+ {
2475
+ $color = $this->coerceColor($args[0]);
2476
+
2477
+ return $color[3];
2478
+ }
2479
+
2480
+ protected static $libAlpha = array('color');
2481
+ protected function libAlpha($args)
2482
+ {
2483
+ if ($color = $this->coerceColor($args[0])) {
2484
+ return isset($color[4]) ? $color[4] : 1;
2485
+ }
2486
+
2487
+ // this might be the IE function, so return value unchanged
2488
+ return null;
2489
+ }
2490
+
2491
+ protected static $libOpacity = array('color');
2492
+ protected function libOpacity($args)
2493
+ {
2494
+ $value = $args[0];
2495
+
2496
+ if ($value[0] === 'number') {
2497
+ return null;
2498
+ }
2499
+
2500
+ return $this->libAlpha($args);
2501
+ }
2502
+
2503
+ // mix two colors
2504
+ protected static $libMix = array('color-1', 'color-2', 'weight');
2505
+ protected function libMix($args)
2506
+ {
2507
+ list($first, $second, $weight) = $args;
2508
+ $first = $this->assertColor($first);
2509
+ $second = $this->assertColor($second);
2510
+
2511
+ if (!isset($weight)) {
2512
+ $weight = 0.5;
2513
+ } else {
2514
+ $weight = $this->coercePercent($weight);
2515
+ }
2516
+
2517
+ $firstAlpha = isset($first[4]) ? $first[4] : 1;
2518
+ $secondAlpha = isset($second[4]) ? $second[4] : 1;
2519
+
2520
+ $w = $weight * 2 - 1;
2521
+ $a = $firstAlpha - $secondAlpha;
2522
+
2523
+ $w1 = (($w * $a == -1 ? $w : ($w + $a)/(1 + $w * $a)) + 1) / 2.0;
2524
+ $w2 = 1.0 - $w1;
2525
+
2526
+ $new = array('color',
2527
+ $w1 * $first[1] + $w2 * $second[1],
2528
+ $w1 * $first[2] + $w2 * $second[2],
2529
+ $w1 * $first[3] + $w2 * $second[3],
2530
+ );
2531
+
2532
+ if ($firstAlpha != 1.0 || $secondAlpha != 1.0) {
2533
+ $new[] = $firstAlpha * $weight + $secondAlpha * ($weight - 1);
2534
+ }
2535
+
2536
+ return $this->fixColor($new);
2537
+ }
2538
+
2539
+ protected static $libHsl = array('hue', 'saturation', 'lightness');
2540
+ protected function libHsl($args)
2541
+ {
2542
+ list($h, $s, $l) = $args;
2543
+
2544
+ return $this->toRGB($h[1], $s[1], $l[1]);
2545
+ }
2546
+
2547
+ protected static $libHsla = array('hue', 'saturation',
2548
+ 'lightness', 'alpha');
2549
+ protected function libHsla($args)
2550
+ {
2551
+ list($h, $s, $l, $a) = $args;
2552
+
2553
+ $color = $this->toRGB($h[1], $s[1], $l[1]);
2554
+ $color[4] = $a[1];
2555
+
2556
+ return $color;
2557
+ }
2558
+
2559
+ protected static $libHue = array('color');
2560
+ protected function libHue($args)
2561
+ {
2562
+ $color = $this->assertColor($args[0]);
2563
+ $hsl = $this->toHSL($color[1], $color[2], $color[3]);
2564
+
2565
+ return array('number', $hsl[1], 'deg');
2566
+ }
2567
+
2568
+ protected static $libSaturation = array('color');
2569
+ protected function libSaturation($args)
2570
+ {
2571
+ $color = $this->assertColor($args[0]);
2572
+ $hsl = $this->toHSL($color[1], $color[2], $color[3]);
2573
+
2574
+ return array('number', $hsl[2], '%');
2575
+ }
2576
+
2577
+ protected static $libLightness = array('color');
2578
+ protected function libLightness($args)
2579
+ {
2580
+ $color = $this->assertColor($args[0]);
2581
+ $hsl = $this->toHSL($color[1], $color[2], $color[3]);
2582
+
2583
+ return array('number', $hsl[3], '%');
2584
+ }
2585
+
2586
+ protected function adjustHsl($color, $idx, $amount)
2587
+ {
2588
+ $hsl = $this->toHSL($color[1], $color[2], $color[3]);
2589
+ $hsl[$idx] += $amount;
2590
+ $out = $this->toRGB($hsl[1], $hsl[2], $hsl[3]);
2591
+
2592
+ if (isset($color[4])) {
2593
+ $out[4] = $color[4];
2594
+ }
2595
+
2596
+ return $out;
2597
+ }
2598
+
2599
+ protected static $libAdjustHue = array('color', 'degrees');
2600
+ protected function libAdjustHue($args)
2601
+ {
2602
+ $color = $this->assertColor($args[0]);
2603
+ $degrees = $this->assertNumber($args[1]);
2604
+
2605
+ return $this->adjustHsl($color, 1, $degrees);
2606
+ }
2607
+
2608
+ protected static $libLighten = array('color', 'amount');
2609
+ protected function libLighten($args)
2610
+ {
2611
+ $color = $this->assertColor($args[0]);
2612
+ $amount = 100*$this->coercePercent($args[1]);
2613
+
2614
+ return $this->adjustHsl($color, 3, $amount);
2615
+ }
2616
+
2617
+ protected static $libDarken = array('color', 'amount');
2618
+ protected function libDarken($args)
2619
+ {
2620
+ $color = $this->assertColor($args[0]);
2621
+ $amount = 100*$this->coercePercent($args[1]);
2622
+
2623
+ return $this->adjustHsl($color, 3, -$amount);
2624
+ }
2625
+
2626
+ protected static $libSaturate = array('color', 'amount');
2627
+ protected function libSaturate($args)
2628
+ {
2629
+ $value = $args[0];
2630
+
2631
+ if ($value[0] === 'number') {
2632
+ return null;
2633
+ }
2634
+
2635
+ $color = $this->assertColor($value);
2636
+ $amount = 100*$this->coercePercent($args[1]);
2637
+
2638
+ return $this->adjustHsl($color, 2, $amount);
2639
+ }
2640
+
2641
+ protected static $libDesaturate = array('color', 'amount');
2642
+ protected function libDesaturate($args)
2643
+ {
2644
+ $color = $this->assertColor($args[0]);
2645
+ $amount = 100*$this->coercePercent($args[1]);
2646
+
2647
+ return $this->adjustHsl($color, 2, -$amount);
2648
+ }
2649
+
2650
+ protected static $libGrayscale = array('color');
2651
+ protected function libGrayscale($args)
2652
+ {
2653
+ $value = $args[0];
2654
+
2655
+ if ($value[0] === 'number') {
2656
+ return null;
2657
+ }
2658
+
2659
+ return $this->adjustHsl($this->assertColor($value), 2, -100);
2660
+ }
2661
+
2662
+ protected static $libComplement = array('color');
2663
+ protected function libComplement($args)
2664
+ {
2665
+ return $this->adjustHsl($this->assertColor($args[0]), 1, 180);
2666
+ }
2667
+
2668
+ protected static $libInvert = array('color');
2669
+ protected function libInvert($args)
2670
+ {
2671
+ $value = $args[0];
2672
+
2673
+ if ($value[0] === 'number') {
2674
+ return null;
2675
+ }
2676
+
2677
+ $color = $this->assertColor($value);
2678
+ $color[1] = 255 - $color[1];
2679
+ $color[2] = 255 - $color[2];
2680
+ $color[3] = 255 - $color[3];
2681
+
2682
+ return $color;
2683
+ }
2684
+
2685
+ // increases opacity by amount
2686
+ protected static $libOpacify = array('color', 'amount');
2687
+ protected function libOpacify($args)
2688
+ {
2689
+ $color = $this->assertColor($args[0]);
2690
+ $amount = $this->coercePercent($args[1]);
2691
+
2692
+ $color[4] = (isset($color[4]) ? $color[4] : 1) + $amount;
2693
+ $color[4] = min(1, max(0, $color[4]));
2694
+
2695
+ return $color;
2696
+ }
2697
+
2698
+ protected static $libFadeIn = array('color', 'amount');
2699
+ protected function libFadeIn($args)
2700
+ {
2701
+ return $this->libOpacify($args);
2702
+ }
2703
+
2704
+ // decreases opacity by amount
2705
+ protected static $libTransparentize = array('color', 'amount');
2706
+ protected function libTransparentize($args)
2707
+ {
2708
+ $color = $this->assertColor($args[0]);
2709
+ $amount = $this->coercePercent($args[1]);
2710
+
2711
+ $color[4] = (isset($color[4]) ? $color[4] : 1) - $amount;
2712
+ $color[4] = min(1, max(0, $color[4]));
2713
+
2714
+ return $color;
2715
+ }
2716
+
2717
+ protected static $libFadeOut = array('color', 'amount');
2718
+ protected function libFadeOut($args)
2719
+ {
2720
+ return $this->libTransparentize($args);
2721
+ }
2722
+
2723
+ protected static $libUnquote = array('string');
2724
+ protected function libUnquote($args)
2725
+ {
2726
+ $str = $args[0];
2727
+
2728
+ if ($str[0] == 'string') {
2729
+ $str[1] = '';
2730
+ }
2731
+
2732
+ return $str;
2733
+ }
2734
+
2735
+ protected static $libQuote = array('string');
2736
+ protected function libQuote($args)
2737
+ {
2738
+ $value = $args[0];
2739
+
2740
+ if ($value[0] == 'string' && !empty($value[1])) {
2741
+ return $value;
2742
+ }
2743
+
2744
+ return array('string', '"', array($value));
2745
+ }
2746
+
2747
+ protected static $libPercentage = array('value');
2748
+ protected function libPercentage($args)
2749
+ {
2750
+ return array('number',
2751
+ $this->coercePercent($args[0]) * 100,
2752
+ '%');
2753
+ }
2754
+
2755
+ protected static $libRound = array('value');
2756
+ protected function libRound($args)
2757
+ {
2758
+ $num = $args[0];
2759
+ $num[1] = round($num[1]);
2760
+
2761
+ return $num;
2762
+ }
2763
+
2764
+ protected static $libFloor = array('value');
2765
+ protected function libFloor($args)
2766
+ {
2767
+ $num = $args[0];
2768
+ $num[1] = floor($num[1]);
2769
+
2770
+ return $num;
2771
+ }
2772
+
2773
+ protected static $libCeil = array('value');
2774
+ protected function libCeil($args)
2775
+ {
2776
+ $num = $args[0];
2777
+ $num[1] = ceil($num[1]);
2778
+
2779
+ return $num;
2780
+ }
2781
+
2782
+ protected static $libAbs = array('value');
2783
+ protected function libAbs($args)
2784
+ {
2785
+ $num = $args[0];
2786
+ $num[1] = abs($num[1]);
2787
+
2788
+ return $num;
2789
+ }
2790
+
2791
+ protected function libMin($args)
2792
+ {
2793
+ $numbers = $this->getNormalizedNumbers($args);
2794
+ $min = null;
2795
+
2796
+ foreach ($numbers as $key => $number) {
2797
+ if (null === $min || $number[1] <= $min[1]) {
2798
+ $min = array($key, $number[1]);
2799
+ }
2800
+ }
2801
+
2802
+ return $args[$min[0]];
2803
+ }
2804
+
2805
+ protected function libMax($args)
2806
+ {
2807
+ $numbers = $this->getNormalizedNumbers($args);
2808
+ $max = null;
2809
+
2810
+ foreach ($numbers as $key => $number) {
2811
+ if (null === $max || $number[1] >= $max[1]) {
2812
+ $max = array($key, $number[1]);
2813
+ }
2814
+ }
2815
+
2816
+ return $args[$max[0]];
2817
+ }
2818
+
2819
+ protected function getNormalizedNumbers($args)
2820
+ {
2821
+ $unit = null;
2822
+ $originalUnit = null;
2823
+ $numbers = array();
2824
+
2825
+ foreach ($args as $key => $item) {
2826
+ if ('number' != $item[0]) {
2827
+ $this->throwError('%s is not a number', $item[0]);
2828
+ }
2829
+
2830
+ $number = $this->normalizeNumber($item);
2831
+
2832
+ if (null === $unit) {
2833
+ $unit = $number[2];
2834
+ $originalUnit = $item[2];
2835
+ } elseif ($unit !== $number[2]) {
2836
+ $this->throwError('Incompatible units: "%s" and "%s".', $originalUnit, $item[2]);
2837
+ }
2838
+
2839
+ $numbers[$key] = $number;
2840
+ }
2841
+
2842
+ return $numbers;
2843
+ }
2844
+
2845
+ protected static $libLength = array('list');
2846
+ protected function libLength($args)
2847
+ {
2848
+ $list = $this->coerceList($args[0]);
2849
+
2850
+ return count($list[2]);
2851
+ }
2852
+
2853
+ protected static $libNth = array('list', 'n');
2854
+ protected function libNth($args)
2855
+ {
2856
+ $list = $this->coerceList($args[0]);
2857
+ $n = $this->assertNumber($args[1]) - 1;
2858
+
2859
+ return isset($list[2][$n]) ? $list[2][$n] : self::$defaultValue;
2860
+ }
2861
+
2862
+ protected function listSeparatorForJoin($list1, $sep)
2863
+ {
2864
+ if (!isset($sep)) {
2865
+ return $list1[1];
2866
+ }
2867
+
2868
+ switch ($this->compileValue($sep)) {
2869
+ case 'comma':
2870
+ return ',';
2871
+ case 'space':
2872
+ return '';
2873
+ default:
2874
+ return $list1[1];
2875
+ }
2876
+ }
2877
+
2878
+ protected static $libJoin = array('list1', 'list2', 'separator');
2879
+ protected function libJoin($args)
2880
+ {
2881
+ list($list1, $list2, $sep) = $args;
2882
+
2883
+ $list1 = $this->coerceList($list1, ' ');
2884
+ $list2 = $this->coerceList($list2, ' ');
2885
+ $sep = $this->listSeparatorForJoin($list1, $sep);
2886
+
2887
+ return array('list', $sep, array_merge($list1[2], $list2[2]));
2888
+ }
2889
+
2890
+ protected static $libAppend = array('list', 'val', 'separator');
2891
+ protected function libAppend($args)
2892
+ {
2893
+ list($list1, $value, $sep) = $args;
2894
+
2895
+ $list1 = $this->coerceList($list1, ' ');
2896
+ $sep = $this->listSeparatorForJoin($list1, $sep);
2897
+
2898
+ return array('list', $sep, array_merge($list1[2], array($value)));
2899
+ }
2900
+
2901
+ protected function libZip($args)
2902
+ {
2903
+ foreach ($args as $arg) {
2904
+ $this->assertList($arg);
2905
+ }
2906
+
2907
+ $lists = array();
2908
+ $firstList = array_shift($args);
2909
+
2910
+ foreach ($firstList[2] as $key => $item) {
2911
+ $list = array('list', '', array($item));
2912
+
2913
+ foreach ($args as $arg) {
2914
+ if (isset($arg[2][$key])) {
2915
+ $list[2][] = $arg[2][$key];
2916
+ } else {
2917
+ break 2;
2918
+ }
2919
+ }
2920
+ $lists[] = $list;
2921
+ }
2922
+
2923
+ return array('list', ',', $lists);
2924
+ }
2925
+
2926
+ protected static $libTypeOf = array('value');
2927
+ protected function libTypeOf($args)
2928
+ {
2929
+ $value = $args[0];
2930
+
2931
+ switch ($value[0]) {
2932
+ case 'keyword':
2933
+ if ($value == self::$true || $value == self::$false) {
2934
+ return 'bool';
2935
+ }
2936
+
2937
+ if ($this->coerceColor($value)) {
2938
+ return 'color';
2939
+ }
2940
+
2941
+ return 'string';
2942
+ default:
2943
+ return $value[0];
2944
+ }
2945
+ }
2946
+
2947
+ protected static $libUnit = array('number');
2948
+ protected function libUnit($args)
2949
+ {
2950
+ $num = $args[0];
2951
+
2952
+ if ($num[0] == 'number') {
2953
+ return array('string', '"', array($num[2]));
2954
+ }
2955
+
2956
+ return '';
2957
+ }
2958
+
2959
+ protected static $libUnitless = array('number');
2960
+ protected function libUnitless($args)
2961
+ {
2962
+ $value = $args[0];
2963
+
2964
+ return $value[0] == 'number' && empty($value[2]);
2965
+ }
2966
+
2967
+ protected static $libComparable = array('number-1', 'number-2');
2968
+ protected function libComparable($args)
2969
+ {
2970
+ list($number1, $number2) = $args;
2971
+
2972
+ if (!isset($number1[0]) || $number1[0] != 'number' || !isset($number2[0]) || $number2[0] != 'number') {
2973
+ $this->throwError('Invalid argument(s) for "comparable"');
2974
+ }
2975
+
2976
+ $number1 = $this->normalizeNumber($number1);
2977
+ $number2 = $this->normalizeNumber($number2);
2978
+
2979
+ return $number1[2] == $number2[2] || $number1[2] == '' || $number2[2] == '';
2980
+ }
2981
+
2982
+ /**
2983
+ * Workaround IE7's content counter bug.
2984
+ *
2985
+ * @param array $args
2986
+ */
2987
+ protected function libCounter($args)
2988
+ {
2989
+ $list = array_map(array($this, 'compileValue'), $args);
2990
+
2991
+ return array('string', '', array('counter(' . implode(',', $list) . ')'));
2992
+ }
2993
+
2994
+ public function throwError($msg = null)
2995
+ {
2996
+ if (func_num_args() > 1) {
2997
+ $msg = call_user_func_array('sprintf', func_get_args());
2998
+ }
2999
+
3000
+ if ($this->sourcePos >= 0 && isset($this->sourceParser)) {
3001
+ $this->sourceParser->throwParseError($msg, $this->sourcePos);
3002
+ }
3003
+
3004
+ throw new \Exception($msg);
3005
+ }
3006
+ }
lib/scssphp/src/Formatter.php ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * SCSSPHP
4
+ *
5
+ * @copyright 2012-2014 Leaf Corcoran
6
+ *
7
+ * @license http://opensource.org/licenses/gpl-license GPL-3.0
8
+ * @license http://opensource.org/licenses/MIT MIT
9
+ *
10
+ * @link http://leafo.net/scssphp
11
+ */
12
+
13
+ namespace Leafo\ScssPhp;
14
+
15
+ /**
16
+ * SCSS base formatter
17
+ *
18
+ * @author Leaf Corcoran <leafot@gmail.com>
19
+ */
20
+ abstract class Formatter
21
+ {
22
+ public $indentLevel;
23
+ public $indentChar;
24
+ public $break;
25
+ public $open;
26
+ public $close;
27
+ public $tagSeparator;
28
+ public $assignSeparator;
29
+
30
+ protected function indentStr($n = 0)
31
+ {
32
+ return str_repeat($this->indentChar, max($this->indentLevel + $n, 0));
33
+ }
34
+
35
+ public function property($name, $value)
36
+ {
37
+ return $name . $this->assignSeparator . $value . ';';
38
+ }
39
+
40
+ protected function blockLines($inner, $block)
41
+ {
42
+ $glue = $this->break.$inner;
43
+ echo $inner . implode($glue, $block->lines);
44
+
45
+ if (!empty($block->children)) {
46
+ echo $this->break;
47
+ }
48
+ }
49
+
50
+ protected function block($block)
51
+ {
52
+ if (empty($block->lines) && empty($block->children)) {
53
+ return;
54
+ }
55
+
56
+ $inner = $pre = $this->indentStr();
57
+
58
+ if (!empty($block->selectors)) {
59
+ echo $pre .
60
+ implode($this->tagSeparator, $block->selectors) .
61
+ $this->open . $this->break;
62
+ $this->indentLevel++;
63
+ $inner = $this->indentStr();
64
+ }
65
+
66
+ if (!empty($block->lines)) {
67
+ $this->blockLines($inner, $block);
68
+ }
69
+
70
+ foreach ($block->children as $child) {
71
+ $this->block($child);
72
+ }
73
+
74
+ if (!empty($block->selectors)) {
75
+ $this->indentLevel--;
76
+
77
+ if (empty($block->children)) {
78
+ echo $this->break;
79
+ }
80
+
81
+ echo $pre . $this->close . $this->break;
82
+ }
83
+ }
84
+
85
+ public function format($block)
86
+ {
87
+ ob_start();
88
+ $this->block($block);
89
+ $out = ob_get_clean();
90
+
91
+ return $out;
92
+ }
93
+ }
lib/scssphp/src/Formatter/Compressed.php ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * SCSSPHP
4
+ *
5
+ * @copyright 2012-2014 Leaf Corcoran
6
+ *
7
+ * @license http://opensource.org/licenses/gpl-license GPL-3.0
8
+ * @license http://opensource.org/licenses/MIT MIT
9
+ *
10
+ * @link http://leafo.net/scssphp
11
+ */
12
+
13
+ namespace Leafo\ScssPhp\Formatter;
14
+
15
+ use Leafo\ScssPhp\Formatter;
16
+
17
+ /**
18
+ * SCSS compressed formatter
19
+ *
20
+ * @author Leaf Corcoran <leafot@gmail.com>
21
+ */
22
+ class Compressed extends Formatter
23
+ {
24
+ public function __construct()
25
+ {
26
+ $this->indentLevel = 0;
27
+ $this->indentChar = ' ';
28
+ $this->break = '';
29
+ $this->open = '{';
30
+ $this->close = '}';
31
+ $this->tagSeparator = ',';
32
+ $this->assignSeparator = ':';
33
+ }
34
+
35
+ public function indentStr($n = 0)
36
+ {
37
+ return '';
38
+ }
39
+
40
+ public function blockLines($inner, $block)
41
+ {
42
+ $glue = $this->break.$inner;
43
+
44
+ foreach ($block->lines as $index => $line) {
45
+ if (substr($line, 0, 2) === '/*' && substr($line, 2, 1) !== '!') {
46
+ unset($block->lines[$index]);
47
+ } elseif (substr($line, 0, 3) === '/*!') {
48
+ $block->lines[$index] = '/*' . substr($line, 3);
49
+ }
50
+ }
51
+
52
+ echo $inner . implode($glue, $block->lines);
53
+
54
+ if (!empty($block->children)) {
55
+ echo $this->break;
56
+ }
57
+ }
58
+ }
lib/scssphp/src/Formatter/Crunched.php ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * SCSSPHP
4
+ *
5
+ * @copyright 2012-2014 Leaf Corcoran
6
+ *
7
+ * @license http://opensource.org/licenses/gpl-license GPL-3.0
8
+ * @license http://opensource.org/licenses/MIT MIT
9
+ *
10
+ * @link http://leafo.net/scssphp
11
+ */
12
+
13
+ namespace Leafo\ScssPhp\Formatter;
14
+
15
+ use Leafo\ScssPhp\Formatter;
16
+
17
+ /**
18
+ * SCSS crunched formatter
19
+ *
20
+ * @author Anthon Pang <anthon.pang@gmail.com>
21
+ */
22
+ class Crunched extends Formatter
23
+ {
24
+ public function __construct()
25
+ {
26
+ $this->indentLevel = 0;
27
+ $this->indentChar = ' ';
28
+ $this->break = '';
29
+ $this->open = '{';
30
+ $this->close = '}';
31
+ $this->tagSeparator = ',';
32
+ $this->assignSeparator = ':';
33
+ }
34
+
35
+ public function indentStr($n = 0)
36
+ {
37
+ return '';
38
+ }
39
+
40
+ public function blockLines($inner, $block)
41
+ {
42
+ $glue = $this->break.$inner;
43
+
44
+ foreach ($block->lines as $index => $line) {
45
+ if (substr($line, 0, 2) === '/*') {
46
+ unset($block->lines[$index]);
47
+ }
48
+ }
49
+
50
+ echo $inner . implode($glue, $block->lines);
51
+
52
+ if (!empty($block->children)) {
53
+ echo $this->break;
54
+ }
55
+ }
56
+ }
lib/scssphp/src/Formatter/Expanded.php ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * SCSSPHP
4
+ *
5
+ * @copyright 2012-2014 Leaf Corcoran
6
+ *
7
+ * @license http://opensource.org/licenses/gpl-license GPL-3.0
8
+ * @license http://opensource.org/licenses/MIT MIT
9
+ *
10
+ * @link http://leafo.net/scssphp
11
+ */
12
+
13
+ namespace Leafo\ScssPhp\Formatter;
14
+
15
+ use Leafo\ScssPhp\Formatter;
16
+
17
+ /**
18
+ * SCSS expanded formatter
19
+ *
20
+ * @author Leaf Corcoran <leafot@gmail.com>
21
+ */
22
+ class Expanded extends Formatter
23
+ {
24
+ public function __construct()
25
+ {
26
+ $this->indentLevel = 0;
27
+ $this->indentChar = ' ';
28
+ $this->break = "\n";
29
+ $this->open = ' {';
30
+ $this->close = '}';
31
+ $this->tagSeparator = ', ';
32
+ $this->assignSeparator = ': ';
33
+ }
34
+ }
lib/scssphp/src/Formatter/Nested.php ADDED
@@ -0,0 +1,133 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * SCSSPHP
4
+ *
5
+ * @copyright 2012-2014 Leaf Corcoran
6
+ *
7
+ * @license http://opensource.org/licenses/gpl-license GPL-3.0
8
+ * @license http://opensource.org/licenses/MIT MIT
9
+ *
10
+ * @link http://leafo.net/scssphp
11
+ */
12
+
13
+ namespace Leafo\ScssPhp\Formatter;
14
+
15
+ use Leafo\ScssPhp\Formatter;
16
+
17
+ /**
18
+ * SCSS nested formatter
19
+ *
20
+ * @author Leaf Corcoran <leafot@gmail.com>
21
+ */
22
+ class Nested extends Formatter
23
+ {
24
+ public function __construct()
25
+ {
26
+ $this->indentLevel = 0;
27
+ $this->indentChar = ' ';
28
+ $this->break = "\n";
29
+ $this->open = ' {';
30
+ $this->close = ' }';
31
+ $this->tagSeparator = ', ';
32
+ $this->assignSeparator = ': ';
33
+ }
34
+
35
+ // adjust the depths of all children, depth first
36
+ public function adjustAllChildren($block)
37
+ {
38
+ // flatten empty nested blocks
39
+ $children = array();
40
+ foreach ($block->children as $i => $child) {
41
+ if (empty($child->lines) && empty($child->children)) {
42
+ if (isset($block->children[$i + 1])) {
43
+ $block->children[$i + 1]->depth = $child->depth;
44
+ }
45
+ continue;
46
+ }
47
+ $children[] = $child;
48
+ }
49
+
50
+ $count = count($children);
51
+ for ($i = 0; $i < $count; $i++) {
52
+ $depth = $children[$i]->depth;
53
+ $j = $i + 1;
54
+ if (isset($children[$j]) && $depth < $children[$j]->depth) {
55
+ $childDepth = $children[$j]->depth;
56
+ for (; $j < $count; $j++) {
57
+ if ($depth < $children[$j]->depth && $childDepth >= $children[$j]->depth) {
58
+ $children[$j]->depth = $depth + 1;
59
+ }
60
+ }
61
+ }
62
+ }
63
+
64
+ $block->children = $children;
65
+
66
+ // make relative to parent
67
+ foreach ($block->children as $child) {
68
+ $this->adjustAllChildren($child);
69
+ $child->depth = $child->depth - $block->depth;
70
+ }
71
+ }
72
+
73
+ protected function blockLines($inner, $block)
74
+ {
75
+ $glue = $this->break . $inner;
76
+
77
+ foreach ($block->lines as $index => $line) {
78
+ if (substr($line, 0, 2) === '/*') {
79
+ $block->lines[$index] = preg_replace('/(\r|\n)+/', $glue, $line);
80
+ }
81
+ }
82
+
83
+ echo $inner . implode($glue, $block->lines);
84
+
85
+ if (!empty($block->children)) {
86
+ echo $this->break;
87
+ }
88
+ }
89
+
90
+ protected function block($block)
91
+ {
92
+ if ($block->type == 'root') {
93
+ $this->adjustAllChildren($block);
94
+ }
95
+
96
+ $inner = $pre = $this->indentStr($block->depth - 1);
97
+ if (!empty($block->selectors)) {
98
+ echo $pre .
99
+ implode($this->tagSeparator, $block->selectors) .
100
+ $this->open . $this->break;
101
+ $this->indentLevel++;
102
+ $inner = $this->indentStr($block->depth - 1);
103
+ }
104
+
105
+ if (!empty($block->lines)) {
106
+ $this->blockLines($inner, $block);
107
+ }
108
+
109
+ foreach ($block->children as $i => $child) {
110
+ // echo "*** block: ".$block->depth." child: ".$child->depth."\n";
111
+ $this->block($child);
112
+ if ($i < count($block->children) - 1) {
113
+ echo $this->break;
114
+
115
+ if (isset($block->children[$i + 1])) {
116
+ $next = $block->children[$i + 1];
117
+ if ($next->depth == max($block->depth, 1) && $child->depth >= $next->depth) {
118
+ echo $this->break;
119
+ }
120
+ }
121
+ }
122
+ }
123
+
124
+ if (!empty($block->selectors)) {
125
+ $this->indentLevel--;
126
+ echo $this->close;
127
+ }
128
+
129
+ if ($block->type == 'root') {
130
+ echo $this->break;
131
+ }
132
+ }
133
+ }
lib/scssphp/src/Parser.php ADDED
@@ -0,0 +1,1811 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * SCSSPHP
4
+ *
5
+ * @copyright 2012-2014 Leaf Corcoran
6
+ *
7
+ * @license http://opensource.org/licenses/gpl-license GPL-3.0
8
+ * @license http://opensource.org/licenses/MIT MIT
9
+ *
10
+ * @link http://leafo.net/scssphp
11
+ */
12
+
13
+ namespace Leafo\ScssPhp;
14
+
15
+ use Leafo\ScssPhp\Compiler;
16
+
17
+ /**
18
+ * SCSS parser
19
+ *
20
+ * @author Leaf Corcoran <leafot@gmail.com>
21
+ */
22
+ class Parser
23
+ {
24
+ protected static $precedence = array(
25
+ 'or' => 0,
26
+ 'and' => 1,
27
+
28
+ '==' => 2,
29
+ '!=' => 2,
30
+ '<=' => 2,
31
+ '>=' => 2,
32
+ '=' => 2,
33
+ '<' => 3,
34
+ '>' => 2,
35
+
36
+ '+' => 3,
37
+ '-' => 3,
38
+ '*' => 4,
39
+ '/' => 4,
40
+ '%' => 4,
41
+ );
42
+
43
+ protected static $operators = array('+', '-', '*', '/', '%',
44
+ '==', '!=', '<=', '>=', '<', '>', 'and', 'or');
45
+
46
+ protected static $operatorStr;
47
+ protected static $whitePattern;
48
+ protected static $commentMulti;
49
+
50
+ protected static $commentSingle = '//';
51
+ protected static $commentMultiLeft = '/*';
52
+ protected static $commentMultiRight = '*/';
53
+
54
+ /**
55
+ * Constructor
56
+ *
57
+ * @param string $sourceName
58
+ * @param boolean $rootParser
59
+ */
60
+ public function __construct($sourceName = null, $rootParser = true)
61
+ {
62
+ $this->sourceName = $sourceName;
63
+ $this->rootParser = $rootParser;
64
+
65
+ if (empty(self::$operatorStr)) {
66
+ self::$operatorStr = $this->makeOperatorStr(self::$operators);
67
+
68
+ $commentSingle = $this->pregQuote(self::$commentSingle);
69
+ $commentMultiLeft = $this->pregQuote(self::$commentMultiLeft);
70
+ $commentMultiRight = $this->pregQuote(self::$commentMultiRight);
71
+ self::$commentMulti = $commentMultiLeft.'.*?'.$commentMultiRight;
72
+ self::$whitePattern = '/'.$commentSingle.'[^\n]*\s*|('.self::$commentMulti.')\s*|\s+/Ais';
73
+ }
74
+ }
75
+
76
+ protected static function makeOperatorStr($operators)
77
+ {
78
+ return '('
79
+ . implode('|', array_map(array('Leafo\ScssPhp\Parser','pregQuote'), $operators))
80
+ . ')';
81
+ }
82
+
83
+ /**
84
+ * Parser buffer
85
+ *
86
+ * @param string $buffer;
87
+ *
88
+ * @return \StdClass
89
+ */
90
+ public function parse($buffer)
91
+ {
92
+ $this->count = 0;
93
+ $this->env = null;
94
+ $this->inParens = false;
95
+ $this->eatWhiteDefault = true;
96
+ $this->buffer = $buffer;
97
+
98
+ $this->pushBlock(null); // root block
99
+
100
+ $this->whitespace();
101
+ $this->pushBlock(null);
102
+ $this->popBlock();
103
+
104
+ while (false !== $this->parseChunk()) {
105
+ ;
106
+ }
107
+
108
+ if ($this->count != strlen($this->buffer)) {
109
+ $this->throwParseError();
110
+ }
111
+
112
+ if (!empty($this->env->parent)) {
113
+ $this->throwParseError('unclosed block');
114
+ }
115
+
116
+ $this->env->isRoot = true;
117
+
118
+ return $this->env;
119
+ }
120
+
121
+ /**
122
+ * Parse a single chunk off the head of the buffer and append it to the
123
+ * current parse environment.
124
+ *
125
+ * Returns false when the buffer is empty, or when there is an error.
126
+ *
127
+ * This function is called repeatedly until the entire document is
128
+ * parsed.
129
+ *
130
+ * This parser is most similar to a recursive descent parser. Single
131
+ * functions represent discrete grammatical rules for the language, and
132
+ * they are able to capture the text that represents those rules.
133
+ *
134
+ * Consider the function Compiler::keyword(). (All parse functions are
135
+ * structured the same.)
136
+ *
137
+ * The function takes a single reference argument. When calling the
138
+ * function it will attempt to match a keyword on the head of the buffer.
139
+ * If it is successful, it will place the keyword in the referenced
140
+ * argument, advance the position in the buffer, and return true. If it
141
+ * fails then it won't advance the buffer and it will return false.
142
+ *
143
+ * All of these parse functions are powered by Compiler::match(), which behaves
144
+ * the same way, but takes a literal regular expression. Sometimes it is
145
+ * more convenient to use match instead of creating a new function.
146
+ *
147
+ * Because of the format of the functions, to parse an entire string of
148
+ * grammatical rules, you can chain them together using &&.
149
+ *
150
+ * But, if some of the rules in the chain succeed before one fails, then
151
+ * the buffer position will be left at an invalid state. In order to
152
+ * avoid this, Compiler::seek() is used to remember and set buffer positions.
153
+ *
154
+ * Before parsing a chain, use $s = $this->seek() to remember the current
155
+ * position into $s. Then if a chain fails, use $this->seek($s) to
156
+ * go back where we started.
157
+ *
158
+ * @return boolean
159
+ */
160
+ protected function parseChunk()
161
+ {
162
+ $s = $this->seek();
163
+
164
+ // the directives
165
+ if (isset($this->buffer[$this->count]) && $this->buffer[$this->count] == '@') {
166
+ if ($this->literal('@media') && $this->mediaQueryList($mediaQueryList) && $this->literal('{')) {
167
+ $media = $this->pushSpecialBlock('media');
168
+ $media->queryList = $mediaQueryList[2];
169
+
170
+ return true;
171
+ }
172
+
173
+ $this->seek($s);
174
+
175
+ if ($this->literal('@mixin') &&
176
+ $this->keyword($mixinName) &&
177
+ ($this->argumentDef($args) || true) &&
178
+ $this->literal('{')
179
+ ) {
180
+ $mixin = $this->pushSpecialBlock('mixin');
181
+ $mixin->name = $mixinName;
182
+ $mixin->args = $args;
183
+
184
+ return true;
185
+ }
186
+
187
+ $this->seek($s);
188
+
189
+ if ($this->literal('@include') &&
190
+ $this->keyword($mixinName) &&
191
+ ($this->literal('(') &&
192
+ ($this->argValues($argValues) || true) &&
193
+ $this->literal(')') || true) &&
194
+ ($this->end() ||
195
+ $this->literal('{') && $hasBlock = true)
196
+ ) {
197
+ $child = array('include',
198
+ $mixinName, isset($argValues) ? $argValues : null, null);
199
+
200
+ if (!empty($hasBlock)) {
201
+ $include = $this->pushSpecialBlock('include');
202
+ $include->child = $child;
203
+ } else {
204
+ $this->append($child, $s);
205
+ }
206
+
207
+ return true;
208
+ }
209
+
210
+ $this->seek($s);
211
+
212
+ if ($this->literal('@import') &&
213
+ $this->valueList($importPath) &&
214
+ $this->end()
215
+ ) {
216
+ $this->append(array('import', $importPath), $s);
217
+
218
+ return true;
219
+ }
220
+
221
+ $this->seek($s);
222
+
223
+ if ($this->literal('@extend') &&
224
+ $this->selectors($selector) &&
225
+ $this->end()
226
+ ) {
227
+ $this->append(array('extend', $selector), $s);
228
+
229
+ return true;
230
+ }
231
+
232
+ $this->seek($s);
233
+
234
+ if ($this->literal('@function') &&
235
+ $this->keyword($fnName) &&
236
+ $this->argumentDef($args) &&
237
+ $this->literal('{')
238
+ ) {
239
+ $func = $this->pushSpecialBlock('function');
240
+ $func->name = $fnName;
241
+ $func->args = $args;
242
+
243
+ return true;
244
+ }
245
+
246
+ $this->seek($s);
247
+
248
+ if ($this->literal('@return') && $this->valueList($retVal) && $this->end()) {
249
+ $this->append(array('return', $retVal), $s);
250
+
251
+ return true;
252
+ }
253
+
254
+ $this->seek($s);
255
+
256
+ if ($this->literal('@each') &&
257
+ $this->variable($varName) &&
258
+ $this->literal('in') &&
259
+ $this->valueList($list) &&
260
+ $this->literal('{')
261
+ ) {
262
+ $each = $this->pushSpecialBlock('each');
263
+ $each->var = $varName[1];
264
+ $each->list = $list;
265
+
266
+ return true;
267
+ }
268
+
269
+ $this->seek($s);
270
+
271
+ if ($this->literal('@while') &&
272
+ $this->expression($cond) &&
273
+ $this->literal('{')
274
+ ) {
275
+ $while = $this->pushSpecialBlock('while');
276
+ $while->cond = $cond;
277
+
278
+ return true;
279
+ }
280
+
281
+ $this->seek($s);
282
+
283
+ if ($this->literal('@for') &&
284
+ $this->variable($varName) &&
285
+ $this->literal('from') &&
286
+ $this->expression($start) &&
287
+ ($this->literal('through') ||
288
+ ($forUntil = true && $this->literal('to'))) &&
289
+ $this->expression($end) &&
290
+ $this->literal('{')
291
+ ) {
292
+ $for = $this->pushSpecialBlock('for');
293
+ $for->var = $varName[1];
294
+ $for->start = $start;
295
+ $for->end = $end;
296
+ $for->until = isset($forUntil);
297
+
298
+ return true;
299
+ }
300
+
301
+ $this->seek($s);
302
+
303
+ if ($this->literal('@if') && $this->valueList($cond) && $this->literal('{')) {
304
+ $if = $this->pushSpecialBlock('if');
305
+ $if->cond = $cond;
306
+ $if->cases = array();
307
+
308
+ return true;
309
+ }
310
+
311
+ $this->seek($s);
312
+
313
+ if (($this->literal('@debug') || $this->literal('@warn')) &&
314
+ $this->valueList($value) &&
315
+ $this->end()) {
316
+ $this->append(array('debug', $value, $s), $s);
317
+
318
+ return true;
319
+ }
320
+
321
+ $this->seek($s);
322
+
323
+ if ($this->literal('@content') && $this->end()) {
324
+ $this->append(array('mixin_content'), $s);
325
+
326
+ return true;
327
+ }
328
+
329
+ $this->seek($s);
330
+
331
+ $last = $this->last();
332
+ if (isset($last) && $last[0] == 'if') {
333
+ list(, $if) = $last;
334
+
335
+ if ($this->literal('@else')) {
336
+ if ($this->literal('{')) {
337
+ $else = $this->pushSpecialBlock('else');
338
+ } elseif ($this->literal('if') && $this->valueList($cond) && $this->literal('{')) {
339
+ $else = $this->pushSpecialBlock('elseif');
340
+ $else->cond = $cond;
341
+ }
342
+
343
+ if (isset($else)) {
344
+ $else->dontAppend = true;
345
+ $if->cases[] = $else;
346
+
347
+ return true;
348
+ }
349
+ }
350
+
351
+ $this->seek($s);
352
+ }
353
+
354
+ if ($this->literal('@charset') &&
355
+ $this->valueList($charset) && $this->end()
356
+ ) {
357
+ $this->append(array('charset', $charset), $s);
358
+
359
+ return true;
360
+ }
361
+
362
+ $this->seek($s);
363
+
364
+ // doesn't match built in directive, do generic one
365
+ if ($this->literal('@', false) && $this->keyword($dirName) &&
366
+ ($this->variable($dirValue) || $this->openString('{', $dirValue) || true) &&
367
+ $this->literal('{')
368
+ ) {
369
+ $directive = $this->pushSpecialBlock('directive');
370
+ $directive->name = $dirName;
371
+
372
+ if (isset($dirValue)) {
373
+ $directive->value = $dirValue;
374
+ }
375
+
376
+ return true;
377
+ }
378
+
379
+ $this->seek($s);
380
+
381
+ return false;
382
+ }
383
+
384
+ // property shortcut
385
+ // captures most properties before having to parse a selector
386
+ if ($this->keyword($name, false) &&
387
+ $this->literal(': ') &&
388
+ $this->valueList($value) &&
389
+ $this->end()
390
+ ) {
391
+ $name = array('string', '', array($name));
392
+ $this->append(array('assign', $name, $value), $s);
393
+
394
+ return true;
395
+ }
396
+
397
+ $this->seek($s);
398
+
399
+ // variable assigns
400
+ if ($this->variable($name) &&
401
+ $this->literal(':') &&
402
+ $this->valueList($value) && $this->end()
403
+ ) {
404
+ // check for !default
405
+ $defaultVar = $value[0] == 'list' && $this->stripDefault($value);
406
+ $this->append(array('assign', $name, $value, $defaultVar), $s);
407
+
408
+ return true;
409
+ }
410
+
411
+ $this->seek($s);
412
+
413
+ // misc
414
+ if ($this->literal('-->')) {
415
+ return true;
416
+ }
417
+
418
+ // opening css block
419
+ if ($this->selectors($selectors) && $this->literal('{')) {
420
+ $b = $this->pushBlock($selectors);
421
+
422
+ return true;
423
+ }
424
+
425
+ $this->seek($s);
426
+
427
+ // property assign, or nested assign
428
+ if ($this->propertyName($name) && $this->literal(':')) {
429
+ $foundSomething = false;
430
+ if ($this->valueList($value)) {
431
+ $this->append(array('assign', $name, $value), $s);
432
+ $foundSomething = true;
433
+ }
434
+
435
+ if ($this->literal('{')) {
436
+ $propBlock = $this->pushSpecialBlock('nestedprop');
437
+ $propBlock->prefix = $name;
438
+ $foundSomething = true;
439
+ } elseif ($foundSomething) {
440
+ $foundSomething = $this->end();
441
+ }
442
+
443
+ if ($foundSomething) {
444
+ return true;
445
+ }
446
+ }
447
+
448
+ $this->seek($s);
449
+
450
+ // closing a block
451
+ if ($this->literal('}')) {
452
+ $block = $this->popBlock();
453
+
454
+ if (isset($block->type) && $block->type == 'include') {
455
+ $include = $block->child;
456
+ unset($block->child);
457
+ $include[3] = $block;
458
+ $this->append($include, $s);
459
+ } elseif (empty($block->dontAppend)) {
460
+ $type = isset($block->type) ? $block->type : 'block';
461
+ $this->append(array($type, $block), $s);
462
+ }
463
+
464
+ return true;
465
+ }
466
+
467
+ // extra stuff
468
+ if ($this->literal(';') ||
469
+ $this->literal('<!--')
470
+ ) {
471
+ return true;
472
+ }
473
+
474
+ return false;
475
+ }
476
+
477
+ protected function stripDefault(&$value)
478
+ {
479
+ $def = end($value[2]);
480
+
481
+ if ($def[0] == 'keyword' && $def[1] == '!default') {
482
+ array_pop($value[2]);
483
+ $value = $this->flattenList($value);
484
+
485
+ return true;
486
+ }
487
+
488
+ if ($def[0] == 'list') {
489
+ return $this->stripDefault($value[2][count($value[2]) - 1]);
490
+ }
491
+
492
+ return false;
493
+ }
494
+
495
+ protected function literal($what, $eatWhitespace = null)
496
+ {
497
+ if (!isset($eatWhitespace)) {
498
+ $eatWhitespace = $this->eatWhiteDefault;
499
+ }
500
+
501
+ // shortcut on single letter
502
+ if (!isset($what[1]) && isset($this->buffer[$this->count])) {
503
+ if ($this->buffer[$this->count] == $what) {
504
+ if (!$eatWhitespace) {
505
+ $this->count++;
506
+
507
+ return true;
508
+ }
509
+ // goes below...
510
+ } else {
511
+ return false;
512
+ }
513
+ }
514
+
515
+ return $this->match($this->pregQuote($what), $m, $eatWhitespace);
516
+ }
517
+
518
+ // tree builders
519
+
520
+ protected function pushBlock($selectors)
521
+ {
522
+ $b = new \stdClass;
523
+ $b->parent = $this->env; // not sure if we need this yet
524
+
525
+ $b->selectors = $selectors;
526
+ $b->comments = array();
527
+
528
+ if (!$this->env) {
529
+ $b->children = array();
530
+ } elseif (empty($this->env->children)) {
531
+ $this->env->children = $this->env->comments;
532
+ $b->children = array();
533
+ $this->env->comments = array();
534
+ } else {
535
+ $b->children = $this->env->comments;
536
+ $this->env->comments = array();
537
+ }
538
+
539
+ $this->env = $b;
540
+
541
+ return $b;
542
+ }
543
+
544
+ protected function pushSpecialBlock($type)
545
+ {
546
+ $block = $this->pushBlock(null);
547
+ $block->type = $type;
548
+
549
+ return $block;
550
+ }
551
+
552
+ protected function popBlock()
553
+ {
554
+ $block = $this->env;
555
+
556
+ if (empty($block->parent)) {
557
+ $this->throwParseError('unexpected }');
558
+ }
559
+
560
+ $this->env = $block->parent;
561
+ unset($block->parent);
562
+
563
+ $comments = $block->comments;
564
+ if (count($comments)) {
565
+ $this->env->comments = $comments;
566
+ unset($block->comments);
567
+ }
568
+
569
+ return $block;
570
+ }
571
+
572
+ protected function appendComment($comment)
573
+ {
574
+ $comment[1] = substr(preg_replace(array('/^\s+/m', '/^(.)/m'), array('', ' \1'), $comment[1]), 1);
575
+
576
+ $this->env->comments[] = $comment;
577
+ }
578
+
579
+ protected function append($statement, $pos = null)
580
+ {
581
+ if ($pos !== null) {
582
+ $statement[-1] = $pos;
583
+
584
+ if (!$this->rootParser) {
585
+ $statement[-2] = $this;
586
+ }
587
+ }
588
+
589
+ $this->env->children[] = $statement;
590
+
591
+ $comments = $this->env->comments;
592
+ if (count($comments)) {
593
+ $this->env->children = array_merge($this->env->children, $comments);
594
+ $this->env->comments = array();
595
+ }
596
+ }
597
+
598
+ // last child that was appended
599
+ protected function last()
600
+ {
601
+ $i = count($this->env->children) - 1;
602
+
603
+ if (isset($this->env->children[$i])) {
604
+ return $this->env->children[$i];
605
+ }
606
+ }
607
+
608
+ // high level parsers (they return parts of ast)
609
+
610
+ protected function mediaQueryList(&$out)
611
+ {
612
+ return $this->genericList($out, 'mediaQuery', ',', false);
613
+ }
614
+
615
+ protected function mediaQuery(&$out)
616
+ {
617
+ $s = $this->seek();
618
+
619
+ $expressions = null;
620
+ $parts = array();
621
+
622
+ if (($this->literal('only') && ($only = true) || $this->literal('not') && ($not = true) || true) &&
623
+ $this->mixedKeyword($mediaType)
624
+ ) {
625
+ $prop = array('mediaType');
626
+
627
+ if (isset($only)) {
628
+ $prop[] = array('keyword', 'only');
629
+ }
630
+
631
+ if (isset($not)) {
632
+ $prop[] = array('keyword', 'not');
633
+ }
634
+
635
+ $media = array('list', '', array());
636
+
637
+ foreach ((array)$mediaType as $type) {
638
+ if (is_array($type)) {
639
+ $media[2][] = $type;
640
+ } else {
641
+ $media[2][] = array('keyword', $type);
642
+ }
643
+ }
644
+
645
+ $prop[] = $media;
646
+ $parts[] = $prop;
647
+ }
648
+
649
+ if (empty($parts) || $this->literal('and')) {
650
+ $this->genericList($expressions, 'mediaExpression', 'and', false);
651
+
652
+ if (is_array($expressions)) {
653
+ $parts = array_merge($parts, $expressions[2]);
654
+ }
655
+ }
656
+
657
+ $out = $parts;
658
+
659
+ return true;
660
+ }
661
+
662
+ protected function mediaExpression(&$out)
663
+ {
664
+ $s = $this->seek();
665
+ $value = null;
666
+
667
+ if ($this->literal('(') &&
668
+ $this->expression($feature) &&
669
+ ($this->literal(':') && $this->expression($value) || true) &&
670
+ $this->literal(')')
671
+ ) {
672
+ $out = array('mediaExp', $feature);
673
+
674
+ if ($value) {
675
+ $out[] = $value;
676
+ }
677
+
678
+ return true;
679
+ }
680
+
681
+ $this->seek($s);
682
+
683
+ return false;
684
+ }
685
+
686
+ protected function argValues(&$out)
687
+ {
688
+ if ($this->genericList($list, 'argValue', ',', false)) {
689
+ $out = $list[2];
690
+
691
+ return true;
692
+ }
693
+
694
+ return false;
695
+ }
696
+
697
+ protected function argValue(&$out)
698
+ {
699
+ $s = $this->seek();
700
+
701
+ $keyword = null;
702
+ if (!$this->variable($keyword) || !$this->literal(':')) {
703
+ $this->seek($s);
704
+ $keyword = null;
705
+ }
706
+
707
+ if ($this->genericList($value, 'expression')) {
708
+ $out = array($keyword, $value, false);
709
+ $s = $this->seek();
710
+
711
+ if ($this->literal('...')) {
712
+ $out[2] = true;
713
+ } else {
714
+ $this->seek($s);
715
+ }
716
+
717
+ return true;
718
+ }
719
+
720
+ return false;
721
+ }
722
+
723
+ /**
724
+ * Parse list
725
+ *
726
+ * @param string $out
727
+ *
728
+ * @return boolean
729
+ */
730
+ public function valueList(&$out)
731
+ {
732
+ return $this->genericList($out, 'spaceList', ',');
733
+ }
734
+
735
+ protected function spaceList(&$out)
736
+ {
737
+ return $this->genericList($out, 'expression');
738
+ }
739
+
740
+ protected function genericList(&$out, $parseItem, $delim = '', $flatten = true)
741
+ {
742
+ $s = $this->seek();
743
+ $items = array();
744
+
745
+ while ($this->$parseItem($value)) {
746
+ $items[] = $value;
747
+
748
+ if ($delim) {
749
+ if (!$this->literal($delim)) {
750
+ break;
751
+ }
752
+ }
753
+ }
754
+
755
+ if (count($items) == 0) {
756
+ $this->seek($s);
757
+
758
+ return false;
759
+ }
760
+
761
+ if ($flatten && count($items) == 1) {
762
+ $out = $items[0];
763
+ } else {
764
+ $out = array('list', $delim, $items);
765
+ }
766
+
767
+ return true;
768
+ }
769
+
770
+ protected function expression(&$out)
771
+ {
772
+ $s = $this->seek();
773
+
774
+ if ($this->literal('(')) {
775
+ if ($this->literal(')')) {
776
+ $out = array('list', '', array());
777
+
778
+ return true;
779
+ }
780
+
781
+ if ($this->valueList($out) && $this->literal(')') && $out[0] == 'list') {
782
+ return true;
783
+ }
784
+
785
+ $this->seek($s);
786
+ }
787
+
788
+ if ($this->value($lhs)) {
789
+ $out = $this->expHelper($lhs, 0);
790
+
791
+ return true;
792
+ }
793
+
794
+ return false;
795
+ }
796
+
797
+ protected function expHelper($lhs, $minP)
798
+ {
799
+ $opstr = self::$operatorStr;
800
+
801
+ $ss = $this->seek();
802
+ $whiteBefore = isset($this->buffer[$this->count - 1]) &&
803
+ ctype_space($this->buffer[$this->count - 1]);
804
+
805
+ while ($this->match($opstr, $m) && self::$precedence[$m[1]] >= $minP) {
806
+ $whiteAfter = isset($this->buffer[$this->count - 1]) &&
807
+ ctype_space($this->buffer[$this->count - 1]);
808
+
809
+ $op = $m[1];
810
+
811
+ // don't turn negative numbers into expressions
812
+ if ($op == '-' && $whiteBefore) {
813
+ if (!$whiteAfter) {
814
+ break;
815
+ }
816
+ }
817
+
818
+ if (!$this->value($rhs)) {
819
+ break;
820
+ }
821
+
822
+ // peek and see if rhs belongs to next operator
823
+ if ($this->peek($opstr, $next) && self::$precedence[$next[1]] > self::$precedence[$op]) {
824
+ $rhs = $this->expHelper($rhs, self::$precedence[$next[1]]);
825
+ }
826
+
827
+ $lhs = array('exp', $op, $lhs, $rhs, $this->inParens, $whiteBefore, $whiteAfter);
828
+ $ss = $this->seek();
829
+ $whiteBefore = isset($this->buffer[$this->count - 1]) &&
830
+ ctype_space($this->buffer[$this->count - 1]);
831
+ }
832
+
833
+ $this->seek($ss);
834
+
835
+ return $lhs;
836
+ }
837
+
838
+ protected function value(&$out)
839
+ {
840
+ $s = $this->seek();
841
+
842
+ if ($this->literal('not', false) && $this->whitespace() && $this->value($inner)) {
843
+ $out = array('unary', 'not', $inner, $this->inParens);
844
+
845
+ return true;
846
+ }
847
+
848
+ $this->seek($s);
849
+
850
+ if ($this->literal('+') && $this->value($inner)) {
851
+ $out = array('unary', '+', $inner, $this->inParens);
852
+
853
+ return true;
854
+ }
855
+
856
+ $this->seek($s);
857
+
858
+ // negation
859
+ if ($this->literal('-', false) &&
860
+ ($this->variable($inner) ||
861
+ $this->unit($inner) ||
862
+ $this->parenValue($inner))
863
+ ) {
864
+ $out = array('unary', '-', $inner, $this->inParens);
865
+
866
+ return true;
867
+ }
868
+
869
+ $this->seek($s);
870
+
871
+ if ($this->parenValue($out) ||
872
+ $this->interpolation($out) ||
873
+ $this->variable($out) ||
874
+ $this->color($out) ||
875
+ $this->unit($out) ||
876
+ $this->string($out) ||
877
+ $this->func($out) ||
878
+ $this->progid($out)
879
+ ) {
880
+ return true;
881
+ }
882
+
883
+ if ($this->keyword($keyword)) {
884
+ if ($keyword == 'null') {
885
+ $out = array('null');
886
+ } else {
887
+ $out = array('keyword', $keyword);
888
+ }
889
+
890
+ return true;
891
+ }
892
+
893
+ return false;
894
+ }
895
+
896
+ // value wrappen in parentheses
897
+ protected function parenValue(&$out)
898
+ {
899
+ $s = $this->seek();
900
+
901
+ $inParens = $this->inParens;
902
+
903
+ if ($this->literal('(') &&
904
+ ($this->inParens = true) && $this->expression($exp) &&
905
+ $this->literal(')')
906
+ ) {
907
+ $out = $exp;
908
+ $this->inParens = $inParens;
909
+
910
+ return true;
911
+ }
912
+
913
+ $this->inParens = $inParens;
914
+ $this->seek($s);
915
+
916
+ return false;
917
+ }
918
+
919
+ protected function progid(&$out)
920
+ {
921
+ $s = $this->seek();
922
+
923
+ if ($this->literal('progid:', false) &&
924
+ $this->openString('(', $fn) &&
925
+ $this->literal('(')
926
+ ) {
927
+ $this->openString(')', $args, '(');
928
+ if ($this->literal(')')) {
929
+ $out = array('string', '', array(
930
+ 'progid:', $fn, '(', $args, ')'
931
+ ));
932
+
933
+ return true;
934
+ }
935
+ }
936
+
937
+ $this->seek($s);
938
+
939
+ return false;
940
+ }
941
+
942
+ protected function func(&$func)
943
+ {
944
+ $s = $this->seek();
945
+
946
+ if ($this->keyword($name, false) &&
947
+ $this->literal('(')
948
+ ) {
949
+ if ($name == 'alpha' && $this->argumentList($args)) {
950
+ $func = array('function', $name, array('string', '', $args));
951
+
952
+ return true;
953
+ }
954
+
955
+ if ($name != 'expression' && !preg_match('/^(-[a-z]+-)?calc$/', $name)) {
956
+ $ss = $this->seek();
957
+
958
+ if ($this->argValues($args) && $this->literal(')')) {
959
+ $func = array('fncall', $name, $args);
960
+
961
+ return true;
962
+ }
963
+
964
+ $this->seek($ss);
965
+ }
966
+
967
+ if (($this->openString(')', $str, '(') || true ) &&
968
+ $this->literal(')')
969
+ ) {
970
+ $args = array();
971
+
972
+ if (!empty($str)) {
973
+ $args[] = array(null, array('string', '', array($str)));
974
+ }
975
+
976
+ $func = array('fncall', $name, $args);
977
+
978
+ return true;
979
+ }
980
+ }
981
+
982
+ $this->seek($s);
983
+
984
+ return false;
985
+ }
986
+
987
+ protected function argumentList(&$out)
988
+ {
989
+ $s = $this->seek();
990
+ $this->literal('(');
991
+
992
+ $args = array();
993
+
994
+ while ($this->keyword($var)) {
995
+ $ss = $this->seek();
996
+
997
+ if ($this->literal('=') && $this->expression($exp)) {
998
+ $args[] = array('string', '', array($var.'='));
999
+ $arg = $exp;
1000
+ } else {
1001
+ break;
1002
+ }
1003
+
1004
+ $args[] = $arg;
1005
+
1006
+ if (!$this->literal(',')) {
1007
+ break;
1008
+ }
1009
+
1010
+ $args[] = array('string', '', array(', '));
1011
+ }
1012
+
1013
+ if (!$this->literal(')') || !count($args)) {
1014
+ $this->seek($s);
1015
+
1016
+ return false;
1017
+ }
1018
+
1019
+ $out = $args;
1020
+
1021
+ return true;
1022
+ }
1023
+
1024
+ protected function argumentDef(&$out)
1025
+ {
1026
+ $s = $this->seek();
1027
+ $this->literal('(');
1028
+
1029
+ $args = array();
1030
+
1031
+ while ($this->variable($var)) {
1032
+ $arg = array($var[1], null, false);
1033
+
1034
+ $ss = $this->seek();
1035
+
1036
+ if ($this->literal(':') && $this->genericList($defaultVal, 'expression')) {
1037
+ $arg[1] = $defaultVal;
1038
+ } else {
1039
+ $this->seek($ss);
1040
+ }
1041
+
1042
+ $ss = $this->seek();
1043
+
1044
+ if ($this->literal('...')) {
1045
+ $sss = $this->seek();
1046
+
1047
+ if (!$this->literal(')')) {
1048
+ $this->throwParseError('... has to be after the final argument');
1049
+ }
1050
+
1051
+ $arg[2] = true;
1052
+ $this->seek($sss);
1053
+ } else {
1054
+ $this->seek($ss);
1055
+ }
1056
+
1057
+ $args[] = $arg;
1058
+
1059
+ if (!$this->literal(',')) {
1060
+ break;
1061
+ }
1062
+ }
1063
+
1064
+ if (!$this->literal(')')) {
1065
+ $this->seek($s);
1066
+
1067
+ return false;
1068
+ }
1069
+
1070
+ $out = $args;
1071
+
1072
+ return true;
1073
+ }
1074
+
1075
+ protected function color(&$out)
1076
+ {
1077
+ $color = array('color');
1078
+
1079
+ if ($this->match('(#([0-9a-f]{6})|#([0-9a-f]{3}))', $m)) {
1080
+ if (isset($m[3])) {
1081
+ $num = $m[3];
1082
+ $width = 16;
1083
+ } else {
1084
+ $num = $m[2];
1085
+ $width = 256;
1086
+ }
1087
+
1088
+ $num = hexdec($num);
1089
+
1090
+ foreach (array(3,2,1) as $i) {
1091
+ $t = $num % $width;
1092
+ $num /= $width;
1093
+
1094
+ $color[$i] = $t * (256/$width) + $t * floor(16/$width);
1095
+ }
1096
+
1097
+ $out = $color;
1098
+
1099
+ return true;
1100
+ }
1101
+
1102
+ return false;
1103
+ }
1104
+
1105
+ protected function unit(&$unit)
1106
+ {
1107
+ if ($this->match('([0-9]*(\.)?[0-9]+)([%a-zA-Z]+)?', $m)) {
1108
+ $unit = array('number', $m[1], empty($m[3]) ? '' : $m[3]);
1109
+
1110
+ return true;
1111
+ }
1112
+
1113
+ return false;
1114
+ }
1115
+
1116
+ protected function string(&$out)
1117
+ {
1118
+ $s = $this->seek();
1119
+
1120
+ if ($this->literal('"', false)) {
1121
+ $delim = '"';
1122
+ } elseif ($this->literal('\'', false)) {
1123
+ $delim = '\'';
1124
+ } else {
1125
+ return false;
1126
+ }
1127
+
1128
+ $content = array();
1129
+ $oldWhite = $this->eatWhiteDefault;
1130
+ $this->eatWhiteDefault = false;
1131
+
1132
+ while ($this->matchString($m, $delim)) {
1133
+ $content[] = $m[1];
1134
+
1135
+ if ($m[2] == '#{') {
1136
+ $this->count -= strlen($m[2]);
1137
+
1138
+ if ($this->interpolation($inter, false)) {
1139
+ $content[] = $inter;
1140
+ } else {
1141
+ $this->count += strlen($m[2]);
1142
+ $content[] = '#{'; // ignore it
1143
+ }
1144
+ } elseif ($m[2] == '\\') {
1145
+ $content[] = $m[2];
1146
+
1147
+ if ($this->literal($delim, false)) {
1148
+ $content[] = $delim;
1149
+ }
1150
+ } else {
1151
+ $this->count -= strlen($delim);
1152
+ break; // delim
1153
+ }
1154
+ }
1155
+
1156
+ $this->eatWhiteDefault = $oldWhite;
1157
+
1158
+ if ($this->literal($delim)) {
1159
+ $out = array('string', $delim, $content);
1160
+
1161
+ return true;
1162
+ }
1163
+
1164
+ $this->seek($s);
1165
+
1166
+ return false;
1167
+ }
1168
+
1169
+ protected function mixedKeyword(&$out)
1170
+ {
1171
+ $s = $this->seek();
1172
+
1173
+ $parts = array();
1174
+
1175
+ $oldWhite = $this->eatWhiteDefault;
1176
+ $this->eatWhiteDefault = false;
1177
+
1178
+ while (true) {
1179
+ if ($this->keyword($key)) {
1180
+ $parts[] = $key;
1181
+ continue;
1182
+ }
1183
+
1184
+ if ($this->interpolation($inter)) {
1185
+ $parts[] = $inter;
1186
+ continue;
1187
+ }
1188
+
1189
+ break;
1190
+ }
1191
+
1192
+ $this->eatWhiteDefault = $oldWhite;
1193
+
1194
+ if (count($parts) == 0) {
1195
+ return false;
1196
+ }
1197
+
1198
+ if ($this->eatWhiteDefault) {
1199
+ $this->whitespace();
1200
+ }
1201
+
1202
+ $out = $parts;
1203
+
1204
+ return true;
1205
+ }
1206
+
1207
+ // an unbounded string stopped by $end
1208
+ protected function openString($end, &$out, $nestingOpen = null)
1209
+ {
1210
+ $oldWhite = $this->eatWhiteDefault;
1211
+ $this->eatWhiteDefault = false;
1212
+
1213
+ $stop = array('\'', '"', '#{', $end);
1214
+ $stop = array_map(array($this, 'pregQuote'), $stop);
1215
+ $stop[] = self::$commentMulti;
1216
+
1217
+ $patt = '(.*?)('.implode('|', $stop).')';
1218
+
1219
+ $nestingLevel = 0;
1220
+
1221
+ $content = array();
1222
+ while ($this->match($patt, $m, false)) {
1223
+ if (isset($m[1]) && $m[1] !== '') {
1224
+ $content[] = $m[1];
1225
+ if ($nestingOpen) {
1226
+ $nestingLevel += substr_count($m[1], $nestingOpen);
1227
+ }
1228
+ }
1229
+
1230
+ $tok = $m[2];
1231
+
1232
+ $this->count-= strlen($tok);
1233
+ if ($tok == $end) {
1234
+ if ($nestingLevel == 0) {
1235
+ break;
1236
+ } else {
1237
+ $nestingLevel--;
1238
+ }
1239
+ }
1240
+
1241
+ if (($tok == '\'' || $tok == '"') && $this->string($str)) {
1242
+ $content[] = $str;
1243
+ continue;
1244
+ }
1245
+
1246
+ if ($tok == '#{' && $this->interpolation($inter)) {
1247
+ $content[] = $inter;
1248
+ continue;
1249
+ }
1250
+
1251
+ $content[] = $tok;
1252
+ $this->count+= strlen($tok);
1253
+ }
1254
+
1255
+ $this->eatWhiteDefault = $oldWhite;
1256
+
1257
+ if (count($content) == 0) {
1258
+ return false;
1259
+ }
1260
+
1261
+ // trim the end
1262
+ if (is_string(end($content))) {
1263
+ $content[count($content) - 1] = rtrim(end($content));
1264
+ }
1265
+
1266
+ $out = array('string', '', $content);
1267
+
1268
+ return true;
1269
+ }
1270
+
1271
+ // $lookWhite: save information about whitespace before and after
1272
+ protected function interpolation(&$out, $lookWhite = true)
1273
+ {
1274
+ $oldWhite = $this->eatWhiteDefault;
1275
+ $this->eatWhiteDefault = true;
1276
+
1277
+ $s = $this->seek();
1278
+ if ($this->literal('#{') && $this->valueList($value) && $this->literal('}', false)) {
1279
+
1280
+ // TODO: don't error if out of bounds
1281
+
1282
+ if ($lookWhite) {
1283
+ $left = preg_match('/\s/', $this->buffer[$s - 1]) ? ' ' : '';
1284
+ $right = preg_match('/\s/', $this->buffer[$this->count]) ? ' ': '';
1285
+ } else {
1286
+ $left = $right = false;
1287
+ }
1288
+
1289
+ $out = array('interpolate', $value, $left, $right);
1290
+ $this->eatWhiteDefault = $oldWhite;
1291
+ if ($this->eatWhiteDefault) {
1292
+ $this->whitespace();
1293
+ }
1294
+ return true;
1295
+ }
1296
+
1297
+ $this->seek($s);
1298
+ $this->eatWhiteDefault = $oldWhite;
1299
+ return false;
1300
+ }
1301
+
1302
+ // low level parsers
1303
+
1304
+ // returns an array of parts or a string
1305
+ protected function propertyName(&$out)
1306
+ {
1307
+ $s = $this->seek();
1308
+ $parts = array();
1309
+
1310
+ $oldWhite = $this->eatWhiteDefault;
1311
+ $this->eatWhiteDefault = false;
1312
+
1313
+ while (true) {
1314
+ if ($this->interpolation($inter)) {
1315
+ $parts[] = $inter;
1316
+ } elseif ($this->keyword($text)) {
1317
+ $parts[] = $text;
1318
+ } elseif (count($parts) == 0 && $this->match('[:.#]', $m, false)) {
1319
+ // css hacks
1320
+ $parts[] = $m[0];
1321
+ } else {
1322
+ break;
1323
+ }
1324
+ }
1325
+
1326
+ $this->eatWhiteDefault = $oldWhite;
1327
+ if (count($parts) == 0) {
1328
+ return false;
1329
+ }
1330
+
1331
+ // match comment hack
1332
+ if (preg_match(
1333
+ self::$whitePattern,
1334
+ $this->buffer,
1335
+ $m,
1336
+ null,
1337
+ $this->count
1338
+ )) {
1339
+ if (!empty($m[0])) {
1340
+ $parts[] = $m[0];
1341
+ $this->count += strlen($m[0]);
1342
+ }
1343
+ }
1344
+
1345
+ $this->whitespace(); // get any extra whitespace
1346
+
1347
+ $out = array('string', '', $parts);
1348
+
1349
+ return true;
1350
+ }
1351
+
1352
+ // comma separated list of selectors
1353
+ protected function selectors(&$out)
1354
+ {
1355
+ $s = $this->seek();
1356
+ $selectors = array();
1357
+
1358
+ while ($this->selector($sel)) {
1359
+ $selectors[] = $sel;
1360
+
1361
+ if (!$this->literal(',')) {
1362
+ break;
1363
+ }
1364
+
1365
+ while ($this->literal(',')) {
1366
+ ; // ignore extra
1367
+ }
1368
+ }
1369
+
1370
+ if (count($selectors) == 0) {
1371
+ $this->seek($s);
1372
+
1373
+ return false;
1374
+ }
1375
+
1376
+ $out = $selectors;
1377
+
1378
+ return true;
1379
+ }
1380
+
1381
+ // whitespace separated list of selectorSingle
1382
+ protected function selector(&$out)
1383
+ {
1384
+ $selector = array();
1385
+
1386
+ while (true) {
1387
+ if ($this->match('[>+~]+', $m)) {
1388
+ $selector[] = array($m[0]);
1389
+ } elseif ($this->selectorSingle($part)) {
1390
+ $selector[] = $part;
1391
+ $this->match('\s+', $m);
1392
+ } elseif ($this->match('\/[^\/]+\/', $m)) {
1393
+ $selector[] = array($m[0]);
1394
+ } else {
1395
+ break;
1396
+ }
1397
+
1398
+ }
1399
+
1400
+ if (count($selector) == 0) {
1401
+ return false;
1402
+ }
1403
+
1404
+ $out = $selector;
1405
+ return true;
1406
+ }
1407
+
1408
+ // the parts that make up
1409
+ // div[yes=no]#something.hello.world:nth-child(-2n+1)%placeholder
1410
+ protected function selectorSingle(&$out)
1411
+ {
1412
+ $oldWhite = $this->eatWhiteDefault;
1413
+ $this->eatWhiteDefault = false;
1414
+
1415
+ $parts = array();
1416
+
1417
+ if ($this->literal('*', false)) {
1418
+ $parts[] = '*';
1419
+ }
1420
+
1421
+ while (true) {
1422
+ // see if we can stop early
1423
+ if ($this->match('\s*[{,]', $m)) {
1424
+ $this->count--;
1425
+ break;
1426
+ }
1427
+
1428
+ $s = $this->seek();
1429
+ // self
1430
+ if ($this->literal('&', false)) {
1431
+ $parts[] = Compiler::$selfSelector;
1432
+ continue;
1433
+ }
1434
+
1435
+ if ($this->literal('.', false)) {
1436
+ $parts[] = '.';
1437
+ continue;
1438
+ }
1439
+
1440
+ if ($this->literal('|', false)) {
1441
+ $parts[] = '|';
1442
+ continue;
1443
+ }
1444
+
1445
+ if ($this->match('\\\\\S', $m)) {
1446
+ $parts[] = $m[0];
1447
+ continue;
1448
+ }
1449
+
1450
+ // for keyframes
1451
+ if ($this->unit($unit)) {
1452
+ $parts[] = $unit;
1453
+ continue;
1454
+ }
1455
+
1456
+ if ($this->keyword($name)) {
1457
+ $parts[] = $name;
1458
+ continue;
1459
+ }
1460
+
1461
+ if ($this->interpolation($inter)) {
1462
+ $parts[] = $inter;
1463
+ continue;
1464
+ }
1465
+
1466
+ if ($this->literal('%', false) && $this->placeholder($placeholder)) {
1467
+ $parts[] = '%';
1468
+ $parts[] = $placeholder;
1469
+ continue;
1470
+ }
1471
+
1472
+ if ($this->literal('#', false)) {
1473
+ $parts[] = '#';
1474
+ continue;
1475
+ }
1476
+
1477
+ // a pseudo selector
1478
+ if ($this->match('::?', $m) && $this->mixedKeyword($nameParts)) {
1479
+ $parts[] = $m[0];
1480
+ foreach ($nameParts as $sub) {
1481
+ $parts[] = $sub;
1482
+ }
1483
+
1484
+ $ss = $this->seek();
1485
+
1486
+ if ($this->literal('(') &&
1487
+ ($this->openString(')', $str, '(') || true ) &&
1488
+ $this->literal(')')
1489
+ ) {
1490
+ $parts[] = '(';
1491
+
1492
+ if (!empty($str)) {
1493
+ $parts[] = $str;
1494
+ }
1495
+
1496
+ $parts[] = ')';
1497
+ } else {
1498
+ $this->seek($ss);
1499
+ }
1500
+
1501
+ continue;
1502
+ } else {
1503
+ $this->seek($s);
1504
+ }
1505
+
1506
+ // attribute selector
1507
+ // TODO: replace with open string?
1508
+ if ($this->literal('[', false)) {
1509
+ $attrParts = array('[');
1510
+ // keyword, string, operator
1511
+ while (true) {
1512
+ if ($this->literal(']', false)) {
1513
+ $this->count--;
1514
+ break; // get out early
1515
+ }
1516
+
1517
+ if ($this->match('\s+', $m)) {
1518
+ $attrParts[] = ' ';
1519
+ continue;
1520
+ }
1521
+ if ($this->string($str)) {
1522
+ $attrParts[] = $str;
1523
+ continue;
1524
+ }
1525
+
1526
+ if ($this->keyword($word)) {
1527
+ $attrParts[] = $word;
1528
+ continue;
1529
+ }
1530
+
1531
+ if ($this->interpolation($inter, false)) {
1532
+ $attrParts[] = $inter;
1533
+ continue;
1534
+ }
1535
+
1536
+ // operator, handles attr namespace too
1537
+ if ($this->match('[|-~\$\*\^=]+', $m)) {
1538
+ $attrParts[] = $m[0];
1539
+ continue;
1540
+ }
1541
+
1542
+ break;
1543
+ }
1544
+
1545
+ if ($this->literal(']', false)) {
1546
+ $attrParts[] = ']';
1547
+
1548
+ foreach ($attrParts as $part) {
1549
+ $parts[] = $part;
1550
+ }
1551
+
1552
+ continue;
1553
+ }
1554
+
1555
+ $this->seek($s);
1556
+ // should just break here?
1557
+ }
1558
+
1559
+ break;
1560
+ }
1561
+
1562
+ $this->eatWhiteDefault = $oldWhite;
1563
+
1564
+ if (count($parts) == 0) {
1565
+ return false;
1566
+ }
1567
+
1568
+ $out = $parts;
1569
+
1570
+ return true;
1571
+ }
1572
+
1573
+ protected function variable(&$out)
1574
+ {
1575
+ $s = $this->seek();
1576
+
1577
+ if ($this->literal('$', false) && $this->keyword($name)) {
1578
+ $out = array('var', $name);
1579
+
1580
+ return true;
1581
+ }
1582
+
1583
+ $this->seek($s);
1584
+
1585
+ return false;
1586
+ }
1587
+
1588
+ protected function keyword(&$word, $eatWhitespace = null)
1589
+ {
1590
+ if ($this->match(
1591
+ '(([\w_\-\*!"\']|[\\\\].)([\w\-_"\']|[\\\\].)*)',
1592
+ $m,
1593
+ $eatWhitespace
1594
+ )) {
1595
+ $word = $m[1];
1596
+
1597
+ return true;
1598
+ }
1599
+
1600
+ return false;
1601
+ }
1602
+
1603
+ protected function placeholder(&$placeholder)
1604
+ {
1605
+ if ($this->match('([\w\-_]+)', $m)) {
1606
+ $placeholder = $m[1];
1607
+
1608
+ return true;
1609
+ }
1610
+
1611
+ return false;
1612
+ }
1613
+
1614
+ // consume an end of statement delimiter
1615
+ protected function end()
1616
+ {
1617
+ if ($this->literal(';')) {
1618
+ return true;
1619
+ }
1620
+
1621
+ if ($this->count == strlen($this->buffer) || $this->buffer[$this->count] == '}') {
1622
+ // if there is end of file or a closing block next then we don't need a ;
1623
+ return true;
1624
+ }
1625
+
1626
+ return false;
1627
+ }
1628
+
1629
+ // advance counter to next occurrence of $what
1630
+ // $until - don't include $what in advance
1631
+ // $allowNewline, if string, will be used as valid char set
1632
+ protected function to($what, &$out, $until = false, $allowNewline = false)
1633
+ {
1634
+ if (is_string($allowNewline)) {
1635
+ $validChars = $allowNewline;
1636
+ } else {
1637
+ $validChars = $allowNewline ? '.' : "[^\n]";
1638
+ }
1639
+
1640
+ if (!$this->match('('.$validChars.'*?)'.$this->pregQuote($what), $m, !$until)) {
1641
+ return false;
1642
+ }
1643
+
1644
+ if ($until) {
1645
+ $this->count -= strlen($what); // give back $what
1646
+ }
1647
+
1648
+ $out = $m[1];
1649
+
1650
+ return true;
1651
+ }
1652
+
1653
+ public function throwParseError($msg = 'parse error', $count = null)
1654
+ {
1655
+ $count = !isset($count) ? $this->count : $count;
1656
+
1657
+ $line = $this->getLineNo($count);
1658
+
1659
+ if (!empty($this->sourceName)) {
1660
+ $loc = "$this->sourceName on line $line";
1661
+ } else {
1662
+ $loc = "line: $line";
1663
+ }
1664
+
1665
+ if ($this->peek("(.*?)(\n|$)", $m, $count)) {
1666
+ throw new \Exception("$msg: failed at `$m[1]` $loc");
1667
+ }
1668
+
1669
+ throw new \Exception("$msg: $loc");
1670
+ }
1671
+
1672
+ public function getLineNo($pos)
1673
+ {
1674
+ return 1 + substr_count(substr($this->buffer, 0, $pos), "\n");
1675
+ }
1676
+
1677
+ /**
1678
+ * Match string looking for either ending delim, escape, or string interpolation
1679
+ *
1680
+ * {@internal This is a workaround for preg_match's 250K string match limit. }}
1681
+ *
1682
+ * @param array $m Matches (passed by reference)
1683
+ * @param string $delim Delimeter
1684
+ *
1685
+ * @return boolean True if match; false otherwise
1686
+ */
1687
+ protected function matchString(&$m, $delim)
1688
+ {
1689
+ $token = null;
1690
+
1691
+ $end = strpos($this->buffer, "\n", $this->count);
1692
+
1693
+ if ($end === false ||
1694
+ $this->buffer[$end - 1] == '\\' ||
1695
+ $this->buffer[$end - 2] == '\\' && $this->buffer[$end - 1] == "\r"
1696
+ ) {
1697
+ $end = strlen($this->buffer);
1698
+ }
1699
+
1700
+ // look for either ending delim, escape, or string interpolation
1701
+ foreach (array('#{', '\\', $delim) as $lookahead) {
1702
+ $pos = strpos($this->buffer, $lookahead, $this->count);
1703
+
1704
+ if ($pos !== false && $pos < $end) {
1705
+ $end = $pos;
1706
+ $token = $lookahead;
1707
+ }
1708
+ }
1709
+
1710
+ if (!isset($token)) {
1711
+ return false;
1712
+ }
1713
+
1714
+ $match = substr($this->buffer, $this->count, $end - $this->count);
1715
+ $m = array(
1716
+ $match . $token,
1717
+ $match,
1718
+ $token
1719
+ );
1720
+ $this->count = $end + strlen($token);
1721
+
1722
+ return true;
1723
+ }
1724
+
1725
+ // try to match something on head of buffer
1726
+ protected function match($regex, &$out, $eatWhitespace = null)
1727
+ {
1728
+ if (!isset($eatWhitespace)) {
1729
+ $eatWhitespace = $this->eatWhiteDefault;
1730
+ }
1731
+
1732
+ $r = '/'.$regex.'/Ais';
1733
+
1734
+ if (preg_match($r, $this->buffer, $out, null, $this->count)) {
1735
+ $this->count += strlen($out[0]);
1736
+
1737
+ if ($eatWhitespace) {
1738
+ $this->whitespace();
1739
+ }
1740
+
1741
+ return true;
1742
+ }
1743
+
1744
+ return false;
1745
+ }
1746
+
1747
+ // match some whitespace
1748
+ protected function whitespace()
1749
+ {
1750
+ $gotWhite = false;
1751
+
1752
+ while (preg_match(self::$whitePattern, $this->buffer, $m, null, $this->count)) {
1753
+ if (isset($m[1]) && empty($this->commentsSeen[$this->count])) {
1754
+ $this->appendComment(array('comment', $m[1]));
1755
+ $this->commentsSeen[$this->count] = true;
1756
+ }
1757
+
1758
+ $this->count += strlen($m[0]);
1759
+ $gotWhite = true;
1760
+ }
1761
+
1762
+ return $gotWhite;
1763
+ }
1764
+
1765
+ protected function peek($regex, &$out, $from = null)
1766
+ {
1767
+ if (!isset($from)) {
1768
+ $from = $this->count;
1769
+ }
1770
+
1771
+ $r = '/'.$regex.'/Ais';
1772
+ $result = preg_match($r, $this->buffer, $out, null, $from);
1773
+
1774
+ return $result;
1775
+ }
1776
+
1777
+ protected function seek($where = null)
1778
+ {
1779
+ if ($where === null) {
1780
+ return $this->count;
1781
+ }
1782
+
1783
+ $this->count = $where;
1784
+
1785
+ return true;
1786
+ }
1787
+
1788
+ public static function pregQuote($what)
1789
+ {
1790
+ return preg_quote($what, '/');
1791
+ }
1792
+
1793
+ protected function show()
1794
+ {
1795
+ if ($this->peek("(.*?)(\n|$)", $m, $this->count)) {
1796
+ return $m[1];
1797
+ }
1798
+
1799
+ return '';
1800
+ }
1801
+
1802
+ // turn list of length 1 into value type
1803
+ protected function flattenList($value)
1804
+ {
1805
+ if ($value[0] == 'list' && count($value[2]) == 1) {
1806
+ return $this->flattenList($value[2][0]);
1807
+ }
1808
+
1809
+ return $value;
1810
+ }
1811
+ }
lib/scssphp/src/Server.php ADDED
@@ -0,0 +1,316 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * SCSSPHP
4
+ *
5
+ * @copyright 2012-2014 Leaf Corcoran
6
+ *
7
+ * @license http://opensource.org/licenses/gpl-license GPL-3.0
8
+ * @license http://opensource.org/licenses/MIT MIT
9
+ *
10
+ * @link http://leafo.net/scssphp
11
+ */
12
+
13
+ namespace Leafo\ScssPhp;
14
+
15
+ use Leafo\ScssPhp\Compiler;
16
+
17
+ /**
18
+ * SCSS server
19
+ *
20
+ * @author Leaf Corcoran <leafot@gmail.com>
21
+ */
22
+ class Server
23
+ {
24
+ /**
25
+ * Join path components
26
+ *
27
+ * @param string $left Path component, left of the directory separator
28
+ * @param string $right Path component, right of the directory separator
29
+ *
30
+ * @return string
31
+ */
32
+ protected function join($left, $right)
33
+ {
34
+ return rtrim($left, '/\\') . DIRECTORY_SEPARATOR . ltrim($right, '/\\');
35
+ }
36
+
37
+ /**
38
+ * Get name of requested .scss file
39
+ *
40
+ * @return string|null
41
+ */
42
+ protected function inputName()
43
+ {
44
+ switch (true) {
45
+ case isset($_GET['p']):
46
+ return $_GET['p'];
47
+ case isset($_SERVER['PATH_INFO']):
48
+ return $_SERVER['PATH_INFO'];
49
+ case isset($_SERVER['DOCUMENT_URI']):
50
+ return substr($_SERVER['DOCUMENT_URI'], strlen($_SERVER['SCRIPT_NAME']));
51
+ }
52
+ }
53
+
54
+ /**
55
+ * Get path to requested .scss file
56
+ *
57
+ * @return string
58
+ */
59
+ protected function findInput()
60
+ {
61
+ if (($input = $this->inputName())
62
+ && strpos($input, '..') === false
63
+ && substr($input, -5) === '.scss'
64
+ ) {
65
+ $name = $this->join($this->dir, $input);
66
+
67
+ if (is_file($name) && is_readable($name)) {
68
+ return $name;
69
+ }
70
+ }
71
+
72
+ return false;
73
+ }
74
+
75
+ /**
76
+ * Get path to cached .css file
77
+ *
78
+ * @return string
79
+ */
80
+ protected function cacheName($fname)
81
+ {
82
+ return $this->join($this->cacheDir, md5($fname) . '.css');
83
+ }
84
+
85
+ /**
86
+ * Get path to meta data
87
+ *
88
+ * @return string
89
+ */
90
+ protected function metadataName($out)
91
+ {
92
+ return $out . '.meta';
93
+ }
94
+
95
+ /**
96
+ * Determine whether .scss file needs to be re-compiled.
97
+ *
98
+ * @param string $in Input path
99
+ * @param string $out Output path
100
+ * @param string $etag ETag
101
+ *
102
+ * @return boolean True if compile required.
103
+ */
104
+ protected function needsCompile($in, $out, &$etag)
105
+ {
106
+ if (! is_file($out)) {
107
+ return true;
108
+ }
109
+
110
+ $mtime = filemtime($out);
111
+
112
+ if (filemtime($in) > $mtime) {
113
+ return true;
114
+ }
115
+
116
+ $metadataName = $this->metadataName($out);
117
+
118
+ if (is_readable($metadataName)) {
119
+ $metadata = unserialize(file_get_contents($metadataName));
120
+
121
+ if ($metadata['etag'] === $etag) {
122
+ return false;
123
+ }
124
+
125
+ foreach ($metadata['imports'] as $import) {
126
+ if (filemtime($import) > $mtime) {
127
+ return true;
128
+ }
129
+ }
130
+
131
+ $etag = $metadata['etag'];
132
+
133
+ return false;
134
+ }
135
+
136
+ return true;
137
+ }
138
+
139
+ /**
140
+ * Get If-Modified-Since header from client request
141
+ *
142
+ * @return string|null
143
+ */
144
+ protected function getIfModifiedSinceHeader()
145
+ {
146
+ $modifiedSince = null;
147
+
148
+ if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
149
+ $modifiedSince = $_SERVER['HTTP_IF_MODIFIED_SINCE'];
150
+
151
+ if (false !== ($semicolonPos = strpos($modifiedSince, ';'))) {
152
+ $modifiedSince = substr($modifiedSince, 0, $semicolonPos);
153
+ }
154
+ }
155
+
156
+ return $modifiedSince;
157
+ }
158
+
159
+ /**
160
+ * Get If-None-Match header from client request
161
+ *
162
+ * @return string|null
163
+ */
164
+ protected function getIfNoneMatchHeader()
165
+ {
166
+ $noneMatch = null;
167
+
168
+ if (isset($_SERVER['HTTP_IF_NONE_MATCH'])) {
169
+ $noneMatch = $_SERVER['HTTP_IF_NONE_MATCH'];
170
+ }
171
+
172
+ return $noneMatch;
173
+ }
174
+
175
+ /**
176
+ * Compile .scss file
177
+ *
178
+ * @param string $in Input path (.scss)
179
+ * @param string $out Output path (.css)
180
+ *
181
+ * @return array
182
+ */
183
+ protected function compile($in, $out)
184
+ {
185
+ $start = microtime(true);
186
+ $css = $this->scss->compile(file_get_contents($in), $in);
187
+ $elapsed = round((microtime(true) - $start), 4);
188
+
189
+ $v = Compiler::$VERSION;
190
+ $t = @date('r');
191
+ $css = "/* compiled by scssphp $v on $t (${elapsed}s) */\n\n" . $css;
192
+ $etag = md5($css);
193
+
194
+ file_put_contents($out, $css);
195
+ file_put_contents(
196
+ $this->metadataName($out),
197
+ serialize(array(
198
+ 'etag' => $etag,
199
+ 'imports' => $this->scss->getParsedFiles(),
200
+ ))
201
+ );
202
+
203
+ return array($css, $etag);
204
+ }
205
+
206
+ /**
207
+ * Compile requested scss and serve css. Outputs HTTP response.
208
+ *
209
+ * @param string $salt Prefix a string to the filename for creating the cache name hash
210
+ */
211
+ public function serve($salt = '')
212
+ {
213
+ $protocol = isset($_SERVER['SERVER_PROTOCOL'])
214
+ ? $_SERVER['SERVER_PROTOCOL']
215
+ : 'HTTP/1.0';
216
+
217
+ if ($input = $this->findInput()) {
218
+ $output = $this->cacheName($salt . $input);
219
+ $etag = $noneMatch = trim($this->getIfNoneMatchHeader(), '"');
220
+
221
+ if ($this->needsCompile($input, $output, $etag)) {
222
+ try {
223
+ list($css, $etag) = $this->compile($input, $output);
224
+
225
+ $lastModified = gmdate('D, d M Y H:i:s', filemtime($output)) . ' GMT';
226
+
227
+ header('Last-Modified: ' . $lastModified);
228
+ header('Content-type: text/css');
229
+ header('ETag: "' . $etag . '"');
230
+
231
+ echo $css;
232
+
233
+ } catch (\Exception $e) {
234
+ header($protocol . ' 500 Internal Server Error');
235
+ header('Content-type: text/plain');
236
+
237
+ echo 'Parse error: ' . $e->getMessage() . "\n";
238
+ }
239
+
240
+ return;
241
+ }
242
+
243
+ header('X-SCSS-Cache: true');
244
+ header('Content-type: text/css');
245
+ header('ETag: "' . $etag . '"');
246
+
247
+ if ($etag === $noneMatch) {
248
+ header($protocol . ' 304 Not Modified');
249
+
250
+ return;
251
+ }
252
+
253
+ $modifiedSince = $this->getIfModifiedSinceHeader();
254
+ $mtime = filemtime($output);
255
+
256
+ if (@strtotime($modifiedSince) === $mtime) {
257
+ header($protocol . ' 304 Not Modified');
258
+
259
+ return;
260
+ }
261
+
262
+ $lastModified = gmdate('D, d M Y H:i:s', $mtime) . ' GMT';
263
+ header('Last-Modified: ' . $lastModified);
264
+
265
+ echo file_get_contents($output);
266
+
267
+ return;
268
+ }
269
+
270
+ header($protocol . ' 404 Not Found');
271
+ header('Content-type: text/plain');
272
+
273
+ $v = Compiler::$VERSION;
274
+ echo "/* INPUT NOT FOUND scss $v */\n";
275
+ }
276
+
277
+ /**
278
+ * Constructor
279
+ *
280
+ * @param string $dir Root directory to .scss files
281
+ * @param string $cacheDir Cache directory
282
+ * @param \Leafo\ScssPhp\Compiler|null $scss SCSS compiler instance
283
+ */
284
+ public function __construct($dir, $cacheDir = null, $scss = null)
285
+ {
286
+ $this->dir = $dir;
287
+
288
+ if (!isset($cacheDir)) {
289
+ $cacheDir = $this->join($dir, 'scss_cache');
290
+ }
291
+
292
+ $this->cacheDir = $cacheDir;
293
+
294
+ if (!is_dir($this->cacheDir)) {
295
+ mkdir($this->cacheDir, 0755, true);
296
+ }
297
+
298
+ if (!isset($scss)) {
299
+ $scss = new Compiler();
300
+ $scss->setImportPaths($this->dir);
301
+ }
302
+
303
+ $this->scss = $scss;
304
+ }
305
+
306
+ /**
307
+ * Helper method to serve compiled scss
308
+ *
309
+ * @param string $path Root path
310
+ */
311
+ public static function serveFrom($path)
312
+ {
313
+ $server = new self($path);
314
+ $server->serve();
315
+ }
316
+ }
lib/scssphp/tests/ApiTest.php ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Leafo\ScssPhp\Tests;
4
+
5
+ use Leafo\ScssPhp\Compiler;
6
+
7
+ class ApiTest extends \PHPUnit_Framework_TestCase
8
+ {
9
+ public function setUp()
10
+ {
11
+ $this->scss = new Compiler();
12
+ }
13
+
14
+ public function testUserFunction()
15
+ {
16
+ $this->scss->registerFunction('add-two', function ($args) {
17
+ list($a, $b) = $args;
18
+ return $a[1] + $b[1];
19
+ });
20
+
21
+ $this->assertEquals(
22
+ 'result: 30;',
23
+ $this->compile('result: add-two(10, 20);')
24
+ );
25
+ }
26
+
27
+ public function testImportMissing()
28
+ {
29
+ $this->assertEquals(
30
+ '@import "missing";',
31
+ $this->compile('@import "missing";')
32
+ );
33
+ }
34
+
35
+ public function testImportCustomCallback()
36
+ {
37
+ $this->scss->addImportPath(function ($path) {
38
+ return __DIR__ . '/inputs/' . str_replace('.css', '.scss', $path);
39
+ });
40
+
41
+ $this->assertEquals(
42
+ trim(file_get_contents(__DIR__ . '/outputs/variables.css')),
43
+ $this->compile('@import "variables.css";')
44
+ );
45
+ }
46
+
47
+ /**
48
+ * @dataProvider provideSetVariables
49
+ */
50
+ public function testSetVariables($expected, $scss, $variables)
51
+ {
52
+ $this->scss->setVariables($variables);
53
+
54
+ $this->assertEquals($expected, $this->compile($scss));
55
+ }
56
+
57
+ public function provideSetVariables()
58
+ {
59
+ return array(
60
+ array(
61
+ ".magic {\n color: red;\n width: 760px; }",
62
+ '.magic { color: $color; width: $base - 200; }',
63
+ array(
64
+ 'color' => 'red',
65
+ 'base' => '960px',
66
+ ),
67
+ ),
68
+ array(
69
+ ".logo {\n color: #808080; }",
70
+ '.logo { color: desaturate($primary, 100%); }',
71
+ array(
72
+ 'primary' => '#ff0000',
73
+ ),
74
+ ),
75
+ );
76
+ }
77
+
78
+ public function compile($str)
79
+ {
80
+ return trim($this->scss->compile($str));
81
+ }
82
+ }
lib/scssphp/tests/ExceptionTest.php ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Leafo\ScssPhp\Tests;
4
+
5
+ use Leafo\ScssPhp\Compiler;
6
+
7
+ class ExceptionTest extends \PHPUnit_Framework_TestCase
8
+ {
9
+ public function setUp()
10
+ {
11
+ $this->scss = new Compiler();
12
+ }
13
+
14
+ /**
15
+ * @param string $scss
16
+ * @param string $expectedExceptionMessage
17
+ *
18
+ * @dataProvider provideScss
19
+ */
20
+ public function testThrowError($scss, $expectedExceptionMessage)
21
+ {
22
+ try {
23
+ $this->compile($scss);
24
+ } catch (\Exception $e) {
25
+ if (strpos($e->getMessage(), $expectedExceptionMessage) !== false) {
26
+ return;
27
+ };
28
+ }
29
+
30
+ $this->fail('Expected exception to be raised: ' . $expectedExceptionMessage);
31
+ }
32
+
33
+ /**
34
+ * @return array
35
+ */
36
+ public function provideScss()
37
+ {
38
+ return array(
39
+ array(<<<END_OF_SCSS
40
+ .test {
41
+ foo : bar;
42
+ END_OF_SCSS
43
+ ,
44
+ 'unclosed block'
45
+ ),
46
+ array(<<<END_OF_SCSS
47
+ .test {
48
+ }}
49
+ END_OF_SCSS
50
+ ,
51
+ 'unexpected }'
52
+ ),
53
+ array(<<<END_OF_SCSS
54
+ .test { color: #fff / 0; }
55
+ END_OF_SCSS
56
+ ,
57
+ 'color: Can\'t divide by zero'
58
+ ),
59
+ array(<<<END_OF_SCSS
60
+ .test {
61
+ @include foo();
62
+ }
63
+ END_OF_SCSS
64
+ ,
65
+ 'Undefined mixin foo'
66
+ ),
67
+ array(<<<END_OF_SCSS
68
+ @mixin do-nothing() {
69
+ }
70
+
71
+ .test {
72
+ @include do-nothing(\$a: "hello");
73
+ }
74
+ END_OF_SCSS
75
+ ,
76
+ 'Mixin or function doesn\'t have an argument named $a.'
77
+ ),
78
+ array(<<<END_OF_SCSS
79
+ div {
80
+ color: darken(cobaltgreen, 10%);
81
+ }
82
+ END_OF_SCSS
83
+ ,
84
+ 'expecting color'
85
+ ),
86
+ );
87
+ }
88
+
89
+ private function compile($str)
90
+ {
91
+ return trim($this->scss->compile($str));
92
+ }
93
+ }
lib/scssphp/tests/InputTest.php ADDED
@@ -0,0 +1,98 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Leafo\ScssPhp\Tests;
4
+
5
+ use Leafo\ScssPhp\Compiler;
6
+
7
+ // Runs all the tests in inputs/ and compares their output to ouputs/
8
+
9
+ function _dump($value)
10
+ {
11
+ fwrite(STDOUT, print_r($value, true));
12
+ }
13
+
14
+ function _quote($str)
15
+ {
16
+ return preg_quote($str, '/');
17
+ }
18
+
19
+ class InputTest extends \PHPUnit_Framework_TestCase
20
+ {
21
+ protected static $inputDir = 'inputs';
22
+ protected static $outputDir = 'outputs';
23
+
24
+ public function setUp()
25
+ {
26
+ $this->scss = new Compiler();
27
+ $this->scss->addImportPath(__DIR__ . '/' . self::$inputDir);
28
+ }
29
+
30
+ /**
31
+ * @dataProvider fileNameProvider
32
+ */
33
+ public function testInputFile($inFname, $outFname)
34
+ {
35
+ if (getenv('BUILD')) {
36
+ return $this->buildInput($inFname, $outFname);
37
+ }
38
+
39
+ if (!is_readable($outFname)) {
40
+ $this->fail("$outFname is missing, consider building tests with BUILD=true");
41
+ }
42
+
43
+ $input = file_get_contents($inFname);
44
+ $output = file_get_contents($outFname);
45
+
46
+ $this->assertEquals($output, $this->scss->compile($input));
47
+ }
48
+
49
+ public function fileNameProvider()
50
+ {
51
+ return array_map(
52
+ function ($a) {
53
+ return array($a, InputTest::outputNameFor($a));
54
+ },
55
+ self::findInputNames()
56
+ );
57
+ }
58
+
59
+ // only run when env is set
60
+ public function buildInput($inFname, $outFname)
61
+ {
62
+ $css = $this->scss->compile(file_get_contents($inFname));
63
+ file_put_contents($outFname, $css);
64
+ }
65
+
66
+ public static function findInputNames($pattern = '*')
67
+ {
68
+ $files = glob(__DIR__ . '/' . self::$inputDir . '/' . $pattern);
69
+ $files = array_filter($files, 'is_file');
70
+ if ($pattern = getenv('MATCH')) {
71
+ $files = array_filter($files, function ($fname) use ($pattern) {
72
+ return preg_match("/$pattern/", $fname);
73
+ });
74
+ }
75
+
76
+ return $files;
77
+ }
78
+
79
+ public static function outputNameFor($input)
80
+ {
81
+ $front = _quote(__DIR__ . '/');
82
+ $out = preg_replace("/^$front/", '', $input);
83
+
84
+ $in = _quote(self::$inputDir . '/');
85
+ $out = preg_replace("/$in/", self::$outputDir . '/', $out);
86
+ $out = preg_replace("/.scss$/", '.css', $out);
87
+
88
+ return __DIR__ . '/' . $out;
89
+ }
90
+
91
+ public static function buildTests($pattern)
92
+ {
93
+ $files = self::findInputNames($pattern);
94
+
95
+ foreach ($files as $file) {
96
+ }
97
+ }
98
+ }
lib/scssphp/tests/compare-scss.sh ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/bin/bash
2
+
3
+ diff_tool="$1"
4
+
5
+ for file in $(ls inputs/*.scss); do
6
+ out_file=$(echo $file | sed -e 's/inputs/outputs/' -e 's/\.scss$/\.css/')
7
+ sass=$(scss < $file 2> /dev/null)
8
+ if [ $? = "0" ]; then
9
+ # echo $file
10
+ # echo "$sass"
11
+ # echo
12
+
13
+ if [ "$(cat $out_file)" != "$sass" ]; then
14
+ echo "* [FAIL] $file"
15
+ if [ -n "$diff_tool" ]; then
16
+ $diff_tool $out_file <(echo "$sass") 2> /dev/null
17
+ fi
18
+ else
19
+ echo " [PASS] $file"
20
+ fi
21
+ else
22
+ echo " $file"
23
+ fi
24
+ done
25
+
lib/scssphp/tests/inputs/builtins.scss ADDED
@@ -0,0 +1,171 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ #color {
3
+ color: rgb(34,234,24);
4
+
5
+ red: red(rgb(34,234,24));
6
+ green: green(rgb(34,234,24));
7
+ blue: blue(rgb(34,234,24));
8
+
9
+ color: rgba(1,2,4, 0.5);
10
+ a1: alpha(rgb(1,2,4));
11
+ a2: alpha(rgba(1,2,4, 0.5));
12
+
13
+ mix: mix(rgb(1,2,3), rgb(3,4,5));
14
+
15
+ rgba: rgba($color: #a7c, $alpha: 0.4);
16
+ rgba: rgba(#a7c, 0.4);
17
+ }
18
+
19
+ #hsl {
20
+ color: hsl(100, 50, 55);
21
+ color: hsla(100, 50, 55, 0.5);
22
+
23
+ hue: hue(hsl(100, 50, 55));
24
+ sat: saturation(hsl(100, 50, 55));
25
+ lig: lightness(hsl(100, 50, 55));
26
+ }
27
+
28
+ #more-color {
29
+ $color: hsl(-80,44,33);
30
+
31
+ light: lighten($color, 10%);
32
+ dark: darken($color, 10%);
33
+
34
+ sat: saturate($color, 10%);
35
+ desat: desaturate($color, 10%);
36
+
37
+ gray: grayscale($color);
38
+ comp: complement($color);
39
+ inv: invert($color);
40
+ }
41
+
42
+ #more-more-color {
43
+ $color: rgba(1,2,3,0.5);
44
+ op: opacity($color);
45
+
46
+ opacify: opacify($color, 0.1);
47
+ opacify: fade-in($color, 0.1);
48
+
49
+ transparentize: transparentize($color, 0.1);
50
+ transparentize: fade-out($color, 0.1);
51
+ transparentize: transparentize(#348203, 0.1);
52
+ }
53
+
54
+ #more-more-more-color {
55
+ $color: rgba(10,10,10,0);
56
+ color: adjust-color($color, $blue: 69, $red: 55, $green: 100, $alpha: 0.4);
57
+ color: adjust-color($color, $hue: 170, $saturation: 100, $lightness: 50);
58
+
59
+ color: change-color($color, $blue: 69, $red: 55, $green: 100, $alpha: 0.4);
60
+ color: change-color($color, $hue: 170, $saturation: 100, $lightness: 50);
61
+
62
+ color: scale-color($color, $red: 55%);
63
+ color: scale-color($color, $red: -55%);
64
+
65
+ color: scale-color($color, $lightness: 55%);
66
+ color: scale-color($color, $lightness: -55%);
67
+
68
+ color: ie-hex-str($color);
69
+ color: ie-hex-str(#abc);
70
+ }
71
+
72
+ #string {
73
+ color: unquote("hello what is going on");
74
+ // color: quote(yeah you know it); // **
75
+ color: quote(yeah);
76
+ color: quote("I do?");
77
+ }
78
+
79
+ #number {
80
+ color: percentage(100/40);
81
+ color: round(3.4);
82
+ color: floor(3.4);
83
+ color: ceil(3.4);
84
+
85
+ top: floor(10.4px);
86
+ top: ceil(.4ex);
87
+ width: percentage(100px / 50px);
88
+ bottom: abs(-10px);
89
+ padding: min(5em, 3em, 4em) max(2px, 1in) min(1in, 96px) max(1in, 72pt);
90
+ }
91
+
92
+ #list {
93
+ len: length(hello world what);
94
+ len: length(thing);
95
+
96
+ n: nth(hello world what, 1);
97
+ // n: nth(hello world what, 100); // **
98
+
99
+ hello: join(one two three, hello, comma);
100
+ hello: join(one two three, hello world what is going, comma);
101
+ hello: append(one two three, hello, comma);
102
+
103
+ index: index(1px solid red, solid);
104
+ index: index(1px solid red, dashed);
105
+ index: index(1px solid red, #f00);
106
+ index: index(96px solid red, 1in);
107
+ index: index((1in 2) a b, 1in);
108
+ index: index((1in 2) a b, (96px 2));
109
+ index: index((1in 2) a b, (1in, 2));
110
+ index: index((1px solid red), solid);
111
+ index: index(1px 3px + 3px, 4+2px);
112
+ $var: oo;
113
+ index: index(foo bar, f#{$var});
114
+
115
+ $yes: one, two, three;
116
+ $no: great job;
117
+ world: join($yes, $no);
118
+ world: append($yes, $no);
119
+
120
+ cool: join($yes, $no, space);
121
+ cool: join($no, $yes);
122
+
123
+ zip: zip((1px, 2px), (solid dashed));
124
+ zip: zip(1px 2px 3px, solid dashed, red green blue);
125
+ }
126
+
127
+ #introspection {
128
+ t: type-of(100px);
129
+ t: type-of(asdf);
130
+ t: type-of("asdf");
131
+ t: type-of(true);
132
+ t: type-of(#fff);
133
+ t: type-of(blue);
134
+ t: type-of(one two three);
135
+
136
+ u: unit(12);
137
+ u: unit(12px);
138
+ u: unit(12em);
139
+
140
+ l: unitless(23);
141
+ l: unitless(23deg);
142
+
143
+ c: comparable(2px, 1px);
144
+ c: comparable(100px, 3em);
145
+ c: comparable(10cm, 3mm);
146
+ c: comparable(1, 4);
147
+ c: comparable(1ex, 4em);
148
+ c: comparable(2em, 5em);
149
+ }
150
+
151
+ #if {
152
+ color: if(true, yes, no);
153
+ color: if(false, yes, no);
154
+ color: if(false or true, yes, no);
155
+ color: if(10px, yes, no);
156
+ }
157
+
158
+ .transparent {
159
+ r: red(transparent);
160
+ g: green(transparent);
161
+ b: blue(transparent);
162
+ a: alpha(transparent);
163
+ }
164
+
165
+ .alpha {
166
+ a: alpha(black);
167
+ a: alpha(#fff);
168
+ a: alpha(rgb(0, 0, 0));
169
+ a: alpha(rgba(0, 0, 0, 0.5));
170
+ a: alpha(currentColor);
171
+ }
lib/scssphp/tests/inputs/comments.scss ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ // what is going on?
3
+
4
+ /** what the heck **/
5
+
6
+ /**
7
+
8
+ Here is a block comment
9
+
10
+ **/
11
+
12
+
13
+ // this is a comment
14
+
15
+ // trailing backslash \
16
+ /*hello*/div /*yeah*/ { //surew
17
+ border: 1px solid red; // world
18
+ /* another property */
19
+ color: url('http://mage-page.com');
20
+ string: "hello /* this is not a comment */";
21
+ world: "// neither is this";
22
+ string: 'hello /* this is not a comment */' /*what if this is a comment */;
23
+ world: '// neither is this' // hell world;
24
+ ;
25
+ what-ever: 100px;
26
+ background: url(/*this is not a comment?*/); // uhh what happens here
27
+ }
28
+
29
+ // begin
30
+
31
+ .dummy {
32
+ color: blue;
33
+ }
34
+
35
+ /* comment 1 */
36
+ a {
37
+ /* comment 2 */
38
+ /* comment 3 */ color: red; /* comment 4 */
39
+ background-color: red; /* comment 5 */
40
+ /* comment 6 */
41
+ }
42
+ /* comment 7 */
43
+
44
+ // end
lib/{phpsass/Extensions/Compass/stylesheets/compass/typography/_vertical_rhythm.scss → scssphp/tests/inputs/compass_extract.scss} RENAMED
@@ -1,4 +1,5 @@
1
- @import "compass/layout/grid-background";
 
2
 
3
  // The base font size.
4
  $base-font-size: 16px !default;
@@ -219,3 +220,29 @@ $base-half-leader: $base-leader / 2;
219
  @mixin h-borders($width: 1px, $lines: 1, $font-size: $base-font-size, $border-style: $default-rhythm-border-style) {
220
  @include horizontal-borders($width, $lines, $font-size, $border-style);
221
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Extracted from compass/typography/vertical_rhythm.scss
2
+
3
 
4
  // The base font size.
5
  $base-font-size: 16px !default;
220
  @mixin h-borders($width: 1px, $lines: 1, $font-size: $base-font-size, $border-style: $default-rhythm-border-style) {
221
  @include horizontal-borders($width, $lines, $font-size, $border-style);
222
  }
223
+
224
+ #test-0 {
225
+ unit: relative-unit(10px);
226
+ unit: relative-unit(50%);
227
+ rhythm: rhythm();
228
+ size: lines-for-font-size(15px);
229
+ size: lines-for-font-size(16px);
230
+ size: lines-for-font-size(17px);
231
+ size: lines-for-font-size(27px);
232
+ size: lines-for-font-size(37px);
233
+ }
234
+
235
+
236
+ #test-1 {
237
+ @include rhythm(5, 6, 7);
238
+ }
239
+
240
+ #test-2 {
241
+ @include rhythm-borders;
242
+ }
243
+
244
+ #test-3 {
245
+ @include horizontal-borders;
246
+ }
247
+
248
+
lib/scssphp/tests/inputs/content.scss ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ @mixin apply-to-ie6-only {
3
+ * html {
4
+ @content;
5
+ }
6
+ }
7
+ @include apply-to-ie6-only {
8
+ #logo {
9
+ background-image: url(/logo.gif);
10
+ }
11
+ }
12
+
13
+
14
+ $color: white;
15
+ @mixin colors($color: blue) {
16
+ background-color: $color;
17
+ @content;
18
+ border-color: $color;
19
+ }
20
+ .colors {
21
+ @include colors { color: $color; }
22
+ }
23
+
24
+
25
+ @mixin iphone {
26
+ @media only screen and (max-width: 480px) {
27
+ @content;
28
+ }
29
+ }
30
+
31
+ @include iphone {
32
+ body { color: red }
33
+ }
34
+
35
+
36
+ #sidebar {
37
+ $sidebar-width: 300px;
38
+ width: $sidebar-width;
39
+ @include iphone {
40
+ width: $sidebar-width / 3;
41
+ }
42
+ }
43
+
44
+
45
+ @mixin respond-to($width) {
46
+ @media only screen and (min-width: $width) { @content; }
47
+ }
48
+
49
+ @include respond-to(40em) {
50
+ @for $i from 1 through 2 {
51
+ .grid-#{$i} { width: 100%; }
52
+ }
53
+ }
54
+
55
+ @include respond-to(40em) {
56
+ $i: 1;
57
+ @while $i <= 2 {
58
+ .grid-#{$i} { width: 100%; }
59
+ $i: $i + 1;
60
+ }
61
+ }
lib/scssphp/tests/inputs/content_with_function.scss ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ $test-var: true;
2
+
3
+ @mixin mixin-using-content() {
4
+ @content;
5
+ }
6
+
7
+ @function test-function($value) {
8
+ @return $value;
9
+ }
10
+
11
+ @include mixin-using-content {
12
+ @if $test-var {
13
+ body {
14
+ padding: test-function(1 px);
15
+ }
16
+ }
17
+ }
lib/scssphp/tests/inputs/default_args.scss ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+
3
+ @mixin cool($color: blue) {
4
+ margin: 100px;
5
+ }
6
+
7
+ @function what($height: red) {
8
+ @return $height;
9
+ }
10
+
11
+ div {
12
+ height: what();
13
+ @include cool;
14
+ }
15
+
lib/scssphp/tests/inputs/directives.scss ADDED
@@ -0,0 +1,108 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ @charset "hello-world";
3
+
4
+ @page :left {
5
+ div {
6
+ color: red;
7
+ }
8
+ }
9
+
10
+ @page test {
11
+ @media yes {
12
+ div {
13
+ color: red;
14
+ }
15
+
16
+ @media no {
17
+ pre {
18
+ color: blue;
19
+ }
20
+ }
21
+ }
22
+ }
23
+
24
+ @media something {
25
+ @page {
26
+ @media else {
27
+ div {
28
+ height: 200px;
29
+ }
30
+ }
31
+ }
32
+ }
33
+
34
+
35
+ div {
36
+ color: red;
37
+ @page yeah {
38
+ pre {
39
+ height: 20px;
40
+ }
41
+ }
42
+ }
43
+
44
+ @font-face {
45
+ color: red;
46
+ height: 20px;
47
+ }
48
+
49
+
50
+ @keyframes 'bounce' {
51
+ from {
52
+ top: 100px;
53
+ animation-timing-function: ease-out;
54
+ }
55
+
56
+ 25% {
57
+ top: 50px;
58
+ animation-timing-function: ease-in;
59
+ }
60
+
61
+ 50% {
62
+ top: 100px;
63
+ animation-timing-function: ease-out;
64
+ }
65
+
66
+ 75% {
67
+ top: 75px;
68
+ animation-timing-function: ease-in;
69
+ }
70
+
71
+ to {
72
+ top: 100px;
73
+ }
74
+ }
75
+
76
+ @-webkit-keyframes flowouttoleft {
77
+ 0% { -webkit-transform: translateX(0) scale(1); }
78
+ 60%, 70% { -webkit-transform: translateX(0) scale(.7); }
79
+ 100% { -webkit-transform: translateX(-100%) scale(.7); }
80
+ }
81
+
82
+ div {
83
+ animation-name: 'diagonal-slide';
84
+ animation-duration: 5s;
85
+ animation-iteration-count: 10;
86
+ }
87
+
88
+ @keyframes 'diagonal-slide' {
89
+
90
+ from {
91
+ left: 0;
92
+ top: 0;
93
+ }
94
+
95
+ to {
96
+ left: 100px;
97
+ top: 100px;
98
+ }
99
+
100
+ }
101
+
102
+ @document url(http://www.w3.org/),
103
+ url-prefix(http://www.w3.org/Style/),
104
+ domain(mozilla.org),
105
+ regexp("https:.*")
106
+ {
107
+ body { color: purple; background: yellow; }
108
+ }
lib/scssphp/tests/inputs/extends.scss ADDED
@@ -0,0 +1,184 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ error, other {
3
+ border: 1px #f00;
4
+ background-color: #fdd;
5
+ }
6
+
7
+ pre, span {
8
+ seriousError {
9
+ @extend error;
10
+ font-size: 20px;
11
+ }
12
+ }
13
+
14
+ hello {
15
+ @extend other;
16
+ color: green;
17
+ div {
18
+ margin: 10px;
19
+ }
20
+ }
21
+
22
+ .cool {
23
+ color: red;
24
+ }
25
+
26
+ .blue {
27
+ color: purple;
28
+ }
29
+
30
+ .me {
31
+ @extend .cool, .blue;
32
+ }
33
+
34
+ .hoverlink { @extend a:hover }
35
+ a:hover { text-decoration: underline }
36
+
37
+
38
+ // partial matching and selector merging:
39
+
40
+ div.hello.world.hmm {
41
+ color: blue;
42
+ }
43
+
44
+ pre, code {
45
+ .okay.span {
46
+ @extend .hello;
47
+ }
48
+ }
49
+
50
+ // multiple matches per selector
51
+ .xxxxx .xxxxx .xxxxx {
52
+ color: green;
53
+ }
54
+
55
+ code {
56
+ @extend .xxxxx;
57
+ color: red;
58
+ }
59
+
60
+
61
+ // chained
62
+
63
+ .alpha {
64
+ color: red;
65
+ }
66
+
67
+ .beta {
68
+ @extend .alpha;
69
+ color: white;
70
+ }
71
+
72
+ .gama {
73
+ @extend .beta;
74
+ color: blue;
75
+ }
76
+
77
+ // merging selector sequences
78
+
79
+ #admin .tabbar a {font-weight: bold}
80
+ #demo .overview .fakelink {@extend a}
81
+
82
+ a1 b1 c1 d1 { color: red; }
83
+ x1 y1 z1 w1 { @extend a1; }
84
+
85
+ a2 b2 c2 d2 { color: red; }
86
+ x2 y2 z2 w2 { @extend b2; }
87
+
88
+
89
+ a3 b3 c3 d3 { color: red; }
90
+ x3 y3 z3 w3 { @extend c3; }
91
+
92
+
93
+ a4 b4 c4 d4 { color: red; }
94
+ x4 y4 z4 w4 { @extend d4; }
95
+
96
+ // removing common prefix
97
+
98
+ #butt .yeah .okay { font-weight: bold }
99
+ #butt .umm .sure { @extend .okay }
100
+
101
+ a9 b9 s9 t9 v9 { color: red; }
102
+
103
+ a9 b9 x9 y9 z9 {
104
+ @extend v9;
105
+ }
106
+
107
+ // extends & media
108
+
109
+ @media print {
110
+ horse {
111
+ color: blue;
112
+ }
113
+ }
114
+
115
+ man {
116
+ color: red;
117
+ @extend horse;
118
+ }
119
+
120
+
121
+ // result == match
122
+
123
+ wassup {
124
+ color: blue;
125
+ @extend wassup;
126
+ }
127
+
128
+ .foo {
129
+ .wassup {
130
+ @extend .wassup;
131
+ color: blue;
132
+ }
133
+ }
134
+
135
+ // multi-extend
136
+
137
+ #something {
138
+ color: red;
139
+ }
140
+
141
+ .x {
142
+ @extend #something;
143
+ }
144
+
145
+ .y {
146
+ @extend #something;
147
+ }
148
+
149
+ // twitter-sass-bootstrap infinite loop
150
+
151
+ .nav-tabs {
152
+ &.nav-justified {
153
+ @extend .nav-justified;
154
+ }
155
+ }
156
+ .nav-justified {
157
+ text-align: justify;
158
+ }
159
+
160
+ // multi-extend with nesting
161
+
162
+ .btn:hover,
163
+ .btn:active,
164
+ .btn.active,
165
+ .btn.disabled,
166
+ .btn[disabled] {
167
+ color: red;
168
+ }
169
+ .edit .actions {
170
+ button {
171
+ float: right;
172
+ @extend .btn;
173
+ }
174
+ }
175
+ .edit {
176
+ .new {
177
+ .actions {
178
+ padding: 0;
179
+ }
180
+ .actions button {
181
+ @extend .btn;
182
+ }
183
+ }
184
+ }
lib/scssphp/tests/inputs/filter_effects.scss ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #number {
2
+ -webkit-filter: grayscale(1)
3
+ sepia(0.5)
4
+ saturate(0.1)
5
+ invert(1)
6
+ opacity(0.5)
7
+ brightness(0.5)
8
+ contrast(0.5);
9
+ }
10
+
11
+ #percentage {
12
+ -webkit-filter: grayscale(100%)
13
+ sepia(50%)
14
+ saturate(10%)
15
+ invert(100%)
16
+ opacity(50%)
17
+ brightness(50%)
18
+ contrast(50%);
19
+ }
20
+
21
+ #misc {
22
+ -webkit-filter: hue-rotate(90deg)
23
+ blur(10px)
24
+ drop-shadow(10px -16px 30px purple);
25
+ }
26
+
27
+ @mixin opacity($opacity, $style: 0) {
28
+ @if ($opacity < 1) {
29
+ opacity: $opacity;
30
+ filter: alpha(opacity=$opacity * 100, style=$style);
31
+ } @else {
32
+ opacity: $opacity / 100;
33
+ filter: alpha(opacity=$opacity);
34
+ }
35
+ }
36
+
37
+ #decimal {
38
+ @include opacity(.5, 1);
39
+ }
40
+
41
+ #percent {
42
+ @include opacity(50);
43
+ }
44
+
45
+ .row {
46
+ background-color: darken(#2ba6cb, 40%);
47
+ color: darken(#2ba6cb, 10%);
48
+ }
lib/scssphp/tests/inputs/functions.scss ADDED
@@ -0,0 +1,89 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ @function hello($x) {
3
+ @return $x + 4;
4
+ }
5
+
6
+ @function add($a, $b) {
7
+ @return $a + $b;
8
+ }
9
+
10
+ div {
11
+ color: hello(10px);
12
+ sum: add(11, 12);
13
+ }
14
+
15
+ // make sure values are being reduced before being passed up to previous scope
16
+
17
+ @function one($a, $b) {
18
+ @return $a $b;
19
+ }
20
+
21
+ @function two($a, $b) {
22
+ @return $a#{$a} $b;
23
+ }
24
+
25
+ @function three($a, $b: default) {
26
+ @return "hello #{$a} and #{$b}"
27
+ }
28
+
29
+ @function all($a...) {
30
+ @return "hello #{$a}"
31
+ }
32
+
33
+ div {
34
+ hello: one(10, 55);
35
+ hello: two(10, 55);
36
+ hello: three(10, 55);
37
+ }
38
+
39
+
40
+ @function hello_world() {
41
+ @return 1000;
42
+ }
43
+
44
+ del {
45
+ color: hello-world();
46
+ }
47
+
48
+ div {
49
+ $args: foo bar;
50
+ hello: three($args...);
51
+ hello: three(bar...);
52
+ hello: all(Alice, Bob, Tom);
53
+ }
54
+
55
+ @function stringConcatCompassStyle($start,$last)
56
+ {
57
+ // Compass still uses it like this
58
+ @return #{$start}-#{$last};
59
+ }
60
+
61
+ .foo
62
+ {
63
+ test2: stringConcatCompassStyle(-moz,art);
64
+ }
65
+
66
+ @mixin content_test {
67
+ span {
68
+ $color: green;
69
+ @content;
70
+ }
71
+ }
72
+
73
+ @function func_test($c) {
74
+ @return $c + 1;
75
+ }
76
+
77
+ div {
78
+ @include content_test {
79
+ height: func_test(2px);
80
+ }
81
+ }
82
+
83
+ @function test ($a, $b: $a/2) {
84
+ @return $b;
85
+ }
86
+
87
+ div {
88
+ width: test(4);
89
+ }
lib/scssphp/tests/inputs/ie7.scss ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // http://jes.st/2013/ie7s-css-breaking-content-counter-bug/
2
+ #foo:before {
3
+ content: counter(item, ".") ": ";
4
+ }
5
+
6
+ #bar:before {
7
+ content: counter(item,".");
8
+ }
9
+
10
+ #fu:before {
11
+ content: counter(item);
12
+ }
lib/scssphp/tests/inputs/if.scss ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ @function conds($val) {
3
+ @if $val {
4
+ @return "red";
5
+ }
6
+
7
+ @return "blue";
8
+ }
9
+
10
+ div {
11
+ @if something {
12
+ color: blue;
13
+ }
14
+ }
15
+
16
+ pre {
17
+ val-1: conds(true);
18
+ val-2: conds(false);
19
+ val-3: conds(null);
20
+ val-4: conds(1);
21
+ val-5: conds(0);
22
+ }
23
+
24
+
25
+ span {
26
+ @if false {
27
+ color: red;
28
+ } @else {
29
+ color: blue;
30
+ }
31
+
32
+ @if true {
33
+ height: 10px;
34
+ } @else {
35
+ color: 20px;
36
+ }
37
+
38
+ @if false {
39
+ height: 10px;
40
+ } @elseif false {
41
+ color: 20px;
42
+ } @else {
43
+ width: 20px;
44
+ }
45
+ }
46
+
47
+ div {
48
+ @if false {
49
+ color: red;
50
+ } @else if false {
51
+ color: green;
52
+ } @else {
53
+ color: blue;
54
+ }
55
+
56
+ @if false {
57
+ border-color: red;
58
+ } @else if true {
59
+ border-color: green;
60
+ } @else {
61
+ border-color: blue;
62
+ }
63
+
64
+ }
65
+
66
+ // doesn't work in scss, thing loses scope
67
+ del {
68
+ @if false {
69
+ $thing: yes;
70
+ } @else {
71
+ $thing: no;
72
+ }
73
+
74
+ thing: $thing;
75
+ }
76
+
lib/scssphp/tests/inputs/if_on_null.scss ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ @function testfunc($pseudo: null) {
2
+ $output: if($pseudo, "green", "red");
3
+ @return $output;
4
+ }
5
+
6
+ body {
7
+ background-color: testfunc();
8
+ }
lib/scssphp/tests/inputs/import.scss ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ @import "foo.css";
3
+ @import "foo" screen;
4
+ @import "http://foo.com/bar";
5
+ @import url(foo);
6
+
7
+ @import "imports/simple";
8
+
9
+ pre {
10
+ color: red;
11
+ @import "imports/simple.scss";
12
+ }
13
+
14
+ code {
15
+ @import "imports/simple", "imports/simple";
16
+ }
17
+
18
+ @import "imports/partial";
19
+
20
+ body {
21
+ color: $variable;
22
+ @include partial-mixin();
23
+ }
lib/scssphp/tests/inputs/imports/_partial.scss ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+
2
+ #partial {
3
+ color: blue;
4
+ }
5
+
6
+ $variable: #7C2;
7
+
8
+ @mixin partial-mixin() {
9
+ background: gray;
10
+ }
lib/scssphp/tests/inputs/imports/simple.scss ADDED
@@ -0,0 +1,4 @@
 
 
 
 
1
+ div {
2
+ height: 200px;
3
+ color: red;
4
+ }
lib/scssphp/tests/inputs/interpolation.scss ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ div {
3
+ color: red#{white} blue;
4
+ color: red #{white} blue;
5
+ color: red #{white}blue;
6
+ color: red#{white}blue;
7
+ color: #{umm}#{yeah}#{what};
8
+ color: #{stacked};
9
+
10
+ font-size: 10px/#{something};
11
+ font-size: 10px / #{something};
12
+
13
+ test: "what#{"world"}wrong";
14
+ test: "what#{'world'}wrong";
15
+ test: "what#{world}wrong";
16
+ test: "what"#{world}"wrong";
17
+
18
+ hi: "what is #{4 + 12} end"
19
+ }
20
+
21
+
22
+ // interpolation in selectors
23
+
24
+ pre {
25
+ $var: cool;
26
+
27
+ #{var} {
28
+ color: red;
29
+ }
30
+
31
+ #{var} dad {
32
+ color: red;
33
+ }
34
+
35
+ bed#{var}dad {
36
+ color: red;
37
+ }
38
+ }
39
+
40
+ cool {
41
+ @for $x from 1 through 5 {
42
+ .thing-#{$x} {
43
+ color: red;
44
+ }
45
+ }
46
+ }
47
+
48
+ a#{b}c#{d}e {
49
+ color: red;
50
+ }
51
+
52
+ ##{hello}, .#{world}{
53
+ color: red;
54
+ }
55
+
56
+ #abc#{hello}yeah, .cool#{world}yes{
57
+ color: red;
58
+ }
59
+
60
+ $scope: 2;
61
+
62
+ div.element:nth-child(#{$scope}n)
63
+ {
64
+ display: none;
65
+ }
66
+
67
+ // property interpolation
68
+
69
+ div {
70
+ $var: hello;
71
+ #{$var}: world;
72
+ cool#{$var}:world;
73
+ #{$var}one:world;
74
+ two#{$var}one:world;
75
+
76
+ one#{a + b}two: cool;
77
+
78
+ #{hello}: {
79
+ #{world}: red;
80
+ #{mold}: white;
81
+ #{$var}: blue;
82
+ }
83
+
84
+ }
85
+
86
+
lib/scssphp/tests/inputs/keyword_args.scss ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ // mixins
3
+
4
+ @mixin hello($a: one, $b:two, $c:three, $d: four) {
5
+ out: $a $b $c $d;
6
+ }
7
+
8
+ pre {
9
+ @include hello(alpha, $d: palace, $b: fort);
10
+ }
11
+
12
+
13
+ // functions
14
+
15
+ @function cool($a, $b) {
16
+ @return $a - $b;
17
+ }
18
+
19
+ div {
20
+ hello: cool($b: 5, $a: 10);
21
+ world: cool(5, 10);
22
+ }
23
+
24
+
lib/scssphp/tests/inputs/list.scss ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ $list: (black);
2
+ $list: join($list, white, comma);
3
+
4
+ div {
5
+ padding: join(10px 20px, 30px 40px);
6
+ margin: join((0, 10px), (10px, 10px), space);
7
+ background: linear-gradient($list);
8
+ }
9
+
10
+ $list: ();
11
+ $list: join($list, (red, blue), comma);
12
+
13
+ p {
14
+ background: linear-gradient($list);
15
+ }
lib/scssphp/tests/inputs/looping.scss ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ div {
3
+ @each $var in what is this {
4
+ color: $var;
5
+ }
6
+
7
+ @each $var in what, is, this {
8
+ font: $var;
9
+ }
10
+
11
+ $list: what is this;
12
+ @each $var in $list {
13
+ background: $var;
14
+ }
15
+
16
+ $list: what, is, this;
17
+ @each $var in $list {
18
+ border: $var;
19
+ }
20
+ }
21
+
22
+
23
+ span {
24
+ $i: 0;
25
+ @while $i <= 10 {
26
+ color: $i;
27
+ $i: $i + 1;
28
+ }
29
+ }
30
+
31
+ pre {
32
+ @for $x from 1 to 5 {
33
+ color: $x;
34
+ }
35
+
36
+ @for $x from 1 through 5 {
37
+ height: $x;
38
+ }
39
+
40
+ $y: 10;
41
+ @for $x from $y through 3 {
42
+ cool: $x;
43
+ }
44
+
45
+ }
46
+
47
+ $j: null;
48
+ @while $j {
49
+ .item { width: 2em; }
50
+ $j: false;
51
+ }
lib/scssphp/tests/inputs/media.scss ADDED
@@ -0,0 +1,208 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ // media syntax
3
+ @media {
4
+ div { color: blue; }
5
+ }
6
+ @media what {
7
+ div { color: blue; }
8
+ }
9
+
10
+ @media (cool) {
11
+ div { color: blue; }
12
+ }
13
+ @media (cool: blue) {
14
+ div { color: blue; }
15
+ }
16
+
17
+ @media hello and (world) and (butt: man) {
18
+ div { color: blue; }
19
+ }
20
+
21
+ $navbarCollapseWidth: 940px;
22
+
23
+ @media (max-width: $navbarCollapseWidth) {
24
+ color: red;
25
+ }
26
+
27
+ // media bubbling
28
+ @media not hello and (world) {
29
+ color: blue;
30
+ pre {
31
+ color: blue;
32
+ }
33
+
34
+ @media butt {
35
+ color: red;
36
+ div {
37
+ color: red;
38
+ }
39
+ }
40
+ }
41
+
42
+ @media a, b {
43
+ @media c {
44
+ color: blue;
45
+ }
46
+ }
47
+
48
+ @media a{
49
+ @media b, c {
50
+ color: blue;
51
+ }
52
+ }
53
+
54
+ @media a, b{
55
+ @media c, d {
56
+ color: blue;
57
+ }
58
+ }
59
+
60
+ $media: cree;
61
+ $feature: -webkit-min-device-pixel-ratio;
62
+ $value: 1.5;
63
+
64
+ div {
65
+ color: blue;
66
+ @media s#{$media}n and ($feature: $value) {
67
+ .sidebar {
68
+ width: 500px;
69
+ }
70
+ }
71
+ }
72
+
73
+ // @media + @mixin
74
+ @mixin color {
75
+ color: red;
76
+ .success {
77
+ color: green;
78
+ }
79
+ }
80
+
81
+ div {
82
+ position: absolute;
83
+ $y: 2em;
84
+ @media screen {
85
+ top: 0;
86
+ $x: 5px;
87
+ p {
88
+ margin: $x;
89
+ }
90
+ bottom: 6em + $y;
91
+ @include color;
92
+ }
93
+ }
94
+
95
+ .button {
96
+ width: 300px;
97
+ height: 100px;
98
+ background: #eee;
99
+
100
+ :hover {
101
+ background: #aaa;
102
+ }
103
+
104
+ @media only screen and (max-width : 300px){
105
+ width: 100px;
106
+ height: 100px;
107
+ }
108
+ }
109
+
110
+ code {
111
+ position: absolute;
112
+ @media screen {
113
+ pre {
114
+ height: 20px;
115
+ }
116
+ height: 10px;
117
+ }
118
+ }
119
+
120
+ dt {
121
+ @media screen {
122
+ @media (color: blue) {
123
+ height: 10px;
124
+ }
125
+ }
126
+ }
127
+
128
+ // nesting media queries
129
+ @media screen {
130
+ .screen {
131
+ width: 12px;
132
+ }
133
+ @media only screen {
134
+ .only-screen {
135
+ height: 11px;
136
+ }
137
+ }
138
+ }
139
+
140
+ @media only screen {
141
+ .only-screen {
142
+ width: 14px;
143
+ }
144
+ @media only screen {
145
+ .only-screen {
146
+ height: 16px;
147
+ }
148
+ }
149
+ }
150
+
151
+ @media not screen {
152
+ @media screen {
153
+ .invalid {
154
+ height: 12px;
155
+ }
156
+ }
157
+ }
158
+
159
+ @media not screen {
160
+ @media print {
161
+ .only-print {
162
+ height: 12px;
163
+ }
164
+ }
165
+ }
166
+
167
+ @media screen {
168
+ @media not print {
169
+ .only-print {
170
+ height: 12px;
171
+ }
172
+ }
173
+ }
174
+
175
+ @media not screen {
176
+ @media not print {
177
+ .invalid {
178
+ height: 12px;
179
+ }
180
+ }
181
+ }
182
+
183
+ @media not screen {
184
+ @media not screen {
185
+ .not-screen {
186
+ height: 15px;
187
+ }
188
+ }
189
+ }
190
+
191
+ @media only screen {
192
+ @media print {
193
+ .invalid {
194
+ height: 15px;
195
+ }
196
+ }
197
+ }
198
+
199
+ @media only screen {
200
+ @media screen and (color: blue) {
201
+ @media screen and (width: 13) {
202
+ .only-screen {
203
+ height: 15px;
204
+ }
205
+ }
206
+ }
207
+ }
208
+
lib/scssphp/tests/inputs/mixins.scss ADDED
@@ -0,0 +1,183 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ @mixin something {
3
+ color: red;
4
+ pre {
5
+ height: 200px;
6
+ }
7
+ }
8
+
9
+ div {
10
+ color: blue;
11
+ @include something;
12
+ }
13
+
14
+ @mixin something($color) {
15
+ color: $color;
16
+
17
+ div {
18
+ height: 20px;
19
+ }
20
+ }
21
+
22
+ @mixin cool($a, $b, $c) {
23
+ height: $a + $b + $c;
24
+ }
25
+
26
+ span {
27
+ @include something(blue);
28
+ }
29
+
30
+ html {
31
+ @include cool(10px, 12px, 21px);
32
+ }
33
+
34
+
35
+ @mixin hello_world {
36
+ height: 20px;
37
+ }
38
+
39
+ del {
40
+ @include hello-world;
41
+ }
42
+
43
+
44
+ // variable shadowing
45
+
46
+
47
+ $color: white;
48
+ @mixin colors($color: blue) {
49
+ color: $color;
50
+ }
51
+
52
+ div {
53
+ color: $color;
54
+ @include colors();
55
+ color: $color;
56
+ }
57
+
58
+ @mixin linear-gradient($from, $to, $pos: left top) {
59
+ background-image: linear-gradient($pos, $from, $to);
60
+ }
61
+
62
+ div {
63
+ @include linear-gradient(red, green);
64
+ }
65
+
66
+ @mixin box-shadow($shadows...) {
67
+ -moz-box-shadow: $shadows;
68
+ -webkit-box-shadow: $shadows;
69
+ box-shadow: $shadows;
70
+ }
71
+
72
+ div {
73
+ @include box-shadow(10px 10px 5px #888);
74
+ @include box-shadow(inset 10px 10px #888, -10px -10px #f4f4f4);
75
+ }
76
+
77
+ @mixin nested {
78
+ @include something(red);
79
+ }
80
+
81
+ div {
82
+ p {
83
+ .class {
84
+ @include nested;
85
+ }
86
+
87
+ @include nested;
88
+
89
+ .top {
90
+ top: 0;
91
+
92
+ div {
93
+ color: red;
94
+ }
95
+ }
96
+
97
+ color: blue;
98
+ }
99
+ }
100
+
101
+ // mixin content (http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html#mixin-content)
102
+ @mixin content-simple {
103
+ div.mixin-content-simple {
104
+ @content;
105
+ }
106
+ }
107
+
108
+ @mixin content-with-arg ( $background ) {
109
+ div.mixin-content-with-arg {
110
+ background: $background;
111
+ @content;
112
+ }
113
+ }
114
+
115
+ @include content-simple {
116
+ color: red;
117
+ }
118
+
119
+ @include content-with-arg($background: blue) {
120
+ color: red;
121
+ }
122
+
123
+ @include content-with-arg($background: purple) {
124
+ @include hello_world;
125
+ }
126
+
127
+ @include content-simple {
128
+ @include cool(10px, 12px, 21px);
129
+ }
130
+
131
+ @include content-simple {
132
+ @include something(orange);
133
+ }
134
+
135
+ @include content-with-arg($background: purple) {
136
+ @include cool(10px, 12px, 21px);
137
+ }
138
+
139
+ @include content-with-arg($background: purple) {
140
+ @include something(orange);
141
+ }
142
+
143
+ @mixin wallpaper($image, $top: 0, $right: 0, $bottom: 0, $left: 0) {
144
+ background: $image;
145
+ position: absolute;
146
+ top: $top;
147
+ right: $right;
148
+ bottom: $bottom;
149
+ left: $left;
150
+ }
151
+
152
+ @mixin logo($offsets...) {
153
+ @include wallpaper(url(/images/logo.png), $offsets...);
154
+ }
155
+
156
+ #please-wait {
157
+ @include logo(1em, $left: 4em, $bottom: 3em);
158
+ }
159
+
160
+ @mixin prefixer($property, $value) {
161
+ -webkit-#{$property}: $value;
162
+ }
163
+
164
+ @mixin transform($property: none) {
165
+ @include prefixer(transform, $property);
166
+ }
167
+
168
+ div.parameter-name-scope {
169
+ @include transform(translateX(50px));
170
+ }
171
+
172
+ @mixin keyframes( $name )
173
+ {
174
+ @-webkit-keyframes $name {
175
+ @content;
176
+ }
177
+ }
178
+
179
+ @include keyframes( change-color )
180
+ {
181
+ 0% { color: green; }
182
+ 100% { color: red; }
183
+ }
lib/scssphp/tests/inputs/nesting.scss ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+
3
+ body {
4
+ color: red;
5
+ }
6
+
7
+
8
+ div {
9
+ color: red;
10
+ height: yes;
11
+
12
+ pre {
13
+ color: blue;
14
+ }
15
+ }
16
+
17
+
18
+ div: blue;
19
+
20
+
21
+ div {
22
+ font: 10px hello world {
23
+ size: 10px;
24
+ color: blue;
25
+ }
26
+
27
+ border: {
28
+ left: 1px solid blue;
29
+ right: 2px dashed green;
30
+ }
31
+ }
32
+
33
+
34
+ #nested-nesting {
35
+ bar: baz;
36
+ bang: {
37
+ bop: bar;
38
+ bip: 1px;
39
+ blat: {
40
+ baf: bort
41
+ }
42
+ }
43
+ }
44
+
45
+
lib/scssphp/tests/inputs/null.scss ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ $list: null;
2
+ .div {
3
+ one: null;
4
+ one: null world;
5
+ one: NULL world;
6
+ one: a null, b;
7
+ two: a $list $list, $list, b;
8
+ three: $list;
9
+ }
10
+
11
+ $value: null;
12
+ p:before {
13
+ content: "I ate #{$value} pies!";
14
+ }
15
+
16
+ @mixin Rounded($radius1, $direction: null, $radius2: false) {
17
+ $corner: null;
18
+ @if $direction == TL { $corner: top-left-; }
19
+ @if $direction == TR { $corner: top-right-; }
20
+ @if $direction == BL { $corner: bottom-left-; }
21
+ @if $direction == BR { $corner: bottom-right-; }
22
+ @if $radius2 {
23
+ -webkit-border-#{$corner}radius: $radius1 $radius2;
24
+ border-#{$corner}radius: $radius1 $radius2;
25
+ } @else {
26
+ -webkit-border-#{$corner}radius: $radius1;
27
+ border-#{$corner}radius: $radius1;
28
+ }
29
+ }
30
+
31
+ .foo {
32
+ @include Rounded(10);
33
+ }
34
+
35
+ .fu {
36
+ @include Rounded(20, null);
37
+ }
38
+
39
+ .bar {
40
+ @include Rounded(30, TL);
41
+ }
lib/scssphp/tests/inputs/operators.scss ADDED
@@ -0,0 +1,143 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+
3
+ body {
4
+ color: 1 + 2 + 5;
5
+ color: 1 + 2 * 5 + 5;
6
+ height: 10px/10px;
7
+ color: 10px/2 + 1;
8
+ color: (10px/2);
9
+ bottom: (4/2px);
10
+ top: 1em * (1 * 24px - 0) / 16px;
11
+ left: 1 - 2cm;
12
+ top: (2cm/12px);
13
+ }
14
+
15
+ div {
16
+ color: 4 == 3;
17
+ color: hello == hello;
18
+
19
+ color: 4 > 3;
20
+ color: 4 < 3;
21
+ color: what > 3;
22
+ }
23
+
24
+
25
+ #units {
26
+ test: 1in + 4cm;
27
+ test: 12mm + 1;
28
+ test: 1 + 3em;
29
+ test: 1mm + 1cm;
30
+ test: 1cm + 1mm;
31
+ }
32
+
33
+ #modulo {
34
+ test: 3 % 2;
35
+ test: 4cm % 3;
36
+ }
37
+
38
+ #colors {
39
+ color: red + rgb(1,2,3);
40
+ color: red - rgb(1,2,3);
41
+ color: rgba(1,2,3, 0.5) * rgba(3,4,5, 0.5);
42
+ color: rgba(10,15,20, 0.5) / rgba(2,2,2, 0.5);
43
+
44
+ color: rgba(1,2,3, 0.5) * 2;
45
+ color: rgba(1,2,3, 0.5) / 2;
46
+ color: rgba(1,2,3, 0.5) + 2;
47
+ color: rgba(1,2,3, 0.5) - 2;
48
+
49
+ color: blue + 34;
50
+
51
+ color: #fff == #000;
52
+ color: #fff == #fff;
53
+
54
+ color: #fff != #000;
55
+ color: #fff != #fff;
56
+ }
57
+
58
+
59
+ #preserve {
60
+ hello: what -going;
61
+ hello: what - going;
62
+ }
63
+
64
+ #strings {
65
+ hello: what -going;
66
+
67
+ hello: what +going;
68
+ hello: what+going;
69
+ hello: what+ going;
70
+ hello: what + going;
71
+
72
+ hello: "what" + going;
73
+ hello: going + "what";
74
+ hello: "what" + "what";
75
+ }
76
+
77
+ #negation {
78
+ $num: 100;
79
+ a: -$num + 40;
80
+ b: 10 -$num;
81
+ b: 10 - $num;
82
+ }
83
+
84
+ #bools-fail {
85
+ and: false and two;
86
+ and: one and two;
87
+ and: one and false;
88
+
89
+ or: false or two;
90
+ or: one or two;
91
+ or: one or false;
92
+ }
93
+
94
+ #bools {
95
+ and: (false and two);
96
+ and: (one and two);
97
+ and: (one and false);
98
+
99
+ or: (false or two);
100
+ or: (one or two);
101
+ or: (one or false);
102
+ }
103
+
104
+
105
+ #nots-fail {
106
+ not: not true + 2;
107
+ not: not false;
108
+ not: not 0;
109
+ not: not 1;
110
+ not: not "";
111
+ not: not hello;
112
+ }
113
+
114
+ #nots {
115
+ not: (not true) + 2;
116
+ not: (not false);
117
+ not: (not 0);
118
+ not: (not 1);
119
+ not: (not "");
120
+ not: (not hello);
121
+ }
122
+
123
+ #string-test {
124
+ str: hi == "hi";
125
+ str: hi == "no";
126
+ str: 'yes' == 'yes';
127
+
128
+ $var1: "hello";
129
+ $var2: hello;
130
+
131
+ str: "#{$var1}" == '#{$var2}';
132
+
133
+ str: xhello#{$var1}x == "x#{$var2}hellox"; // xhellohellofalse
134
+
135
+ str: unit(10px) == px;
136
+ }
137
+
138
+
139
+ #special {
140
+ cancel-unit: (10px / 10px);
141
+ }
142
+
143
+
lib/scssphp/tests/inputs/parsing_comments.scss ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* comment 1 */
2
+ a {
3
+ /* comment 2 */
4
+ color: red; /* comment 3 */
5
+ /* comment 4 */
6
+ }
7
+ /* comment 5 */
8
+
9
+ /*! comment 1 */
10
+ b {
11
+ /*! comment 2 */
12
+ color: red; /*! comment 3 */
13
+ /*! comment 4 */
14
+ }
15
+ /*! comment 5 */
16
+
17
+ /*
18
+ * multi-line comment 1
19
+ */
20
+ c {
21
+ /*
22
+ * multi-line comment 2
23
+ */
24
+ color: red; /*
25
+ * multi-line comment 3
26
+ */
27
+ /*
28
+ * multi-line comment 4
29
+ */
30
+ }
31
+ /*
32
+ * multi-line comment 5
33
+ */
34
+
35
+ /*!
36
+ * multi-line comment 1
37
+ */
38
+ d {
39
+ /*!
40
+ * multi-line comment 2
41
+ */
42
+ color: red; /*!
43
+ * multi-line comment 3
44
+ */
45
+ /*!
46
+ * multi-line comment 4
47
+ */
48
+ }
49
+ /*!
50
+ * multi-line comment 5
51
+ */
52
+
53
+ // comment 1
54
+ e {
55
+ // comment 2
56
+ color: red; // comment 3
57
+ // comment 4
58
+ }
59
+ // comment 5
lib/scssphp/tests/inputs/placeholder_selector.scss ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #context a%extreme span {
2
+ color: blue;
3
+ font-weight: bold;
4
+ font-size: 2em;
5
+ }
6
+
7
+ .notice, .error { @extend %extreme; }
8
+
9
+ .hidden %placeholder {
10
+ margin: 0;
11
+ }
12
+
13
+ p {
14
+ @extend #context;
15
+ padding: 2em;
16
+ }
17
+
18
+ div { @extend .hidden; }
lib/scssphp/tests/inputs/scss_css.scss ADDED
@@ -0,0 +1,986 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [foo~=bar] {
2
+ a: b; }
3
+
4
+
5
+ [foo^=bar] {
6
+ a: b; }
7
+
8
+
9
+ [foo$=bar] {
10
+ a: b; }
11
+
12
+
13
+ [foo*=bar] {
14
+ a: b; }
15
+
16
+
17
+ [foo|=en] {
18
+ a: b; }
19
+
20
+
21
+ foo {
22
+ a: 2;
23
+ b: 2.3em;
24
+ c: 50%;
25
+ d: "fraz bran";
26
+ e: flanny-blanny-blan;
27
+ f: url(http://sass-lang.com);
28
+ // g: U+ffa?;
29
+ h: #aabbcc; }
30
+
31
+
32
+ selector {
33
+ property: value;
34
+ property2: value; }
35
+
36
+
37
+ sel{p:v}
38
+
39
+ .foo {
40
+ /* Foo
41
+ Bar
42
+ Baz */
43
+ a: b; }
44
+
45
+
46
+ .foo {
47
+ /* Foo
48
+ Bar
49
+ Baz */
50
+ a: b; }
51
+
52
+
53
+ .foo {/* Foo
54
+ Bar */
55
+ a: b; }
56
+
57
+
58
+ .foo {/* Foo
59
+ Bar
60
+ Baz */
61
+ a: b; }
62
+
63
+
64
+ @foo {
65
+ rule {
66
+ a: b; }
67
+
68
+ a: b; }
69
+
70
+
71
+ @foo {a:b};
72
+ @bar {a:b};
73
+
74
+
75
+ @foo "bar"
76
+
77
+ foo {
78
+ a: 12px calc(100%/3 - 2*1em - 2*1px);
79
+ b: 12px -moz-calc(100%/3 - 2*1em - 2*1px);
80
+ b: 12px -webkit-calc(100%/3 - 2*1em - 2*1px);
81
+ b: 12px -foobar-calc(100%/3 - 2*1em - 2*1px); }
82
+
83
+
84
+ foo {bar: baz}
85
+ <!--
86
+ bar {bar: baz}
87
+ -->
88
+ baz {bar: baz}
89
+
90
+
91
+ /*
92
+ * foo
93
+ */
94
+ bar {baz: bang}
95
+
96
+
97
+ E, F {
98
+ a: b; }
99
+
100
+
101
+ E F, G H {
102
+ a: b; }
103
+
104
+
105
+ E > F, G > H {
106
+ a: b; }
107
+
108
+
109
+ /* This is a CSS comment. */
110
+ .one {color: green;} /* Another comment */
111
+ /* The following should not be used:
112
+ .two {color: red;} */
113
+ .three {color: green; /* color: red; */}
114
+ /**
115
+ .four {color: red;} */
116
+ .five {color: green;}
117
+ /**/
118
+ .six {color: green;}
119
+ /*********/
120
+ .seven {color: green;}
121
+ /* a comment **/
122
+ .eight {color: green;}
123
+
124
+
125
+ foo {
126
+ a: \foo bar;
127
+ b: foo\ bar;
128
+ c: \2022 \0020;
129
+ d: foo\\bar;
130
+ e: foo\"\'bar; }
131
+
132
+
133
+ foo {
134
+ a: "\foo bar";
135
+ b: "foo\ bar";
136
+ c: "\2022 \0020";
137
+ d: "foo\\bar";
138
+ e: "foo\"'bar"; }
139
+
140
+
141
+ foo {
142
+ _name: val;
143
+ *name: val;
144
+ :name: val;
145
+ .name: val;
146
+ #name: val;
147
+ name/**/: val;
148
+ name/*\**/: val;
149
+ name: val; }
150
+
151
+
152
+ @foo "bar" ;
153
+
154
+ foo {
155
+ a: -moz-element(#foo);
156
+ b: -webkit-element(#foo);
157
+ b: -foobar-element(#foo); }
158
+
159
+
160
+ @foo {}
161
+
162
+ @foo {
163
+ }
164
+
165
+
166
+ @foo;
167
+
168
+ foo {;;;;
169
+ bar: baz;;;;
170
+ ;;}
171
+
172
+
173
+ #foo .bar {}
174
+
175
+ #foo .bar {
176
+ }
177
+
178
+
179
+ 0% {
180
+ a: b; }
181
+
182
+
183
+ 60% {
184
+ a: b; }
185
+
186
+
187
+ 100% {
188
+ a: b; }
189
+
190
+
191
+ 12px {
192
+ a: b; }
193
+
194
+
195
+ "foo" {
196
+ a: b; }
197
+
198
+
199
+ foo {
200
+ a: 12px expression(1 + (3 / Foo.bar("baz" + "bang") + function() {return 12;}) % 12); }
201
+
202
+
203
+ :foo("bar") {
204
+ a: b; }
205
+
206
+
207
+ :foo(bar) {
208
+ a: b; }
209
+
210
+
211
+ :foo(12px) {
212
+ a: b; }
213
+
214
+
215
+ :foo(+) {
216
+ a: b; }
217
+
218
+
219
+ :foo(-) {
220
+ a: b; }
221
+
222
+
223
+ :foo(+"bar") {
224
+ a: b; }
225
+
226
+
227
+ :foo(-++--baz-"bar"12px) {
228
+ a: b; }
229
+
230
+
231
+ foo {
232
+ a: foo-bar(12);
233
+ b: -foo-bar-baz(13, 14 15); }
234
+
235
+
236
+ @import "foo.css";
237
+
238
+ @import 'foo.css';
239
+
240
+ @import url("foo.css");
241
+
242
+ @import url('foo.css');
243
+
244
+ @import url(foo.css);
245
+
246
+ @import "foo.css" screen;
247
+
248
+ @import "foo.css" screen, print;
249
+
250
+ @import "foo.css" screen, print and (foo: 0);
251
+
252
+ @import "foo.css" screen, only print, screen and (foo: 0);
253
+
254
+ foo {
255
+ a: foo !important;
256
+ b: foo bar !important;
257
+ b: foo, bar !important; }
258
+
259
+
260
+ foo {
261
+ a: -moz-bar-baz;
262
+ b: foo -o-bar-baz; }
263
+
264
+
265
+ foo {a: /* b; c: */ d}
266
+
267
+
268
+ foo {a /*: b; c */: d}
269
+
270
+
271
+ /* Foo
272
+ * Bar */
273
+
274
+
275
+ .foo {
276
+ /* Foo
277
+ * Bar */ }
278
+
279
+
280
+ [foo] {
281
+ a: b; }
282
+
283
+
284
+ [foo="bar"] {
285
+ a: b; }
286
+
287
+
288
+ [foo~="bar"] {
289
+ a: b; }
290
+
291
+
292
+ [foo^="bar"] {
293
+ a: b; }
294
+
295
+
296
+ [foo$="bar"] {
297
+ a: b; }
298
+
299
+
300
+ [foo*="bar"] {
301
+ a: b; }
302
+
303
+
304
+ [foo|="en"] {
305
+ a: b; }
306
+
307
+
308
+ :root {
309
+ a: b; }
310
+
311
+
312
+ :nth-child(n) {
313
+ a: b; }
314
+
315
+
316
+ :nth-last-child(n) {
317
+ a: b; }
318
+
319
+
320
+ :nth-of-type(n) {
321
+ a: b; }
322
+
323
+
324
+ :nth-last-of-type(n) {
325
+ a: b; }
326
+
327
+
328
+ :first-child {
329
+ a: b; }
330
+
331
+
332
+ :last-child {
333
+ a: b; }
334
+
335
+
336
+ :first-of-type {
337
+ a: b; }
338
+
339
+
340
+ :last-of-type {
341
+ a: b; }
342
+
343
+
344
+ :only-child {
345
+ a: b; }
346
+
347
+
348
+ :only-of-type {
349
+ a: b; }
350
+
351
+
352
+ :empty {
353
+ a: b; }
354
+
355
+
356
+ :link {
357
+ a: b; }
358
+
359
+
360
+ :visited {
361
+ a: b; }
362
+
363
+
364
+ :active {
365
+ a: b; }
366
+
367
+
368
+ :hover {
369
+ a: b; }
370
+
371
+
372
+ :focus {
373
+ a: b; }
374
+
375
+
376
+ :target {
377
+ a: b; }
378
+
379
+
380
+ :lang(fr) {
381
+ a: b; }
382
+
383
+
384
+ :enabled {
385
+ a: b; }
386
+
387
+
388
+ :disabled {
389
+ a: b; }
390
+
391
+
392
+ :checked {
393
+ a: b; }
394
+
395
+
396
+ ::first-line {
397
+ a: b; }
398
+
399
+
400
+ ::first-letter {
401
+ a: b; }
402
+
403
+
404
+ ::before {
405
+ a: b; }
406
+
407
+
408
+ ::after {
409
+ a: b; }
410
+
411
+
412
+ .warning {
413
+ a: b; }
414
+
415
+
416
+ #myid {
417
+ a: b; }
418
+
419
+
420
+ :not(s) {
421
+ a: b; }
422
+
423
+
424
+ @media all {
425
+ rule1 {
426
+ prop: val; }
427
+
428
+ rule2 {
429
+ prop: val; } }
430
+
431
+
432
+ @media screen, print {
433
+ rule1 {
434
+ prop: val; }
435
+
436
+ rule2 {
437
+ prop: val; } }
438
+
439
+
440
+ @media screen and (-webkit-min-device-pixel-ratio:0) {
441
+ a: b; }
442
+
443
+
444
+ @media only screen, print and (foo: 0px) and (bar: flam(12px solid)) {
445
+ a: b; }
446
+
447
+
448
+ :-moz-any(h1, h2, h3) {
449
+ a: b; }
450
+
451
+
452
+ :-moz-any(.foo) {
453
+ a: b; }
454
+
455
+
456
+ :-moz-any(foo bar, .baz > .bang) {
457
+ a: b; }
458
+
459
+
460
+ @-moz-document url(http://www.w3.org/),
461
+ url-prefix(http://www.w3.org/Style/),
462
+ domain(mozilla.org),
463
+ regexp("^https:.*") {
464
+ .foo {a: b}
465
+ }
466
+
467
+
468
+ foo {
469
+ filter: progid:DXImageTransform.Microsoft.gradient(GradientType=1, startColorstr=#c0ff3300, endColorstr=#ff000000);
470
+ filter:progid:DXImageTransform.Microsoft.gradient(GradientType=1, startColorstr=#c0ff3300, endColorstr=#ff000000); }
471
+
472
+
473
+ foo {
474
+ filter: alpha(opacity=20);
475
+ filter: alpha(opacity=20, enabled=true);
476
+ filter: blaznicate(foo=bar, baz=bang bip, bart=#fa4600); }
477
+
478
+
479
+ @foo bar {
480
+ a: b; }
481
+
482
+ @bar baz {
483
+ c: d; }
484
+
485
+
486
+ @foo bar;
487
+ @bar baz;
488
+
489
+
490
+ /* Foo
491
+ * Bar */
492
+ /* Baz
493
+ * Bang */
494
+
495
+
496
+ .foo {
497
+ /* Foo
498
+ * Bar */
499
+ /* Baz
500
+ * Bang */ }
501
+
502
+
503
+ .foo {
504
+ /* Foo Bar *//* Baz Bang */ }
505
+
506
+
507
+ @namespace "http://www.w3.org/Profiles/xhtml1-strict";
508
+
509
+ @namespace url(http://www.w3.org/Profiles/xhtml1-strict);
510
+
511
+ @namespace html url("http://www.w3.org/Profiles/xhtml1-strict");
512
+
513
+ [foo|bar=baz] {
514
+ a: b; }
515
+
516
+
517
+ [*|bar=baz] {
518
+ a: b; }
519
+
520
+
521
+ [foo|bar|=baz] {
522
+ a: b; }
523
+
524
+
525
+ foo|E {
526
+ a: b; }
527
+
528
+
529
+ *|E {
530
+ a: b; }
531
+
532
+
533
+ foo|* {
534
+ a: b; }
535
+
536
+
537
+ *|* {
538
+ a: b; }
539
+
540
+
541
+ :not(foo|bar) {
542
+ a: b; }
543
+
544
+
545
+ :not(*|bar) {
546
+ a: b; }
547
+
548
+
549
+ :not(foo|*) {
550
+ a: b; }
551
+
552
+
553
+ :not(*|*) {
554
+ a: b; }
555
+
556
+
557
+ :not(#blah) {
558
+ a: b; }
559
+
560
+
561
+ :not(.blah) {
562
+ a: b; }
563
+
564
+
565
+ :not([foo]) {
566
+ a: b; }
567
+
568
+
569
+ :not([foo^="bar"]) {
570
+ a: b; }
571
+
572
+
573
+ :not([baz|foo~="bar"]) {
574
+ a: b; }
575
+
576
+
577
+ :not(:hover) {
578
+ a: b; }
579
+
580
+
581
+ :not(:nth-child(2n + 3)) {
582
+ a: b; }
583
+
584
+
585
+ :not(:not(#foo)) {
586
+ a: b; }
587
+
588
+
589
+ :not(a#foo.bar) {
590
+ a: b; }
591
+
592
+
593
+ :not(#foo .bar > baz) {
594
+ a: b; }
595
+
596
+
597
+ :not(h1, h2, h3) {
598
+ a: b; }
599
+
600
+
601
+ @mixin foo {
602
+ a: b; }
603
+
604
+
605
+ foo {
606
+ a: "bang #{1 + " bar "} bip"; }
607
+
608
+
609
+ :nth-child(-n) {
610
+ a: b; }
611
+
612
+
613
+ :nth-child(+n) {
614
+ a: b; }
615
+
616
+
617
+ :nth-child(even) {
618
+ a: b; }
619
+
620
+
621
+ :nth-child(odd) {
622
+ a: b; }
623
+
624
+
625
+ :nth-child(50) {
626
+ a: b; }
627
+
628
+
629
+ :nth-child(-50) {
630
+ a: b; }
631
+
632
+
633
+ :nth-child(+50) {
634
+ a: b; }
635
+
636
+
637
+ :nth-child(2n+3) {
638
+ a: b; }
639
+
640
+
641
+ :nth-child(2n-3) {
642
+ a: b; }
643
+
644
+
645
+ :nth-child(+2n-3) {
646
+ a: b; }
647
+
648
+
649
+ :nth-child(-2n+3) {
650
+ a: b; }
651
+
652
+
653
+ :nth-child(-2n+ 3) {
654
+ a: b; }
655
+
656
+
657
+ :nth-child( 2n + 3 ) {
658
+ a: b; }
659
+
660
+
661
+ foo {
662
+ a: foo bar baz;
663
+ b: foo, #aabbcc, -12;
664
+ c: 1px/2px/-3px;
665
+ d: foo bar, baz/bang; }
666
+
667
+
668
+ @page {
669
+ prop1: val;
670
+ prop2: val; }
671
+
672
+
673
+ @page flap {
674
+ prop1: val;
675
+ prop2: val; }
676
+
677
+
678
+ @page :first {
679
+ prop1: val;
680
+ prop2: val; }
681
+
682
+
683
+ @page flap:first {
684
+ prop1: val;
685
+ prop2: val; }
686
+
687
+
688
+ .foo {
689
+ /* Foo */
690
+ a: b; }
691
+
692
+
693
+ .foo {
694
+ /* Foo
695
+ * Bar */a: b; }
696
+
697
+
698
+ /* Foo */
699
+ .foo {
700
+ a: b; }
701
+
702
+
703
+ /* Foo
704
+ * Bar */.foo {
705
+ a: b; }
706
+
707
+
708
+ .foo /* .a #foo */ #bar:baz(/* bang )*/ bip) {
709
+ a: b; }
710
+
711
+
712
+ > E {
713
+ a: b; }
714
+
715
+
716
+ + E {
717
+ a: b; }
718
+
719
+
720
+ ~ E {
721
+ a: b; }
722
+
723
+
724
+ > > E {
725
+ a: b; }
726
+
727
+
728
+ >> E {
729
+ a: b; }
730
+
731
+
732
+ E* {
733
+ a: b; }
734
+
735
+
736
+ E*.foo {
737
+ a: b; }
738
+
739
+
740
+ E*:hover {
741
+ a: b; }
742
+
743
+
744
+ E,
745
+ F {
746
+ a: b; }
747
+
748
+
749
+ E
750
+ F {
751
+ a: b; }
752
+
753
+
754
+ E, F
755
+ G, H {
756
+ a: b; }
757
+
758
+
759
+ body {
760
+ /*
761
+ //comment here
762
+ */
763
+ }
764
+
765
+
766
+ E>F { a: b;}
767
+
768
+ E~F { a: b;}
769
+
770
+ E+F { a: b;}
771
+
772
+ * {
773
+ a: b; }
774
+
775
+
776
+ E {
777
+ a: b; }
778
+
779
+
780
+ E[foo] {
781
+ a: b; }
782
+
783
+
784
+ E[foo="bar"] {
785
+ a: b; }
786
+
787
+
788
+ E[foo~="bar"] {
789
+ a: b; }
790
+
791
+
792
+ E[foo^="bar"] {
793
+ a: b; }
794
+
795
+
796
+ E[foo$="bar"] {
797
+ a: b; }
798
+
799
+
800
+ E[foo*="bar"] {
801
+ a: b; }
802
+
803
+
804
+ E[foo|="en"] {
805
+ a: b; }
806
+
807
+
808
+ E:root {
809
+ a: b; }
810
+
811
+
812
+ E:nth-child(n) {
813
+ a: b; }
814
+
815
+
816
+ E:nth-last-child(n) {
817
+ a: b; }
818
+
819
+
820
+ E:nth-of-type(n) {
821
+ a: b; }
822
+
823
+
824
+ E:nth-last-of-type(n) {
825
+ a: b; }
826
+
827
+
828
+ E:first-child {
829
+ a: b; }
830
+
831
+
832
+ E:last-child {
833
+ a: b; }
834
+
835
+
836
+ E:first-of-type {
837
+ a: b; }
838
+
839
+
840
+ E:last-of-type {
841
+ a: b; }
842
+
843
+
844
+ E:only-child {
845
+ a: b; }
846
+
847
+
848
+ E:only-of-type {
849
+ a: b; }
850
+
851
+
852
+ E:empty {
853
+ a: b; }
854
+
855
+
856
+ E:link {
857
+ a: b; }
858
+
859
+
860
+ E:visited {
861
+ a: b; }
862
+
863
+
864
+ E:active {
865
+ a: b; }
866
+
867
+
868
+ E:hover {
869
+ a: b; }
870
+
871
+
872
+ E:focus {
873
+ a: b; }
874
+
875
+
876
+ E:target {
877
+ a: b; }
878
+
879
+
880
+ E:lang(fr) {
881
+ a: b; }
882
+
883
+
884
+ E:enabled {
885
+ a: b; }
886
+
887
+
888
+ E:disabled {
889
+ a: b; }
890
+
891
+
892
+ E:checked {
893
+ a: b; }
894
+
895
+
896
+ E::first-line {
897
+ a: b; }
898
+
899
+
900
+ E::first-letter {
901
+ a: b; }
902
+
903
+
904
+ E::before {
905
+ a: b; }
906
+
907
+
908
+ E::after {
909
+ a: b; }
910
+
911
+
912
+ E.warning {
913
+ a: b; }
914
+
915
+
916
+ E#myid {
917
+ a: b; }
918
+
919
+
920
+ E:not(s) {
921
+ a: b; }
922
+
923
+
924
+ E F {
925
+ a: b; }
926
+
927
+
928
+ E > F {
929
+ a: b; }
930
+
931
+
932
+ E + F {
933
+ a: b; }
934
+
935
+
936
+ E ~ F {
937
+ a: b; }
938
+
939
+
940
+ @supports (a: b) and (c: d) or (not (d: e)) and ((not (f: g)) or (not ((h: i) and (j: k)))) {
941
+ .foo {
942
+ a: b;
943
+ }
944
+ }
945
+
946
+
947
+ @-prefix-supports (a: b) and (c: d) or (not (d: e)) and ((not (f: g)) or (not ((h: i) and (j: k)))) {
948
+ .foo {
949
+ a: b;
950
+ }
951
+ }
952
+
953
+
954
+ foo {
955
+ foo: bar;
956
+ #baz: bang;
957
+ #bip: bop; }
958
+
959
+
960
+ foo {
961
+ a: -2;
962
+ b: -2.3em;
963
+ c: -50%;
964
+ d: -foo(bar baz); }
965
+
966
+
967
+ foo {
968
+ a: -0.5em;
969
+ b: +0.5em;
970
+ c: -foo(12px);
971
+ d: +foo(12px);
972
+ }
973
+
974
+
975
+ @charset "UTF-8";
976
+
977
+ foo {
978
+ -moz-foo-bar: blat;
979
+ -o-flat-blang: wibble; }
980
+
981
+
982
+ foo {
983
+ a: foo();
984
+ b: bar baz-bang() bip; }
985
+
986
+
lib/scssphp/tests/inputs/selectors.scss ADDED
@@ -0,0 +1,195 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ * { color: blue; }
2
+ E { color: blue; }
3
+
4
+ E:not(:link) { color: blue; }
5
+ E:not(:link):not(:visited) { color: blue; }
6
+ E:not(:link, :visited) { color: blue; }
7
+ E:matches(:hover, :focus) { color: blue; }
8
+
9
+ E.warning { color: blue; }
10
+ E#id { color: blue; }
11
+ E[foo] { color: blue; }
12
+ E[foo="barbar"] { color: blue; }
13
+ E[foo="barbar" i] { color: blue; }
14
+ E[foo~="hello#$@%@$#^"] { color: blue; }
15
+ E[foo^="color: green;"] { color: blue; }
16
+ E[foo$="239023"] { color: blue; }
17
+ E[foo*="29302"] { color: blue; }
18
+ E[foo|="239032"] { color: blue; }
19
+
20
+ [foo] { color: blue; }
21
+ [foo] .helloWorld { color: blue; }
22
+ [foo].helloWorld { color: blue; }
23
+ [foo="barbar"] { color: blue; }
24
+ [foo~="hello#$@%@$#^"] { color: blue; }
25
+ [foo^="color: green;"] { color: blue; }
26
+ [foo$="239023"] { color: blue; }
27
+ [foo*="29302"] { color: blue; }
28
+ [foo|="239032"] { color: blue; }
29
+
30
+ E:dir(ltr) { color: blue; }
31
+ E:lang(en) { color: blue; }
32
+ E:lang(en, fr) { color: blue; }
33
+
34
+ E:any-link { color: blue; }
35
+ E:link { color: blue; }
36
+ E:visited { color: blue; }
37
+ E:local-link { color: blue; }
38
+ E:local-link(0) { color: red; }
39
+ E:local-link(1) { color: white; }
40
+ E:local-link(2) { color: red; }
41
+ E:target { color: blue; }
42
+ E:scope { color: blue; }
43
+
44
+ E:current { color: blue; }
45
+ E:current(:link) { color: blue; }
46
+ E:past { color: blue; }
47
+ E:future { color: blue; }
48
+
49
+ E:active { color: blue; }
50
+ E:hover { color: blue; }
51
+ E:focus { color: blue; }
52
+ E:enabled { color: blue; }
53
+ E:disabled { color: blue; }
54
+ E:indeterminate { color: blue; }
55
+ E:default { color: blue; }
56
+ E:in-range { color: blue; }
57
+ E:out-of-range { color: blue; }
58
+ E:required { color: blue; }
59
+ E:optional { color: blue; }
60
+ E:read-only { color: blue; }
61
+ E:read-write { color: blue; }
62
+
63
+ E:root { color: blue; }
64
+ E:empty { color: blue; }
65
+ E:first-child { color: blue; }
66
+ E:nth-child(odd) { color: blue; }
67
+ E:nth-child(2n+1) { color: blue; }
68
+ E:nth-child(5) { color: blue; }
69
+ E:last-child { color: blue; }
70
+ E:nth-last-child(-n+2) { color: blue; }
71
+ E:only-child { color: blue; }
72
+ E:first-of-type { color: blue; }
73
+ E:nth-of-type(2n) { color: blue; }
74
+ E:last-of-type { color: blue; }
75
+ E:nth-last-of-type(n) { color: blue; }
76
+ E:only-of-type { color: blue; }
77
+ E:nth-match(odd) { color: blue; }
78
+ E:nth-last-match(odd) { color: blue; }
79
+
80
+ E:column(n) { color: blue; }
81
+ E:nth-column(n) { color: blue; }
82
+ E:nth-last-column(n) { color: blue; }
83
+
84
+ E F { color: blue; }
85
+ E > F { color: blue; }
86
+ E + F { color: blue; }
87
+ E ~ F { color: blue; }
88
+ E /foo/ F { color: blue; }
89
+ E! > F { color: blue; }
90
+
91
+ // namespaces
92
+ [foo|att=val] { color: blue }
93
+ [*|att] { color: yellow }
94
+ [|att] { color: green }
95
+ [att] { color: green }
96
+
97
+ // CSS2.1
98
+ E::first-line { color: blue; }
99
+ E::first-letter { color: blue; }
100
+ E::before { color: blue; }
101
+ E::after { color: blue; }
102
+
103
+ // CSS3 UI (at risk)
104
+ E::choices { color: blue; }
105
+ E::value { color: blue; }
106
+ E::repeat-index { color: blue; }
107
+ E::repeat-item { color: blue; }
108
+
109
+ E:first { color: blue; }
110
+ E:first-line { color: blue; }
111
+ E:first-letter { color: blue; }
112
+ E:before{ color: blue; }
113
+ E:after { color: blue; }
114
+ E:checked { color: blue; }
115
+ E:invalid { color: blue; }
116
+ E:valid { color: blue; }
117
+ E:left { color: blue; }
118
+ E:right { color: blue; }
119
+
120
+ // -moz experimental
121
+ E:any(ol) { color: blue; }
122
+ E::selection { color: blue; }
123
+
124
+ // one of these is nested property,
125
+ // the other is a css block.
126
+ div {
127
+ font:something {
128
+ size: 30em;
129
+ }
130
+
131
+ font: something {
132
+ size: 30em;
133
+ }
134
+
135
+ }
136
+
137
+ // self selector
138
+
139
+ .something {
140
+ &.world {
141
+ color: blue;
142
+ }
143
+
144
+ & .mold {
145
+ height: 200px;
146
+ }
147
+
148
+ .dog & {
149
+ color: blue;
150
+ }
151
+ }
152
+
153
+ .simple {
154
+ .dad & .wolf {
155
+ color: blue;
156
+ }
157
+
158
+ .rad&.bad {
159
+ color: blue;
160
+ }
161
+
162
+ }
163
+
164
+ div {
165
+ .something & .what {
166
+ &.world {
167
+ color: blue;
168
+ }
169
+ }
170
+ }
171
+
172
+ div {
173
+ &.foo & {
174
+ color: blue;
175
+ }
176
+ }
177
+
178
+ .main, div {
179
+ .message div {
180
+ .title {
181
+ .nice-fonts & {
182
+ font-size: 24px;
183
+ }
184
+ }
185
+ }
186
+ }
187
+
188
+ $name: escape;
189
+ .#{$name}\% {
190
+ color: red;
191
+ }
192
+
193
+ .escape-plan\% {
194
+ color: green;
195
+ }
lib/scssphp/tests/inputs/values.scss ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ #values {
3
+ color: #eee;
4
+ color: #eeeeee;
5
+ height: 20px;
6
+ width: 80%;
7
+ color: "hello world";
8
+ height: url("http://google.com");
9
+ dads: url(http://leafo.net);
10
+ padding: 10px 10px 10px 10px, 3px 3px 3px;
11
+ textblock: "This is a \
12
+ multiline block \
13
+ #not { color: #eee;}";
14
+ margin: 4,3,1;
15
+ content: "This is a \
16
+ multiline string.";
17
+ border-radius: -1px -1px -1px black;
18
+ }
19
+
20
+ #subtraction {
21
+ lit: 10 -11;
22
+ lit: 10 - 11;
23
+ lit: 10- 11;
24
+ lit: 10-11;
25
+
26
+ $num: 100;
27
+ var: 10 -$num;
28
+ var: 10 - $num;
29
+ var: 10- $num;
30
+ var: 10-$num;
31
+ }
32
+
33
+
34
+ #special {
35
+ a: 12px expression(1 + (3 / Foo.bar("baz" + "bang") + function() {return 12;}) % 12);
36
+ }
37
+
38
+ #unary {
39
+ b: +0.5em;
40
+ c: -foo(12px);
41
+ d: +foo(12px);
42
+ }
43
+
lib/scssphp/tests/inputs/variables.scss ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ $color: red, two, three;
3
+
4
+ div {
5
+ height: $color;
6
+ }
7
+
8
+ $a: 1000;
9
+
10
+ div {
11
+ $a: 2000 !default;
12
+ num: $a;
13
+ }
14
+
15
+ div {
16
+ $b: 2000 !default;
17
+ num: $b;
18
+ }
19
+
20
+ $cool_color: null;
21
+ $cool_color: blue !default;
22
+
23
+ pre {
24
+ color: $cool_color;
25
+ }
26
+
27
+ $something_man: 100px;
28
+ cool: $something_man;
29
+
30
+
31
+ del {
32
+ $something: blue;
33
+
34
+ div {
35
+ $something: red;
36
+ pre {
37
+ color: $something;
38
+ }
39
+ }
40
+
41
+ color: $something;
42
+ }
43
+
44
+ $font-family-simple: Arial !default;
45
+ $font-family-spaces: Helvetica Neue !default;
46
+ $font-family-quotes: "Helvetica Neue" !default;
47
+ $font-family-commas: Helvetica, Arial, sans-serif !default;
48
+ $font-family-sans: "Helvetica Neue", Helvetica, Arial, sans-serif !default;
49
+
50
+ body {
51
+ font-family: $font-family-simple;
52
+ font-family: $font-family-spaces;
53
+ font-family: $font-family-quotes;
54
+ font-family: $font-family-commas;
55
+ font-family: $font-family-sans;
56
+ }
lib/scssphp/tests/outputs/builtins.css ADDED
@@ -0,0 +1,126 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #color {
2
+ color: #22ea18;
3
+ red: 34;
4
+ green: 234;
5
+ blue: 24;
6
+ color: rgba(1, 2, 4, 0.5);
7
+ a1: 1;
8
+ a2: 0.5;
9
+ mix: #020304;
10
+ rgba: rgba(170, 119, 204, 0.4);
11
+ rgba: rgba(170, 119, 204, 0.4); }
12
+
13
+ #hsl {
14
+ color: #79c653;
15
+ color: rgba(121, 198, 83, 0.5);
16
+ hue: 100deg;
17
+ sat: 50%;
18
+ lig: 55%; }
19
+
20
+ #more-color {
21
+ light: #7e3d9e;
22
+ dark: #432154;
23
+ sat: #632782;
24
+ desat: #5e3871;
25
+ gray: #545454;
26
+ comp: #48792f;
27
+ inv: #9fd086; }
28
+
29
+ #more-more-color {
30
+ op: 0.5;
31
+ opacify: rgba(1, 2, 3, 0.6);
32
+ opacify: rgba(1, 2, 3, 0.6);
33
+ transparentize: rgba(1, 2, 3, 0.4);
34
+ transparentize: rgba(1, 2, 3, 0.4);
35
+ transparentize: rgba(52, 130, 3, 0.9); }
36
+
37
+ #more-more-more-color {
38
+ color: rgba(65, 110, 79, 0.4);
39
+ color: rgba(20, 255, 216, 0);
40
+ color: rgba(55, 100, 69, 0.4);
41
+ color: rgba(0, 255, 213, 0);
42
+ color: rgba(145, 10, 10, 0);
43
+ color: rgba(5, 10, 10, 0);
44
+ color: rgba(145, 145, 145, 0);
45
+ color: rgba(5, 5, 5, 0);
46
+ color: #000A0A0A;
47
+ color: #FFAABBCC; }
48
+
49
+ #string {
50
+ color: hello what is going on;
51
+ color: "yeah";
52
+ color: "I do?"; }
53
+
54
+ #number {
55
+ color: 250%;
56
+ color: 3;
57
+ color: 3;
58
+ color: 4;
59
+ top: 10px;
60
+ top: 1ex;
61
+ width: 200%;
62
+ bottom: 10px;
63
+ padding: 3em 1in 96px 72pt; }
64
+
65
+ #list {
66
+ len: 3;
67
+ len: 1;
68
+ n: hello;
69
+ hello: one, two, three, hello;
70
+ hello: one, two, three, hello, world, what, is, going;
71
+ hello: one, two, three, hello;
72
+ index: 2;
73
+ index: false;
74
+ index: 3;
75
+ index: 1;
76
+ index: false;
77
+ index: 1;
78
+ index: false;
79
+ index: 2;
80
+ index: 2;
81
+ index: 1;
82
+ world: one, two, three, great, job;
83
+ world: one, two, three, great job;
84
+ cool: one two three great job;
85
+ cool: great job one two three;
86
+ zip: 1px solid, 2px dashed;
87
+ zip: 1px solid red, 2px dashed green; }
88
+
89
+ #introspection {
90
+ t: number;
91
+ t: string;
92
+ t: string;
93
+ t: bool;
94
+ t: color;
95
+ t: color;
96
+ t: list;
97
+ u: "";
98
+ u: "px";
99
+ u: "em";
100
+ l: true;
101
+ l: false;
102
+ c: true;
103
+ c: false;
104
+ c: true;
105
+ c: true;
106
+ c: false;
107
+ c: true; }
108
+
109
+ #if {
110
+ color: yes;
111
+ color: no;
112
+ color: yes;
113
+ color: yes; }
114
+
115
+ .transparent {
116
+ r: 0;
117
+ g: 0;
118
+ b: 0;
119
+ a: 0; }
120
+
121
+ .alpha {
122
+ a: 1;
123
+ a: 1;
124
+ a: 1;
125
+ a: 0.5;
126
+ a: alpha(currentColor); }
lib/scssphp/tests/outputs/comments.css ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /** what the heck **/
2
+ /**
3
+ Here is a block comment
4
+ **/
5
+ /*hello*/
6
+ div {
7
+ /*yeah*/
8
+ border: 1px solid red;
9
+ /* another property */
10
+ color: url('http://mage-page.com');
11
+ string: "hello /* this is not a comment */";
12
+ world: "// neither is this";
13
+ string: 'hello /* this is not a comment */';
14
+ /*what if this is a comment */
15
+ world: '// neither is this';
16
+ what-ever: 100px;
17
+ background: url();
18
+ /*this is not a comment?*/ }
19
+
20
+ .dummy {
21
+ color: blue; }
22
+ /* comment 1 */
23
+ a {
24
+ /* comment 2 */
25
+ /* comment 3 */
26
+ color: red;
27
+ /* comment 4 */
28
+ background-color: red;
29
+ /* comment 5 */
30
+ /* comment 6 */ }
31
+ /* comment 7 */
lib/scssphp/tests/outputs/compass_extract.css ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #test-0 {
2
+ unit: false;
3
+ unit: true;
4
+ rhythm: 1.5em;
5
+ size: 1;
6
+ size: 1;
7
+ size: 1;
8
+ size: 2;
9
+ size: 2; }
10
+
11
+ #test-1 {
12
+ margin-top: 7.5em;
13
+ padding-top: 9em;
14
+ padding-bottom: 10.5em;
15
+ margin-bottom: 0em; }
16
+
17
+ #test-2 {
18
+ border-style: solid;
19
+ border-width: 0.0625em;
20
+ padding: 1.4375em; }
21
+
22
+ #test-3 {
23
+ border-top-style: solid;
24
+ border-top-width: 0.0625em;
25
+ padding-top: 1.4375em;
26
+ border-bottom-style: solid;
27
+ border-bottom-width: 0.0625em;
28
+ padding-bottom: 1.4375em; }
lib/scssphp/tests/outputs/content.css ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ * html #logo {
2
+ background-image: url(/logo.gif); }
3
+
4
+ .colors {
5
+ background-color: blue;
6
+ color: white;
7
+ border-color: blue; }
8
+
9
+ @media only screen and (max-width: 480px) {
10
+ body {
11
+ color: red; } }
12
+
13
+ #sidebar {
14
+ width: 300px; }
15
+ @media only screen and (max-width: 480px) {
16
+ #sidebar {
17
+ width: 100px; } }
18
+
19
+ @media only screen and (min-width: 40em) {
20
+ .grid-1 {
21
+ width: 100%; }
22
+ .grid-2 {
23
+ width: 100%; } }
24
+
25
+ @media only screen and (min-width: 40em) {
26
+ .grid-1 {
27
+ width: 100%; }
28
+ .grid-2 {
29
+ width: 100%; } }
lib/scssphp/tests/outputs/content_with_function.css ADDED
@@ -0,0 +1,2 @@
 
 
1
+ body {
2
+ padding: 1 px; }
lib/scssphp/tests/outputs/default_args.css ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ div {
2
+ height: red;
3
+ margin: 100px; }
lib/scssphp/tests/outputs/directives.css ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @charset "hello-world";
2
+ @page :left {
3
+ div {
4
+ color: red; } }
5
+
6
+ @page test {
7
+ @media yes {
8
+ div {
9
+ color: red; } } }
10
+
11
+ @media something {
12
+ @page {
13
+ @media else {
14
+ div {
15
+ height: 200px; } } } }
16
+
17
+ div {
18
+ color: red; }
19
+ @page yeah {
20
+ div pre {
21
+ height: 20px; } }
22
+
23
+ @font-face {
24
+ color: red;
25
+ height: 20px; }
26
+
27
+ @keyframes 'bounce' {
28
+ from {
29
+ top: 100px;
30
+ animation-timing-function: ease-out; }
31
+
32
+ 25% {
33
+ top: 50px;
34
+ animation-timing-function: ease-in; }
35
+
36
+ 50% {
37
+ top: 100px;
38
+ animation-timing-function: ease-out; }
39
+
40
+ 75% {
41
+ top: 75px;
42
+ animation-timing-function: ease-in; }
43
+
44
+ to {
45
+ top: 100px; } }
46
+
47
+ @-webkit-keyframes flowouttoleft {
48
+ 0% {
49
+ -webkit-transform: translateX(0) scale(1); }
50
+
51
+ 60%, 70% {
52
+ -webkit-transform: translateX(0) scale(0.7); }
53
+
54
+ 100% {
55
+ -webkit-transform: translateX(-100%) scale(0.7); } }
56
+
57
+ div {
58
+ animation-name: 'diagonal-slide';
59
+ animation-duration: 5s;
60
+ animation-iteration-count: 10; }
61
+
62
+ @keyframes 'diagonal-slide' {
63
+ from {
64
+ left: 0;
65
+ top: 0; }
66
+
67
+ to {
68
+ left: 100px;
69
+ top: 100px; } }
70
+
71
+ @document url(http://www.w3.org/),
72
+ url-prefix(http://www.w3.org/Style/),
73
+ domain(mozilla.org),
74
+ regexp("https:.*") {
75
+ body {
76
+ color: purple;
77
+ background: yellow; } }
lib/scssphp/tests/outputs/extends.css ADDED
@@ -0,0 +1,87 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ error, pre seriousError, span seriousError, other, hello {
2
+ border: 1px #f00;
3
+ background-color: #fdd; }
4
+
5
+ pre seriousError, span seriousError {
6
+ font-size: 20px; }
7
+
8
+ hello {
9
+ color: green; }
10
+ hello div {
11
+ margin: 10px; }
12
+
13
+ .cool, .me {
14
+ color: red; }
15
+
16
+ .blue, .me {
17
+ color: purple; }
18
+
19
+ a:hover, .hoverlink, #demo .overview .fakelink:hover {
20
+ text-decoration: underline; }
21
+
22
+ div.hello.world.hmm, pre div.okay.span.world.hmm, pre #butt .umm div.sure.span.world.hmm, #butt .umm pre div.sure.span.world.hmm, code div.okay.span.world.hmm, code #butt .umm div.sure.span.world.hmm, #butt .umm code div.sure.span.world.hmm {
23
+ color: blue; }
24
+
25
+ .xxxxx .xxxxx .xxxxx, code .xxxxx .xxxxx, code code .xxxxx, code code code, code .xxxxx code, .xxxxx code .xxxxx, .xxxxx code code, .xxxxx .xxxxx code {
26
+ color: green; }
27
+
28
+ code {
29
+ color: red; }
30
+
31
+ .alpha, .beta, .gama {
32
+ color: red; }
33
+
34
+ .beta, .gama {
35
+ color: white; }
36
+
37
+ .gama {
38
+ color: blue; }
39
+
40
+ #admin .tabbar a, #admin .tabbar #demo .overview .fakelink, #demo .overview #admin .tabbar .fakelink {
41
+ font-weight: bold; }
42
+
43
+ a1 b1 c1 d1, x1 y1 z1 w1 b1 c1 d1 {
44
+ color: red; }
45
+
46
+ a2 b2 c2 d2, a2 x2 y2 z2 w2 c2 d2, x2 y2 z2 a2 w2 c2 d2 {
47
+ color: red; }
48
+
49
+ a3 b3 c3 d3, a3 b3 x3 y3 z3 w3 d3, x3 y3 z3 a3 b3 w3 d3 {
50
+ color: red; }
51
+
52
+ a4 b4 c4 d4, a4 b4 c4 x4 y4 z4 w4, x4 y4 z4 a4 b4 c4 w4 {
53
+ color: red; }
54
+
55
+ #butt .yeah .okay, #butt .yeah .umm .sure, #butt .umm .yeah .sure {
56
+ font-weight: bold; }
57
+
58
+ a9 b9 s9 t9 v9, a9 b9 s9 t9 x9 y9 z9, a9 b9 x9 y9 s9 t9 z9 {
59
+ color: red; }
60
+
61
+ @media print {
62
+ horse, man {
63
+ color: blue; } }
64
+
65
+ man {
66
+ color: red; }
67
+
68
+ wassup {
69
+ color: blue; }
70
+
71
+ .foo .wassup {
72
+ color: blue; }
73
+
74
+ #something, .x, .y {
75
+ color: red; }
76
+
77
+ .nav-justified, .nav-tabs.nav-justified {
78
+ text-align: justify; }
79
+
80
+ .btn:hover, .edit .actions button:hover, .edit .new .actions button:hover, .btn:active, .edit .actions button:active, .edit .new .actions button:active, .btn.active, .edit .actions button.active, .edit .new .actions button.active, .btn.disabled, .edit .actions button.disabled, .edit .new .actions button.disabled, .btn[disabled], .edit .actions button[disabled], .edit .new .actions button[disabled] {
81
+ color: red; }
82
+
83
+ .edit .actions button {
84
+ float: right; }
85
+
86
+ .edit .new .actions {
87
+ padding: 0; }
lib/scssphp/tests/outputs/filter_effects.css ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #number {
2
+ -webkit-filter: grayscale(1) sepia(0.5) saturate(0.1) invert(1) opacity(0.5) brightness(0.5) contrast(0.5); }
3
+
4
+ #percentage {
5
+ -webkit-filter: grayscale(100%) sepia(50%) saturate(10%) invert(100%) opacity(50%) brightness(50%) contrast(50%); }
6
+
7
+ #misc {
8
+ -webkit-filter: hue-rotate(90deg) blur(10px) drop-shadow(10px -16px 30px purple); }
9
+
10
+ #decimal {
11
+ opacity: 0.5;
12
+ filter: alpha(opacity=50, style=1); }
13
+
14
+ #percent {
15
+ opacity: 0.5;
16
+ filter: alpha(opacity=50); }
17
+
18
+ .row {
19
+ background-color: #071c23;
20
+ color: #2284a1; }
lib/scssphp/tests/outputs/functions.css ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ div {
2
+ color: 14px;
3
+ sum: 23; }
4
+
5
+ div {
6
+ hello: 10 55;
7
+ hello: 1010 55;
8
+ hello: "hello 10 and 55"; }
9
+
10
+ del {
11
+ color: 1000; }
12
+
13
+ div {
14
+ hello: "hello foo and bar";
15
+ hello: "hello bar and default";
16
+ hello: "hello Alice, Bob, Tom"; }
17
+
18
+ .foo {
19
+ test2: -moz-art; }
20
+
21
+ div span {
22
+ height: 3px; }
23
+
24
+ div {
25
+ width: 2; }
lib/scssphp/tests/outputs/ie7.css ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ #foo:before {
2
+ content: counter(item,".") ": "; }
3
+
4
+ #bar:before {
5
+ content: counter(item,"."); }
6
+
7
+ #fu:before {
8
+ content: counter(item); }
lib/scssphp/tests/outputs/if.css ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ div {
2
+ color: blue; }
3
+
4
+ pre {
5
+ val-1: "red";
6
+ val-2: "blue";
7
+ val-3: "blue";
8
+ val-4: "red";
9
+ val-5: "red"; }
10
+
11
+ span {
12
+ color: blue;
13
+ height: 10px;
14
+ width: 20px; }
15
+
16
+ div {
17
+ color: blue;
18
+ border-color: green; }
19
+
20
+ del {
21
+ thing: no; }
lib/scssphp/tests/outputs/if_on_null.css ADDED
@@ -0,0 +1,2 @@
 
 
1
+ body {
2
+ background-color: "red"; }
lib/scssphp/tests/outputs/import.css ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @import "foo.css";
2
+ @import "foo" screen;
3
+ @import "http://foo.com/bar";
4
+ @import url(foo);
5
+ div {
6
+ height: 200px;
7
+ color: red; }
8
+
9
+ pre {
10
+ color: red; }
11
+ pre div {
12
+ height: 200px;
13
+ color: red; }
14
+
15
+ code div {
16
+ height: 200px;
17
+ color: red; }
18
+ code div {
19
+ height: 200px;
20
+ color: red; }
21
+
22
+ #partial {
23
+ color: blue; }
24
+
25
+ body {
26
+ color: #7c2;
27
+ background: gray; }
lib/scssphp/tests/outputs/interpolation.css ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ div {
2
+ color: redwhite blue;
3
+ color: red white blue;
4
+ color: red whiteblue;
5
+ color: redwhiteblue;
6
+ color: ummyeahwhat;
7
+ color: stacked;
8
+ font-size: 10px/something;
9
+ font-size: 10px / something;
10
+ test: "whatworldwrong";
11
+ test: "whatworldwrong";
12
+ test: "whatworldwrong";
13
+ test: "what"world"wrong";
14
+ hi: "what is 16 end"; }
15
+
16
+ pre var {
17
+ color: red; }
18
+ pre var dad {
19
+ color: red; }
20
+ pre bedvardad {
21
+ color: red; }
22
+
23
+ cool .thing-1 {
24
+ color: red; }
25
+ cool .thing-2 {
26
+ color: red; }
27
+ cool .thing-3 {
28
+ color: red; }
29
+ cool .thing-4 {
30
+ color: red; }
31
+ cool .thing-5 {
32
+ color: red; }
33
+
34
+ abcde {
35
+ color: red; }
36
+
37
+ #hello, .world {
38
+ color: red; }
39
+
40
+ #abchelloyeah, .coolworldyes {
41
+ color: red; }
42
+
43
+ div.element:nth-child(2n) {
44
+ display: none; }
45
+
46
+ div {
47
+ hello: world;
48
+ coolhello: world;
49
+ helloone: world;
50
+ twohelloone: world;
51
+ oneabtwo: cool;
52
+ hello-world: red;
53
+ hello-mold: white;
54
+ hello-hello: blue; }
lib/scssphp/tests/outputs/keyword_args.css ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
1
+ pre {
2
+ out: alpha fort three palace; }
3
+
4
+ div {
5
+ hello: 5;
6
+ world: -5; }
lib/scssphp/tests/outputs/list.css ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ div {
2
+ padding: 10px 20px 30px 40px;
3
+ margin: 0 10px 10px 10px;
4
+ background: linear-gradient(black, white); }
5
+
6
+ p {
7
+ background: linear-gradient(red, blue); }
lib/scssphp/tests/outputs/looping.css ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ div {
2
+ color: what;
3
+ color: is;
4
+ color: this;
5
+ font: what;
6
+ font: is;
7
+ font: this;
8
+ background: what;
9
+ background: is;
10
+ background: this;
11
+ border: what;
12
+ border: is;
13
+ border: this; }
14
+
15
+ span {
16
+ color: 0;
17
+ color: 1;
18
+ color: 2;
19
+ color: 3;
20
+ color: 4;
21
+ color: 5;
22
+ color: 6;
23
+ color: 7;
24
+ color: 8;
25
+ color: 9;
26
+ color: 10; }
27
+
28
+ pre {
29
+ color: 1;
30
+ color: 2;
31
+ color: 3;
32
+ color: 4;
33
+ height: 1;
34
+ height: 2;
35
+ height: 3;
36
+ height: 4;
37
+ height: 5;
38
+ cool: 10;
39
+ cool: 9;
40
+ cool: 8;
41
+ cool: 7;
42
+ cool: 6;
43
+ cool: 5;
44
+ cool: 4;
45
+ cool: 3; }
lib/scssphp/tests/outputs/media.css ADDED
@@ -0,0 +1,103 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @media {
2
+ div {
3
+ color: blue; } }
4
+
5
+ @media what {
6
+ div {
7
+ color: blue; } }
8
+
9
+ @media (cool) {
10
+ div {
11
+ color: blue; } }
12
+
13
+ @media (cool: blue) {
14
+ div {
15
+ color: blue; } }
16
+
17
+ @media hello and (world) and (butt: man) {
18
+ div {
19
+ color: blue; } }
20
+
21
+ @media (max-width: 940px) {
22
+ color: red; }
23
+
24
+ @media not hello and (world) {
25
+ color: blue;
26
+ pre {
27
+ color: blue; } }
28
+ @media butt and (world) {
29
+ color: red;
30
+ div {
31
+ color: red; } }
32
+
33
+ div {
34
+ color: blue; }
35
+ @media screen and (-webkit-min-device-pixel-ratio: 1.5) {
36
+ div .sidebar {
37
+ width: 500px; } }
38
+
39
+ div {
40
+ position: absolute; }
41
+ @media screen {
42
+ div {
43
+ top: 0;
44
+ bottom: 8em;
45
+ color: red; }
46
+ div p {
47
+ margin: 5px; }
48
+
49
+ div .success {
50
+ color: green; } }
51
+
52
+ .button {
53
+ width: 300px;
54
+ height: 100px;
55
+ background: #eee; }
56
+ .button :hover {
57
+ background: #aaa; }
58
+ @media only screen and (max-width: 300px) {
59
+ .button {
60
+ width: 100px;
61
+ height: 100px; } }
62
+
63
+ code {
64
+ position: absolute; }
65
+ @media screen {
66
+ code {
67
+ height: 10px; }
68
+ code pre {
69
+ height: 20px; } }
70
+
71
+ @media screen and (color: blue) {
72
+ dt {
73
+ height: 10px; } }
74
+
75
+ @media screen {
76
+ .screen {
77
+ width: 12px; } }
78
+ @media only screen {
79
+ .only-screen {
80
+ height: 11px; } }
81
+
82
+ @media only screen {
83
+ .only-screen {
84
+ width: 14px; } }
85
+ @media only screen {
86
+ .only-screen {
87
+ height: 16px; } }
88
+
89
+ @media print {
90
+ .only-print {
91
+ height: 12px; } }
92
+
93
+ @media screen {
94
+ .only-print {
95
+ height: 12px; } }
96
+
97
+ @media not screen {
98
+ .not-screen {
99
+ height: 15px; } }
100
+
101
+ @media only screen and (color: blue) and (width: 13) {
102
+ .only-screen {
103
+ height: 15px; } }
lib/scssphp/tests/outputs/mixins.css ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ div {
2
+ color: blue;
3
+ color: red; }
4
+ div pre {
5
+ height: 200px; }
6
+
7
+ span {
8
+ color: blue; }
9
+ span div {
10
+ height: 20px; }
11
+
12
+ html {
13
+ height: 43px; }
14
+
15
+ del {
16
+ height: 20px; }
17
+
18
+ div {
19
+ color: white;
20
+ color: blue;
21
+ color: white; }
22
+
23
+ div {
24
+ background-image: linear-gradient(left top, red, green); }
25
+
26
+ div {
27
+ -moz-box-shadow: 10px 10px 5px #888;
28
+ -webkit-box-shadow: 10px 10px 5px #888;
29
+ box-shadow: 10px 10px 5px #888;
30
+ -moz-box-shadow: inset 10px 10px #888, -10px -10px #f4f4f4;
31
+ -webkit-box-shadow: inset 10px 10px #888, -10px -10px #f4f4f4;
32
+ box-shadow: inset 10px 10px #888, -10px -10px #f4f4f4; }
33
+
34
+ div p {
35
+ color: red;
36
+ color: blue; }
37
+ div p .class {
38
+ color: red; }
39
+ div p .class div {
40
+ height: 20px; }
41
+ div p div {
42
+ height: 20px; }
43
+ div p .top {
44
+ top: 0; }
45
+ div p .top div {
46
+ color: red; }
47
+
48
+ div.mixin-content-simple {
49
+ color: red; }
50
+
51
+ div.mixin-content-with-arg {
52
+ background: blue;
53
+ color: red; }
54
+
55
+ div.mixin-content-with-arg {
56
+ background: purple;
57
+ height: 20px; }
58
+
59
+ div.mixin-content-simple {
60
+ height: 43px; }
61
+
62
+ div.mixin-content-simple {
63
+ color: orange; }
64
+ div.mixin-content-simple div {
65
+ height: 20px; }
66
+
67
+ div.mixin-content-with-arg {
68
+ background: purple;
69
+ height: 43px; }
70
+
71
+ div.mixin-content-with-arg {
72
+ background: purple;
73
+ color: orange; }
74
+ div.mixin-content-with-arg div {
75
+ height: 20px; }
76
+
77
+ #please-wait {
78
+ background: url(/images/logo.png);
79
+ position: absolute;
80
+ top: 1em;
81
+ right: 0;
82
+ bottom: 3em;
83
+ left: 4em; }
84
+
85
+ div.parameter-name-scope {
86
+ -webkit-transform: translateX(50px); }
87
+
88
+ @-webkit-keyframes change-color {
89
+ 0% {
90
+ color: green; }
91
+
92
+ 100% {
93
+ color: red; } }
lib/scssphp/tests/outputs/nesting.css ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ div: blue;
2
+ body {
3
+ color: red; }
4
+
5
+ div {
6
+ color: red;
7
+ height: yes; }
8
+ div pre {
9
+ color: blue; }
10
+
11
+ div {
12
+ font: 10px hello world;
13
+ font-size: 10px;
14
+ font-color: blue;
15
+ border-left: 1px solid blue;
16
+ border-right: 2px dashed green; }
17
+
18
+ #nested-nesting {
19
+ bar: baz;
20
+ bang-bop: bar;
21
+ bang-bip: 1px;
22
+ bang-blat-baf: bort; }
lib/scssphp/tests/outputs/null.css ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .div {
2
+ one: null;
3
+ one: world;
4
+ one: NULL world;
5
+ one: a, b;
6
+ two: a, b; }
7
+
8
+ p:before {
9
+ content: "I ate pies!"; }
10
+
11
+ .foo {
12
+ -webkit-border-radius: 10;
13
+ border-radius: 10; }
14
+
15
+ .fu {
16
+ -webkit-border-radius: 20;
17
+ border-radius: 20; }
18
+
19
+ .bar {
20
+ -webkit-border-top-left-radius: 30;
21
+ border-top-left-radius: 30; }
lib/scssphp/tests/outputs/operators.css ADDED
@@ -0,0 +1,105 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ body {
2
+ color: 8;
3
+ color: 16;
4
+ height: 10px/10px;
5
+ color: 6px;
6
+ color: 5px;
7
+ bottom: 2px;
8
+ top: 1.5em;
9
+ left: -1cm;
10
+ top: 6.29921; }
11
+
12
+ div {
13
+ color: false;
14
+ color: true;
15
+ color: true;
16
+ color: false;
17
+ color: what > 3; }
18
+
19
+ #units {
20
+ test: 2.5748in;
21
+ test: 13mm;
22
+ test: 4em;
23
+ test: 11mm;
24
+ test: 1.1cm; }
25
+
26
+ #modulo {
27
+ test: 1;
28
+ test: 1cm; }
29
+
30
+ #colors {
31
+ color: #ff0203;
32
+ color: #fe0000;
33
+ color: rgba(3, 8, 15, 0.5);
34
+ color: rgba(5, 8, 10, 0.5);
35
+ color: rgba(2, 4, 6, 0.5);
36
+ color: rgba(1, 1, 2, 0.5);
37
+ color: rgba(3, 4, 5, 0.5);
38
+ color: rgba(0, 0, 1, 0.5);
39
+ color: #22f;
40
+ color: false;
41
+ color: true;
42
+ color: true;
43
+ color: false; }
44
+
45
+ #preserve {
46
+ hello: what -going;
47
+ hello: what - going; }
48
+
49
+ #strings {
50
+ hello: what -going;
51
+ hello: whatgoing;
52
+ hello: whatgoing;
53
+ hello: whatgoing;
54
+ hello: whatgoing;
55
+ hello: "whatgoing";
56
+ hello: goingwhat;
57
+ hello: "whatwhat"; }
58
+
59
+ #negation {
60
+ a: -60;
61
+ b: 10 -100;
62
+ b: -90; }
63
+
64
+ #bools-fail {
65
+ and: false and two;
66
+ and: one and two;
67
+ and: one and false;
68
+ or: false or two;
69
+ or: one or two;
70
+ or: one or false; }
71
+
72
+ #bools {
73
+ and: false;
74
+ and: two;
75
+ and: false;
76
+ or: two;
77
+ or: one;
78
+ or: one; }
79
+
80
+ #nots-fail {
81
+ not: false2;
82
+ not: not false;
83
+ not: not 0;
84
+ not: not 1;
85
+ not: not "";
86
+ not: not hello; }
87
+
88
+ #nots {
89
+ not: false2;
90
+ not: true;
91
+ not: false;
92
+ not: false;
93
+ not: false;
94
+ not: false; }
95
+
96
+ #string-test {
97
+ str: true;
98
+ str: false;
99
+ str: true;
100
+ str: true;
101
+ str: xhellohellofalse;
102
+ str: true; }
103
+
104
+ #special {
105
+ cancel-unit: 1; }
lib/scssphp/tests/outputs/parsing_comments.css ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* comment 1 */
2
+ a {
3
+ /* comment 2 */
4
+ color: red;
5
+ /* comment 3 */
6
+ /* comment 4 */ }
7
+ /* comment 5 */
8
+ /*! comment 1 */
9
+ b {
10
+ /*! comment 2 */
11
+ color: red;
12
+ /*! comment 3 */
13
+ /*! comment 4 */ }
14
+ /*! comment 5 */
15
+ /*
16
+ * multi-line comment 1
17
+ */
18
+ c {
19
+ /*
20
+ * multi-line comment 2
21
+ */
22
+ color: red;
23
+ /*
24
+ * multi-line comment 3
25
+ */
26
+ /*
27
+ * multi-line comment 4
28
+ */ }
29
+ /*
30
+ * multi-line comment 5
31
+ */
32
+ /*!
33
+ * multi-line comment 1
34
+ */
35
+ d {
36
+ /*!
37
+ * multi-line comment 2
38
+ */
39
+ color: red;
40
+ /*!
41
+ * multi-line comment 3
42
+ */
43
+ /*!
44
+ * multi-line comment 4
45
+ */ }
46
+ /*!
47
+ * multi-line comment 5
48
+ */
49
+ e {
50
+ color: red; }
lib/scssphp/tests/outputs/placeholder_selector.css ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ p a.notice span, p a.error span, #context a.notice span, #context a.error span {
2
+ color: blue;
3
+ font-weight: bold;
4
+ font-size: 2em; }
5
+
6
+ p {
7
+ padding: 2em; }
lib/scssphp/tests/outputs/scss_css.css ADDED
@@ -0,0 +1,771 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @import "foo.css";
2
+ @import 'foo.css';
3
+ @import url("foo.css");
4
+ @import url('foo.css');
5
+ @import url(foo.css);
6
+ @import "foo.css" screen;
7
+ @import "foo.css" screen, print;
8
+ @charset "UTF-8";
9
+ [foo~=bar] {
10
+ a: b; }
11
+
12
+ [foo^=bar] {
13
+ a: b; }
14
+
15
+ [foo$=bar] {
16
+ a: b; }
17
+
18
+ [foo*=bar] {
19
+ a: b; }
20
+
21
+ [foo|=en] {
22
+ a: b; }
23
+
24
+ foo {
25
+ a: 2;
26
+ b: 2.3em;
27
+ c: 50%;
28
+ d: "fraz bran";
29
+ e: flanny-blanny-blan;
30
+ f: url(http://sass-lang.com);
31
+ h: #abc; }
32
+
33
+ selector {
34
+ property: value;
35
+ property2: value; }
36
+
37
+ sel {
38
+ p: v; }
39
+
40
+ .foo {
41
+ /* Foo
42
+ Bar
43
+ Baz */
44
+ a: b; }
45
+
46
+ .foo {
47
+ /* Foo
48
+ Bar
49
+ Baz */
50
+ a: b; }
51
+
52
+ .foo {
53
+ /* Foo
54
+ Bar */
55
+ a: b; }
56
+
57
+ .foo {
58
+ /* Foo
59
+ Bar
60
+ Baz */
61
+ a: b; }
62
+
63
+ @foo {
64
+ a: b;
65
+ rule {
66
+ a: b; } }
67
+
68
+ @foo {
69
+ a: b; }
70
+
71
+ @bar {
72
+ a: b; }
73
+
74
+ @foo "bar"
75
+
76
+ foo {
77
+ a: 12px calc(100%/3 - 2*1em - 2*1px);
78
+ b: 12px -moz-calc(100%/3 - 2*1em - 2*1px);
79
+ b: 12px -webkit-calc(100%/3 - 2*1em - 2*1px);
80
+ b: 12px -foobar-calc(100%/3 - 2*1em - 2*1px); }
81
+
82
+ foo {
83
+ bar: baz; }
84
+
85
+ bar {
86
+ bar: baz; }
87
+
88
+ baz {
89
+ bar: baz; }
90
+ /*
91
+ * foo
92
+ */
93
+ bar {
94
+ baz: bang; }
95
+
96
+ E, F {
97
+ a: b; }
98
+
99
+ E F, G H {
100
+ a: b; }
101
+
102
+ E > F, G > H {
103
+ a: b; }
104
+ /* This is a CSS comment. */
105
+ .one {
106
+ color: green; }
107
+ /* Another comment */
108
+ /* The following should not be used:
109
+ .two {color: red;} */
110
+ .three {
111
+ color: green;
112
+ /* color: red; */ }
113
+ /**
114
+ .four {color: red;} */
115
+ .five {
116
+ color: green; }
117
+ /**/
118
+ .six {
119
+ color: green; }
120
+ /*********/
121
+ .seven {
122
+ color: green; }
123
+ /* a comment **/
124
+ .eight {
125
+ color: green; }
126
+
127
+ foo {
128
+ a: \foo bar;
129
+ b: foo\ bar;
130
+ c: \2022 \0020;
131
+ d: foo\\bar;
132
+ e: foo\"\'bar; }
133
+
134
+ foo {
135
+ a: "\foo bar";
136
+ b: "foo\ bar";
137
+ c: "\2022 \0020";
138
+ d: "foo\\bar";
139
+ e: "foo\"'bar"; }
140
+
141
+ foo {
142
+ _name: val;
143
+ *name: val;
144
+ :name: val;
145
+ .name: val;
146
+ #name: val;
147
+ name/**/: val;
148
+ name/*\**/: val;
149
+ name: val; }
150
+
151
+ @foo "bar" ;
152
+
153
+ foo {
154
+ a: -moz-element(#foo);
155
+ b: -webkit-element(#foo);
156
+ b: -foobar-element(#foo); }
157
+
158
+ @foo ;
159
+
160
+ foo {
161
+ bar: baz; }
162
+
163
+ 0% {
164
+ a: b; }
165
+
166
+ 60% {
167
+ a: b; }
168
+
169
+ 100% {
170
+ a: b; }
171
+
172
+ 12px {
173
+ a: b; }
174
+
175
+ "foo" {
176
+ a: b; }
177
+
178
+ foo {
179
+ a: 12px expression(1 + (3 / Foo.bar("baz" + "bang") + function() {return 12;}) % 12); }
180
+
181
+ :foo("bar") {
182
+ a: b; }
183
+
184
+ :foo(bar) {
185
+ a: b; }
186
+
187
+ :foo(12px) {
188
+ a: b; }
189
+
190
+ :foo(+) {
191
+ a: b; }
192
+
193
+ :foo(-) {
194
+ a: b; }
195
+
196
+ :foo(+"bar") {
197
+ a: b; }
198
+
199
+ :foo(-++--baz-"bar"12px) {
200
+ a: b; }
201
+
202
+ foo {
203
+ a: foo-bar(12);
204
+ b: -foo-bar-baz(13, 14 15); }
205
+
206
+ @import "foo.css" screen, print and (foo: 0);
207
+
208
+ @import "foo.css" screen, only print, screen and (foo: 0);
209
+
210
+ foo {
211
+ a: foo !important;
212
+ b: foo bar !important;
213
+ b: foo, bar !important; }
214
+
215
+ foo {
216
+ a: -moz-bar-baz;
217
+ b: foo -o-bar-baz; }
218
+
219
+ foo {
220
+ a: d;
221
+ /* b; c: */ }
222
+
223
+ foo {
224
+ a : d;
225
+ /*: b; c */ }
226
+ /* Foo
227
+ * Bar */
228
+ .foo {
229
+ /* Foo
230
+ * Bar */ }
231
+
232
+ [foo] {
233
+ a: b; }
234
+
235
+ [foo="bar"] {
236
+ a: b; }
237
+
238
+ [foo~="bar"] {
239
+ a: b; }
240
+
241
+ [foo^="bar"] {
242
+ a: b; }
243
+
244
+ [foo$="bar"] {
245
+ a: b; }
246
+
247
+ [foo*="bar"] {
248
+ a: b; }
249
+
250
+ [foo|="en"] {
251
+ a: b; }
252
+
253
+ :root {
254
+ a: b; }
255
+
256
+ :nth-child(n) {
257
+ a: b; }
258
+
259
+ :nth-last-child(n) {
260
+ a: b; }
261
+
262
+ :nth-of-type(n) {
263
+ a: b; }
264
+
265
+ :nth-last-of-type(n) {
266
+ a: b; }
267
+
268
+ :first-child {
269
+ a: b; }
270
+
271
+ :last-child {
272
+ a: b; }
273
+
274
+ :first-of-type {
275
+ a: b; }
276
+
277
+ :last-of-type {
278
+ a: b; }
279
+
280
+ :only-child {
281
+ a: b; }
282
+
283
+ :only-of-type {
284
+ a: b; }
285
+
286
+ :empty {
287
+ a: b; }
288
+
289
+ :link {
290
+ a: b; }
291
+
292
+ :visited {
293
+ a: b; }
294
+
295
+ :active {
296
+ a: b; }
297
+
298
+ :hover {
299
+ a: b; }
300
+
301
+ :focus {
302
+ a: b; }
303
+
304
+ :target {
305
+ a: b; }
306
+
307
+ :lang(fr) {
308
+ a: b; }
309
+
310
+ :enabled {
311
+ a: b; }
312
+
313
+ :disabled {
314
+ a: b; }
315
+
316
+ :checked {
317
+ a: b; }
318
+
319
+ ::first-line {
320
+ a: b; }
321
+
322
+ ::first-letter {
323
+ a: b; }
324
+
325
+ ::before {
326
+ a: b; }
327
+
328
+ ::after {
329
+ a: b; }
330
+
331
+ .warning {
332
+ a: b; }
333
+
334
+ #myid {
335
+ a: b; }
336
+
337
+ :not(s) {
338
+ a: b; }
339
+
340
+ @media all {
341
+ rule1 {
342
+ prop: val; }
343
+
344
+ rule2 {
345
+ prop: val; } }
346
+
347
+ @media screen, print {
348
+ rule1 {
349
+ prop: val; }
350
+
351
+ rule2 {
352
+ prop: val; } }
353
+
354
+ @media screen and (-webkit-min-device-pixel-ratio: 0) {
355
+ a: b; }
356
+
357
+ @media only screen, print and (foo: 0px) and (bar: flam(12px solid)) {
358
+ a: b; }
359
+
360
+ :-moz-any(h1, h2, h3) {
361
+ a: b; }
362
+
363
+ :-moz-any(.foo) {
364
+ a: b; }
365
+
366
+ :-moz-any(foo bar, .baz > .bang) {
367
+ a: b; }
368
+
369
+ @-moz-document url(http://www.w3.org/),
370
+ url-prefix(http://www.w3.org/Style/),
371
+ domain(mozilla.org),
372
+ regexp("^https:.*") {
373
+ .foo {
374
+ a: b; } }
375
+
376
+ foo {
377
+ filter: progid:DXImageTransform.Microsoft.gradient(GradientType=1, startColorstr=#c0ff3300, endColorstr=#ff000000);
378
+ filter: progid:DXImageTransform.Microsoft.gradient(GradientType=1, startColorstr=#c0ff3300, endColorstr=#ff000000); }
379
+
380
+ foo {
381
+ filter: alpha(opacity=20);
382
+ filter: alpha(opacity=20, enabled=true);
383
+ filter: blaznicate(foo=bar, baz=bang bip, bart=#fa4600); }
384
+
385
+ @foo bar {
386
+ a: b; }
387
+
388
+ @bar baz {
389
+ c: d; }
390
+
391
+ @foo bar;
392
+ @bar baz;
393
+
394
+
395
+ /* Foo
396
+ * Bar */
397
+ /* Baz
398
+ * Bang */
399
+
400
+
401
+ .foo {
402
+ /* Foo
403
+ * Bar */
404
+ /* Baz
405
+ * Bang */ }
406
+
407
+ .foo {
408
+ /* Foo Bar */
409
+ /* Baz Bang */ }
410
+
411
+ @namespace "http://www.w3.org/Profiles/xhtml1-strict";
412
+
413
+ @namespace url(http://www.w3.org/Profiles/xhtml1-strict);
414
+
415
+ @namespace html url("http://www.w3.org/Profiles/xhtml1-strict");
416
+
417
+ [foo|bar=baz] {
418
+ a: b; }
419
+
420
+ [*|bar=baz] {
421
+ a: b; }
422
+
423
+ [foo|bar|=baz] {
424
+ a: b; }
425
+
426
+ foo|E {
427
+ a: b; }
428
+
429
+ *|E {
430
+ a: b; }
431
+
432
+ foo|* {
433
+ a: b; }
434
+
435
+ *|* {
436
+ a: b; }
437
+
438
+ :not(foo|bar) {
439
+ a: b; }
440
+
441
+ :not(*|bar) {
442
+ a: b; }
443
+
444
+ :not(foo|*) {
445
+ a: b; }
446
+
447
+ :not(*|*) {
448
+ a: b; }
449
+
450
+ :not(#blah) {
451
+ a: b; }
452
+
453
+ :not(.blah) {
454
+ a: b; }
455
+
456
+ :not([foo]) {
457
+ a: b; }
458
+
459
+ :not([foo^="bar"]) {
460
+ a: b; }
461
+
462
+ :not([baz|foo~="bar"]) {
463
+ a: b; }
464
+
465
+ :not(:hover) {
466
+ a: b; }
467
+
468
+ :not(:nth-child(2n + 3)) {
469
+ a: b; }
470
+
471
+ :not(:not(#foo)) {
472
+ a: b; }
473
+
474
+ :not(a#foo.bar) {
475
+ a: b; }
476
+
477
+ :not(#foo .bar > baz) {
478
+ a: b; }
479
+
480
+ :not(h1, h2, h3) {
481
+ a: b; }
482
+
483
+ foo {
484
+ a: "bang 1 bar bip"; }
485
+
486
+ :nth-child(-n) {
487
+ a: b; }
488
+
489
+ :nth-child(+n) {
490
+ a: b; }
491
+
492
+ :nth-child(even) {
493
+ a: b; }
494
+
495
+ :nth-child(odd) {
496
+ a: b; }
497
+
498
+ :nth-child(50) {
499
+ a: b; }
500
+
501
+ :nth-child(-50) {
502
+ a: b; }
503
+
504
+ :nth-child(+50) {
505
+ a: b; }
506
+
507
+ :nth-child(2n+3) {
508
+ a: b; }
509
+
510
+ :nth-child(2n-3) {
511
+ a: b; }
512
+
513
+ :nth-child(+2n-3) {
514
+ a: b; }
515
+
516
+ :nth-child(-2n+3) {
517
+ a: b; }
518
+
519
+ :nth-child(-2n+ 3) {
520
+ a: b; }
521
+
522
+ :nth-child( 2n + 3) {
523
+ a: b; }
524
+
525
+ foo {
526
+ a: foo bar baz;
527
+ b: foo, #abc, -12;
528
+ c: 1px/2px/-3px;
529
+ d: foo bar, baz/bang; }
530
+
531
+ @page {
532
+ prop1: val;
533
+ prop2: val; }
534
+
535
+ @page flap {
536
+ prop1: val;
537
+ prop2: val; }
538
+
539
+ @page :first {
540
+ prop1: val;
541
+ prop2: val; }
542
+
543
+ @page flap:first {
544
+ prop1: val;
545
+ prop2: val; }
546
+
547
+ .foo {
548
+ /* Foo */
549
+ a: b; }
550
+
551
+ .foo {
552
+ /* Foo
553
+ * Bar */
554
+ a: b; }
555
+ /* Foo */
556
+ .foo {
557
+ a: b; }
558
+ /* Foo
559
+ * Bar */
560
+ .foo {
561
+ a: b; }
562
+
563
+ .foo #bar:baz(/* bang )*/ bip) {
564
+ /* .a #foo */
565
+ a: b; }
566
+
567
+ > E {
568
+ a: b; }
569
+
570
+ + E {
571
+ a: b; }
572
+
573
+ ~ E {
574
+ a: b; }
575
+
576
+ > > E {
577
+ a: b; }
578
+
579
+ >> E {
580
+ a: b; }
581
+
582
+ E* {
583
+ a: b; }
584
+
585
+ E*.foo {
586
+ a: b; }
587
+
588
+ E*:hover {
589
+ a: b; }
590
+
591
+ E, F {
592
+ a: b; }
593
+
594
+ E F {
595
+ a: b; }
596
+
597
+ E, F G, H {
598
+ a: b; }
599
+
600
+ body {
601
+ /*
602
+ //comment here
603
+ */ }
604
+
605
+ E > F {
606
+ a: b; }
607
+
608
+ E ~ F {
609
+ a: b; }
610
+
611
+ E + F {
612
+ a: b; }
613
+
614
+ * {
615
+ a: b; }
616
+
617
+ E {
618
+ a: b; }
619
+
620
+ E[foo] {
621
+ a: b; }
622
+
623
+ E[foo="bar"] {
624
+ a: b; }
625
+
626
+ E[foo~="bar"] {
627
+ a: b; }
628
+
629
+ E[foo^="bar"] {
630
+ a: b; }
631
+
632
+ E[foo$="bar"] {
633
+ a: b; }
634
+
635
+ E[foo*="bar"] {
636
+ a: b; }
637
+
638
+ E[foo|="en"] {
639
+ a: b; }
640
+
641
+ E:root {
642
+ a: b; }
643
+
644
+ E:nth-child(n) {
645
+ a: b; }
646
+
647
+ E:nth-last-child(n) {
648
+ a: b; }
649
+
650
+ E:nth-of-type(n) {
651
+ a: b; }
652
+
653
+ E:nth-last-of-type(n) {
654
+ a: b; }
655
+
656
+ E:first-child {
657
+ a: b; }
658
+
659
+ E:last-child {
660
+ a: b; }
661
+
662
+ E:first-of-type {
663
+ a: b; }
664
+
665
+ E:last-of-type {
666
+ a: b; }
667
+
668
+ E:only-child {
669
+ a: b; }
670
+
671
+ E:only-of-type {
672
+ a: b; }
673
+
674
+ E:empty {
675
+ a: b; }
676
+
677
+ E:link {
678
+ a: b; }
679
+
680
+ E:visited {
681
+ a: b; }
682
+
683
+ E:active {
684
+ a: b; }
685
+
686
+ E:hover {
687
+ a: b; }
688
+
689
+ E:focus {
690
+ a: b; }
691
+
692
+ E:target {
693
+ a: b; }
694
+
695
+ E:lang(fr) {
696
+ a: b; }
697
+
698
+ E:enabled {
699
+ a: b; }
700
+
701
+ E:disabled {
702
+ a: b; }
703
+
704
+ E:checked {
705
+ a: b; }
706
+
707
+ E::first-line {
708
+ a: b; }
709
+
710
+ E::first-letter {
711
+ a: b; }
712
+
713
+ E::before {
714
+ a: b; }
715
+
716
+ E::after {
717
+ a: b; }
718
+
719
+ E.warning {
720
+ a: b; }
721
+
722
+ E#myid {
723
+ a: b; }
724
+
725
+ E:not(s) {
726
+ a: b; }
727
+
728
+ E F {
729
+ a: b; }
730
+
731
+ E > F {
732
+ a: b; }
733
+
734
+ E + F {
735
+ a: b; }
736
+
737
+ E ~ F {
738
+ a: b; }
739
+
740
+ @supports (a: b) and (c: d) or (not (d: e)) and ((not (f: g)) or (not ((h: i) and (j: k)))) {
741
+ .foo {
742
+ a: b; } }
743
+
744
+ @-prefix-supports (a: b) and (c: d) or (not (d: e)) and ((not (f: g)) or (not ((h: i) and (j: k)))) {
745
+ .foo {
746
+ a: b; } }
747
+
748
+ foo {
749
+ foo: bar;
750
+ #baz: bang;
751
+ #bip: bop; }
752
+
753
+ foo {
754
+ a: -2;
755
+ b: -2.3em;
756
+ c: -50%;
757
+ d: -foo(bar baz); }
758
+
759
+ foo {
760
+ a: -0.5em;
761
+ b: 0.5em;
762
+ c: -foo(12px);
763
+ d: +foo(12px); }
764
+
765
+ foo {
766
+ -moz-foo-bar: blat;
767
+ -o-flat-blang: wibble; }
768
+
769
+ foo {
770
+ a: foo();
771
+ b: bar baz-bang() bip; }
lib/scssphp/tests/outputs/selectors.css ADDED
@@ -0,0 +1,341 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ * {
2
+ color: blue; }
3
+
4
+ E {
5
+ color: blue; }
6
+
7
+ E:not(:link) {
8
+ color: blue; }
9
+
10
+ E:not(:link):not(:visited) {
11
+ color: blue; }
12
+
13
+ E:not(:link, :visited) {
14
+ color: blue; }
15
+
16
+ E:matches(:hover, :focus) {
17
+ color: blue; }
18
+
19
+ E.warning {
20
+ color: blue; }
21
+
22
+ E#id {
23
+ color: blue; }
24
+
25
+ E[foo] {
26
+ color: blue; }
27
+
28
+ E[foo="barbar"] {
29
+ color: blue; }
30
+
31
+ E[foo="barbar" i] {
32
+ color: blue; }
33
+
34
+ E[foo~="hello#$@%@$#^"] {
35
+ color: blue; }
36
+
37
+ E[foo^="color: green;"] {
38
+ color: blue; }
39
+
40
+ E[foo$="239023"] {
41
+ color: blue; }
42
+
43
+ E[foo*="29302"] {
44
+ color: blue; }
45
+
46
+ E[foo|="239032"] {
47
+ color: blue; }
48
+
49
+ [foo] {
50
+ color: blue; }
51
+
52
+ [foo] .helloWorld {
53
+ color: blue; }
54
+
55
+ [foo].helloWorld {
56
+ color: blue; }
57
+
58
+ [foo="barbar"] {
59
+ color: blue; }
60
+
61
+ [foo~="hello#$@%@$#^"] {
62
+ color: blue; }
63
+
64
+ [foo^="color: green;"] {
65
+ color: blue; }
66
+
67
+ [foo$="239023"] {
68
+ color: blue; }
69
+
70
+ [foo*="29302"] {
71
+ color: blue; }
72
+
73
+ [foo|="239032"] {
74
+ color: blue; }
75
+
76
+ E:dir(ltr) {
77
+ color: blue; }
78
+
79
+ E:lang(en) {
80
+ color: blue; }
81
+
82
+ E:lang(en, fr) {
83
+ color: blue; }
84
+
85
+ E:any-link {
86
+ color: blue; }
87
+
88
+ E:link {
89
+ color: blue; }
90
+
91
+ E:visited {
92
+ color: blue; }
93
+
94
+ E:local-link {
95
+ color: blue; }
96
+
97
+ E:local-link(0) {
98
+ color: red; }
99
+
100
+ E:local-link(1) {
101
+ color: white; }
102
+
103
+ E:local-link(2) {
104
+ color: red; }
105
+
106
+ E:target {
107
+ color: blue; }
108
+
109
+ E:scope {
110
+ color: blue; }
111
+
112
+ E:current {
113
+ color: blue; }
114
+
115
+ E:current(:link) {
116
+ color: blue; }
117
+
118
+ E:past {
119
+ color: blue; }
120
+
121
+ E:future {
122
+ color: blue; }
123
+
124
+ E:active {
125
+ color: blue; }
126
+
127
+ E:hover {
128
+ color: blue; }
129
+
130
+ E:focus {
131
+ color: blue; }
132
+
133
+ E:enabled {
134
+ color: blue; }
135
+
136
+ E:disabled {
137
+ color: blue; }
138
+
139
+ E:indeterminate {
140
+ color: blue; }
141
+
142
+ E:default {
143
+ color: blue; }
144
+
145
+ E:in-range {
146
+ color: blue; }
147
+
148
+ E:out-of-range {
149
+ color: blue; }
150
+
151
+ E:required {
152
+ color: blue; }
153
+
154
+ E:optional {
155
+ color: blue; }
156
+
157
+ E:read-only {
158
+ color: blue; }
159
+
160
+ E:read-write {
161
+ color: blue; }
162
+
163
+ E:root {
164
+ color: blue; }
165
+
166
+ E:empty {
167
+ color: blue; }
168
+
169
+ E:first-child {
170
+ color: blue; }
171
+
172
+ E:nth-child(odd) {
173
+ color: blue; }
174
+
175
+ E:nth-child(2n+1) {
176
+ color: blue; }
177
+
178
+ E:nth-child(5) {
179
+ color: blue; }
180
+
181
+ E:last-child {
182
+ color: blue; }
183
+
184
+ E:nth-last-child(-n+2) {
185
+ color: blue; }
186
+
187
+ E:only-child {
188
+ color: blue; }
189
+
190
+ E:first-of-type {
191
+ color: blue; }
192
+
193
+ E:nth-of-type(2n) {
194
+ color: blue; }
195
+
196
+ E:last-of-type {
197
+ color: blue; }
198
+
199
+ E:nth-last-of-type(n) {
200
+ color: blue; }
201
+
202
+ E:only-of-type {
203
+ color: blue; }
204
+
205
+ E:nth-match(odd) {
206
+ color: blue; }
207
+
208
+ E:nth-last-match(odd) {
209
+ color: blue; }
210
+
211
+ E:column(n) {
212
+ color: blue; }
213
+
214
+ E:nth-column(n) {
215
+ color: blue; }
216
+
217
+ E:nth-last-column(n) {
218
+ color: blue; }
219
+
220
+ E F {
221
+ color: blue; }
222
+
223
+ E > F {
224
+ color: blue; }
225
+
226
+ E + F {
227
+ color: blue; }
228
+
229
+ E ~ F {
230
+ color: blue; }
231
+
232
+ E /foo/ F {
233
+ color: blue; }
234
+
235
+ E! > F {
236
+ color: blue; }
237
+
238
+ [foo|att=val] {
239
+ color: blue; }
240
+
241
+ [*|att] {
242
+ color: yellow; }
243
+
244
+ [|att] {
245
+ color: green; }
246
+
247
+ [att] {
248
+ color: green; }
249
+
250
+ E::first-line {
251
+ color: blue; }
252
+
253
+ E::first-letter {
254
+ color: blue; }
255
+
256
+ E::before {
257
+ color: blue; }
258
+
259
+ E::after {
260
+ color: blue; }
261
+
262
+ E::choices {
263
+ color: blue; }
264
+
265
+ E::value {
266
+ color: blue; }
267
+
268
+ E::repeat-index {
269
+ color: blue; }
270
+
271
+ E::repeat-item {
272
+ color: blue; }
273
+
274
+ E:first {
275
+ color: blue; }
276
+
277
+ E:first-line {
278
+ color: blue; }
279
+
280
+ E:first-letter {
281
+ color: blue; }
282
+
283
+ E:before {
284
+ color: blue; }
285
+
286
+ E:after {
287
+ color: blue; }
288
+
289
+ E:checked {
290
+ color: blue; }
291
+
292
+ E:invalid {
293
+ color: blue; }
294
+
295
+ E:valid {
296
+ color: blue; }
297
+
298
+ E:left {
299
+ color: blue; }
300
+
301
+ E:right {
302
+ color: blue; }
303
+
304
+ E:any(ol) {
305
+ color: blue; }
306
+
307
+ E::selection {
308
+ color: blue; }
309
+
310
+ div {
311
+ font: something;
312
+ font-size: 30em; }
313
+ div font:something {
314
+ size: 30em; }
315
+
316
+ .something.world {
317
+ color: blue; }
318
+ .something .mold {
319
+ height: 200px; }
320
+ .dog .something {
321
+ color: blue; }
322
+
323
+ .dad .simple .wolf {
324
+ color: blue; }
325
+ .rad.simple.bad {
326
+ color: blue; }
327
+
328
+ .something div .what.world {
329
+ color: blue; }
330
+
331
+ div.foo div {
332
+ color: blue; }
333
+
334
+ .nice-fonts .main .message div .title, .nice-fonts div .message div .title {
335
+ font-size: 24px; }
336
+
337
+ .escape\% {
338
+ color: red; }
339
+
340
+ .escape-plan\% {
341
+ color: green; }
lib/scssphp/tests/outputs/values.css ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #values {
2
+ color: #eee;
3
+ color: #eee;
4
+ height: 20px;
5
+ width: 80%;
6
+ color: "hello world";
7
+ height: url("http://google.com");
8
+ dads: url(http://leafo.net);
9
+ padding: 10px 10px 10px 10px, 3px 3px 3px;
10
+ textblock: "This is a \
11
+ multiline block \
12
+ #not { color: #eee;}";
13
+ margin: 4, 3, 1;
14
+ content: "This is a \
15
+ multiline string.";
16
+ border-radius: -1px -1px -1px black; }
17
+
18
+ #subtraction {
19
+ lit: 10 -11;
20
+ lit: -1;
21
+ lit: -1;
22
+ lit: -1;
23
+ var: 10 -100;
24
+ var: -90;
25
+ var: -90;
26
+ var: -90; }
27
+
28
+ #special {
29
+ a: 12px expression(1 + (3 / Foo.bar("baz" + "bang") + function() {return 12;}) % 12); }
30
+
31
+ #unary {
32
+ b: 0.5em;
33
+ c: -foo(12px);
34
+ d: +foo(12px); }
lib/scssphp/tests/outputs/variables.css ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ cool: 100px;
2
+ div {
3
+ height: red, two, three; }
4
+
5
+ div {
6
+ num: 1000; }
7
+
8
+ div {
9
+ num: 2000; }
10
+
11
+ pre {
12
+ color: blue; }
13
+
14
+ del {
15
+ color: red; }
16
+ del div pre {
17
+ color: red; }
18
+
19
+ body {
20
+ font-family: Arial;
21
+ font-family: Helvetica Neue;
22
+ font-family: "Helvetica Neue";
23
+ font-family: Helvetica, Arial, sans-serif;
24
+ font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; }
lib/scssphp/todo ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ * change all calls to reduce to not suppress division where appropriate
3
+ * store count in elements so we can have position of compile time errors
4
+ * failed parsing paths can add comments early
5
+
6
+ * fix indentation for @content, see @content tests
7
+
8
+ misc:
9
+
10
+ # sequence merging:
11
+
12
+ a b c d { color: red; }
13
+ x y z w { @extend a; }
14
+
15
+ a b c d, x y z w b c d { color: red; }
16
+
17
+
18
+ a b c d { color: red; }
19
+ x y z w { @extend b; }
20
+
21
+ a b c d, a x y z w c d, x y z a w c d { color: red; }
22
+
23
+
24
+ a b c d { color: red; }
25
+ x y z w { @extend c; }
26
+
27
+ a b c d, a b x y z w d, x y z a b w d { color: red; }
28
+
29
+ x y z a b w d
30
+
31
+ before: a b
32
+ after: d
33
+ new: x y z w
34
+
35
+
36
+ a b c d { color: red; }
37
+ x y z w { @extend d; }
38
+
39
+ a b c d, a b c x y z w, x y z a b c w { color: red; }
40
+
41
+
42
+ ->> new[:-1] . before . new[-1] . after
43
+
44
+ new.len > 1
45
+ before not empty
46
+
47
+
package.xml CHANGED
@@ -1,7 +1,7 @@
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>Sass</name>
4
- <version>1.1.5</version>
5
  <stability>stable</stability>
6
  <license uri="http://opensource.org/licenses/osl-3.0.php">Open Software License (OSL 3.0)</license>
7
  <channel>community</channel>
@@ -12,12 +12,11 @@
12
  You just need to create you sass file and add it to your layout like default css file.&#xD;
13
  &#xD;
14
  This extension will then convert it to css file using phpSass or sass in command line if available</description>
15
- <notes>Support of Magento CE 1.8.1&#xD;
16
- phpsass library updated.</notes>
17
  <authors><author><name>Laurent Clouet</name><user>laurent35240</user><email>laurent35240@gmail.com</email></author></authors>
18
- <date>2014-02-09</date>
19
- <time>20:03:06</time>
20
- <contents><target name="magecommunity"><dir name="Laurent"><dir name="Sass"><dir name="Helper"><file name="Data.php" hash="9c43132dba73d4b3f37ccfb91f0d5dbe"/></dir><dir name="Model"><dir name="Config"><file name="Style.php" hash="413571124dcf58d950200499a144420d"/></dir><dir name="Design"><file name="Package.php" hash="9ad012e66d168bde93f48518aa82cdf4"/></dir></dir><dir name="etc"><file name="config.xml" hash="e3f9875a014b5ed2f229b0d88a1654d1"/><file name="system.xml" hash="a2db1af0d9bae017b46805a80aedb442"/></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Laurent_Sass.xml" hash="4ad004de851457681610553228973c30"/></dir></target><target name="magelocale"><dir name="en_US"><file name="Laurent_Sass.csv" hash="d9e8c184cbe72e810c7da9154581e1e4"/></dir><dir name="fr_FR"><file name="Laurent_Sass.csv" hash="676b2c597fe0b829fb2c48c1428c295f"/></dir></target><target name="magelib"><dir name="phpsass"><dir name="Extensions"><dir name="Compass"><file name="Compass.php" hash="133465f9483db4a0cd8f2f0745b7c4f0"/><dir name="stylesheets"><file name="_compass.scss" hash="923227de5043435d74c39f0609ce9f76"/><file name="_lemonade.scss" hash="5883254c8046f814601563801d8734c9"/><dir name="compass"><file name="_css3.scss" hash="b82217c21019ca2eb2a40f6a9e044b12"/><file name="_layout.scss" hash="ade265ba9afe952ed07cd2bca858aa85"/><file name="_reset-legacy.scss" hash="485a40cbe1263d244c49d341535da137"/><file name="_reset.scss" hash="f3ba8694329af7d839e77ba770990929"/><file name="_support.scss" hash="a19d4dbb7658196886212ef0105b6b66"/><file name="_typography.scss" hash="918742a5cf560d0f19b19fdbe8ae6aab"/><file name="_utilities.scss" hash="08acdaa4834dbe549b74a1098f19bc7b"/><dir name="css3"><file name="_appearance.scss" hash="acca7f89ed3c92d86e12150aca56ce89"/><file name="_background-clip.scss" hash="6b87b6ed6aad32c3d56e45440854e8b4"/><file name="_background-origin.scss" hash="bfc89088ed9515bb96c8d1a37835f2f0"/><file name="_background-size.scss" hash="7281b0fb3fd2cfebb83d39d79602d49f"/><file name="_border-radius.scss" hash="e791791cb121251afc23ef54d8680682"/><file name="_box-shadow.scss" hash="218306afcdfc6824edad428d22de91b4"/><file name="_box-sizing.scss" hash="ddb42be3b4d2b256785c1a9b78550f51"/><file name="_box.scss" hash="78dcd7150d63b159e7eb8bc2ff8519f9"/><file name="_columns.scss" hash="4adba9442997c3535bd6dd03cc393dc8"/><file name="_filter.scss" hash="bc1e638a924805bf098fd892a1353ac1"/><file name="_font-face.scss" hash="d44f61e599ea7db8119471ed527b3f95"/><file name="_hyphenation.scss" hash="b4cc046662de1d54aa385104b257fd11"/><file name="_images.scss" hash="d21bf95cc8fef7bebff9bfeb15c23634"/><file name="_inline-block.scss" hash="0ddfde10e192213f01dfa122d15bf473"/><file name="_opacity.scss" hash="9191ab6617583e17dcc26d250dc1212d"/><file name="_pie.scss" hash="bf0a4b83809dab91b81454a4b2398fc7"/><file name="_regions.scss" hash="620d1e2235b0cb0ea67306158c536730"/><file name="_shared.scss" hash="2ef8a5f26cf39fbb9875957d9da943ab"/><file name="_text-shadow.scss" hash="2021656239f4853c9d43756b7e3b889c"/><file name="_transform-legacy.scss" hash="927f4115f0cd99df08fd70a33af0e1ec"/><file name="_transform.scss" hash="94088f096d93f4e7cc875d4067bc4ae5"/><file name="_transition.scss" hash="882fb3097235091678f4dc8e85453787"/><file name="_user-interface.scss" hash="7f5b8e3138bf1d2ca8cda702ffddf0c0"/></dir><dir name="layout"><file name="_grid-background.scss" hash="cc3db4c7d9ca43733d0995c7905db89d"/><file name="_sticky-footer.scss" hash="b3cf39ed65213a93f2b3d37fb8029448"/><file name="_stretching.scss" hash="8694407f678486cca2ab280c06016313"/></dir><dir name="reset"><file name="_utilities-legacy.scss" hash="bddb0e2273e06e79169021ccf083f44e"/><file name="_utilities.scss" hash="64c2610e860a105b2bbd22345101655a"/></dir><dir name="typography"><file name="_links.scss" hash="ec36c795f2d5b348e25145f3bde4264e"/><file name="_lists.scss" hash="8694e645f66cd4bdfa8aca26abd109a0"/><file name="_text.scss" hash="59a9a0f38c0f3591ca02dd7eda8cd518"/><file name="_vertical_rhythm.scss" hash="8578b0cae2dda8c5d8d0708d9cd2d5f6"/><dir name="links"><file name="_hover-link.scss" hash="eefccdadf38d1786d14d0471e1a3b6a4"/><file name="_link-colors.scss" hash="c83d0003dade99991a26328d4c6fe147"/><file name="_unstyled-link.scss" hash="81a5cbb33efc9a93cf906679b0c1223c"/></dir><dir name="lists"><file name="_bullets.scss" hash="56a14c0cea06b3522293f06a7e419cd8"/><file name="_horizontal-list.scss" hash="57f1807ae5c1efc55eb20a1877df3ae4"/><file name="_inline-block-list.scss" hash="6e1af07745f4ede2c9464d8a77364413"/><file name="_inline-list.scss" hash="8d1cc4cf2ecf61e5588523a39dcd151b"/></dir><dir name="text"><file name="_ellipsis.scss" hash="838c4ff68ca1cb19732a44f89be1db9b"/><file name="_force-wrap.scss" hash="0261457502e63b860c52e2485a34e71a"/><file name="_nowrap.scss" hash="7f33c936bae2a6bc3365b665eaf9e8ed"/><file name="_replacement.scss" hash="7bde7de4afebabea678dcadba649cfa8"/></dir></dir><dir name="utilities"><file name="_color.scss" hash="a5d6e262ee23ca5037413d20d5718be8"/><file name="_general.scss" hash="154bdd4b44b3868263edc2f618633fbd"/><file name="_links.scss" hash="c7f0403244151201a86639cf89f2d1e2"/><file name="_lists.scss" hash="6c93b9b38fb4f0cc2f576c07548833f8"/><file name="_print.scss" hash="3a4bafc1f1bd2fddfd7e54611142db8d"/><file name="_sprites.scss" hash="3d1cea8528cf128baa7662f5da6f3e23"/><file name="_tables.scss" hash="9ef43b5ebbebaabdbf30af1dfa4d076e"/><file name="_text.scss" hash="898792ca84be5c4aa21eb20eb20b9103"/><dir name="color"><file name="_contrast.scss" hash="9e78f467742891f43dd4aa56a9bf4c4f"/></dir><dir name="general"><file name="_clearfix.scss" hash="bc20f2c9c1d2913f97c94391fc97b113"/><file name="_float.scss" hash="e94dcc3ffdd92302cb3fd08cbfd58ac8"/><file name="_hacks.scss" hash="b569537940dbe9a2edf890d3817f7183"/><file name="_min.scss" hash="a406a7fa7de15370144c305115462f9c"/><file name="_reset.scss" hash="960b40e5f99d8e7de75d2230ba034a0d"/><file name="_tabs.scss" hash="68b329da9893e34099c7d8ad5cb9c940"/><file name="_tag-cloud.scss" hash="ab5b977c6d8ae4aca12273f1b391ff66"/></dir><dir name="links"><file name="_hover-link.scss" hash="9ac5ecb61975921d45102fc7423340ab"/><file name="_link-colors.scss" hash="da9338d176b03d3512e3a1ae0db305f7"/><file name="_unstyled-link.scss" hash="f7a2b8401f536a0e0510018aaf98ab29"/></dir><dir name="lists"><file name="_bullets.scss" hash="6109ae81701fa19782c82c9b22023a62"/><file name="_horizontal-list.scss" hash="706db7e29717c9acd481b9fe7ce8d83c"/><file name="_inline-block-list.scss" hash="f41e9e58f8a265e83b193905330b1161"/><file name="_inline-list.scss" hash="c893a4574a75c9f307db1347aade94be"/></dir><dir name="sprites"><file name="_base.scss" hash="ab8ac113a902eaf87aa6ff5a990485fd"/><file name="_sprite-img.scss" hash="6e998392f987c1859416efc9882d6114"/></dir><dir name="tables"><file name="_alternating-rows-and-columns.scss" hash="ce8dd53487aeaaeac364a316e2121502"/><file name="_borders.scss" hash="ba7a62a006b196aa29f19eab4cec1e9a"/><file name="_scaffolding.scss" hash="3e4054500fad740f12b4464e26ef6ca6"/></dir><dir name="text"><file name="_ellipsis.scss" hash="b05ba46a15279650894bb87d45e36db7"/><file name="_nowrap.scss" hash="eae37e54891bc61116862483d717a948"/><file name="_replacement.scss" hash="6a2e2d60fffc2650962c22d3384a72db"/></dir></dir></dir></dir><file name="test.php" hash="493e43f4577636cae876922155ed32c7"/></dir><file name="ExtensionInterface.php" hash="f02f77afac08968fca0ca8f7cd750456"/><dir name="Own"><file name="Own.php" hash="fb185a20331ce4f185d7fdc318bf0b50"/><dir name="css"><dir name="test"><dir name="test2"><file name="test.scss" hash="b406241e81f4cbd2509a3a7daa50ba6e"/></dir></dir></dir></dir><file name="README.md" hash="0adcca717d8c0113986c95cfa6fa341f"/><dir name="Susy"><file name="Susy.php" hash="36a66b10b093bfa6d09e10f84f5c7d18"/><dir name="stylesheets"><file name="_susy.scss" hash="e60bb0cc5234c86628f4e0345bd2d48a"/><dir name="susy"><file name="_background.scss" hash="e7125e6d00deae7955c61ef9ce5b7557"/><file name="_functions.scss" hash="33d52f0bb6a333da77ac8c4482a1d862"/><file name="_grid.scss" hash="687c942dcaba8b87dac49db2d734e594"/><file name="_isolation.scss" hash="8e097d991625106869a96101bdc2bde4"/><file name="_margin.scss" hash="cb03e121a2800a47d569b456f247a0e4"/><file name="_media.scss" hash="89c7da945f0159b5e97ce705e8d06ae6"/><file name="_padding.scss" hash="b775d9b8f5465ae985da128e31818342"/><file name="_settings.scss" hash="e9942cc79f66826c45c525705aca4c5b"/><file name="_support.scss" hash="7c51df6bd18e85e6954b46e37b47db48"/><file name="_units.scss" hash="fea6309f28d01dc5cbf3fa8503f6bfae"/></dir></dir></dir><file name="example.php" hash="909400c241ad5d58484d600b7d0c4c92"/><file name="example.scss" hash="1c36b8695ac3d22afa9caa72a5e0a96f"/><file name="theme.scss" hash="7210d729d56c93a23b91d4d280570e17"/></dir><file name="README.md" hash="f680aedff15c35475551bf0e0652be57"/><file name="SassException.php" hash="1b481a8b5ddaa54b372ada4eb8598bb5"/><file name="SassFile.php" hash="76ba06279ded72bb92388ec51c32b560"/><file name="SassParser.php" hash="538f2a5a5795d7dfd065d9b80b9aaf1d"/><file name="VERSION" hash="fc3abbf04899a7be14a6aef73d83c120"/><file name="compile-apache.php" hash="7a95ffbe3baf88cd27260645e51d326d"/><file name="composer.json" hash="fb5dad84d70d71d3ad3ea36e06238c21"/><dir name="renderers"><file name="SassCompactRenderer.php" hash="efa3e80cb179be28b933c674cd06d70b"/><file name="SassCompressedRenderer.php" hash="a76e47ecc939efb39ad3bd091d90cc52"/><file name="SassExpandedRenderer.php" hash="938e703678e01367f8bfbfc0af2c9aca"/><file name="SassNestedRenderer.php" hash="963cade34043342728476d4b80a8f66d"/><file name="SassRenderer.php" hash="cba7988395cfc8ceba91dd1ae5777abd"/></dir><dir name="script"><file name="SassScriptFunction.php" hash="1682579a7b1fe57ba5ae30d52e7effc2"/><file name="SassScriptFunctions.php" hash="d423c2837d5c72443ed37926b1e0b4e4"/><file name="SassScriptLexer.php" hash="888286d5b2542bcf57f292966953f3ad"/><file name="SassScriptOperation.php" hash="b4f2eabeedd761157c378d4b36272b65"/><file name="SassScriptParser.php" hash="122201f80fb07cb78b5a1d32f4ec2a78"/><file name="SassScriptParserExceptions.php" hash="b24e0948e0e07f38bcfded7ddd0220ce"/><file name="SassScriptVariable.php" hash="b7450d09a86722cb89755fdc259820dd"/><dir name="literals"><file name="SassBoolean.php" hash="09644008ffd1b31bd13d4191fbcbdfa1"/><file name="SassColour.php" hash="05e81b7dfc201eeebecec47a96269055"/><file name="SassList.php" hash="9c1a851b068515b08d7c0bdb0c01d355"/><file name="SassLiteral.php" hash="77cf2a7af40aeaea5f27a2f055949aad"/><file name="SassLiteralExceptions.php" hash="dee1ed83e9fbbb173c2d1ae8a3cd5ba8"/><file name="SassNumber.php" hash="b05dda4d89b992d7252a9e0b3168f660"/><file name="SassString.php" hash="3a6350304d07995a93c68824628bcd3a"/></dir></dir><file name="test-extensions.php" hash="3741d805557c174ec5b3b9bd58201a82"/><file name="test.css" hash="1655ffa4e91349bbe84d9e9f87b5ae39"/><file name="test.php" hash="b596b4143f17090e77fb094100ef61c3"/><dir name="tests"><file name="_imported_charset_ibm866.sass" hash="92b1d97a137e4219bb7796d7751aa847"/><file name="_imported_charset_utf8.sass" hash="51489125c07d0e8f2b055295d40d2549"/><file name="_imported_content.sass" hash="aafd4b9ba2de82e4f977e04934f204d7"/><file name="_partial.sass" hash="529fb954d7e0f6b42c484c869e60fbcf"/><file name="alt.css" hash="d48efc67765cb14b1c532b36b036a064"/><file name="alt.sass" hash="66be58fb872cd96be90fb95425a0aadf"/><file name="alt.scss" hash="ec1074aaba9b4a1ef3933d091c547c63"/><file name="basic.css" hash="22c341ec6e41dba84606032a40ea21c3"/><file name="basic.sass" hash="450faf5ca8e4bacefd01a74509ae135c"/><file name="bork1.sass" hash="0608533ebc4c4a16ddff507f818a709e"/><file name="bork2.sass" hash="036c6e0bcebc36908f9093d1b536ceb1"/><file name="bork3.sass" hash="ad06e4551ead8422ac443ae0cad7994b"/><file name="bork4.sass" hash="0bd4b0aed58208f5abf4418eb9672ef9"/><file name="bork5.sass" hash="e467427a1e928d1d72ef8db10482e262"/><file name="colour-nth.css" hash="8e457058415890dd4aac86f75a6e39e4"/><file name="colour-nth.scss" hash="3de860789a01fa9b5cf2d9a74a85dba7"/><file name="comments.css" hash="0ca95a61ccc49717e465173fb0c2e6c6"/><file name="comments.sass" hash="41bb5d2d2e14e3dd16c8b0296608a00e"/><file name="compact.css" hash="96105d0147b6881651b723eabe303f65"/><file name="compact.sass" hash="d51cfe7db78fe0d81793c7e24cb32e46"/><file name="complex.css" hash="3ffea6ccf80b24cc136bb102b3b41a67"/><file name="complex.sass" hash="b1426382fb915456b5efc0877ae7072d"/><file name="compressed.css" hash="1975f89cc758e39302d317578fdfdedb"/><file name="compressed.sass" hash="d51cfe7db78fe0d81793c7e24cb32e46"/><file name="content.css" hash="0c0892c48d74761fee54e09ccba6e662"/><file name="content.scss" hash="e624a12355435c147c0772f9fd1fe065"/><file name="css3.css" hash="8b2a0df29de7f2158baa3e97e76d91f2"/><file name="css3.scss" hash="819f570dae1e0c8c77007a03a2642158"/><file name="default.css" hash="8296f416c47ae4b66fa6bdf3259b1015"/><file name="default.sass" hash="90e19da7fd8144eeab4d93e5d3adb3bd"/><file name="default_imported.sass" hash="dbea23754dce7bc6c0f7ff69863c05c5"/><file name="each.css" hash="3f84fdb19433d6c2fb0e63c60c06d072"/><file name="each.scss" hash="9661d8222338cfdd6ba8ff771f1c881c"/><file name="expanded.css" hash="88ee2a16c4d88965bcbcf573a2d7c0fa"/><file name="expanded.sass" hash="66dbccbf13e56c23c9b12401ef4edb2d"/><file name="extend.css" hash="c4e9ba7d8748202d2c1351d5b69e3353"/><file name="extend.sass" hash="f34bd79d09364600631ea4889232ad64"/><file name="extend_included.scss" hash="be61d8166e45b16c08e49087985ed1fb"/><file name="extend_placeholders.css" hash="369b772056769bece364221f3c069a8e"/><file name="extend_placeholders.scss" hash="4af5f1ee5888e7cd6cf6c6de45dbfc17"/><dir name="extensions"><file name="linear_gradient_compass.css" hash="1b95f551ddcf942cd8e87e7e1ea07092"/><file name="linear_gradient_compass.scss" hash="21964541e0a0d245ae9b785c1b2fc263"/></dir><file name="filters.css" hash="f37ab5406ea00310513ce2e114cf6f07"/><file name="filters.scss" hash="ea989dd11a1d2a147b72d748b3a9c8c9"/><file name="functions.css" hash="0a039fdec50d756df0ca5430fdc25a0a"/><file name="functions.scss" hash="c9669b01b11b3abe4d82f701180ac2b0"/><file name="holmes.css" hash="07772c914ace61121cba53beb6ad8ca6"/><file name="holmes.sass" hash="e2199b90032b5f14a4dfc5233a915223"/><file name="hsl-functions.css" hash="b90a44e5919a286a8a62040f211b3580"/><file name="hsl-functions.scss" hash="fa055c7d603b5436613ecac898351cae"/><file name="if.css" hash="82391ad41348b41fc209cca5412ed740"/><file name="if.sass" hash="c3a27a421eb7e3d463918e189195b573"/><file name="if_parentheses.css" hash="7f5bc7f906a7cd678c9598c2e5650833"/><file name="if_parentheses.scss" hash="5140ac11b185061d3c5f7dc238e8ee86"/><file name="import.css" hash="3c8abb5481ee0c0002916b49681af2a5"/><file name="import.sass" hash="4d43389aa785393a47d57734724dad2f"/><file name="import_content.css" hash="4b78a566882b2768336f603d54f73fa4"/><file name="import_content.sass" hash="2db9b7a5b9a581e9f44256b6c8dbedd1"/><file name="importee.sass" hash="606678a5d48f7653f6d8e2e327109310"/><file name="interpolation.css" hash="ef048c83424f05a9c0882007ba0f4958"/><file name="interpolation.scss" hash="ce66433664f7f37277a8d4726a39556c"/><file name="introspection.css" hash="0d9f0e64e263388ec0e87eadef41193e"/><file name="introspection.scss" hash="9d57f03789f7a947ce62d6ab0320f886"/><file name="line_numbers.css" hash="802e2285df194c362503f849647a1380"/><file name="line_numbers.sass" hash="4770a812ab401d2bd35b352408623a17"/><file name="list.css" hash="4dd913d85cf2a28cb12d8af0f622ce03"/><file name="list.scss" hash="24f96a097c84d0da64cb3e753e2439ee"/><file name="list_empty.css" hash="c2fae66e0a28506f1733ac469a1c95ec"/><file name="list_empty.scss" hash="25d245b57859102ba6b36c12e89f3e7e"/><file name="list_variable.css" hash="d10df2dc91b4221bbfe4c3464bd34d5b"/><file name="list_variable.scss" hash="17a541748f730b9da21275a75852cf4e"/><file name="media.css" hash="409f2c0c468598dc19067376a796828f"/><file name="media.scss" hash="1fadbcd19113ff5855d1137be0693799"/><file name="media_in_for.css" hash="fd8292f715cc999ba7b64f8224c40a8a"/><file name="media_in_for.scss" hash="ad7702a6b95e121da52b93d69d782683"/><file name="media_in_mixin.css" hash="8c2bd3f961ab4336c55a5249f78e6bf4"/><file name="media_in_mixin.scss" hash="084e6f0edd3da537020a43d7ce8dbac4"/><file name="media_in_mixin_in_mixin.css" hash="8adc138ca27531ac5693c7e2274fdf9f"/><file name="media_in_mixin_in_mixin.scss" hash="049301e720820f076ceec6cc08037ede"/><file name="misc-functions.css" hash="7da15f26cab9b6df784ce1e37e9a30f1"/><file name="misc-functions.scss" hash="b133df9bb8cf346a3e6d3b3612c1de64"/><file name="misc.css" hash="a05a0a6b49ddbfdd803e92c5abe97594"/><file name="misc.scss" hash="36b58121127544b6a8179ae8a0c90a35"/><file name="mixin-content.css" hash="1b2490ce75d60d2b0c495a5db87a9f49"/><file name="mixin-content.sass" hash="41fa6bbd93b8d0b4ea8826fdd5585381"/><file name="mixin-content.scss" hash="f3252f583aac7dd5bbb7017fbd5654df"/><file name="mixin-ja1.css" hash="c551c8ffd0723e1c9e5795708d5dbda5"/><file name="mixin-ja1.sass" hash="90d3f2653ccbccbc00a9009bd31f8071"/><file name="mixin-list-params.css" hash="47064a4d242dfec9debba53326e529f3"/><file name="mixin-list-params.scss" hash="34478559346aec44c56c867a6b898af3"/><file name="mixin-params.css" hash="1a1f609e66c1dbe24383fe6855e95526"/><file name="mixin-params.scss" hash="a874ab4cacc02475acc827c956275cfe"/><file name="mixin-rgba-param.css" hash="bc5dc6caac3c74b37b82b1ed3cc2e553"/><file name="mixin-rgba-param.scss" hash="961219de858ecf7c17f2f7df24cf68cb"/><file name="mixin_bork.sass" hash="259fd0cca5a94583c0d406646b3217eb"/><file name="mixin_in_mixin.css" hash="46690de92ec525f39d5568bc2e46ee54"/><file name="mixin_in_mixin.scss" hash="0a6bef40d3215b63bb9f972896784a89"/><file name="mixin_setvar.css" hash="757520a01eca279c109d494d7fb4cd02"/><file name="mixin_setvar.scss" hash="12cd65c514056b3c0df1e4e92640a808"/><file name="mixins.css" hash="76ea6005844a4339745b1afe66274c74"/><file name="mixins.sass" hash="55fb1a104a59d6e5411987447af96b55"/><file name="multiline.css" hash="4a3d9bfe75a3b98c52ed95f3d785b079"/><file name="multiline.sass" hash="2f4ff6cfefa20eece2830170e29ea25e"/><file name="nested-media.css" hash="4fc2c8503b918fe9add9fcb230215fe2"/><file name="nested-media.scss" hash="2ee9901f1413f1f0839cfdc9b2ea00af"/><file name="nested.css" hash="26bd112a486652342cbfd55060552576"/><file name="nested.sass" hash="0bdc5d64efc02766544553f968bb82fd"/><file name="nested_bork1.sass" hash="56fa9072b6cc553909bfbd18f571a11d"/><file name="nested_bork2.sass" hash="999ae47bdbc6190972f0f52958870130"/><file name="nested_bork3.sass" hash="ccb998041d90cfe54a39f01afc4c4cc0"/><file name="nested_bork4.sass" hash="eed6453ea8564978c35d60f26a9bbb25"/><file name="nested_bork5.sass" hash="d6de98aee6d80aaecc1aa97311136003"/><file name="nested_import.css" hash="de8bc2a3cd89496c22ff564e65c2b046"/><file name="nested_import.sass" hash="b4493203dae52b5757ca91e17dd42e42"/><file name="nested_media.css" hash="d910a2026928133ce7235e8e1143a425"/><file name="nested_media.scss" hash="6e2dceddb572a0caa6f3959e00d332f4"/><file name="nested_mixin_bork.sass" hash="d9f57da9545e6c9a54d89bebe2f750b9"/><file name="nested_pseudo.css" hash="435b969153bc5030ceb8c251d241d358"/><file name="nested_pseudo.scss" hash="145d425a42541236d8952ea9f5e68ae7"/><file name="number.css" hash="000ca28603c30a49647d53bc5aabed94"/><file name="number.scss" hash="c585efaf419263809a1c91b76d8a0799"/><file name="opacity.css" hash="f54a7fbecddad66df7a6dae52bea4c21"/><file name="opacity.scss" hash="3a20a779e1becfcfaba90758d907c05e"/><file name="other-color.css" hash="45d9e1061d0e71b1c55362c2974b7bdf"/><file name="other-color.scss" hash="e2b8b86016461cbcdae6365ee14b0a5d"/><file name="parent_ref.css" hash="cbecced10861e9c060fa05187f94ee5f"/><file name="parent_ref.sass" hash="b5a3fe6fd3384b0853211e3515427796"/><file name="phpSassTest.php" hash="85b1d8fa19f923311ad45c00672a3a26"/><file name="phpunit.xml.dist" hash="3f11a2a97eb3d9b8bb48f60915daefda"/><file name="proprietary-selector.css" hash="6da7ab22184ed10ec679065835fc0f5f"/><file name="proprietary-selector.scss" hash="a7fa95fad2ae9aa0b93d8b49101eaf5f"/><file name="rgb-functions.css" hash="24177c2bc7b35526bf06334ea4174e27"/><file name="rgb-functions.scss" hash="7ad824885f782f15738ef67bbf00ae2a"/><file name="scss_import.css" hash="9eeec339e1ce59cbf3f2d29efab1382b"/><file name="scss_import.scss" hash="7ae409e52a06ad89582fe89063cf6bdd"/><file name="scss_importee.css" hash="7cad5194c7f7bb18e50f1ca093597033"/><file name="scss_importee.scss" hash="20c55fb516c7b137eadc6462f74cfa94"/><file name="splats.css" hash="3d11bc1d58858e4967ed498a3d75d008"/><file name="splats.scss" hash="4fab47d7391ff72a2e8d6de13c5e1b80"/><file name="string.css" hash="9f1482fe5b4964e96d24c00765c2503d"/><file name="string.scss" hash="f89f2aad48738bb1fa33a67f733e2e90"/><dir name="subdir"><dir name="nested_subdir"><file name="_nested_partial.sass" hash="24985866e9414ee4ef69621b738833ee"/><file name="nested_subdir.css" hash="759df6872a88c4174a39c32fe7d95a04"/><file name="nested_subdir.sass" hash="9e5e623f6765e28d5bec3bb2d3944eac"/></dir><file name="subdir.css" hash="ddd9dd41c2b72164a7ba634e359c2872"/><file name="subdir.sass" hash="acde24bd965d15ae3f19bf74b1f1c2a8"/></dir><file name="units.css" hash="ebc7390d227439bf2694a3ce29c54a6d"/><file name="units.sass" hash="040de247b027e6368c7edbc57d6e331f"/><file name="warn.css" hash="31c098880201803dc33c8785ecf3de26"/><file name="warn.sass" hash="47c7543a6a374523514669e108249f41"/><file name="warn_imported.sass" hash="2b7455acd686bf2511fce0b710874b01"/></dir><dir name="tree"><file name="SassCommentNode.php" hash="807249e546eb578d6087ed95e2f4e305"/><file name="SassContentNode.php" hash="2a20a58b2e1e43b82cac4cff908aa241"/><file name="SassContext.php" hash="4b7dc36ef0866a3678a0c53c5bb5a4b6"/><file name="SassDebugNode.php" hash="07c197af56822312088191a73e3225ff"/><file name="SassDirectiveNode.php" hash="813e62abcd27a49bbb2062e5a3e54acf"/><file name="SassEachNode.php" hash="c514b6b558faf12a5c56b233a9f4b01a"/><file name="SassElseNode.php" hash="1b5e603ccf2de0edfda2f7075e642dd2"/><file name="SassExtendNode.php" hash="d415ada9c7974775cc00de239ad8d8a2"/><file name="SassForNode.php" hash="9fc5364ce7a8c9557e26d62bd0aaeb59"/><file name="SassFunctionDefinitionNode.php" hash="67a5bf31c0e8f0225161f9ecdd61084e"/><file name="SassIfNode.php" hash="586e0ac2339af4e0836ee15168398801"/><file name="SassImportNode.php" hash="ea27128d9923cd0af8b7dae8b49edd69"/><file name="SassMediaNode.php" hash="8f88befb058bdb6f02c9f66bbca54b7a"/><file name="SassMixinDefinitionNode.php" hash="27fb3a6e0b141b8413ea657986950dcb"/><file name="SassMixinNode.php" hash="0112bd92ca1ddb3a180b28797bc8395b"/><file name="SassNode.php" hash="218a90269cb7f32ff47f94dee2af8b59"/><file name="SassNodeExceptions.php" hash="be582689b346f1ff54eba30d3e6550f5"/><file name="SassPropertyNode.php" hash="6186a8e35f8dd07c78c1f98f1aa13cd9"/><file name="SassReturnNode.php" hash="8218ceb0ed55b37c901d31952330d9c5"/><file name="SassRootNode.php" hash="5330f46536b9a7c8212b51516b35490a"/><file name="SassRuleNode.php" hash="3f3d01641155acdddd1322f3043b20dd"/><file name="SassVariableNode.php" hash="d15e503dd71000ae9100b473d1436f43"/><file name="SassWarnNode.php" hash="70875fe1e5d4e806def3d9b4984bb855"/><file name="SassWhileNode.php" hash="809afdba4213c5549dc7923125dbe10a"/></dir><file name=".travis.yml" hash="d0ac6ce1cf8465183941fa3ac326a54e"/></dir></target></contents>
21
  <compatible/>
22
  <dependencies><required><php><min>5.3.0</min><max>6.0.0</max></php></required></dependencies>
23
  </package>
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>Sass</name>
4
+ <version>1.2.0</version>
5
  <stability>stable</stability>
6
  <license uri="http://opensource.org/licenses/osl-3.0.php">Open Software License (OSL 3.0)</license>
7
  <channel>community</channel>
12
  You just need to create you sass file and add it to your layout like default css file.&#xD;
13
  &#xD;
14
  This extension will then convert it to css file using phpSass or sass in command line if available</description>
15
+ <notes>switch to leafo/scssphp library</notes>
 
16
  <authors><author><name>Laurent Clouet</name><user>laurent35240</user><email>laurent35240@gmail.com</email></author></authors>
17
+ <date>2015-05-16</date>
18
+ <time>10:55:51</time>
19
+ <contents><target name="magecommunity"><dir name="Laurent"><dir name="Sass"><dir name="Helper"><file name="Data.php" hash="49a578dba31df83e5f25b119b4177249"/></dir><dir name="Model"><dir name="Config"><file name="Style.php" hash="4595af950fa6be29fd31e368ff5889c3"/></dir><dir name="Design"><file name="Package.php" hash="9ad012e66d168bde93f48518aa82cdf4"/></dir></dir><dir name="etc"><file name="config.xml" hash="c28768982361d19279254d91fe1c0a3d"/><file name="system.xml" hash="a2db1af0d9bae017b46805a80aedb442"/></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Laurent_Sass.xml" hash="4ad004de851457681610553228973c30"/></dir></target><target name="magelocale"><dir name="en_US"><file name="Laurent_Sass.csv" hash="d9e8c184cbe72e810c7da9154581e1e4"/></dir><dir name="fr_FR"><file name="Laurent_Sass.csv" hash="676b2c597fe0b829fb2c48c1428c295f"/></dir></target><target name="magelib"><dir name="scssphp"><file name="LICENSE.md" hash="a5f85b275af63c75ebcafdd5f6f19e6c"/><file name="Makefile" hash="2a2ef5d8238c82336c9484942164674b"/><file name="README.md" hash="3d983076541e85b4167327d5ea0df9fd"/><dir name="bin"><file name="pscss" hash="05602e59f9ed664477703ac2c79f3ab7"/></dir><file name="classmap.php" hash="0aab4acb605d5b03ddfc289a77c2f3c8"/><file name="composer.json" hash="841a73f028f964077602db70bb8d8655"/><file name="package.sh" hash="37aa7c3c5856f8b3a3ae89566b68eea7"/><file name="phpunit.xml.dist" hash="ebb4627ec49f94ff5f9108a9867110d2"/><file name="scss.inc.php" hash="64053cc554a5f9f81316fef8e2b0cf43"/><dir name="site"><file name="composer.html" hash="66f5365cf467b41f6f7389fdf92e1aef"/><dir name="docs"><file name="index.md" hash="18458bed9657ae468da653f54da702f2"/></dir><file name="index.md" hash="81d090b68b69c55c8115dd9f6ad46885"/><file name="site.moon" hash="0b983aaba2b330f034fa81188559932f"/><file name="style.scss" hash="e36ffe6812770578aecb484b3e48c7d1"/><dir name="templates"><file name="index.html" hash="61a32877fe0b3f0b2afdfeebaae38ac6"/></dir><dir name="www"><dir name="img"><file name="tile.png" hash="69a17a59adb73a7cd9d2ecea2b38760e"/></dir><dir name="style"><file name="normalize.css" hash="19248e3a3d02f3371cf59057385be735"/></dir></dir></dir><dir name="src"><file name="Colors.php" hash="2d7392d62ab8931c3eed734c63b40701"/><file name="Compiler.php" hash="6361d3867110950f767ff462b5c8fb2b"/><dir name="Formatter"><file name="Compressed.php" hash="a46085cc42c10a8eae1fd4f40e12f3c9"/><file name="Crunched.php" hash="8fff6b15b47efa77b78278bf376a183f"/><file name="Expanded.php" hash="11864ce9971609970f17391f9add78b6"/><file name="Nested.php" hash="8a4d6a5fa9efd24ed001f848dcacb931"/></dir><file name="Formatter.php" hash="2f707858ba39e7a9366b29ca051c08d8"/><file name="Parser.php" hash="f1e2310435c1798de8fc4bba11795750"/><file name="Server.php" hash="44a8c4d6d6a3d59cb291288602606e54"/></dir><dir name="tests"><file name="ApiTest.php" hash="5f143263bc985e0ce8454d328be7194d"/><file name="ExceptionTest.php" hash="3ab1f6a49130a52acfae3d628ad56364"/><file name="InputTest.php" hash="b2c1d58af1c0f3758c3a5b48cb840702"/><file name="compare-scss.sh" hash="07f71046bd48a8e94059c78d60cf0483"/><dir name="inputs"><file name="builtins.scss" hash="0736b0e8bff23a9cf2e0f3ad24234bdc"/><file name="comments.scss" hash="4a8ec9fd27da4250ed1ff71c404b90bf"/><file name="compass_extract.scss" hash="ccc85bcd88b797ae3f928a31c4474816"/><file name="content.scss" hash="0e729ff6baf7b645288a3a755b3483f0"/><file name="content_with_function.scss" hash="f66aa9992ce1da064081e660ce596f6b"/><file name="default_args.scss" hash="5acdce6f293cce01416667a44b2932d3"/><file name="directives.scss" hash="c99fd3058c6ec1576cf2bb10e804b983"/><file name="extends.scss" hash="70d1d005785e263fe8db16c1f27743f4"/><file name="filter_effects.scss" hash="ab1e43957190ac21f423f09b39a4c373"/><file name="functions.scss" hash="6a867050708e012a49537fd411568857"/><file name="ie7.scss" hash="d81329c896816f7a8ab8f2be48d73792"/><file name="if.scss" hash="34355cf5c6f35feec07aad35f8f38292"/><file name="if_on_null.scss" hash="54ab0097dcb085b23ceaa1c19de5d31d"/><file name="import.scss" hash="c9d77a21acd60dc2e334f99060189a0b"/><dir name="imports"><file name="_partial.scss" hash="9c487a1b3be79d90fab92218ce11ec27"/><file name="simple.scss" hash="6763334861096cf85e4d5b7e9fbb137f"/></dir><file name="interpolation.scss" hash="66405bc6f7acf516d14840ae2d1d3598"/><file name="keyword_args.scss" hash="f53d216a6d7043d8fa7efb841cd02abb"/><file name="list.scss" hash="d98c67a9eb32053c387d9bdf967cabd0"/><file name="looping.scss" hash="530f9da5cca0c8e6b77ace8e5928f085"/><file name="media.scss" hash="02d3525f1c5bb1b154ce0e59574610af"/><file name="mixins.scss" hash="5c9d19a10699a811d1b62688358e95cd"/><file name="nesting.scss" hash="a25d03e262622d4ae0366625c9241d20"/><file name="null.scss" hash="04a0c624a31a6107d7d525c2f23b1ce6"/><file name="operators.scss" hash="daebfbf54fe6f88e782166709bcb0d52"/><file name="parsing_comments.scss" hash="dfee0633a6566ab2ca31d553d90bfe2b"/><file name="placeholder_selector.scss" hash="28fbc2b5c7d47eb2422d8b6dfbcec9ef"/><file name="scss_css.scss" hash="44d90092f84e84d5c09e280e062346bc"/><file name="selectors.scss" hash="ad2f85fe48aad9148c78166769765308"/><file name="values.scss" hash="1045b0a7e236e979e598f475aede9645"/><file name="variables.scss" hash="7742372a6fc6824e0fcb0fc667d2b3ed"/></dir><dir name="outputs"><file name="builtins.css" hash="1b860574aa7659cd74ae48b5285a8300"/><file name="comments.css" hash="dd1d7f108ff33ddad11b0b3a90879f64"/><file name="compass_extract.css" hash="c026d200e752c391fdb8487dc91f4927"/><file name="content.css" hash="45ddae35a7edebc8f09be7a936ed8b11"/><file name="content_with_function.css" hash="828e93e45a039a2155446c7b1a0a230a"/><file name="default_args.css" hash="e9f57363040ca2f4f6cf87bb8e502a15"/><file name="directives.css" hash="1e1ca4d240c93f006cf2a2e434c641d4"/><file name="extends.css" hash="6ac4f4e462d6e4c50df38c60c7867708"/><file name="filter_effects.css" hash="b3bc8c0c1ddbef46b1b488f81f649149"/><file name="functions.css" hash="8c673faf3c33ab399d58e143b0d69fc9"/><file name="ie7.css" hash="02705d6078ac648aae2beea0178d8f5a"/><file name="if.css" hash="5e07937e709296bdcfcee3a1325b6ba1"/><file name="if_on_null.css" hash="eb26bd69f0ab284d04ee47e8e716e072"/><file name="import.css" hash="2deefd3310f3bfa8443680cd4beddb79"/><file name="interpolation.css" hash="f718f5aa1a2f5cdc9d19cce01422d18a"/><file name="keyword_args.css" hash="e42b505f62f95a91b9935c211d5e9cae"/><file name="list.css" hash="e60adfffd42351576c70258f7966def1"/><file name="looping.css" hash="4cda4d402d70326060b1f093e9a6dfc3"/><file name="media.css" hash="1a086589245eb9a0f271503fb64651b0"/><file name="mixins.css" hash="635d7264c9203c9d18a42a26d7033186"/><file name="nesting.css" hash="7b373d9ab5965690648af65e7af0b74a"/><file name="null.css" hash="a513b01f2da11fb4b3a55eb7b51817f5"/><file name="operators.css" hash="92abba7301ddb0783199a2c04a239c96"/><file name="parsing_comments.css" hash="41f7e3c79e180990eea446d727d8b482"/><file name="placeholder_selector.css" hash="6bfe80651acce0461982dbafd59f4439"/><file name="scss_css.css" hash="a8c810b91fce8da032bdf05cd5abfbbc"/><file name="selectors.css" hash="b850ac49aeddee4c414095bd795c6772"/><file name="values.css" hash="fc4bae7cbe8d15eb1099f3dcb1a00183"/><file name="variables.css" hash="93829f2eef904cda5b0361336868efac"/></dir></dir><file name="todo" hash="f9831bfb5d9c1aec7989dc557104a379"/><file name=".travis.yml" hash="197ef7688643d31e1419f2f6d27353b6"/></dir></target></contents>
20
  <compatible/>
21
  <dependencies><required><php><min>5.3.0</min><max>6.0.0</max></php></required></dependencies>
22
  </package>