From a122243a8930ac2aa837e9f31a61d6aa45b9a5b4 Mon Sep 17 00:00:00 2001 From: "Edward Z. Yang" Date: Sun, 4 Feb 2007 16:23:26 +0000 Subject: [PATCH] Implement Tables Module. - Fix HTMLDefinition rendering of table children git-svn-id: http://htmlpurifier.org/svnroot/htmlpurifier/trunk@714 48356398-32a2-884e-a903-53898d9a118a --- library/HTMLPurifier/AttrCollection.php | 4 +- library/HTMLPurifier/AttrTypes.php | 3 + library/HTMLPurifier/HTMLModule/Tables.php | 76 +++++++++++++++++++ .../HTMLPurifier/Printer/HTMLDefinition.php | 4 +- library/HTMLPurifier/XHTMLDefinition.php | 6 +- 5 files changed, 87 insertions(+), 6 deletions(-) create mode 100644 library/HTMLPurifier/HTMLModule/Tables.php diff --git a/library/HTMLPurifier/AttrCollection.php b/library/HTMLPurifier/AttrCollection.php index c92081af..3239e2f4 100644 --- a/library/HTMLPurifier/AttrCollection.php +++ b/library/HTMLPurifier/AttrCollection.php @@ -47,7 +47,7 @@ class HTMLPurifier_AttrCollection // merge attribute collections that include others $this->performInclusions($info[$name]); // replace string identifiers with actual attribute objects - $this->expandStringIdentifiers($info[$name], $attr_types); + $this->expandIdentifiers($info[$name], $attr_types); } } @@ -69,7 +69,7 @@ class HTMLPurifier_AttrCollection unset($attr[0]); } - function expandStringIdentifiers(&$attr, $attr_types) { + function expandIdentifiers(&$attr, $attr_types) { foreach ($attr as $def_i => $def) { if ($def_i === 0) continue; if (!is_string($def)) continue; diff --git a/library/HTMLPurifier/AttrTypes.php b/library/HTMLPurifier/AttrTypes.php index 95819776..59ed4e56 100644 --- a/library/HTMLPurifier/AttrTypes.php +++ b/library/HTMLPurifier/AttrTypes.php @@ -14,8 +14,11 @@ class HTMLPurifier_AttrTypes function HTMLPurifier_AttrTypes() { $this->info['NMTOKENS'] = new HTMLPurifier_AttrDef_Nmtokens(); $this->info['CDATA'] = new HTMLPurifier_AttrDef_Text(); + $this->info['Text'] = new HTMLPurifier_AttrDef_Text(); $this->info['ID'] = new HTMLPurifier_AttrDef_ID(); $this->info['URI'] = new HTMLPurifier_AttrDef_URI(); + $this->info['Pixels'] = new HTMLPurifier_AttrDef_Pixels(); + $this->info['Length'] = new HTMLPurifier_AttrDef_Length(); } } diff --git a/library/HTMLPurifier/HTMLModule/Tables.php b/library/HTMLPurifier/HTMLModule/Tables.php new file mode 100644 index 00000000..10263a2a --- /dev/null +++ b/library/HTMLPurifier/HTMLModule/Tables.php @@ -0,0 +1,76 @@ + 'table'); + + function HTMLPurifier_HTMLModule_Tables() { + foreach ($this->elements as $e) { + $this->info[$e] = new HTMLPurifier_ElementDef(); + $this->info[$e]->attr = array(0 => array('Common')); + $attr =& $this->info[$e]->attr; + if ($e == 'caption') continue; + if ($e == 'table'){ + $attr['border'] = 'Pixels'; + $attr['cellpadding'] = 'Length'; + $attr['cellspacing'] = 'Length'; + $attr['frame'] = new HTMLPurifier_AttrDef_Enum(array( + 'void', 'above', 'below', 'hsides', 'lhs', 'rhs', + 'vsides', 'box', 'border' + ), false); + $attr['rules'] = new HTMLPurifier_AttrDef_Enum(array( + 'none', 'groups', 'rows', 'cols', 'all' + ), false); + $attr['summary'] = 'Text'; + $attr['width'] = 'Length'; + continue; + } + if ($e == 'td' || $e == 'th') $attr['abbr'] = 'Text'; + $attr['align'] = new HTMLPurifier_AttrDef_Enum(array( + 'left', 'center', 'right', 'justify', 'char' + ), false); + $attr['valign'] = new HTMLPurifier_AttrDef_Enum(array( + 'top', 'middle', 'bottom', 'baseline' + ), false); + $attr['charoff'] = 'Length'; + } + $this->info['caption']->content_model = '#PCDATA | Inline'; + $this->info['caption']->content_model_type = 'optional'; + + $this->info['table']->content_model = 'caption?, ( col* | colgroup* ), (( thead?, tfoot?, tbody+ ) | ( tr+ ))'; + $this->info['table']->content_model_type = 'table'; + + $this->info['td']->content_model = + $this->info['th']->content_model = '#PCDATA | Flow'; + $this->info['td']->content_model_type = + $this->info['th']->content_model_type = 'optional'; + + $this->info['tr']->content_model = 'td | th'; + $this->info['tr']->content_model_type = 'required'; + + $this->info['col']->content_model_type = 'empty'; + + $this->info['colgroup']->content_model = 'col'; + $this->info['colgroup']->content_model_type = 'optional'; + + $this->info['tbody']->content_model = + $this->info['thead']->content_model = + $this->info['tfoot']->content_model = 'tr'; + $this->info['tbody']->content_model_type = + $this->info['thead']->content_model_type = + $this->info['tfoot']->content_model_type = 'required'; + + } + +} + +?> \ No newline at end of file diff --git a/library/HTMLPurifier/Printer/HTMLDefinition.php b/library/HTMLPurifier/Printer/HTMLDefinition.php index c7314bcd..fb1a357f 100644 --- a/library/HTMLPurifier/Printer/HTMLDefinition.php +++ b/library/HTMLPurifier/Printer/HTMLDefinition.php @@ -143,8 +143,8 @@ class HTMLPurifier_Printer_HTMLDefinition extends HTMLPurifier_Printer } elseif ($def->type == 'empty') { $elements = array(); } elseif ($def->type == 'table') { - $elements = array('col', 'caption', 'colgroup', 'thead', - 'tfoot', 'tbody', 'tr'); + $elements = array_flip(array('col', 'caption', 'colgroup', 'thead', + 'tfoot', 'tbody', 'tr')); } $ret .= $this->element('th', 'Allowed children', $attr); diff --git a/library/HTMLPurifier/XHTMLDefinition.php b/library/HTMLPurifier/XHTMLDefinition.php index 144a8ccf..2cd72d67 100644 --- a/library/HTMLPurifier/XHTMLDefinition.php +++ b/library/HTMLPurifier/XHTMLDefinition.php @@ -12,6 +12,7 @@ require_once 'HTMLPurifier/HTMLModule/List.php'; require_once 'HTMLPurifier/HTMLModule/Presentation.php'; require_once 'HTMLPurifier/HTMLModule/Edit.php'; require_once 'HTMLPurifier/HTMLModule/Bdo.php'; +require_once 'HTMLPurifier/HTMLModule/Tables.php'; /** * Next-generation HTML definition that will supplant HTMLPurifier_HTMLDefinition @@ -32,6 +33,7 @@ class HTMLPurifier_XHTMLDefinition extends HTMLPurifier_HTMLDefinition $this->modules['Presentation'] = new HTMLPurifier_HTMLModule_Presentation(); $this->modules['Edit'] = new HTMLPurifier_HTMLModule_Edit(); $this->modules['Bdo'] = new HTMLPurifier_HTMLModule_Bdo(); + $this->modules['Tables'] = new HTMLPurifier_HTMLModule_Tables(); $this->attr_types = new HTMLPurifier_AttrTypes(); $this->attr_collection = new HTMLPurifier_AttrCollection(); @@ -80,7 +82,7 @@ class HTMLPurifier_XHTMLDefinition extends HTMLPurifier_HTMLDefinition // attribute value expansions $this->attr_collection->performInclusions($def->attr); - $this->attr_collection->expandStringIdentifiers( + $this->attr_collection->expandIdentifiers( $def->attr, $this->attr_types); // perform content model expansions @@ -156,7 +158,7 @@ class HTMLPurifier_XHTMLDefinition extends HTMLPurifier_HTMLDefinition return new HTMLPurifier_ChildDef_Custom($value); } if ($value) return new HTMLPurifier_ChildDef_Optional($value); - return HTMLPurifier_ChildDef_Empty(); + return new HTMLPurifier_ChildDef_Empty(); } function convertToLookup($string) {