Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 4.0.x will end 8 May 2023 (12 months).
  • Bug fixes for security issues in 4.0.x will end 13 November 2023 (18 months).
  • PHP version: minimum PHP 7.3.0 Note: the minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is also supported.

Differences Between: [Versions 400 and 401] [Versions 400 and 402] [Versions 400 and 403]

   1  <?php
   2  
   3  namespace Sabberworm\CSS\Value;
   4  
   5  use Sabberworm\CSS\Parsing\ParserState;
   6  
   7  class Size extends PrimitiveValue {
   8  
   9  	 const ABSOLUTE_SIZE_UNITS = 'px/cm/mm/mozmm/in/pt/pc/vh/vw/vm/vmin/vmax/rem'; //vh/vw/vm(ax)/vmin/rem are absolute insofar as they don’t scale to the immediate parent (only the viewport)
  10  	 const RELATIVE_SIZE_UNITS = '%/em/ex/ch/fr';
  11  	 const NON_SIZE_UNITS = 'deg/grad/rad/s/ms/turns/Hz/kHz';
  12  
  13  	 private static $SIZE_UNITS = null;
  14  
  15  	 private $fSize;
  16  	 private $sUnit;
  17  	 private $bIsColorComponent;
  18  
  19  	public function __construct($fSize, $sUnit = null, $bIsColorComponent = false, $iLineNo = 0) {
  20  	 	 parent::__construct($iLineNo);
  21  	 	 $this->fSize = floatval($fSize);
  22  	 	 $this->sUnit = $sUnit;
  23  	 	 $this->bIsColorComponent = $bIsColorComponent;
  24  	 }
  25  
  26  	public static function parse(ParserState $oParserState, $bIsColorComponent = false) {
  27  	 	 $sSize = '';
  28  	 	 if ($oParserState->comes('-')) {
  29  	 	 	 $sSize .= $oParserState->consume('-');
  30  	 	 }
  31  	 	 while (is_numeric($oParserState->peek()) || $oParserState->comes('.')) {
  32  	 	 	 if ($oParserState->comes('.')) {
  33  	 	 	 	 $sSize .= $oParserState->consume('.');
  34  	 	 	 } else {
  35  	 	 	 	 $sSize .= $oParserState->consume(1);
  36  	 	 	 }
  37  	 	 }
  38  
  39  	 	 $sUnit = null;
  40  	 	 $aSizeUnits = self::getSizeUnits();
  41  	 	 foreach($aSizeUnits as $iLength => &$aValues) {
  42  	 	 	 $sKey = strtolower($oParserState->peek($iLength));
  43  	 	 	 if(array_key_exists($sKey, $aValues)) {
  44  	 	 	 	 if (($sUnit = $aValues[$sKey]) !== null) {
  45  	 	 	 	 	 $oParserState->consume($iLength);
  46  	 	 	 	 	 break;
  47  	 	 	 	 }
  48  	 	 	 }
  49  	 	 }
  50  	 	 return new Size(floatval($sSize), $sUnit, $bIsColorComponent, $oParserState->currentLine());
  51  	 }
  52  
  53  	private static function getSizeUnits() {
  54  	 	 if(self::$SIZE_UNITS === null) {
  55  	 	 	 self::$SIZE_UNITS = array();
  56  	 	 	 foreach (explode('/', Size::ABSOLUTE_SIZE_UNITS.'/'.Size::RELATIVE_SIZE_UNITS.'/'.Size::NON_SIZE_UNITS) as $val) {
  57  	 	 	 	 $iSize = strlen($val);
  58  	 	 	 	 if(!isset(self::$SIZE_UNITS[$iSize])) {
  59  	 	 	 	 	 self::$SIZE_UNITS[$iSize] = array();
  60  	 	 	 	 }
  61  	 	 	 	 self::$SIZE_UNITS[$iSize][strtolower($val)] = $val;
  62  	 	 	 }
  63  
  64  	 	 	 // FIXME: Should we not order the longest units first?
  65  	 	 	 ksort(self::$SIZE_UNITS, SORT_NUMERIC);
  66  	 	 }
  67  
  68  	 	 return self::$SIZE_UNITS;
  69  	 }
  70  
  71  	public function setUnit($sUnit) {
  72  	 	 $this->sUnit = $sUnit;
  73  	 }
  74  
  75  	public function getUnit() {
  76  	 	 return $this->sUnit;
  77  	 }
  78  
  79  	public function setSize($fSize) {
  80  	 	 $this->fSize = floatval($fSize);
  81  	 }
  82  
  83  	public function getSize() {
  84  	 	 return $this->fSize;
  85  	 }
  86  
  87  	public function isColorComponent() {
  88  	 	 return $this->bIsColorComponent;
  89  	 }
  90  
  91  	 /**
  92  	  * Returns whether the number stored in this Size really represents a size (as in a length of something on screen).
  93  	  * @return false if the unit an angle, a duration, a frequency or the number is a component in a Color object.
  94  	  */
  95  	public function isSize() {
  96  	 	 if (in_array($this->sUnit, explode('/', self::NON_SIZE_UNITS))) {
  97  	 	 	 return false;
  98  	 	 }
  99  	 	 return !$this->isColorComponent();
 100  	 }
 101  
 102  	public function isRelative() {
 103  	 	 if (in_array($this->sUnit, explode('/', self::RELATIVE_SIZE_UNITS))) {
 104  	 	 	 return true;
 105  	 	 }
 106  	 	 if ($this->sUnit === null && $this->fSize != 0) {
 107  	 	 	 return true;
 108  	 	 }
 109  	 	 return false;
 110  	 }
 111  
 112  	public function __toString() {
 113  	 	 return $this->render(new \Sabberworm\CSS\OutputFormat());
 114  	 }
 115  
 116  	public function render(\Sabberworm\CSS\OutputFormat $oOutputFormat) {
 117  	 	 $l = localeconv();
 118  	 	 $sPoint = preg_quote($l['decimal_point'], '/');
 119  	 	 return preg_replace(array("/$sPoint/", "/^(-?)0\./"), array('.', '$1.'), $this->fSize) . ($this->sUnit === null ? '' : $this->sUnit);
 120  	 }
 121  
 122  }