1<?php
2
3/**
4 * Validates shorthand CSS property list-style.
5 * @warning Does not support url tokens that have internal spaces.
6 */
7class HTMLPurifier_AttrDef_CSS_ListStyle extends HTMLPurifier_AttrDef
8{
9
10    /**
11     * Local copy of validators.
12     * @type HTMLPurifier_AttrDef[]
13     * @note See HTMLPurifier_AttrDef_CSS_Font::$info for a similar impl.
14     */
15    protected $info;
16
17    /**
18     * @param HTMLPurifier_Config $config
19     */
20    public function __construct($config)
21    {
22        $def = $config->getCSSDefinition();
23        $this->info['list-style-type'] = $def->info['list-style-type'];
24        $this->info['list-style-position'] = $def->info['list-style-position'];
25        $this->info['list-style-image'] = $def->info['list-style-image'];
26    }
27
28    /**
29     * @param string $string
30     * @param HTMLPurifier_Config $config
31     * @param HTMLPurifier_Context $context
32     * @return bool|string
33     */
34    public function validate($string, $config, $context)
35    {
36        // regular pre-processing
37        $string = $this->parseCDATA($string);
38        if ($string === '') {
39            return false;
40        }
41
42        // assumes URI doesn't have spaces in it
43        $bits = explode(' ', strtolower($string)); // bits to process
44
45        $caught = array();
46        $caught['type'] = false;
47        $caught['position'] = false;
48        $caught['image'] = false;
49
50        $i = 0; // number of catches
51        $none = false;
52
53        foreach ($bits as $bit) {
54            if ($i >= 3) {
55                return;
56            } // optimization bit
57            if ($bit === '') {
58                continue;
59            }
60            foreach ($caught as $key => $status) {
61                if ($status !== false) {
62                    continue;
63                }
64                $r = $this->info['list-style-' . $key]->validate($bit, $config, $context);
65                if ($r === false) {
66                    continue;
67                }
68                if ($r === 'none') {
69                    if ($none) {
70                        continue;
71                    } else {
72                        $none = true;
73                    }
74                    if ($key == 'image') {
75                        continue;
76                    }
77                }
78                $caught[$key] = $r;
79                $i++;
80                break;
81            }
82        }
83
84        if (!$i) {
85            return false;
86        }
87
88        $ret = array();
89
90        // construct type
91        if ($caught['type']) {
92            $ret[] = $caught['type'];
93        }
94
95        // construct image
96        if ($caught['image']) {
97            $ret[] = $caught['image'];
98        }
99
100        // construct position
101        if ($caught['position']) {
102            $ret[] = $caught['position'];
103        }
104
105        if (empty($ret)) {
106            return false;
107        }
108        return implode(' ', $ret);
109    }
110}
111
112// vim: et sw=4 sts=4
113