ILIAS  Release_5_0_x_branch Revision 61816
 All Data Structures Namespaces Files Functions Variables Groups Pages
CSSDefinition.php
Go to the documentation of this file.
1 <?php
2 
8 {
9 
10  public $type = 'CSS';
11 
16  public $info = array();
17 
22  protected function doSetup($config)
23  {
24  $this->info['text-align'] = new HTMLPurifier_AttrDef_Enum(
25  array('left', 'right', 'center', 'justify'),
26  false
27  );
28 
29  $border_style =
30  $this->info['border-bottom-style'] =
31  $this->info['border-right-style'] =
32  $this->info['border-left-style'] =
33  $this->info['border-top-style'] = new HTMLPurifier_AttrDef_Enum(
34  array(
35  'none',
36  'hidden',
37  'dotted',
38  'dashed',
39  'solid',
40  'double',
41  'groove',
42  'ridge',
43  'inset',
44  'outset'
45  ),
46  false
47  );
48 
49  $this->info['border-style'] = new HTMLPurifier_AttrDef_CSS_Multiple($border_style);
50 
51  $this->info['clear'] = new HTMLPurifier_AttrDef_Enum(
52  array('none', 'left', 'right', 'both'),
53  false
54  );
55  $this->info['float'] = new HTMLPurifier_AttrDef_Enum(
56  array('none', 'left', 'right'),
57  false
58  );
59  $this->info['font-style'] = new HTMLPurifier_AttrDef_Enum(
60  array('normal', 'italic', 'oblique'),
61  false
62  );
63  $this->info['font-variant'] = new HTMLPurifier_AttrDef_Enum(
64  array('normal', 'small-caps'),
65  false
66  );
67 
68  $uri_or_none = new HTMLPurifier_AttrDef_CSS_Composite(
69  array(
70  new HTMLPurifier_AttrDef_Enum(array('none')),
72  )
73  );
74 
75  $this->info['list-style-position'] = new HTMLPurifier_AttrDef_Enum(
76  array('inside', 'outside'),
77  false
78  );
79  $this->info['list-style-type'] = new HTMLPurifier_AttrDef_Enum(
80  array(
81  'disc',
82  'circle',
83  'square',
84  'decimal',
85  'lower-roman',
86  'upper-roman',
87  'lower-alpha',
88  'upper-alpha',
89  'none'
90  ),
91  false
92  );
93  $this->info['list-style-image'] = $uri_or_none;
94 
95  $this->info['list-style'] = new HTMLPurifier_AttrDef_CSS_ListStyle($config);
96 
97  $this->info['text-transform'] = new HTMLPurifier_AttrDef_Enum(
98  array('capitalize', 'uppercase', 'lowercase', 'none'),
99  false
100  );
101  $this->info['color'] = new HTMLPurifier_AttrDef_CSS_Color();
102 
103  $this->info['background-image'] = $uri_or_none;
104  $this->info['background-repeat'] = new HTMLPurifier_AttrDef_Enum(
105  array('repeat', 'repeat-x', 'repeat-y', 'no-repeat')
106  );
107  $this->info['background-attachment'] = new HTMLPurifier_AttrDef_Enum(
108  array('scroll', 'fixed')
109  );
110  $this->info['background-position'] = new HTMLPurifier_AttrDef_CSS_BackgroundPosition();
111 
112  $border_color =
113  $this->info['border-top-color'] =
114  $this->info['border-bottom-color'] =
115  $this->info['border-left-color'] =
116  $this->info['border-right-color'] =
117  $this->info['background-color'] = new HTMLPurifier_AttrDef_CSS_Composite(
118  array(
119  new HTMLPurifier_AttrDef_Enum(array('transparent')),
121  )
122  );
123 
124  $this->info['background'] = new HTMLPurifier_AttrDef_CSS_Background($config);
125 
126  $this->info['border-color'] = new HTMLPurifier_AttrDef_CSS_Multiple($border_color);
127 
128  $border_width =
129  $this->info['border-top-width'] =
130  $this->info['border-bottom-width'] =
131  $this->info['border-left-width'] =
132  $this->info['border-right-width'] = new HTMLPurifier_AttrDef_CSS_Composite(
133  array(
134  new HTMLPurifier_AttrDef_Enum(array('thin', 'medium', 'thick')),
135  new HTMLPurifier_AttrDef_CSS_Length('0') //disallow negative
136  )
137  );
138 
139  $this->info['border-width'] = new HTMLPurifier_AttrDef_CSS_Multiple($border_width);
140 
141  $this->info['letter-spacing'] = new HTMLPurifier_AttrDef_CSS_Composite(
142  array(
143  new HTMLPurifier_AttrDef_Enum(array('normal')),
145  )
146  );
147 
148  $this->info['word-spacing'] = new HTMLPurifier_AttrDef_CSS_Composite(
149  array(
150  new HTMLPurifier_AttrDef_Enum(array('normal')),
152  )
153  );
154 
155  $this->info['font-size'] = new HTMLPurifier_AttrDef_CSS_Composite(
156  array(
158  array(
159  'xx-small',
160  'x-small',
161  'small',
162  'medium',
163  'large',
164  'x-large',
165  'xx-large',
166  'larger',
167  'smaller'
168  )
169  ),
172  )
173  );
174 
175  $this->info['line-height'] = new HTMLPurifier_AttrDef_CSS_Composite(
176  array(
177  new HTMLPurifier_AttrDef_Enum(array('normal')),
178  new HTMLPurifier_AttrDef_CSS_Number(true), // no negatives
181  )
182  );
183 
184  $margin =
185  $this->info['margin-top'] =
186  $this->info['margin-bottom'] =
187  $this->info['margin-left'] =
188  $this->info['margin-right'] = new HTMLPurifier_AttrDef_CSS_Composite(
189  array(
192  new HTMLPurifier_AttrDef_Enum(array('auto'))
193  )
194  );
195 
196  $this->info['margin'] = new HTMLPurifier_AttrDef_CSS_Multiple($margin);
197 
198  // non-negative
199  $padding =
200  $this->info['padding-top'] =
201  $this->info['padding-bottom'] =
202  $this->info['padding-left'] =
203  $this->info['padding-right'] = new HTMLPurifier_AttrDef_CSS_Composite(
204  array(
207  )
208  );
209 
210  $this->info['padding'] = new HTMLPurifier_AttrDef_CSS_Multiple($padding);
211 
212  $this->info['text-indent'] = new HTMLPurifier_AttrDef_CSS_Composite(
213  array(
216  )
217  );
218 
219  $trusted_wh = new HTMLPurifier_AttrDef_CSS_Composite(
220  array(
223  new HTMLPurifier_AttrDef_Enum(array('auto'))
224  )
225  );
226  $max = $config->get('CSS.MaxImgLength');
227 
228  $this->info['width'] =
229  $this->info['height'] =
230  $max === null ?
231  $trusted_wh :
233  'img',
234  // For img tags:
236  array(
237  new HTMLPurifier_AttrDef_CSS_Length('0', $max),
238  new HTMLPurifier_AttrDef_Enum(array('auto'))
239  )
240  ),
241  // For everyone else:
242  $trusted_wh
243  );
244 
245  $this->info['text-decoration'] = new HTMLPurifier_AttrDef_CSS_TextDecoration();
246 
247  $this->info['font-family'] = new HTMLPurifier_AttrDef_CSS_FontFamily();
248 
249  // this could use specialized code
250  $this->info['font-weight'] = new HTMLPurifier_AttrDef_Enum(
251  array(
252  'normal',
253  'bold',
254  'bolder',
255  'lighter',
256  '100',
257  '200',
258  '300',
259  '400',
260  '500',
261  '600',
262  '700',
263  '800',
264  '900'
265  ),
266  false
267  );
268 
269  // MUST be called after other font properties, as it references
270  // a CSSDefinition object
271  $this->info['font'] = new HTMLPurifier_AttrDef_CSS_Font($config);
272 
273  // same here
274  $this->info['border'] =
275  $this->info['border-bottom'] =
276  $this->info['border-top'] =
277  $this->info['border-left'] =
278  $this->info['border-right'] = new HTMLPurifier_AttrDef_CSS_Border($config);
279 
280  $this->info['border-collapse'] = new HTMLPurifier_AttrDef_Enum(
281  array('collapse', 'separate')
282  );
283 
284  $this->info['caption-side'] = new HTMLPurifier_AttrDef_Enum(
285  array('top', 'bottom')
286  );
287 
288  $this->info['table-layout'] = new HTMLPurifier_AttrDef_Enum(
289  array('auto', 'fixed')
290  );
291 
292  $this->info['vertical-align'] = new HTMLPurifier_AttrDef_CSS_Composite(
293  array(
295  array(
296  'baseline',
297  'sub',
298  'super',
299  'top',
300  'text-top',
301  'middle',
302  'bottom',
303  'text-bottom'
304  )
305  ),
308  )
309  );
310 
311  $this->info['border-spacing'] = new HTMLPurifier_AttrDef_CSS_Multiple(new HTMLPurifier_AttrDef_CSS_Length(), 2);
312 
313  // These CSS properties don't work on many browsers, but we live
314  // in THE FUTURE!
315  $this->info['white-space'] = new HTMLPurifier_AttrDef_Enum(
316  array('nowrap', 'normal', 'pre', 'pre-wrap', 'pre-line')
317  );
318 
319  if ($config->get('CSS.Proprietary')) {
320  $this->doSetupProprietary($config);
321  }
322 
323  if ($config->get('CSS.AllowTricky')) {
324  $this->doSetupTricky($config);
325  }
326 
327  if ($config->get('CSS.Trusted')) {
328  $this->doSetupTrusted($config);
329  }
330 
331  $allow_important = $config->get('CSS.AllowImportant');
332  // wrap all attr-defs with decorator that handles !important
333  foreach ($this->info as $k => $v) {
334  $this->info[$k] = new HTMLPurifier_AttrDef_CSS_ImportantDecorator($v, $allow_important);
335  }
336 
337  $this->setupConfigStuff($config);
338  }
339 
343  protected function doSetupProprietary($config)
344  {
345  // Internet Explorer only scrollbar colors
346  $this->info['scrollbar-arrow-color'] = new HTMLPurifier_AttrDef_CSS_Color();
347  $this->info['scrollbar-base-color'] = new HTMLPurifier_AttrDef_CSS_Color();
348  $this->info['scrollbar-darkshadow-color'] = new HTMLPurifier_AttrDef_CSS_Color();
349  $this->info['scrollbar-face-color'] = new HTMLPurifier_AttrDef_CSS_Color();
350  $this->info['scrollbar-highlight-color'] = new HTMLPurifier_AttrDef_CSS_Color();
351  $this->info['scrollbar-shadow-color'] = new HTMLPurifier_AttrDef_CSS_Color();
352 
353  // technically not proprietary, but CSS3, and no one supports it
354  $this->info['opacity'] = new HTMLPurifier_AttrDef_CSS_AlphaValue();
355  $this->info['-moz-opacity'] = new HTMLPurifier_AttrDef_CSS_AlphaValue();
356  $this->info['-khtml-opacity'] = new HTMLPurifier_AttrDef_CSS_AlphaValue();
357 
358  // only opacity, for now
359  $this->info['filter'] = new HTMLPurifier_AttrDef_CSS_Filter();
360 
361  // more CSS3
362  $this->info['page-break-after'] =
363  $this->info['page-break-before'] = new HTMLPurifier_AttrDef_Enum(
364  array(
365  'auto',
366  'always',
367  'avoid',
368  'left',
369  'right'
370  )
371  );
372  $this->info['page-break-inside'] = new HTMLPurifier_AttrDef_Enum(array('auto', 'avoid'));
373 
374  }
375 
379  protected function doSetupTricky($config)
380  {
381  $this->info['display'] = new HTMLPurifier_AttrDef_Enum(
382  array(
383  'inline',
384  'block',
385  'list-item',
386  'run-in',
387  'compact',
388  'marker',
389  'table',
390  'inline-block',
391  'inline-table',
392  'table-row-group',
393  'table-header-group',
394  'table-footer-group',
395  'table-row',
396  'table-column-group',
397  'table-column',
398  'table-cell',
399  'table-caption',
400  'none'
401  )
402  );
403  $this->info['visibility'] = new HTMLPurifier_AttrDef_Enum(
404  array('visible', 'hidden', 'collapse')
405  );
406  $this->info['overflow'] = new HTMLPurifier_AttrDef_Enum(array('visible', 'hidden', 'auto', 'scroll'));
407  }
408 
412  protected function doSetupTrusted($config)
413  {
414  $this->info['position'] = new HTMLPurifier_AttrDef_Enum(
415  array('static', 'relative', 'absolute', 'fixed')
416  );
417  $this->info['top'] =
418  $this->info['left'] =
419  $this->info['right'] =
420  $this->info['bottom'] = new HTMLPurifier_AttrDef_CSS_Composite(
421  array(
424  new HTMLPurifier_AttrDef_Enum(array('auto')),
425  )
426  );
427  $this->info['z-index'] = new HTMLPurifier_AttrDef_CSS_Composite(
428  array(
430  new HTMLPurifier_AttrDef_Enum(array('auto')),
431  )
432  );
433  }
434 
442  protected function setupConfigStuff($config)
443  {
444  // setup allowed elements
445  $support = "(for information on implementing this, see the " .
446  "support forums) ";
447  $allowed_properties = $config->get('CSS.AllowedProperties');
448  if ($allowed_properties !== null) {
449  foreach ($this->info as $name => $d) {
450  if (!isset($allowed_properties[$name])) {
451  unset($this->info[$name]);
452  }
453  unset($allowed_properties[$name]);
454  }
455  // emit errors
456  foreach ($allowed_properties as $name => $d) {
457  // :TODO: Is this htmlspecialchars() call really necessary?
458  $name = htmlspecialchars($name);
459  trigger_error("Style attribute '$name' is not supported $support", E_USER_WARNING);
460  }
461  }
462 
463  $forbidden_properties = $config->get('CSS.ForbiddenProperties');
464  if ($forbidden_properties !== null) {
465  foreach ($this->info as $name => $d) {
466  if (isset($forbidden_properties[$name])) {
467  unset($this->info[$name]);
468  }
469  }
470  }
471  }
472 }
473 
474 // vim: et sw=4 sts=4