mirror of
https://github.com/ezyang/htmlpurifier.git
synced 2025-03-15 19:07:05 +00:00
[1.7.0] Add more convenience functions to HTMLModule, wire Edit and Hypertext to use new functionality
- Added LanguageCode to AttrTypes. We should prefer string representations of attribute definitions. git-svn-id: http://htmlpurifier.org/svnroot/htmlpurifier/trunk@1040 48356398-32a2-884e-a903-53898d9a118a
This commit is contained in:
parent
47fe34ad81
commit
b81fb0af90
@ -32,6 +32,7 @@ class HTMLPurifier_AttrTypes
|
||||
$this->info['Pixels'] = new HTMLPurifier_AttrDef_HTML_Pixels();
|
||||
$this->info['Text'] = new HTMLPurifier_AttrDef_Text();
|
||||
$this->info['URI'] = new HTMLPurifier_AttrDef_URI();
|
||||
$this->info['LanguageCode'] = new HTMLPurifier_AttrDef_Lang();
|
||||
|
||||
// number is really a positive integer (one or more digits)
|
||||
$this->info['Number'] = new HTMLPurifier_AttrDef_Integer(false, false, true);
|
||||
|
@ -16,6 +16,9 @@
|
||||
|
||||
class HTMLPurifier_HTMLModule
|
||||
{
|
||||
|
||||
// -- Overloadable ----------------------------------------------------
|
||||
|
||||
/**
|
||||
* Short unique string identifier of the module
|
||||
*/
|
||||
@ -120,13 +123,15 @@ class HTMLPurifier_HTMLModule
|
||||
*/
|
||||
function setup(&$definition) {}
|
||||
|
||||
// -- Convenience -----------------------------------------------------
|
||||
|
||||
/**
|
||||
* Convenience function that sets up a new element
|
||||
* @param $element Name of element to add
|
||||
* @param $safe Is element safe for untrusted users to use?
|
||||
* @param $type What content set should element be registered to?
|
||||
* Set as false to skip this step.
|
||||
* @param $content_model Content model definition in form of:
|
||||
* @param $contents Allowed children in form of:
|
||||
* "$content_model_type: $content_model"
|
||||
* @param $attr_includes What attribute collections to register to
|
||||
* element?
|
||||
@ -134,14 +139,12 @@ class HTMLPurifier_HTMLModule
|
||||
* @note See ElementDef for in-depth descriptions of these parameters.
|
||||
* @protected
|
||||
*/
|
||||
function addElement($element, $safe, $type, $content_model, $attr_includes, $attr) {
|
||||
function addElement($element, $safe, $type, $contents, $attr_includes, $attr) {
|
||||
$this->elements[] = $element;
|
||||
// parse content_model
|
||||
list($content_model_type, $content_model) = explode(':', $content_model);
|
||||
$content_model_type = strtolower(trim($content_model_type));
|
||||
$content_model = trim($content_model);
|
||||
list($content_model_type, $content_model) = $this->parseContents($contents);
|
||||
// merge in attribute inclusions
|
||||
$attr[0] = $attr_includes;
|
||||
$this->mergeInAttrIncludes($attr, $attr_includes);
|
||||
// add element to content sets
|
||||
if ($type) $this->addElementToContentSet($element, $type);
|
||||
// create element
|
||||
@ -163,6 +166,41 @@ class HTMLPurifier_HTMLModule
|
||||
$this->content_sets[$type] .= $element;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience function that transforms single-string contents
|
||||
* into separate content model and content model type
|
||||
* @param $contents Allowed children in form of:
|
||||
* "$content_model_type: $content_model"
|
||||
*/
|
||||
function parseContents($contents) {
|
||||
switch ($contents) {
|
||||
// check for shorthand content model forms
|
||||
case 'Inline':
|
||||
$contents = 'Optional: Inline | #PCDATA';
|
||||
break;
|
||||
case 'Flow':
|
||||
$contents = 'Optional: Flow | #PCDATA';
|
||||
break;
|
||||
}
|
||||
list($content_model_type, $content_model) = explode(':', $contents);
|
||||
$content_model_type = strtolower(trim($content_model_type));
|
||||
$content_model = trim($content_model);
|
||||
return array($content_model_type, $content_model);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience function that merges a list of attribute includes into
|
||||
* an attribute array.
|
||||
* @param $attr Reference to attr array to modify
|
||||
* @param $attr_includes Array of includes / string include to merge in
|
||||
*/
|
||||
function mergeInAttrIncludes(&$attr, $attr_includes) {
|
||||
if (!is_array($attr_includes)) {
|
||||
if (empty($attr_includes)) $attr_includes = array();
|
||||
else $attr_includes = array($attr_includes);
|
||||
}
|
||||
$attr[0] = $attr_includes;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@ -18,7 +18,7 @@ class HTMLPurifier_HTMLModule_Bdo extends HTMLPurifier_HTMLModule
|
||||
function HTMLPurifier_HTMLModule_Bdo() {
|
||||
$dir = new HTMLPurifier_AttrDef_Enum(array('ltr','rtl'), false);
|
||||
$this->addElement(
|
||||
'bdo', true, 'Inline', 'Optional: #PCDATA | Inline', array('Core', 'Lang'),
|
||||
'bdo', true, 'Inline', 'Inline', array('Core', 'Lang'),
|
||||
array(
|
||||
'dir' => $dir, // required
|
||||
// The Abstract Module specification has the attribute
|
||||
|
@ -13,7 +13,7 @@ class HTMLPurifier_HTMLModule_CommonAttributes extends HTMLPurifier_HTMLModule
|
||||
'title' => 'CDATA',
|
||||
),
|
||||
'Lang' => array(
|
||||
'xml:lang' => false, // see constructor
|
||||
'xml:lang' => 'LanguageCode',
|
||||
),
|
||||
'I18N' => array(
|
||||
0 => array('Lang'), // proprietary, for xml:lang/lang
|
||||
@ -22,10 +22,6 @@ class HTMLPurifier_HTMLModule_CommonAttributes extends HTMLPurifier_HTMLModule
|
||||
0 => array('Core', 'I18N')
|
||||
)
|
||||
);
|
||||
|
||||
function HTMLPurifier_HTMLModule_CommonAttributes() {
|
||||
$this->attr_collections['Lang']['xml:lang'] = new HTMLPurifier_AttrDef_Lang();
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@ -11,28 +11,28 @@ class HTMLPurifier_HTMLModule_Edit extends HTMLPurifier_HTMLModule
|
||||
{
|
||||
|
||||
var $name = 'Edit';
|
||||
var $elements = array('del', 'ins');
|
||||
var $content_sets = array('Inline' => 'del | ins');
|
||||
|
||||
function HTMLPurifier_HTMLModule_Edit() {
|
||||
foreach ($this->elements as $element) {
|
||||
$this->info[$element] = new HTMLPurifier_ElementDef();
|
||||
$this->info[$element]->attr = array(
|
||||
0 => array('Common'),
|
||||
'cite' => 'URI',
|
||||
// 'datetime' => 'Datetime' // Datetime not implemented
|
||||
);
|
||||
// Inline context ! Block context (exclamation mark is
|
||||
// separator, see getChildDef for parsing)
|
||||
$this->info[$element]->content_model =
|
||||
'#PCDATA | Inline ! #PCDATA | Flow';
|
||||
// HTML 4.01 specifies that ins/del must not contain block
|
||||
// elements when used in an inline context, chameleon is
|
||||
// a complicated workaround to acheive this effect
|
||||
$this->info[$element]->content_model_type = 'chameleon';
|
||||
}
|
||||
$contents = 'Chameleon: #PCDATA | Inline ! #PCDATA | Flow';
|
||||
$attr = array(
|
||||
'cite' => 'URI',
|
||||
// 'datetime' => 'Datetime', // not implemented
|
||||
);
|
||||
$this->addElement(
|
||||
'del', true, 'Inline', $contents, 'Common', $attr
|
||||
);
|
||||
$this->addElement(
|
||||
'ins', true, 'Inline', $contents, 'Common', $attr
|
||||
);
|
||||
}
|
||||
|
||||
// HTML 4.01 specifies that ins/del must not contain block
|
||||
// elements when used in an inline context, chameleon is
|
||||
// a complicated workaround to acheive this effect
|
||||
|
||||
// Inline context ! Block context (exclamation mark is
|
||||
// separator, see getChildDef for parsing)
|
||||
|
||||
var $defines_child_def = true;
|
||||
function getChildDef($def) {
|
||||
if ($def->content_model_type != 'chameleon') return false;
|
||||
|
@ -10,24 +10,21 @@ class HTMLPurifier_HTMLModule_Hypertext extends HTMLPurifier_HTMLModule
|
||||
{
|
||||
|
||||
var $name = 'Hypertext';
|
||||
var $elements = array('a');
|
||||
var $content_sets = array('Inline' => 'a');
|
||||
|
||||
function HTMLPurifier_HTMLModule_Hypertext() {
|
||||
$this->info['a'] = new HTMLPurifier_ElementDef();
|
||||
$this->info['a']->attr = array(
|
||||
0 => array('Common'),
|
||||
// 'accesskey' => 'Character',
|
||||
// 'charset' => 'Charset',
|
||||
'href' => 'URI',
|
||||
//'hreflang' => 'LanguageCode',
|
||||
'rel' => new HTMLPurifier_AttrDef_HTML_LinkTypes('rel'),
|
||||
'rev' => new HTMLPurifier_AttrDef_HTML_LinkTypes('rev'),
|
||||
//'tabindex' => 'Number',
|
||||
//'type' => 'ContentType',
|
||||
$this->addElement(
|
||||
'a', true, 'Inline', 'Inline', 'Common',
|
||||
array(
|
||||
// 'accesskey' => 'Character',
|
||||
// 'charset' => 'Charset',
|
||||
'href' => 'URI',
|
||||
// 'hreflang' => 'LanguageCode',
|
||||
'rel' => new HTMLPurifier_AttrDef_HTML_LinkTypes('rel'),
|
||||
'rev' => new HTMLPurifier_AttrDef_HTML_LinkTypes('rev'),
|
||||
// 'tabindex' => 'Number',
|
||||
// 'type' => 'ContentType',
|
||||
)
|
||||
);
|
||||
$this->info['a']->content_model = '#PCDATA | Inline';
|
||||
$this->info['a']->content_model_type = 'optional';
|
||||
$this->info['a']->excludes = array('a' => true);
|
||||
}
|
||||
|
||||
|
@ -45,6 +45,56 @@ class HTMLPurifier_HTMLModuleTest extends UnitTestCase
|
||||
|
||||
}
|
||||
|
||||
function test_parseContents() {
|
||||
|
||||
$module = new HTMLPurifier_HTMLModule();
|
||||
|
||||
// pre-defined templates
|
||||
$this->assertIdentical(
|
||||
$module->parseContents('Inline'),
|
||||
array('optional', 'Inline | #PCDATA')
|
||||
);
|
||||
$this->assertIdentical(
|
||||
$module->parseContents('Flow'),
|
||||
array('optional', 'Flow | #PCDATA')
|
||||
);
|
||||
|
||||
// normalization procedures
|
||||
$this->assertIdentical(
|
||||
$module->parseContents('optional: a'),
|
||||
array('optional', 'a')
|
||||
);
|
||||
$this->assertIdentical(
|
||||
$module->parseContents('OPTIONAL :a'),
|
||||
array('optional', 'a')
|
||||
);
|
||||
$this->assertIdentical(
|
||||
$module->parseContents('Optional: a'),
|
||||
array('optional', 'a')
|
||||
);
|
||||
|
||||
// others
|
||||
$this->assertIdentical(
|
||||
$module->parseContents('Optional: a | b | c'),
|
||||
array('optional', 'a | b | c')
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function test_mergeInAttrIncludes() {
|
||||
|
||||
$module = new HTMLPurifier_HTMLModule();
|
||||
|
||||
$attr = array();
|
||||
$module->mergeInAttrIncludes($attr, 'Common');
|
||||
$this->assertIdentical($attr, array(0 => array('Common')));
|
||||
|
||||
$attr = array('a' => 'b');
|
||||
$module->mergeInAttrIncludes($attr, array('Common', 'Good'));
|
||||
$this->assertIdentical($attr, array('a' => 'b', 0 => array('Common', 'Good')));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
Loading…
x
Reference in New Issue
Block a user