104 if (!isset($module->info[$element_name])) {
105 $element = $module->addBlankElement($element_name);
107 $element = $module->info[$element_name];
109 $element->attr[$attr_name] = $def;
117 public function addElement($element_name,
$type, $contents, $attr_collections, $attributes = array()) {
121 $element = $module->addElement($element_name,
$type, $contents, $attr_collections, $attributes);
133 $element = $module->addBlankElement($element_name);
143 if (!$this->_anonModule) {
145 $this->_anonModule->name =
'Anonymous';
168 unset($this->manager);
171 foreach ($this->info as $k => $v) {
172 unset($this->info[$k]->content_model);
173 unset($this->info[$k]->content_model_type);
182 if ($this->_anonModule) {
186 $this->manager->addModule($this->_anonModule);
187 unset($this->_anonModule);
190 $this->manager->setup($config);
191 $this->doctype = $this->manager->doctype;
193 foreach ($this->manager->modules as $module) {
194 foreach($module->info_tag_transform as $k => $v) {
195 if ($v ===
false) unset($this->info_tag_transform[$k]);
196 else $this->info_tag_transform[$k] = $v;
198 foreach($module->info_attr_transform_pre as $k => $v) {
199 if ($v ===
false) unset($this->info_attr_transform_pre[$k]);
200 else $this->info_attr_transform_pre[$k] = $v;
202 foreach($module->info_attr_transform_post as $k => $v) {
203 if ($v ===
false) unset($this->info_attr_transform_post[$k]);
204 else $this->info_attr_transform_post[$k] = $v;
206 foreach ($module->info_injector as $k => $v) {
207 if ($v ===
false) unset($this->info_injector[$k]);
208 else $this->info_injector[$k] = $v;
212 $this->info = $this->manager->getElements();
213 $this->info_content_sets = $this->manager->contentSets->lookup;
222 $block_wrapper = $config->get(
'HTML.BlockWrapper');
223 if (isset($this->info_content_sets[
'Block'][$block_wrapper])) {
224 $this->info_block_wrapper = $block_wrapper;
226 trigger_error(
'Cannot use non-block element as block wrapper',
230 $parent = $config->get(
'HTML.Parent');
231 $def = $this->manager->getElement($parent,
true);
233 $this->info_parent = $parent;
234 $this->info_parent_def = $def;
236 trigger_error(
'Cannot use unrecognized element as parent',
238 $this->info_parent_def = $this->manager->getElement($this->info_parent,
true);
242 $support =
"(for information on implementing this, see the ".
247 $allowed_elements = $config->get(
'HTML.AllowedElements');
248 $allowed_attributes = $config->get(
'HTML.AllowedAttributes');
250 if (!is_array($allowed_elements) && !is_array($allowed_attributes)) {
251 $allowed = $config->get(
'HTML.Allowed');
252 if (is_string($allowed)) {
257 if (is_array($allowed_elements)) {
258 foreach ($this->info as $name =>
$d) {
259 if(!isset($allowed_elements[$name])) unset($this->info[$name]);
260 unset($allowed_elements[$name]);
263 foreach ($allowed_elements as $element =>
$d) {
264 $element = htmlspecialchars($element);
265 trigger_error(
"Element '$element' is not supported $support", E_USER_WARNING);
271 $allowed_attributes_mutable = $allowed_attributes;
272 if (is_array($allowed_attributes)) {
277 foreach ($this->info_global_attr as $attr => $x) {
278 $keys = array($attr,
"*@$attr",
"*.$attr");
280 foreach ($keys as $key) {
281 if ($delete && isset($allowed_attributes[$key])) {
284 if (isset($allowed_attributes_mutable[$key])) {
285 unset($allowed_attributes_mutable[$key]);
288 if ($delete) unset($this->info_global_attr[$attr]);
291 foreach ($this->info as $tag =>
$info) {
292 foreach (
$info->attr as $attr => $x) {
293 $keys = array(
"$tag@$attr", $attr,
"*@$attr",
"$tag.$attr",
"*.$attr");
295 foreach ($keys as $key) {
296 if ($delete && isset($allowed_attributes[$key])) {
299 if (isset($allowed_attributes_mutable[$key])) {
300 unset($allowed_attributes_mutable[$key]);
304 if ($this->info[$tag]->attr[$attr]->required) {
305 trigger_error(
"Required attribute '$attr' in element '$tag' was not allowed, which means '$tag' will not be allowed either", E_USER_WARNING);
307 unset($this->info[$tag]->attr[$attr]);
312 foreach ($allowed_attributes_mutable as $elattr =>
$d) {
313 $bits = preg_split(
'/[.@]/', $elattr, 2);
317 if ($bits[0] !==
'*') {
318 $element = htmlspecialchars($bits[0]);
319 $attribute = htmlspecialchars($bits[1]);
320 if (!isset($this->info[$element])) {
321 trigger_error(
"Cannot allow attribute '$attribute' if element '$element' is not allowed/supported $support");
323 trigger_error(
"Attribute '$attribute' in element '$element' not supported $support",
330 $attribute = htmlspecialchars($bits[0]);
331 trigger_error(
"Global attribute '$attribute' is not ".
332 "supported in any elements $support",
342 $forbidden_elements = $config->get(
'HTML.ForbiddenElements');
343 $forbidden_attributes = $config->get(
'HTML.ForbiddenAttributes');
345 foreach ($this->info as $tag =>
$info) {
346 if (isset($forbidden_elements[$tag])) {
347 unset($this->info[$tag]);
350 foreach (
$info->attr as $attr => $x) {
352 isset($forbidden_attributes[
"$tag@$attr"]) ||
353 isset($forbidden_attributes[
"*@$attr"]) ||
354 isset($forbidden_attributes[$attr])
356 unset($this->info[$tag]->attr[$attr]);
359 elseif (isset($forbidden_attributes[
"$tag.$attr"])) {
361 trigger_error(
"Error with $tag.$attr: tag.attr syntax not supported for HTML.ForbiddenAttributes; use tag@attr instead", E_USER_WARNING);
365 foreach ($forbidden_attributes as $key => $v) {
366 if (strlen($key) < 2)
continue;
367 if ($key[0] !=
'*')
continue;
368 if ($key[1] ==
'.') {
369 trigger_error(
"Error with $key: *.attr syntax not supported for HTML.ForbiddenAttributes; use attr instead", E_USER_WARNING);
374 foreach ($this->info_injector as $i => $injector) {
375 if ($injector->checkNeeded($config) !==
false) {
378 unset($this->info_injector[$i]);
394 $list = str_replace(array(
' ',
"\t"),
'', $list);
397 $attributes = array();
399 $chunks = preg_split(
'/(,|[\n\r]+)/', $list);
400 foreach ($chunks as $chunk) {
401 if (empty($chunk))
continue;
403 if (!strpos($chunk,
'[')) {
407 list($element, $attr) = explode(
'[', $chunk);
409 if ($element !==
'*') $elements[$element] =
true;
410 if (!$attr)
continue;
411 $attr = substr($attr, 0, strlen($attr) - 1);
412 $attr = explode(
'|', $attr);
413 foreach ($attr as $key) {
414 $attributes[
"$element.$key"] =
true;
418 return array($elements, $attributes);