1: | <?php
|
2: |
|
3: | |
4: | |
5: |
|
6: | class HTMLPurifier_AttrDef_CSS_Font extends HTMLPurifier_AttrDef
|
7: | {
|
8: |
|
9: | |
10: | |
11: | |
12: | |
13: | |
14: | |
15: | |
16: |
|
17: | protected $info = array();
|
18: |
|
19: | |
20: | |
21: |
|
22: | public function __construct($config)
|
23: | {
|
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'];
|
31: | }
|
32: |
|
33: | |
34: | |
35: | |
36: | |
37: | |
38: |
|
39: | public function validate($string, $config, $context)
|
40: | {
|
41: | static $system_fonts = array(
|
42: | 'caption' => true,
|
43: | 'icon' => true,
|
44: | 'menu' => true,
|
45: | 'message-box' => true,
|
46: | 'small-caption' => true,
|
47: | 'status-bar' => true
|
48: | );
|
49: |
|
50: |
|
51: | $string = $this->parseCDATA($string);
|
52: | if ($string === '') {
|
53: | return false;
|
54: | }
|
55: |
|
56: |
|
57: | $lowercase_string = strtolower($string);
|
58: | if (isset($system_fonts[$lowercase_string])) {
|
59: | return $lowercase_string;
|
60: | }
|
61: |
|
62: | $bits = explode(' ', $string);
|
63: | $stage = 0;
|
64: | $caught = array();
|
65: | $stage_1 = array('font-style', 'font-variant', 'font-weight');
|
66: | $final = '';
|
67: |
|
68: | for ($i = 0, $size = count($bits); $i < $size; $i++) {
|
69: | if ($bits[$i] === '') {
|
70: | continue;
|
71: | }
|
72: | switch ($stage) {
|
73: | case 0:
|
74: | foreach ($stage_1 as $validator_name) {
|
75: | if (isset($caught[$validator_name])) {
|
76: | continue;
|
77: | }
|
78: | $r = $this->info[$validator_name]->validate(
|
79: | $bits[$i],
|
80: | $config,
|
81: | $context
|
82: | );
|
83: | if ($r !== false) {
|
84: | $final .= $r . ' ';
|
85: | $caught[$validator_name] = true;
|
86: | break;
|
87: | }
|
88: | }
|
89: |
|
90: | if (count($caught) >= 3) {
|
91: | $stage = 1;
|
92: | }
|
93: | if ($r !== false) {
|
94: | break;
|
95: | }
|
96: | case 1:
|
97: | $found_slash = false;
|
98: | if (strpos($bits[$i], '/') !== false) {
|
99: | list($font_size, $line_height) =
|
100: | explode('/', $bits[$i]);
|
101: | if ($line_height === '') {
|
102: |
|
103: | $line_height = false;
|
104: | $found_slash = true;
|
105: | }
|
106: | } else {
|
107: | $font_size = $bits[$i];
|
108: | $line_height = false;
|
109: | }
|
110: | $r = $this->info['font-size']->validate(
|
111: | $font_size,
|
112: | $config,
|
113: | $context
|
114: | );
|
115: | if ($r !== false) {
|
116: | $final .= $r;
|
117: |
|
118: | if ($line_height === false) {
|
119: |
|
120: | for ($j = $i + 1; $j < $size; $j++) {
|
121: | if ($bits[$j] === '') {
|
122: | continue;
|
123: | }
|
124: | if ($bits[$j] === '/') {
|
125: | if ($found_slash) {
|
126: | return false;
|
127: | } else {
|
128: | $found_slash = true;
|
129: | continue;
|
130: | }
|
131: | }
|
132: | $line_height = $bits[$j];
|
133: | break;
|
134: | }
|
135: | } else {
|
136: |
|
137: | $found_slash = true;
|
138: | $j = $i;
|
139: | }
|
140: | if ($found_slash) {
|
141: | $i = $j;
|
142: | $r = $this->info['line-height']->validate(
|
143: | $line_height,
|
144: | $config,
|
145: | $context
|
146: | );
|
147: | if ($r !== false) {
|
148: | $final .= '/' . $r;
|
149: | }
|
150: | }
|
151: | $final .= ' ';
|
152: | $stage = 2;
|
153: | break;
|
154: | }
|
155: | return false;
|
156: | case 2:
|
157: | $font_family =
|
158: | implode(' ', array_slice($bits, $i, $size - $i));
|
159: | $r = $this->info['font-family']->validate(
|
160: | $font_family,
|
161: | $config,
|
162: | $context
|
163: | );
|
164: | if ($r !== false) {
|
165: | $final .= $r . ' ';
|
166: |
|
167: | return rtrim($final);
|
168: | }
|
169: | return false;
|
170: | }
|
171: | }
|
172: | return false;
|
173: | }
|
174: | }
|
175: |
|
176: |
|
177: | |