diff --git a/library/HTMLPurifier/AttrCollection.php b/library/HTMLPurifier/AttrCollection.php index 52d6820d..c92081af 100644 --- a/library/HTMLPurifier/AttrCollection.php +++ b/library/HTMLPurifier/AttrCollection.php @@ -36,6 +36,13 @@ class HTMLPurifier_AttrCollection function setup($attr_types, $modules) { $info =& $this->info; + foreach ($modules as $module) { + foreach ($module->attr_collection as $coll_i => $coll) { + foreach ($coll as $attr_i => $attr) { + $info[$coll_i][$attr_i] = $attr; + } + } + } foreach ($info as $name => $attr) { // merge attribute collections that include others $this->performInclusions($info[$name]); diff --git a/library/HTMLPurifier/HTMLDefinition.php b/library/HTMLPurifier/HTMLDefinition.php index ea2582c2..0a529f7a 100644 --- a/library/HTMLPurifier/HTMLDefinition.php +++ b/library/HTMLPurifier/HTMLDefinition.php @@ -626,9 +626,23 @@ class HTMLPurifier_ElementDef */ var $child; + /** + * Abstract string representation of internal ChildDef rules + * @public + */ var $content_model; + + /** + * Value of $child->type, used to determine which ChildDef to use + * @public + */ var $content_model_type; + /** + * Does the element have a content model (#PCDATA | Inline)*? This + * is important for chameleon ins and del processing. + * @public + */ var $descendants_are_inline; /** diff --git a/library/HTMLPurifier/HTMLModule.php b/library/HTMLPurifier/HTMLModule.php index 1c8647cd..0f9480b2 100644 --- a/library/HTMLPurifier/HTMLModule.php +++ b/library/HTMLPurifier/HTMLModule.php @@ -15,6 +15,7 @@ class HTMLPurifier_HTMLModule var $elements = array(); var $info = array(); var $content_sets = array(); + var $attr_collection = array(); } ?> \ No newline at end of file diff --git a/library/HTMLPurifier/HTMLModule/Bdo.php b/library/HTMLPurifier/HTMLModule/Bdo.php new file mode 100644 index 00000000..acba4d59 --- /dev/null +++ b/library/HTMLPurifier/HTMLModule/Bdo.php @@ -0,0 +1,35 @@ + 'bdo'); + var $attr_collection = array( + 'I18N' => array('dir' => false) + ); + + function HTMLPurifier_HTMLModule_Bdo() { + $dir = new HTMLPurifier_AttrDef_Enum(array('ltr','rtl'), false); + $this->attr_collection['I18N']['dir'] = $dir; + $this->info['bdo'] = new HTMLPurifier_ElementDef(); + $this->info['bdo']->attr = array( + 0 => array('Core'), + 'dir' => $dir + ); + $this->info['bdo']->content_model = '#PCDATA | Inline'; + $this->info['bdo']->content_model_type = 'optional'; + $this->info['bdo']->content_model_type = 'optional'; + $this->info['bdo']->attr_transform_post[] = new HTMLPurifier_AttrTransform_BdoDir(); + } + +} + +?> \ No newline at end of file diff --git a/library/HTMLPurifier/HTMLModule/List.php b/library/HTMLPurifier/HTMLModule/List.php index 55c0909c..dcab1f36 100644 --- a/library/HTMLPurifier/HTMLModule/List.php +++ b/library/HTMLPurifier/HTMLModule/List.php @@ -33,6 +33,7 @@ class HTMLPurifier_HTMLModule_List extends HTMLPurifier_HTMLModule $this->info['dt']->content_model_type = 'optional'; $this->info['dl']->content_model = 'dt | dd'; $this->info['dl']->content_model_type = 'required'; + $this->info['li']->auto_close = array('li' => true); } } diff --git a/library/HTMLPurifier/HTMLModule/Text.php b/library/HTMLPurifier/HTMLModule/Text.php index 2b6a9578..0a3d27fc 100644 --- a/library/HTMLPurifier/HTMLModule/Text.php +++ b/library/HTMLPurifier/HTMLModule/Text.php @@ -47,6 +47,11 @@ class HTMLPurifier_HTMLModule_Text extends HTMLPurifier_HTMLModule $this->info[$element]->content_model_type = 'optional'; } } + $this->info['p']->auto_close = array_flip(array( + 'address', 'blockquote', 'dd', 'dir', 'div', 'dl', 'dt', + 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'ol', 'p', 'pre', + 'table', 'ul' + )); } } diff --git a/library/HTMLPurifier/XHTMLDefinition.php b/library/HTMLPurifier/XHTMLDefinition.php index ef101538..144a8ccf 100644 --- a/library/HTMLPurifier/XHTMLDefinition.php +++ b/library/HTMLPurifier/XHTMLDefinition.php @@ -11,6 +11,7 @@ require_once 'HTMLPurifier/HTMLModule/Hypertext.php'; require_once 'HTMLPurifier/HTMLModule/List.php'; require_once 'HTMLPurifier/HTMLModule/Presentation.php'; require_once 'HTMLPurifier/HTMLModule/Edit.php'; +require_once 'HTMLPurifier/HTMLModule/Bdo.php'; /** * Next-generation HTML definition that will supplant HTMLPurifier_HTMLDefinition @@ -30,6 +31,7 @@ class HTMLPurifier_XHTMLDefinition extends HTMLPurifier_HTMLDefinition $this->modules['List'] = new HTMLPurifier_HTMLModule_List(); $this->modules['Presentation'] = new HTMLPurifier_HTMLModule_Presentation(); $this->modules['Edit'] = new HTMLPurifier_HTMLModule_Edit(); + $this->modules['Bdo'] = new HTMLPurifier_HTMLModule_Bdo(); $this->attr_types = new HTMLPurifier_AttrTypes(); $this->attr_collection = new HTMLPurifier_AttrCollection(); @@ -102,6 +104,35 @@ class HTMLPurifier_XHTMLDefinition extends HTMLPurifier_HTMLDefinition } } + $this->setupAttrTransform($config); + $this->setupBlockWrapper($config); + $this->setupParent($config); + + } + + function setupAttrTransform($config) { + $this->info_attr_transform_post[] = new HTMLPurifier_AttrTransform_Lang(); + } + + function setupBlockWrapper($config) { + $block_wrapper = $config->get('HTML', 'BlockWrapper'); + if (isset($this->content_sets['Block'][$block_wrapper])) { + $this->info_block_wrapper = $block_wrapper; + } else { + trigger_error('Cannot use non-block element as block wrapper.', + E_USER_ERROR); + } + } + + function setupParent($config) { + $parent = $config->get('HTML', 'Parent'); + if (isset($this->info[$parent])) { + $this->info_parent = $parent; + } else { + trigger_error('Cannot use unrecognized element as parent.', + E_USER_ERROR); + } + $this->info_parent_def = $this->info[$this->info_parent]; } function getChildDef($def) { @@ -130,10 +161,11 @@ class HTMLPurifier_XHTMLDefinition extends HTMLPurifier_HTMLDefinition function convertToLookup($string) { $array = explode('|', str_replace(' ', '', $string)); + $ret = array(); foreach ($array as $i => $k) { - $array[$i] = true; + $ret[$k] = true; } - return $array; + return $ret; } }