View source
<?php
class CompassList extends SassLiteral {
public function __construct($values) {
$this->value = $values;
}
public function getValues() {
return $this->value;
}
protected function getTypeOf() {
return 'list';
}
public function toString() {
$values = array();
foreach ($this->value as $value) {
$values[] = $value
->toString();
}
return join(', ', $values);
}
public static function isa($subject) {
}
}
class CompassColourStop extends SassLiteral {
private $colour;
public $stop;
public function __construct($colour, $stop = null) {
$this->colour = $colour;
$this->stop = $stop;
}
protected function getColor() {
return $this
->getColour();
}
protected function getColour() {
return $this->colour;
}
public function toString() {
$s = $this->colour
->toString();
if (!empty($this->stop)) {
$s .= ' ';
if ($this->stop
->isUnitless()) {
$s .= $this->stop
->op_times(new SassNumber('100%'))
->toString();
}
else {
$s .= $this->stop
->toString();
}
}
return $s;
}
public static function isa($subject) {
}
}
class SassExtentionsCompassFunctionsColourStops {
public static function grad_color_stops($colour_list) {
return self::grad_colour_stops($colour_list);
}
public static function grad_colour_stops($colour_list) {
SassLiteral::assertType($colour_list, 'CompassList');
self::normalize_stops($colour_list);
$v = array_reverse($colour_list->values);
$max = $v[0]->stop;
$last_value = null;
$colourStops = array();
foreach ($colour_list->values as $pos) {
$stop = $pos->stop;
if ($stop->numeratorUnits === $max->numeratorUnits) {
$stop = $stop
->op_div($max)
->op_times(new SassNumber('100%'));
}
if ($last_value && $last_value->value > $stop->value) {
throw new SassScriptFunctionException('Colour stops must be specified in increasing order', array(), SassScriptParser::$context->node);
}
$last_value = $stop;
$colourStops[] = "color-stop({$stop->toString()}, {$pos->colour->toString()})";
}
return new SassString(join(', ', $colourStops));
}
public static function grad_end_position($colourList, $radial = null) {
SassLiteral::assertType($colourList, 'CompassList');
if (is_null($radial)) {
$radial = new SassBoolean(false);
}
else {
SassLiteral::assertType($radial, 'SassBoolean');
}
return self::grad_position($colourList, new SassNumber(sizeof($colourList->values)), new SassNumber(100), $radial);
}
public static function grad_position($colourList, $index, $default, $radial = null) {
SassLiteral::assertType($colourList, 'CompassList');
if (is_null($radial)) {
$radial = new SassBoolean(false);
}
else {
SassLiteral::assertType($radial, 'SassBoolean');
}
$stop = $colourList->values[$index->value - 1]->stop;
if ($stop && $radial->value) {
$orig_stop = $stop;
if ($stop
->isUnitless()) {
if ($stop->value <= 1) {
$stop = $stop
->op_times(new SassNumber('100%'));
}
else {
$stop = $stop
->op_times(new SassNumber('1px'));
}
}
if ($stop->numeratorUnits === '%' && isset($colourList->values[sizeof($colourList->values) - 1]->stop) && $colourList->values[sizeof($colourList->values) - 1]->stop->numeratorUnits === 'px') {
$stop = $stop
->op_times($colourList->values[sizeof($colourList->values) - 1]->stop)
->op_div(new SassNumber('100%'));
}
return $stop
->op_div(new SassNumber('1' . $stop->units));
}
elseif ($stop) {
return $stop;
}
else {
return $default;
}
}
public static function grad_point($position) {
$position = $position->value;
if (strpos($position, ' ') !== false) {
if (preg_match('/(top|bottom|center) (left|right|center)/', $position, $matches)) {
$position = "{$matches[2]} {$matches[1]}";
}
}
else {
switch ($position) {
case 'top':
case 'bottom':
$position = "left {$position}";
break;
case 'left':
case 'right':
$position .= ' top';
break;
}
}
return new SassString(preg_replace(array(
'/top/',
'/bottom/',
'/left/',
'/right/',
'/center/',
), array(
'0%',
'100%',
'0%',
'100%',
'50%',
), $position));
}
public static function color_stops() {
$args = func_get_args();
return call_user_func_array(array(
'SassExtentionsCompassFunctionsColourStops',
'colour_stops',
), $args);
}
public static function colour_stops() {
$args = func_get_args();
$list = array();
foreach ($args as $arg) {
if ($arg instanceof SassColour) {
$list[] = new CompassColourStop($arg);
}
elseif ($arg instanceof SassString) {
$colour = $stop = null;
if (empty($parser)) {
$parser = new SassScriptParser();
}
$expr = $parser
->parse($arg->value, SassScriptParser::$context);
$x = array_pop($expr);
if ($x instanceof SassColour) {
$colour = $x;
}
elseif ($x instanceof SassScriptOperation) {
if ($x->operator != 'concat') {
throw new SassScriptFunctionException("Couldn't parse a colour stop from: {value}", array(
'{value}' => $arg->value,
), SassScriptParser::$context->node);
}
$colour = $expr[0];
$stop = $expr[1];
}
else {
throw new SassScriptFunctionException("Couldn't parse a colour stop from: {value}", array(
'{value}' => $arg->value,
), SassScriptParser::$context->node);
}
$list[] = new CompassColourStop($colour, $stop);
}
else {
throw new SassScriptFunctionException('Not a valid color stop: {arg}', array(
'{arg}' => $arg->value,
), SassScriptParser::$context->node);
}
}
return new CompassList($list);
}
private static function normalize_stops($colourList) {
$positions = $colourList->values;
$s = sizeof($positions);
if (empty($positions[0]->stop)) {
$positions[0]->stop = new SassNumber(0);
}
if (empty($positions[$s - 1]->stop)) {
$positions[$s - 1]->stop = new SassNumber('100%');
}
for ($i = 0; $i < $s; $i++) {
if (is_null($positions[$i]->stop)) {
$num = 2;
for ($j = $i + 1; $j < $s; $j++) {
if (isset($positions[$j]->stop)) {
$positions[$i]->stop = $positions[$i - 1]->stop
->op_plus($positions[$j]->stop
->op_minus($positions[$i - 1]->stop))
->op_div(new SassNumber($num));
break;
}
else {
$num += 1;
}
}
}
}
foreach ($positions as &$pos) {
if ($pos->stop
->isUnitless()) {
$pos->stop = $pos->stop->value <= 1 ? $pos->stop
->op_times(new SassNumber('100%')) : $pos->stop
->op_times(new SassNumber('1px'));
}
}
if ($positions[$s - 1]->stop
->op_eq(new SassNumber('0px'))
->toBoolean() || $positions[$s - 1]->stop
->op_eq(new SassNumber('0%'))
->toBoolean()) {
throw new SassScriptFunctionException('Colour stops must be specified in increasing order', array(), SassScriptParser::$context->node);
}
return null;
}
}