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;
}
}