/** * Initialises a background style * * @param type $value The value of the style * @return array An array of background component. */ public static function init($value) { // colour - image - repeat - attachment - position $imageurl = null; if (preg_match('#url\\(([^\\)]+)\\)#', $value, $matches)) { $imageurl = trim($matches[1]); $value = str_replace($matches[1], '', $value); } $value = preg_replace('#\\s+#', ' ', $value); $bits = explode(' ', $value); $repeats = array('repeat', 'repeat-x', 'repeat-y', 'no-repeat', 'inherit'); $attachments = array('scroll', 'fixed', 'inherit'); $return = array(); $unknownbits = array(); if (count($bits) > 0 && css_is_colour(reset($bits))) { $return[] = new css_style_backgroundcolor('background-color', array_shift($bits)); } if (count($bits) > 0 && preg_match('#(none|inherit|url\\(\\))#', reset($bits))) { $image = array_shift($bits); if ($image == 'url()') { $image = "url({$imageurl})"; } $return[] = new css_style_backgroundimage('background-image', $image); } if (count($bits) > 0 && in_array(reset($bits), $repeats)) { $return[] = new css_style_backgroundrepeat('background-repeat', array_shift($bits)); } if (count($bits) > 0 && in_array(reset($bits), $attachments)) { // scroll , fixed, inherit $return[] = new css_style_backgroundattachment('background-attachment', array_shift($bits)); } if (count($bits) > 0) { $widthbits = array(); foreach ($bits as $bit) { if (in_array($bit, array('top', 'left', 'bottom', 'right', 'center')) || css_is_width($bit)) { $widthbits[] = $bit; } else { $unknownbits[] = $bit; } } $return[] = new css_style_backgroundposition('background-position', join(' ', $widthbits)); } if (count($unknownbits)) { foreach ($unknownbits as $bit) { if (css_is_colour($bit)) { $return[] = new css_style_backgroundcolor('background-color', $bit); } else { if (in_array($bit, $repeats)) { $return[] = new css_style_backgroundrepeat('background-repeat', $bit); } else { if (in_array($bit, $attachments)) { $return[] = new css_style_backgroundattachment('background-attachment', $bit); } } } } } return $return; }
/** * Test CSS colour matching */ public function test_css_is_colour() { // First lets test hex colours $this->assertTrue(css_is_colour('#123456')); $this->assertTrue(css_is_colour('#123')); $this->assertTrue(css_is_colour('#ABCDEF')); $this->assertTrue(css_is_colour('#ABC')); $this->assertTrue(css_is_colour('#abcdef')); $this->assertTrue(css_is_colour('#abc')); $this->assertTrue(css_is_colour('#aBcDeF')); $this->assertTrue(css_is_colour('#aBc')); $this->assertTrue(css_is_colour('#1a2Bc3')); $this->assertTrue(css_is_colour('#1Ac')); // Note the following two colour's arn't really colours but browsers process // them still. $this->assertTrue(css_is_colour('#A')); $this->assertTrue(css_is_colour('#12')); // Having four or five characters however are not valid colours and // browsers don't parse them. They need to fail so that broken CSS // stays broken after optimisation. $this->assertFalse(css_is_colour('#1234')); $this->assertFalse(css_is_colour('#12345')); $this->assertFalse(css_is_colour('#BCDEFG')); $this->assertFalse(css_is_colour('#')); $this->assertFalse(css_is_colour('#0000000')); $this->assertFalse(css_is_colour('#132-245')); $this->assertFalse(css_is_colour('#13 23 43')); $this->assertFalse(css_is_colour('123456')); // Next lets test real browser mapped colours $this->assertTrue(css_is_colour('black')); $this->assertTrue(css_is_colour('blue')); $this->assertTrue(css_is_colour('BLACK')); $this->assertTrue(css_is_colour('Black')); $this->assertTrue(css_is_colour('bLACK')); $this->assertTrue(css_is_colour('mediumaquamarine')); $this->assertTrue(css_is_colour('mediumAquamarine')); $this->assertFalse(css_is_colour('monkey')); $this->assertFalse(css_is_colour('')); $this->assertFalse(css_is_colour('not a colour')); // Next lets test rgb(a) colours $this->assertTrue(css_is_colour('rgb(255,255,255)')); $this->assertTrue(css_is_colour('rgb(0, 0, 0)')); $this->assertTrue(css_is_colour('RGB (255, 255 , 255)')); $this->assertTrue(css_is_colour('rgba(0,0,0,0)')); $this->assertTrue(css_is_colour('RGBA(255,255,255,1)')); $this->assertTrue(css_is_colour('rgbA(255,255,255,0.5)')); $this->assertFalse(css_is_colour('rgb(-255,-255,-255)')); $this->assertFalse(css_is_colour('rgb(256,-256,256)')); // Now lets test HSL colours $this->assertTrue(css_is_colour('hsl(0,0%,100%)')); $this->assertTrue(css_is_colour('hsl(180, 0%, 10%)')); $this->assertTrue(css_is_colour('hsl (360, 100% , 95%)')); // Finally test the special values $this->assertTrue(css_is_colour('inherit')); }
/** * Initialises a background style * * @param string $value The value of the style * @return array An array of background component. */ public static function init($value) { // colour - image - repeat - attachment - position $imageurl = null; if (preg_match('#url\\(([^\\)]+)\\)#', $value, $matches)) { $imageurl = trim($matches[1]); $value = str_replace($matches[1], '', $value); } // Switch out the brackets so that they don't get messed up when we explode $brackets = array(); $bracketcount = 0; while (preg_match('#\\([^\\)\\(]+\\)#', $value, $matches)) { $key = "##BRACKET-{$bracketcount}##"; $bracketcount++; $brackets[$key] = $matches[0]; $value = str_replace($matches[0], $key, $value); } $important = stripos($value, '!important') !== false; if ($important) { // Great some genius put !important in the background shorthand property $value = str_replace('!important', '', $value); } $value = preg_replace('#\\s+#', ' ', $value); $bits = explode(' ', $value); foreach ($bits as $key => $bit) { $bits[$key] = self::replace_bracket_placeholders($bit, $brackets); } unset($bracketcount); unset($brackets); $repeats = array('repeat', 'repeat-x', 'repeat-y', 'no-repeat', 'inherit'); $attachments = array('scroll', 'fixed', 'inherit'); $positions = array('top', 'left', 'bottom', 'right', 'center'); $return = array(); $unknownbits = array(); $color = self::NULL_VALUE; if (count($bits) > 0 && css_is_colour(reset($bits))) { $color = array_shift($bits); } $image = self::NULL_VALUE; if (count($bits) > 0 && preg_match('#^\\s*(none|inherit|url\\(\\))\\s*$#', reset($bits))) { $image = array_shift($bits); if ($image == 'url()') { $image = "url({$imageurl})"; } } $repeat = self::NULL_VALUE; if (count($bits) > 0 && in_array(reset($bits), $repeats)) { $repeat = array_shift($bits); } $attachment = self::NULL_VALUE; if (count($bits) > 0 && in_array(reset($bits), $attachments)) { // scroll , fixed, inherit $attachment = array_shift($bits); } $position = self::NULL_VALUE; if (count($bits) > 0) { $widthbits = array(); foreach ($bits as $bit) { if (in_array($bit, $positions) || css_is_width($bit)) { $widthbits[] = $bit; } else { $unknownbits[] = $bit; } } if (count($widthbits)) { $position = join(' ', $widthbits); } } if (count($unknownbits)) { foreach ($unknownbits as $bit) { $bit = trim($bit); if ($color === self::NULL_VALUE && css_is_colour($bit)) { $color = $bit; } else { if ($repeat === self::NULL_VALUE && in_array($bit, $repeats)) { $repeat = $bit; } else { if ($attachment === self::NULL_VALUE && in_array($bit, $attachments)) { $attachment = $bit; } else { if ($bit !== '') { $advanced = css_style_background_advanced::init($bit); if ($important) { $advanced->set_important(); } $return[] = $advanced; } } } } } } if ($color === self::NULL_VALUE && $image === self::NULL_VALUE && $repeat === self::NULL_VALUE && $attachment === self::NULL_VALUE && $position === self::NULL_VALUE) { // All primaries are null, return without doing anything else. There may be advanced madness there. return $return; } $return[] = new css_style_backgroundcolor('background-color', $color); $return[] = new css_style_backgroundimage('background-image', $image); $return[] = new css_style_backgroundrepeat('background-repeat', $repeat); $return[] = new css_style_backgroundattachment('background-attachment', $attachment); $return[] = new css_style_backgroundposition('background-position', $position); if ($important) { foreach ($return as $style) { $style->set_important(); } } return $return; }