0
0
mirror of https://github.com/ezyang/htmlpurifier.git synced 2025-01-05 14:11:52 +00:00

[1.7.0] Convert table module to new format. Add support for literal object $contents variable.

git-svn-id: http://htmlpurifier.org/svnroot/htmlpurifier/trunk@1045 48356398-32a2-884e-a903-53898d9a118a
This commit is contained in:
Edward Z. Yang 2007-05-12 20:26:26 +00:00
parent eaea42f827
commit ed73fdd5b8
4 changed files with 63 additions and 59 deletions

View File

@ -93,7 +93,7 @@ class HTMLPurifier_ElementDef
var $safe = false; var $safe = false;
/** /**
* Factory constructor for creating new standalone element defs * Low-level factory constructor for creating new standalone element defs
* @static * @static
*/ */
function create($safe, $content_model, $content_model_type, $attr) { function create($safe, $content_model, $content_model_type, $attr) {

View File

@ -151,6 +151,8 @@ class HTMLPurifier_HTMLModule
$this->info[$element] = HTMLPurifier_ElementDef::create( $this->info[$element] = HTMLPurifier_ElementDef::create(
$safe, $content_model, $content_model_type, $attr $safe, $content_model, $content_model_type, $attr
); );
// literal object $contents means direct child manipulation
if (!is_string($contents)) $this->info[$element]->child = $contents;
} }
/** /**
@ -171,8 +173,12 @@ class HTMLPurifier_HTMLModule
* into separate content model and content model type * into separate content model and content model type
* @param $contents Allowed children in form of: * @param $contents Allowed children in form of:
* "$content_model_type: $content_model" * "$content_model_type: $content_model"
* @note If contents is an object, an array of two nulls will be
* returned, and the callee needs to take the original $contents
* and use it directly.
*/ */
function parseContents($contents) { function parseContents($contents) {
if (!is_string($contents)) return array(null, null); // defer
switch ($contents) { switch ($contents) {
// check for shorthand content model forms // check for shorthand content model forms
case 'Empty': case 'Empty':

View File

@ -10,75 +10,66 @@ class HTMLPurifier_HTMLModule_Tables extends HTMLPurifier_HTMLModule
{ {
var $name = 'Tables'; var $name = 'Tables';
var $elements = array('caption', 'table', 'td', 'th', 'tr', 'col',
'colgroup', 'tbody', 'thead', 'tfoot');
var $content_sets = array('Block' => 'table');
function HTMLPurifier_HTMLModule_Tables() { function HTMLPurifier_HTMLModule_Tables() {
foreach ($this->elements as $e) {
$this->info[$e] = new HTMLPurifier_ElementDef(); $this->addElement('table', true, 'Block',
$this->info[$e]->attr = array(0 => array('Common')); new HTMLPurifier_ChildDef_Table(), 'Common',
$attr =& $this->info[$e]->attr; array(
if ($e == 'caption') continue; 'border' => 'Pixels',
if ($e == 'table'){ 'cellpadding' => 'Length',
$attr['border'] = 'Pixels'; 'cellspacing' => 'Length',
$attr['cellpadding'] = 'Length'; 'frame' => new HTMLPurifier_AttrDef_Enum(array(
$attr['cellspacing'] = 'Length';
$attr['frame'] = new HTMLPurifier_AttrDef_Enum(array(
'void', 'above', 'below', 'hsides', 'lhs', 'rhs', 'void', 'above', 'below', 'hsides', 'lhs', 'rhs',
'vsides', 'box', 'border' 'vsides', 'box', 'border'
), false); ), false),
$attr['rules'] = new HTMLPurifier_AttrDef_Enum(array( 'rules' => new HTMLPurifier_AttrDef_Enum(array(
'none', 'groups', 'rows', 'cols', 'all' 'none', 'groups', 'rows', 'cols', 'all'
), false); ), false),
$attr['summary'] = 'Text'; 'summary' => 'Text',
$attr['width'] = 'Length'; 'width' => 'Length'
continue; )
} );
if ($e == 'col' || $e == 'colgroup') {
$attr['span'] = 'Number'; $this->addElement('caption', true, false, 'Inline', 'Common');
$attr['width'] = 'MultiLength';
} // common attributes
if ($e == 'td' || $e == 'th') { $cell_align = array(
$attr['abbr'] = 'Text'; 'align' => new HTMLPurifier_AttrDef_Enum(array(
$attr['colspan'] = 'Number';
$attr['rowspan'] = 'Number';
}
$attr['align'] = new HTMLPurifier_AttrDef_Enum(array(
'left', 'center', 'right', 'justify', 'char' 'left', 'center', 'right', 'justify', 'char'
), false); ), false),
$attr['valign'] = new HTMLPurifier_AttrDef_Enum(array( 'valign' => new HTMLPurifier_AttrDef_Enum(array(
'top', 'middle', 'bottom', 'baseline' 'top', 'middle', 'bottom', 'baseline'
), false); ), false),
$attr['charoff'] = 'Length'; 'charoff' => 'Length',
} );
$this->info['caption']->content_model = '#PCDATA | Inline';
$this->info['caption']->content_model_type = 'optional';
// Is done directly because it doesn't leverage substitution $cell_t = array_merge(
// mechanisms. True model is: array(
// 'caption?, ( col* | colgroup* ), (( thead?, tfoot?, tbody+ ) | ( tr+ ))' 'abbr' => 'Text',
$this->info['table']->child = new HTMLPurifier_ChildDef_Table(); 'colspan' => 'Number',
'rowspan' => 'Number',
),
$cell_align
);
$this->addElement('td', true, false, 'Flow', 'Common', $cell_t);
$this->addElement('th', true, false, 'Flow', 'Common', $cell_t);
$this->info['td']->content_model = $this->addElement('tr', true, false, 'Required: td | th', 'Common', $cell_align);
$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'; $cell_col = array_merge(
$this->info['tr']->content_model_type = 'required'; array(
'span' => 'Number',
'width' => 'MultiLength',
),
$cell_align
);
$this->addElement('col', true, false, 'Empty', 'Common', $cell_col);
$this->addElement('colgroup', true, false, 'Optional: col', 'Common', $cell_col);
$this->info['col']->content_model_type = 'empty'; $this->addElement('tbody', true, false, 'Required: tr', 'Common', $cell_align);
$this->addElement('thead', true, false, 'Required: tr', 'Common', $cell_align);
$this->info['colgroup']->content_model = 'col'; $this->addElement('tfoot', true, false, 'Required: tr', 'Common', $cell_align);
$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';
} }

View File

@ -83,6 +83,13 @@ class HTMLPurifier_HTMLModuleTest extends UnitTestCase
array('optional', 'a | b | c') array('optional', 'a | b | c')
); );
// object pass-through
generate_mock_once('HTMLPurifier_AttrDef');
$this->assertIdentical(
$module->parseContents(new HTMLPurifier_AttrDefMock()),
array(null, null)
);
} }
function test_mergeInAttrIncludes() { function test_mergeInAttrIncludes() {