]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - extlib/HTMLPurifier/HTMLPurifier/CSSDefinition.php
Merge branch 'master' of git.gnu.io:gnu/gnu-social into mmn_fixes
[quix0rs-gnu-social.git] / extlib / HTMLPurifier / HTMLPurifier / CSSDefinition.php
1 <?php
2
3 /**
4  * Defines allowed CSS attributes and what their values are.
5  * @see HTMLPurifier_HTMLDefinition
6  */
7 class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
8 {
9
10     public $type = 'CSS';
11
12     /**
13      * Assoc array of attribute name to definition object.
14      * @type HTMLPurifier_AttrDef[]
15      */
16     public $info = array();
17
18     /**
19      * Constructs the info array.  The meat of this class.
20      * @param HTMLPurifier_Config $config
21      */
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')),
71                 new HTMLPurifier_AttrDef_CSS_URI()
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')),
120                     new HTMLPurifier_AttrDef_CSS_Color()
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')),
144                 new HTMLPurifier_AttrDef_CSS_Length()
145             )
146         );
147
148         $this->info['word-spacing'] = new HTMLPurifier_AttrDef_CSS_Composite(
149             array(
150                 new HTMLPurifier_AttrDef_Enum(array('normal')),
151                 new HTMLPurifier_AttrDef_CSS_Length()
152             )
153         );
154
155         $this->info['font-size'] = new HTMLPurifier_AttrDef_CSS_Composite(
156             array(
157                 new HTMLPurifier_AttrDef_Enum(
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                 ),
170                 new HTMLPurifier_AttrDef_CSS_Percentage(),
171                 new HTMLPurifier_AttrDef_CSS_Length()
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
179                 new HTMLPurifier_AttrDef_CSS_Length('0'),
180                 new HTMLPurifier_AttrDef_CSS_Percentage(true)
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(
190                     new HTMLPurifier_AttrDef_CSS_Length(),
191                     new HTMLPurifier_AttrDef_CSS_Percentage(),
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(
205                     new HTMLPurifier_AttrDef_CSS_Length('0'),
206                     new HTMLPurifier_AttrDef_CSS_Percentage(true)
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(
214                 new HTMLPurifier_AttrDef_CSS_Length(),
215                 new HTMLPurifier_AttrDef_CSS_Percentage()
216             )
217         );
218
219         $trusted_wh = new HTMLPurifier_AttrDef_CSS_Composite(
220             array(
221                 new HTMLPurifier_AttrDef_CSS_Length('0'),
222                 new HTMLPurifier_AttrDef_CSS_Percentage(true),
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 :
232                 new HTMLPurifier_AttrDef_Switch(
233                     'img',
234                     // For img tags:
235                     new HTMLPurifier_AttrDef_CSS_Composite(
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(
294                 new HTMLPurifier_AttrDef_Enum(
295                     array(
296                         'baseline',
297                         'sub',
298                         'super',
299                         'top',
300                         'text-top',
301                         'middle',
302                         'bottom',
303                         'text-bottom'
304                     )
305                 ),
306                 new HTMLPurifier_AttrDef_CSS_Length(),
307                 new HTMLPurifier_AttrDef_CSS_Percentage()
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
340     /**
341      * @param HTMLPurifier_Config $config
342      */
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         // vendor specific prefixes of opacity
354         $this->info['-moz-opacity'] = new HTMLPurifier_AttrDef_CSS_AlphaValue();
355         $this->info['-khtml-opacity'] = new HTMLPurifier_AttrDef_CSS_AlphaValue();
356
357         // only opacity, for now
358         $this->info['filter'] = new HTMLPurifier_AttrDef_CSS_Filter();
359
360         // more CSS3
361         $this->info['page-break-after'] =
362         $this->info['page-break-before'] = new HTMLPurifier_AttrDef_Enum(
363             array(
364                 'auto',
365                 'always',
366                 'avoid',
367                 'left',
368                 'right'
369             )
370         );
371         $this->info['page-break-inside'] = new HTMLPurifier_AttrDef_Enum(array('auto', 'avoid'));
372
373     }
374
375     /**
376      * @param HTMLPurifier_Config $config
377      */
378     protected function doSetupTricky($config)
379     {
380         $this->info['display'] = new HTMLPurifier_AttrDef_Enum(
381             array(
382                 'inline',
383                 'block',
384                 'list-item',
385                 'run-in',
386                 'compact',
387                 'marker',
388                 'table',
389                 'inline-block',
390                 'inline-table',
391                 'table-row-group',
392                 'table-header-group',
393                 'table-footer-group',
394                 'table-row',
395                 'table-column-group',
396                 'table-column',
397                 'table-cell',
398                 'table-caption',
399                 'none'
400             )
401         );
402         $this->info['visibility'] = new HTMLPurifier_AttrDef_Enum(
403             array('visible', 'hidden', 'collapse')
404         );
405         $this->info['overflow'] = new HTMLPurifier_AttrDef_Enum(array('visible', 'hidden', 'auto', 'scroll'));
406         $this->info['opacity'] = new HTMLPurifier_AttrDef_CSS_AlphaValue();
407     }
408
409     /**
410      * @param HTMLPurifier_Config $config
411      */
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(
422                 new HTMLPurifier_AttrDef_CSS_Length(),
423                 new HTMLPurifier_AttrDef_CSS_Percentage(),
424                 new HTMLPurifier_AttrDef_Enum(array('auto')),
425             )
426         );
427         $this->info['z-index'] = new HTMLPurifier_AttrDef_CSS_Composite(
428             array(
429                 new HTMLPurifier_AttrDef_Integer(),
430                 new HTMLPurifier_AttrDef_Enum(array('auto')),
431             )
432         );
433     }
434
435     /**
436      * Performs extra config-based processing. Based off of
437      * HTMLPurifier_HTMLDefinition.
438      * @param HTMLPurifier_Config $config
439      * @todo Refactor duplicate elements into common class (probably using
440      *       composition, not inheritance).
441      */
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