116 if (!isset($module->info[$element_name])) {
117 $element = $module->addBlankElement($element_name);
119 $element = $module->info[$element_name];
121 $element->attr[$attr_name] = $def;
129 public function addElement($element_name,
$type, $contents, $attr_collections, $attributes = array())
134 $element = $module->addElement($element_name,
$type, $contents, $attr_collections, $attributes);
149 $element = $module->addBlankElement($element_name);
161 if (!$this->_anonModule) {
163 $this->_anonModule->name =
'Anonymous';
197 unset($this->manager);
200 foreach ($this->info as $k => $v) {
201 unset($this->info[$k]->content_model);
202 unset($this->info[$k]->content_model_type);
212 if ($this->_anonModule) {
216 $this->manager->addModule($this->_anonModule);
217 unset($this->_anonModule);
220 $this->manager->setup($config);
221 $this->doctype = $this->manager->doctype;
223 foreach ($this->manager->modules as $module) {
224 foreach ($module->info_tag_transform as $k => $v) {
226 unset($this->info_tag_transform[$k]);
228 $this->info_tag_transform[$k] = $v;
231 foreach ($module->info_attr_transform_pre as $k => $v) {
233 unset($this->info_attr_transform_pre[$k]);
235 $this->info_attr_transform_pre[$k] = $v;
238 foreach ($module->info_attr_transform_post as $k => $v) {
240 unset($this->info_attr_transform_post[$k]);
242 $this->info_attr_transform_post[$k] = $v;
245 foreach ($module->info_injector as $k => $v) {
247 unset($this->info_injector[$k]);
249 $this->info_injector[$k] = $v;
253 $this->info = $this->manager->getElements();
254 $this->info_content_sets = $this->manager->contentSets->lookup;
263 $block_wrapper = $config->get(
'HTML.BlockWrapper');
264 if (isset($this->info_content_sets[
'Block'][$block_wrapper])) {
265 $this->info_block_wrapper = $block_wrapper;
268 'Cannot use non-block element as block wrapper',
273 $parent = $config->get(
'HTML.Parent');
274 $def = $this->manager->getElement($parent,
true);
276 $this->info_parent = $parent;
277 $this->info_parent_def = $def;
280 'Cannot use unrecognized element as parent',
283 $this->info_parent_def = $this->manager->getElement($this->info_parent,
true);
287 $support =
"(for information on implementing this, see the support forums) ";
291 $allowed_elements = $config->get(
'HTML.AllowedElements');
292 $allowed_attributes = $config->get(
'HTML.AllowedAttributes');
294 if (!is_array($allowed_elements) && !is_array($allowed_attributes)) {
295 $allowed = $config->get(
'HTML.Allowed');
296 if (is_string($allowed)) {
301 if (is_array($allowed_elements)) {
302 foreach ($this->info as $name =>
$d) {
303 if (!isset($allowed_elements[$name])) {
304 unset($this->info[$name]);
306 unset($allowed_elements[$name]);
309 foreach ($allowed_elements as $element =>
$d) {
310 $element = htmlspecialchars($element);
311 trigger_error(
"Element '$element' is not supported $support", E_USER_WARNING);
317 $allowed_attributes_mutable = $allowed_attributes;
318 if (is_array($allowed_attributes)) {
322 foreach ($this->info_global_attr as $attr => $x) {
323 $keys = array($attr,
"*@$attr",
"*.$attr");
325 foreach ($keys as $key) {
326 if ($delete && isset($allowed_attributes[$key])) {
329 if (isset($allowed_attributes_mutable[$key])) {
330 unset($allowed_attributes_mutable[$key]);
334 unset($this->info_global_attr[$attr]);
338 foreach ($this->info as $tag =>
$info) {
339 foreach (
$info->attr as $attr => $x) {
340 $keys = array(
"$tag@$attr", $attr,
"*@$attr",
"$tag.$attr",
"*.$attr");
342 foreach ($keys as $key) {
343 if ($delete && isset($allowed_attributes[$key])) {
346 if (isset($allowed_attributes_mutable[$key])) {
347 unset($allowed_attributes_mutable[$key]);
351 if ($this->info[$tag]->attr[$attr]->required) {
353 "Required attribute '$attr' in element '$tag' " .
354 "was not allowed, which means '$tag' will not be allowed either",
358 unset($this->info[$tag]->attr[$attr]);
363 foreach ($allowed_attributes_mutable as $elattr =>
$d) {
364 $bits = preg_split(
'/[.@]/', $elattr, 2);
368 if ($bits[0] !==
'*') {
369 $element = htmlspecialchars($bits[0]);
370 $attribute = htmlspecialchars($bits[1]);
371 if (!isset($this->info[$element])) {
373 "Cannot allow attribute '$attribute' if element " .
374 "'$element' is not allowed/supported $support"
378 "Attribute '$attribute' in element '$element' not supported $support",
386 $attribute = htmlspecialchars($bits[0]);
388 "Global attribute '$attribute' is not ".
389 "supported in any elements $support",
399 $forbidden_elements = $config->get(
'HTML.ForbiddenElements');
400 $forbidden_attributes = $config->get(
'HTML.ForbiddenAttributes');
402 foreach ($this->info as $tag =>
$info) {
403 if (isset($forbidden_elements[$tag])) {
404 unset($this->info[$tag]);
407 foreach (
$info->attr as $attr => $x) {
408 if (isset($forbidden_attributes[
"$tag@$attr"]) ||
409 isset($forbidden_attributes[
"*@$attr"]) ||
410 isset($forbidden_attributes[$attr])
412 unset($this->info[$tag]->attr[$attr]);
414 } elseif (isset($forbidden_attributes[
"$tag.$attr"])) {
417 "Error with $tag.$attr: tag.attr syntax not supported for " .
418 "HTML.ForbiddenAttributes; use tag@attr instead",
424 foreach ($forbidden_attributes as $key => $v) {
425 if (strlen($key) < 2) {
428 if ($key[0] !=
'*') {
431 if ($key[1] ==
'.') {
433 "Error with $key: *.attr syntax not supported for HTML.ForbiddenAttributes; use attr instead",
440 foreach ($this->info_injector as $i => $injector) {
441 if ($injector->checkNeeded($config) !==
false) {
444 unset($this->info_injector[$i]);
460 $list = str_replace(array(
' ',
"\t"),
'', $list);
463 $attributes = array();
465 $chunks = preg_split(
'/(,|[\n\r]+)/', $list);
466 foreach ($chunks as $chunk) {
471 if (!strpos($chunk,
'[')) {
475 list($element, $attr) = explode(
'[', $chunk);
477 if ($element !==
'*') {
478 $elements[$element] =
true;
483 $attr = substr($attr, 0, strlen($attr) - 1);
484 $attr = explode(
'|', $attr);
485 foreach ($attr as $key) {
486 $attributes[
"$element.$key"] =
true;
489 return array($elements, $attributes);