4 * Validates shorthand CSS property font.
6 class HTMLPurifier_AttrDef_CSS_Font extends HTMLPurifier_AttrDef
10 * Local copy of validators
11 * @type HTMLPurifier_AttrDef[]
12 * @note If we moved specific CSS property definitions to their own
13 * classes instead of having them be assembled at run time by
14 * CSSDefinition, this wouldn't be necessary. We'd instantiate
17 protected $info = array();
20 * @param HTMLPurifier_Config $config
22 public function __construct($config)
24 $def = $config->getCSSDefinition();
25 $this->info['font-style'] = $def->info['font-style'];
26 $this->info['font-variant'] = $def->info['font-variant'];
27 $this->info['font-weight'] = $def->info['font-weight'];
28 $this->info['font-size'] = $def->info['font-size'];
29 $this->info['line-height'] = $def->info['line-height'];
30 $this->info['font-family'] = $def->info['font-family'];
34 * @param string $string
35 * @param HTMLPurifier_Config $config
36 * @param HTMLPurifier_Context $context
39 public function validate($string, $config, $context)
41 static $system_fonts = array(
45 'message-box' => true,
46 'small-caption' => true,
50 // regular pre-processing
51 $string = $this->parseCDATA($string);
56 // check if it's one of the keywords
57 $lowercase_string = strtolower($string);
58 if (isset($system_fonts[$lowercase_string])) {
59 return $lowercase_string;
62 $bits = explode(' ', $string); // bits to process
63 $stage = 0; // this indicates what we're looking for
64 $caught = array(); // which stage 0 properties have we caught?
65 $stage_1 = array('font-style', 'font-variant', 'font-weight');
66 $final = ''; // output
68 for ($i = 0, $size = count($bits); $i < $size; $i++) {
69 if ($bits[$i] === '') {
73 case 0: // attempting to catch font-style, font-variant or font-weight
74 foreach ($stage_1 as $validator_name) {
75 if (isset($caught[$validator_name])) {
78 $r = $this->info[$validator_name]->validate(
85 $caught[$validator_name] = true;
89 // all three caught, continue on
90 if (count($caught) >= 3) {
96 case 1: // attempting to catch font-size and perhaps line-height
98 if (strpos($bits[$i], '/') !== false) {
99 list($font_size, $line_height) =
100 explode('/', $bits[$i]);
101 if ($line_height === '') {
102 // ooh, there's a space after the slash!
103 $line_height = false;
107 $font_size = $bits[$i];
108 $line_height = false;
110 $r = $this->info['font-size']->validate(
117 // attempt to catch line-height
118 if ($line_height === false) {
119 // we need to scroll forward
120 for ($j = $i + 1; $j < $size; $j++) {
121 if ($bits[$j] === '') {
124 if ($bits[$j] === '/') {
132 $line_height = $bits[$j];
136 // slash already found
142 $r = $this->info['line-height']->validate(
156 case 2: // attempting to catch font-family
158 implode(' ', array_slice($bits, $i, $size - $i));
159 $r = $this->info['font-family']->validate(
166 // processing completed successfully
167 return rtrim($final);
176 // vim: et sw=4 sts=4