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:
parent
eaea42f827
commit
ed73fdd5b8
@ -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) {
|
||||||
|
@ -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':
|
||||||
|
@ -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';
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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() {
|
||||||
|
Loading…
Reference in New Issue
Block a user