HTMLPurifier_CSSDefinition::doSetup()   C
last analyzed

Complexity

Conditions 8
Paths 128

Size

Total Lines 394
Code Lines 237

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 8
eloc 237
nc 128
nop 1
dl 0
loc 394
rs 6.5688
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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 = [];
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
            ['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
                [
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
            ['none', 'left', 'right', 'both'],
53
            false
54
        );
55
        $this->info['float'] = new HTMLPurifier_AttrDef_Enum(
56
            ['none', 'left', 'right'],
57
            false
58
        );
59
        $this->info['font-style'] = new HTMLPurifier_AttrDef_Enum(
60
            ['normal', 'italic', 'oblique'],
61
            false
62
        );
63
        $this->info['font-variant'] = new HTMLPurifier_AttrDef_Enum(
64
            ['normal', 'small-caps'],
65
            false
66
        );
67
68
        $uri_or_none = new HTMLPurifier_AttrDef_CSS_Composite(
69
            [
70
                new HTMLPurifier_AttrDef_Enum(['none']),
71
                new HTMLPurifier_AttrDef_CSS_URI()
72
            ]
73
        );
74
75
        $this->info['list-style-position'] = new HTMLPurifier_AttrDef_Enum(
76
            ['inside', 'outside'],
77
            false
78
        );
79
        $this->info['list-style-type'] = new HTMLPurifier_AttrDef_Enum(
80
            [
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
            ['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
            ['repeat', 'repeat-x', 'repeat-y', 'no-repeat']
106
        );
107
        $this->info['background-attachment'] = new HTMLPurifier_AttrDef_Enum(
108
            ['scroll', 'fixed']
109
        );
110
        $this->info['background-position'] = new HTMLPurifier_AttrDef_CSS_BackgroundPosition();
111
112
        $this->info['background-size'] = new HTMLPurifier_AttrDef_CSS_Composite(
113
            [
114
                new HTMLPurifier_AttrDef_Enum(
115
                    [
116
                        'auto',
117
                        'cover',
118
                        'contain',
119
                    ]
120
                ),
121
                new HTMLPurifier_AttrDef_CSS_Percentage(),
122
                new HTMLPurifier_AttrDef_CSS_Length()
123
            ]
124
        );
125
126
        $border_color =
127
            $this->info['border-top-color'] =
128
            $this->info['border-bottom-color'] =
129
            $this->info['border-left-color'] =
130
            $this->info['border-right-color'] =
131
            $this->info['background-color'] = new HTMLPurifier_AttrDef_CSS_Composite(
132
                [
133
                    new HTMLPurifier_AttrDef_Enum(['transparent']),
134
                    new HTMLPurifier_AttrDef_CSS_Color()
135
                ]
136
            );
137
138
        $this->info['background'] = new HTMLPurifier_AttrDef_CSS_Background($config);
139
140
        $this->info['border-color'] = new HTMLPurifier_AttrDef_CSS_Multiple($border_color);
141
142
        $border_width =
143
            $this->info['border-top-width'] =
144
            $this->info['border-bottom-width'] =
145
            $this->info['border-left-width'] =
146
            $this->info['border-right-width'] = new HTMLPurifier_AttrDef_CSS_Composite(
147
                [
148
                    new HTMLPurifier_AttrDef_Enum(['thin', 'medium', 'thick']),
149
                    new HTMLPurifier_AttrDef_CSS_Length('0') //disallow negative
150
                ]
151
            );
152
153
        $this->info['border-width'] = new HTMLPurifier_AttrDef_CSS_Multiple($border_width);
154
155
        $this->info['letter-spacing'] = new HTMLPurifier_AttrDef_CSS_Composite(
156
            [
157
                new HTMLPurifier_AttrDef_Enum(['normal']),
158
                new HTMLPurifier_AttrDef_CSS_Length()
159
            ]
160
        );
161
162
        $this->info['word-spacing'] = new HTMLPurifier_AttrDef_CSS_Composite(
163
            [
164
                new HTMLPurifier_AttrDef_Enum(['normal']),
165
                new HTMLPurifier_AttrDef_CSS_Length()
166
            ]
167
        );
168
169
        $this->info['font-size'] = new HTMLPurifier_AttrDef_CSS_Composite(
170
            [
171
                new HTMLPurifier_AttrDef_Enum(
172
                    [
173
                        'xx-small',
174
                        'x-small',
175
                        'small',
176
                        'medium',
177
                        'large',
178
                        'x-large',
179
                        'xx-large',
180
                        'larger',
181
                        'smaller'
182
                    ]
183
                ),
184
                new HTMLPurifier_AttrDef_CSS_Percentage(),
185
                new HTMLPurifier_AttrDef_CSS_Length()
186
            ]
187
        );
188
189
        $this->info['line-height'] = new HTMLPurifier_AttrDef_CSS_Composite(
190
            [
191
                new HTMLPurifier_AttrDef_Enum(['normal']),
192
                new HTMLPurifier_AttrDef_CSS_Number(true), // no negatives
193
                new HTMLPurifier_AttrDef_CSS_Length('0'),
194
                new HTMLPurifier_AttrDef_CSS_Percentage(true)
195
            ]
196
        );
197
198
        $margin =
199
            $this->info['margin-top'] =
200
            $this->info['margin-bottom'] =
201
            $this->info['margin-left'] =
202
            $this->info['margin-right'] = new HTMLPurifier_AttrDef_CSS_Composite(
203
                [
204
                    new HTMLPurifier_AttrDef_CSS_Length(),
205
                    new HTMLPurifier_AttrDef_CSS_Percentage(),
206
                    new HTMLPurifier_AttrDef_Enum(['auto'])
207
                ]
208
            );
209
210
        $this->info['margin'] = new HTMLPurifier_AttrDef_CSS_Multiple($margin);
211
212
        // non-negative
213
        $padding =
214
            $this->info['padding-top'] =
215
            $this->info['padding-bottom'] =
216
            $this->info['padding-left'] =
217
            $this->info['padding-right'] = new HTMLPurifier_AttrDef_CSS_Composite(
218
                [
219
                    new HTMLPurifier_AttrDef_CSS_Length('0'),
220
                    new HTMLPurifier_AttrDef_CSS_Percentage(true)
221
                ]
222
            );
223
224
        $this->info['padding'] = new HTMLPurifier_AttrDef_CSS_Multiple($padding);
225
226
        $this->info['text-indent'] = new HTMLPurifier_AttrDef_CSS_Composite(
227
            [
228
                new HTMLPurifier_AttrDef_CSS_Length(),
229
                new HTMLPurifier_AttrDef_CSS_Percentage()
230
            ]
231
        );
232
233
        $trusted_wh = new HTMLPurifier_AttrDef_CSS_Composite(
234
            [
235
                new HTMLPurifier_AttrDef_CSS_Length('0'),
236
                new HTMLPurifier_AttrDef_CSS_Percentage(true),
237
                new HTMLPurifier_AttrDef_Enum(['auto'])
238
            ]
239
        );
240
        $trusted_min_wh = new HTMLPurifier_AttrDef_CSS_Composite(
241
            [
242
                new HTMLPurifier_AttrDef_CSS_Length('0'),
243
                new HTMLPurifier_AttrDef_CSS_Percentage(true),
244
            ]
245
        );
246
        $trusted_max_wh = new HTMLPurifier_AttrDef_CSS_Composite(
247
            [
248
                new HTMLPurifier_AttrDef_CSS_Length('0'),
249
                new HTMLPurifier_AttrDef_CSS_Percentage(true),
250
                new HTMLPurifier_AttrDef_Enum(['none'])
251
            ]
252
        );
253
        $max = $config->get('CSS.MaxImgLength');
254
255
        $this->info['width'] =
256
        $this->info['height'] =
257
            $max === null ?
258
                $trusted_wh :
259
                new HTMLPurifier_AttrDef_Switch(
260
                    'img',
261
                    // For img tags:
262
                    new HTMLPurifier_AttrDef_CSS_Composite(
263
                        [
264
                            new HTMLPurifier_AttrDef_CSS_Length('0', $max),
265
                            new HTMLPurifier_AttrDef_Enum(['auto'])
266
                        ]
267
                    ),
268
                    // For everyone else:
269
                    $trusted_wh
270
                );
271
        $this->info['min-width'] =
272
        $this->info['min-height'] =
273
            $max === null ?
274
                $trusted_min_wh :
275
                new HTMLPurifier_AttrDef_Switch(
276
                    'img',
277
                    // For img tags:
278
                    new HTMLPurifier_AttrDef_CSS_Length('0', $max),
279
                    // For everyone else:
280
                    $trusted_min_wh
281
                );
282
        $this->info['max-width'] =
283
        $this->info['max-height'] =
284
            $max === null ?
285
                $trusted_max_wh :
286
                new HTMLPurifier_AttrDef_Switch(
287
                    'img',
288
                    // For img tags:
289
                    new HTMLPurifier_AttrDef_CSS_Composite(
290
                        [
291
                            new HTMLPurifier_AttrDef_CSS_Length('0', $max),
292
                            new HTMLPurifier_AttrDef_Enum(['none'])
293
                        ]
294
                    ),
295
                    // For everyone else:
296
                    $trusted_max_wh
297
                );
298
299
        $this->info['aspect-ratio'] = new HTMLPurifier_AttrDef_CSS_Multiple(
300
            new HTMLPurifier_AttrDef_CSS_Composite([
301
                new HTMLPurifier_AttrDef_CSS_Ratio(),
302
                new HTMLPurifier_AttrDef_Enum(['auto']),
303
            ])
304
        );
305
306
        // text-decoration and related shorthands
307
        $this->info['text-decoration'] = new HTMLPurifier_AttrDef_CSS_TextDecoration();
308
309
        $this->info['text-decoration-line'] = new HTMLPurifier_AttrDef_Enum(
310
            ['none', 'underline', 'overline', 'line-through']
311
        );
312
313
        $this->info['text-decoration-style'] = new HTMLPurifier_AttrDef_Enum(
314
            ['solid', 'double', 'dotted', 'dashed', 'wavy']
315
        );
316
317
        $this->info['text-decoration-color'] = new HTMLPurifier_AttrDef_CSS_Color();
318
319
        $this->info['text-decoration-thickness'] = new HTMLPurifier_AttrDef_CSS_Composite([
320
            new HTMLPurifier_AttrDef_CSS_Length(),
321
            new HTMLPurifier_AttrDef_CSS_Percentage(),
322
            new HTMLPurifier_AttrDef_Enum(['auto', 'from-font'])
323
        ]);
324
325
        $this->info['font-family'] = new HTMLPurifier_AttrDef_CSS_FontFamily();
326
327
        // this could use specialized code
328
        $this->info['font-weight'] = new HTMLPurifier_AttrDef_Enum(
329
            [
330
                'normal',
331
                'bold',
332
                'bolder',
333
                'lighter',
334
                '100',
335
                '200',
336
                '300',
337
                '400',
338
                '500',
339
                '600',
340
                '700',
341
                '800',
342
                '900'
343
            ],
344
            false
345
        );
346
347
        // MUST be called after other font properties, as it references
348
        // a CSSDefinition object
349
        $this->info['font'] = new HTMLPurifier_AttrDef_CSS_Font($config);
350
351
        // same here
352
        $this->info['border'] =
353
        $this->info['border-bottom'] =
354
        $this->info['border-top'] =
355
        $this->info['border-left'] =
356
        $this->info['border-right'] = new HTMLPurifier_AttrDef_CSS_Border($config);
357
358
        $this->info['border-collapse'] = new HTMLPurifier_AttrDef_Enum(
359
            ['collapse', 'separate']
360
        );
361
362
        $this->info['caption-side'] = new HTMLPurifier_AttrDef_Enum(
363
            ['top', 'bottom']
364
        );
365
366
        $this->info['table-layout'] = new HTMLPurifier_AttrDef_Enum(
367
            ['auto', 'fixed']
368
        );
369
370
        $this->info['vertical-align'] = new HTMLPurifier_AttrDef_CSS_Composite(
371
            [
372
                new HTMLPurifier_AttrDef_Enum(
373
                    [
374
                        'baseline',
375
                        'sub',
376
                        'super',
377
                        'top',
378
                        'text-top',
379
                        'middle',
380
                        'bottom',
381
                        'text-bottom'
382
                    ]
383
                ),
384
                new HTMLPurifier_AttrDef_CSS_Length(),
385
                new HTMLPurifier_AttrDef_CSS_Percentage()
386
            ]
387
        );
388
389
        $this->info['border-spacing'] = new HTMLPurifier_AttrDef_CSS_Multiple(new HTMLPurifier_AttrDef_CSS_Length(), 2);
390
391
        // These CSS properties don't work on many browsers, but we live
392
        // in THE FUTURE!
393
        $this->info['white-space'] = new HTMLPurifier_AttrDef_Enum(
394
            ['nowrap', 'normal', 'pre', 'pre-wrap', 'pre-line']
395
        );
396
397
        if ($config->get('CSS.Proprietary')) {
398
            $this->doSetupProprietary($config);
399
        }
400
401
        if ($config->get('CSS.AllowTricky')) {
402
            $this->doSetupTricky($config);
403
        }
404
405
        if ($config->get('CSS.Trusted')) {
406
            $this->doSetupTrusted($config);
407
        }
408
409
        $allow_important = $config->get('CSS.AllowImportant');
410
        // wrap all attr-defs with decorator that handles !important
411
        foreach ($this->info as $k => $v) {
412
            $this->info[$k] = new HTMLPurifier_AttrDef_CSS_ImportantDecorator($v, $allow_important);
413
        }
414
415
        $this->setupConfigStuff($config);
416
    }
417
418
    /**
419
     * @param HTMLPurifier_Config $config
420
     */
421
    protected function doSetupProprietary($config)
0 ignored issues
show
Unused Code introduced by
The parameter $config is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

421
    protected function doSetupProprietary(/** @scrutinizer ignore-unused */ $config)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
422
    {
423
        // Internet Explorer only scrollbar colors
424
        $this->info['scrollbar-arrow-color'] = new HTMLPurifier_AttrDef_CSS_Color();
425
        $this->info['scrollbar-base-color'] = new HTMLPurifier_AttrDef_CSS_Color();
426
        $this->info['scrollbar-darkshadow-color'] = new HTMLPurifier_AttrDef_CSS_Color();
427
        $this->info['scrollbar-face-color'] = new HTMLPurifier_AttrDef_CSS_Color();
428
        $this->info['scrollbar-highlight-color'] = new HTMLPurifier_AttrDef_CSS_Color();
429
        $this->info['scrollbar-shadow-color'] = new HTMLPurifier_AttrDef_CSS_Color();
430
431
        // vendor specific prefixes of opacity
432
        $this->info['-moz-opacity'] = new HTMLPurifier_AttrDef_CSS_AlphaValue();
433
        $this->info['-khtml-opacity'] = new HTMLPurifier_AttrDef_CSS_AlphaValue();
434
435
        // only opacity, for now
436
        $this->info['filter'] = new HTMLPurifier_AttrDef_CSS_Filter();
437
438
        // more CSS3
439
        $this->info['page-break-after'] =
440
        $this->info['page-break-before'] = new HTMLPurifier_AttrDef_Enum(
441
            [
442
                'auto',
443
                'always',
444
                'avoid',
445
                'left',
446
                'right'
447
            ]
448
        );
449
        $this->info['page-break-inside'] = new HTMLPurifier_AttrDef_Enum(['auto', 'avoid']);
450
451
        $border_radius = new HTMLPurifier_AttrDef_CSS_Composite(
452
            [
453
                new HTMLPurifier_AttrDef_CSS_Percentage(true), // disallow negative
454
                new HTMLPurifier_AttrDef_CSS_Length('0') // disallow negative
455
            ]);
456
457
        $this->info['border-top-left-radius'] =
458
        $this->info['border-top-right-radius'] =
459
        $this->info['border-bottom-right-radius'] =
460
        $this->info['border-bottom-left-radius'] = new HTMLPurifier_AttrDef_CSS_Multiple($border_radius, 2);
461
        // TODO: support SLASH syntax
462
        $this->info['border-radius'] = new HTMLPurifier_AttrDef_CSS_Multiple($border_radius, 4);
463
464
    }
465
466
    /**
467
     * @param HTMLPurifier_Config $config
468
     */
469
    protected function doSetupTricky($config)
0 ignored issues
show
Unused Code introduced by
The parameter $config is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

469
    protected function doSetupTricky(/** @scrutinizer ignore-unused */ $config)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
470
    {
471
        $this->info['display'] = new HTMLPurifier_AttrDef_Enum(
472
            [
473
                'inline',
474
                'block',
475
                'list-item',
476
                'run-in',
477
                'compact',
478
                'marker',
479
                'table',
480
                'inline-block',
481
                'inline-table',
482
                'table-row-group',
483
                'table-header-group',
484
                'table-footer-group',
485
                'table-row',
486
                'table-column-group',
487
                'table-column',
488
                'table-cell',
489
                'table-caption',
490
                'none'
491
            ]
492
        );
493
        $this->info['visibility'] = new HTMLPurifier_AttrDef_Enum(
494
            ['visible', 'hidden', 'collapse']
495
        );
496
        $this->info['overflow'] = new HTMLPurifier_AttrDef_Enum(['visible', 'hidden', 'auto', 'scroll']);
497
        $this->info['opacity'] = new HTMLPurifier_AttrDef_CSS_AlphaValue();
498
    }
499
500
    /**
501
     * @param HTMLPurifier_Config $config
502
     */
503
    protected function doSetupTrusted($config)
0 ignored issues
show
Unused Code introduced by
The parameter $config is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

503
    protected function doSetupTrusted(/** @scrutinizer ignore-unused */ $config)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
504
    {
505
        $this->info['position'] = new HTMLPurifier_AttrDef_Enum(
506
            ['static', 'relative', 'absolute', 'fixed']
507
        );
508
        $this->info['top'] =
509
        $this->info['left'] =
510
        $this->info['right'] =
511
        $this->info['bottom'] = new HTMLPurifier_AttrDef_CSS_Composite(
512
            [
513
                new HTMLPurifier_AttrDef_CSS_Length(),
514
                new HTMLPurifier_AttrDef_CSS_Percentage(),
515
                new HTMLPurifier_AttrDef_Enum(['auto']),
516
            ]
517
        );
518
        $this->info['z-index'] = new HTMLPurifier_AttrDef_CSS_Composite(
519
            [
520
                new HTMLPurifier_AttrDef_Integer(),
521
                new HTMLPurifier_AttrDef_Enum(['auto']),
522
            ]
523
        );
524
    }
525
526
    /**
527
     * Performs extra config-based processing. Based off of
528
     * HTMLPurifier_HTMLDefinition.
529
     * @param HTMLPurifier_Config $config
530
     * @todo Refactor duplicate elements into common class (probably using
531
     *       composition, not inheritance).
532
     */
533
    protected function setupConfigStuff($config)
534
    {
535
        // setup allowed elements
536
        $support = "(for information on implementing this, see the " .
537
            "support forums) ";
538
        $allowed_properties = $config->get('CSS.AllowedProperties');
539
        if ($allowed_properties !== null) {
540
            foreach ($this->info as $name => $d) {
541
                if (!isset($allowed_properties[$name])) {
542
                    unset($this->info[$name]);
543
                }
544
                unset($allowed_properties[$name]);
545
            }
546
            // emit errors
547
            foreach ($allowed_properties as $name => $d) {
548
                // :TODO: Is this htmlspecialchars() call really necessary?
549
                $name = htmlspecialchars($name);
550
                trigger_error("Style attribute '$name' is not supported $support", E_USER_WARNING);
551
            }
552
        }
553
554
        $forbidden_properties = $config->get('CSS.ForbiddenProperties');
555
        if ($forbidden_properties !== null) {
556
            foreach ($this->info as $name => $d) {
557
                if (isset($forbidden_properties[$name])) {
558
                    unset($this->info[$name]);
559
                }
560
            }
561
        }
562
    }
563
}
564
565
// vim: et sw=4 sts=4
566