00001 <?php
00002
00006 class HTMLPurifier_AttrDef_CSS_Font extends HTMLPurifier_AttrDef
00007 {
00008
00017 protected $info = array();
00018
00019 public function __construct($config) {
00020 $def = $config->getCSSDefinition();
00021 $this->info['font-style'] = $def->info['font-style'];
00022 $this->info['font-variant'] = $def->info['font-variant'];
00023 $this->info['font-weight'] = $def->info['font-weight'];
00024 $this->info['font-size'] = $def->info['font-size'];
00025 $this->info['line-height'] = $def->info['line-height'];
00026 $this->info['font-family'] = $def->info['font-family'];
00027 }
00028
00029 public function validate($string, $config, $context) {
00030
00031 static $system_fonts = array(
00032 'caption' => true,
00033 'icon' => true,
00034 'menu' => true,
00035 'message-box' => true,
00036 'small-caption' => true,
00037 'status-bar' => true
00038 );
00039
00040
00041 $string = $this->parseCDATA($string);
00042 if ($string === '') return false;
00043
00044
00045 $lowercase_string = strtolower($string);
00046 if (isset($system_fonts[$lowercase_string])) {
00047 return $lowercase_string;
00048 }
00049
00050 $bits = explode(' ', $string);
00051 $stage = 0;
00052 $caught = array();
00053 $stage_1 = array('font-style', 'font-variant', 'font-weight');
00054 $final = '';
00055
00056 for ($i = 0, $size = count($bits); $i < $size; $i++) {
00057 if ($bits[$i] === '') continue;
00058 switch ($stage) {
00059
00060
00061 case 0:
00062 foreach ($stage_1 as $validator_name) {
00063 if (isset($caught[$validator_name])) continue;
00064 $r = $this->info[$validator_name]->validate(
00065 $bits[$i], $config, $context);
00066 if ($r !== false) {
00067 $final .= $r . ' ';
00068 $caught[$validator_name] = true;
00069 break;
00070 }
00071 }
00072
00073 if (count($caught) >= 3) $stage = 1;
00074 if ($r !== false) break;
00075
00076
00077 case 1:
00078 $found_slash = false;
00079 if (strpos($bits[$i], '/') !== false) {
00080 list($font_size, $line_height) =
00081 explode('/', $bits[$i]);
00082 if ($line_height === '') {
00083
00084 $line_height = false;
00085 $found_slash = true;
00086 }
00087 } else {
00088 $font_size = $bits[$i];
00089 $line_height = false;
00090 }
00091 $r = $this->info['font-size']->validate(
00092 $font_size, $config, $context);
00093 if ($r !== false) {
00094 $final .= $r;
00095
00096 if ($line_height === false) {
00097
00098 for ($j = $i + 1; $j < $size; $j++) {
00099 if ($bits[$j] === '') continue;
00100 if ($bits[$j] === '/') {
00101 if ($found_slash) {
00102 return false;
00103 } else {
00104 $found_slash = true;
00105 continue;
00106 }
00107 }
00108 $line_height = $bits[$j];
00109 break;
00110 }
00111 } else {
00112
00113 $found_slash = true;
00114 $j = $i;
00115 }
00116 if ($found_slash) {
00117 $i = $j;
00118 $r = $this->info['line-height']->validate(
00119 $line_height, $config, $context);
00120 if ($r !== false) {
00121 $final .= '/' . $r;
00122 }
00123 }
00124 $final .= ' ';
00125 $stage = 2;
00126 break;
00127 }
00128 return false;
00129
00130
00131 case 2:
00132 $font_family =
00133 implode(' ', array_slice($bits, $i, $size - $i));
00134 $r = $this->info['font-family']->validate(
00135 $font_family, $config, $context);
00136 if ($r !== false) {
00137 $final .= $r . ' ';
00138
00139 return rtrim($final);
00140 }
00141 return false;
00142 }
00143 }
00144 return false;
00145 }
00146
00147 }
00148