]>
Commit | Line | Data |
---|---|---|
f45a286b AD |
1 | <?php |
2 | ||
3 | /** | |
4 | * Represents an XHTML 1.1 module, with information on elements, tags | |
5 | * and attributes. | |
6 | * @note Even though this is technically XHTML 1.1, it is also used for | |
7 | * regular HTML parsing. We are using modulization as a convenient | |
8 | * way to represent the internals of HTMLDefinition, and our | |
9 | * implementation is by no means conforming and does not directly | |
10 | * use the normative DTDs or XML schemas. | |
11 | * @note The public variables in a module should almost directly | |
12 | * correspond to the variables in HTMLPurifier_HTMLDefinition. | |
13 | * However, the prefix info carries no special meaning in these | |
14 | * objects (include it anyway if that's the correspondence though). | |
15 | * @todo Consider making some member functions protected | |
16 | */ | |
17 | ||
18 | class HTMLPurifier_HTMLModule | |
19 | { | |
20 | ||
21 | // -- Overloadable ---------------------------------------------------- | |
22 | ||
23 | /** | |
24 | * Short unique string identifier of the module | |
25 | */ | |
26 | public $name; | |
27 | ||
28 | /** | |
29 | * Informally, a list of elements this module changes. Not used in | |
30 | * any significant way. | |
31 | */ | |
32 | public $elements = array(); | |
33 | ||
34 | /** | |
35 | * Associative array of element names to element definitions. | |
36 | * Some definitions may be incomplete, to be merged in later | |
37 | * with the full definition. | |
38 | */ | |
39 | public $info = array(); | |
40 | ||
41 | /** | |
42 | * Associative array of content set names to content set additions. | |
43 | * This is commonly used to, say, add an A element to the Inline | |
44 | * content set. This corresponds to an internal variable $content_sets | |
45 | * and NOT info_content_sets member variable of HTMLDefinition. | |
46 | */ | |
47 | public $content_sets = array(); | |
48 | ||
49 | /** | |
50 | * Associative array of attribute collection names to attribute | |
51 | * collection additions. More rarely used for adding attributes to | |
52 | * the global collections. Example is the StyleAttribute module adding | |
53 | * the style attribute to the Core. Corresponds to HTMLDefinition's | |
54 | * attr_collections->info, since the object's data is only info, | |
55 | * with extra behavior associated with it. | |
56 | */ | |
57 | public $attr_collections = array(); | |
58 | ||
59 | /** | |
60 | * Associative array of deprecated tag name to HTMLPurifier_TagTransform | |
61 | */ | |
62 | public $info_tag_transform = array(); | |
63 | ||
64 | /** | |
65 | * List of HTMLPurifier_AttrTransform to be performed before validation. | |
66 | */ | |
67 | public $info_attr_transform_pre = array(); | |
68 | ||
69 | /** | |
70 | * List of HTMLPurifier_AttrTransform to be performed after validation. | |
71 | */ | |
72 | public $info_attr_transform_post = array(); | |
73 | ||
74 | /** | |
75 | * List of HTMLPurifier_Injector to be performed during well-formedness fixing. | |
76 | * An injector will only be invoked if all of it's pre-requisites are met; | |
77 | * if an injector fails setup, there will be no error; it will simply be | |
78 | * silently disabled. | |
79 | */ | |
80 | public $info_injector = array(); | |
81 | ||
82 | /** | |
83 | * Boolean flag that indicates whether or not getChildDef is implemented. | |
84 | * For optimization reasons: may save a call to a function. Be sure | |
85 | * to set it if you do implement getChildDef(), otherwise it will have | |
86 | * no effect! | |
87 | */ | |
88 | public $defines_child_def = false; | |
89 | ||
90 | /** | |
91 | * Boolean flag whether or not this module is safe. If it is not safe, all | |
92 | * of its members are unsafe. Modules are safe by default (this might be | |
93 | * slightly dangerous, but it doesn't make much sense to force HTML Purifier, | |
94 | * which is based off of safe HTML, to explicitly say, "This is safe," even | |
95 | * though there are modules which are "unsafe") | |
96 | * | |
97 | * @note Previously, safety could be applied at an element level granularity. | |
98 | * We've removed this ability, so in order to add "unsafe" elements | |
99 | * or attributes, a dedicated module with this property set to false | |
100 | * must be used. | |
101 | */ | |
102 | public $safe = true; | |
103 | ||
104 | /** | |
105 | * Retrieves a proper HTMLPurifier_ChildDef subclass based on | |
106 | * content_model and content_model_type member variables of | |
107 | * the HTMLPurifier_ElementDef class. There is a similar function | |
108 | * in HTMLPurifier_HTMLDefinition. | |
109 | * @param $def HTMLPurifier_ElementDef instance | |
110 | * @return HTMLPurifier_ChildDef subclass | |
111 | */ | |
112 | public function getChildDef($def) {return false;} | |
113 | ||
114 | // -- Convenience ----------------------------------------------------- | |
115 | ||
116 | /** | |
117 | * Convenience function that sets up a new element | |
118 | * @param $element Name of element to add | |
119 | * @param $type What content set should element be registered to? | |
120 | * Set as false to skip this step. | |
121 | * @param $contents Allowed children in form of: | |
122 | * "$content_model_type: $content_model" | |
123 | * @param $attr_includes What attribute collections to register to | |
124 | * element? | |
125 | * @param $attr What unique attributes does the element define? | |
126 | * @note See ElementDef for in-depth descriptions of these parameters. | |
127 | * @return Created element definition object, so you | |
128 | * can set advanced parameters | |
129 | */ | |
130 | public function addElement($element, $type, $contents, $attr_includes = array(), $attr = array()) { | |
131 | $this->elements[] = $element; | |
132 | // parse content_model | |
133 | list($content_model_type, $content_model) = $this->parseContents($contents); | |
134 | // merge in attribute inclusions | |
135 | $this->mergeInAttrIncludes($attr, $attr_includes); | |
136 | // add element to content sets | |
137 | if ($type) $this->addElementToContentSet($element, $type); | |
138 | // create element | |
139 | $this->info[$element] = HTMLPurifier_ElementDef::create( | |
140 | $content_model, $content_model_type, $attr | |
141 | ); | |
142 | // literal object $contents means direct child manipulation | |
143 | if (!is_string($contents)) $this->info[$element]->child = $contents; | |
144 | return $this->info[$element]; | |
145 | } | |
146 | ||
147 | /** | |
148 | * Convenience function that creates a totally blank, non-standalone | |
149 | * element. | |
150 | * @param $element Name of element to create | |
151 | * @return Created element | |
152 | */ | |
153 | public function addBlankElement($element) { | |
154 | if (!isset($this->info[$element])) { | |
155 | $this->elements[] = $element; | |
156 | $this->info[$element] = new HTMLPurifier_ElementDef(); | |
157 | $this->info[$element]->standalone = false; | |
158 | } else { | |
159 | trigger_error("Definition for $element already exists in module, cannot redefine"); | |
160 | } | |
161 | return $this->info[$element]; | |
162 | } | |
163 | ||
164 | /** | |
165 | * Convenience function that registers an element to a content set | |
166 | * @param Element to register | |
167 | * @param Name content set (warning: case sensitive, usually upper-case | |
168 | * first letter) | |
169 | */ | |
170 | public function addElementToContentSet($element, $type) { | |
171 | if (!isset($this->content_sets[$type])) $this->content_sets[$type] = ''; | |
172 | else $this->content_sets[$type] .= ' | '; | |
173 | $this->content_sets[$type] .= $element; | |
174 | } | |
175 | ||
176 | /** | |
177 | * Convenience function that transforms single-string contents | |
178 | * into separate content model and content model type | |
179 | * @param $contents Allowed children in form of: | |
180 | * "$content_model_type: $content_model" | |
181 | * @note If contents is an object, an array of two nulls will be | |
182 | * returned, and the callee needs to take the original $contents | |
183 | * and use it directly. | |
184 | */ | |
185 | public function parseContents($contents) { | |
186 | if (!is_string($contents)) return array(null, null); // defer | |
187 | switch ($contents) { | |
188 | // check for shorthand content model forms | |
189 | case 'Empty': | |
190 | return array('empty', ''); | |
191 | case 'Inline': | |
192 | return array('optional', 'Inline | #PCDATA'); | |
193 | case 'Flow': | |
194 | return array('optional', 'Flow | #PCDATA'); | |
195 | } | |
196 | list($content_model_type, $content_model) = explode(':', $contents); | |
197 | $content_model_type = strtolower(trim($content_model_type)); | |
198 | $content_model = trim($content_model); | |
199 | return array($content_model_type, $content_model); | |
200 | } | |
201 | ||
202 | /** | |
203 | * Convenience function that merges a list of attribute includes into | |
204 | * an attribute array. | |
205 | * @param $attr Reference to attr array to modify | |
206 | * @param $attr_includes Array of includes / string include to merge in | |
207 | */ | |
208 | public function mergeInAttrIncludes(&$attr, $attr_includes) { | |
209 | if (!is_array($attr_includes)) { | |
210 | if (empty($attr_includes)) $attr_includes = array(); | |
211 | else $attr_includes = array($attr_includes); | |
212 | } | |
213 | $attr[0] = $attr_includes; | |
214 | } | |
215 | ||
216 | /** | |
217 | * Convenience function that generates a lookup table with boolean | |
218 | * true as value. | |
219 | * @param $list List of values to turn into a lookup | |
220 | * @note You can also pass an arbitrary number of arguments in | |
221 | * place of the regular argument | |
222 | * @return Lookup array equivalent of list | |
223 | */ | |
224 | public function makeLookup($list) { | |
225 | if (is_string($list)) $list = func_get_args(); | |
226 | $ret = array(); | |
227 | foreach ($list as $value) { | |
228 | if (is_null($value)) continue; | |
229 | $ret[$value] = true; | |
230 | } | |
231 | return $ret; | |
232 | } | |
233 | ||
234 | /** | |
235 | * Lazy load construction of the module after determining whether | |
236 | * or not it's needed, and also when a finalized configuration object | |
237 | * is available. | |
238 | * @param $config Instance of HTMLPurifier_Config | |
239 | */ | |
240 | public function setup($config) {} | |
241 | ||
242 | } | |
243 | ||
244 | // vim: et sw=4 sts=4 |