2007-02-04 00:07:52 +00:00
|
|
|
<?php
|
|
|
|
|
|
|
|
require_once 'HTMLPurifier/HTMLDefinition.php';
|
|
|
|
|
|
|
|
require_once 'HTMLPurifier/AttrTypes.php';
|
|
|
|
require_once 'HTMLPurifier/AttrCollection.php';
|
2007-02-04 01:52:13 +00:00
|
|
|
|
2007-02-04 20:09:35 +00:00
|
|
|
// we'll manage loading extremely commonly used attr definitions
|
|
|
|
require_once 'HTMLPurifier/AttrDef.php';
|
|
|
|
require_once 'HTMLPurifier/AttrDef/Enum.php';
|
|
|
|
|
|
|
|
// technically speaking, these includes would be more appropriate for
|
|
|
|
// other modules, but we're going to include all the common ones. A
|
|
|
|
// custom one would have to be fed in as an actual object
|
|
|
|
require_once 'HTMLPurifier/ChildDef.php';
|
|
|
|
require_once 'HTMLPurifier/ChildDef/Empty.php';
|
|
|
|
require_once 'HTMLPurifier/ChildDef/Required.php';
|
|
|
|
require_once 'HTMLPurifier/ChildDef/Optional.php';
|
|
|
|
require_once 'HTMLPurifier/ChildDef/StrictBlockquote.php';
|
|
|
|
|
2007-02-04 00:07:52 +00:00
|
|
|
require_once 'HTMLPurifier/HTMLModule.php';
|
|
|
|
require_once 'HTMLPurifier/HTMLModule/Text.php';
|
2007-02-04 01:01:27 +00:00
|
|
|
require_once 'HTMLPurifier/HTMLModule/Hypertext.php';
|
2007-02-04 01:52:13 +00:00
|
|
|
require_once 'HTMLPurifier/HTMLModule/List.php';
|
2007-02-04 04:41:34 +00:00
|
|
|
require_once 'HTMLPurifier/HTMLModule/Presentation.php';
|
2007-02-04 14:56:55 +00:00
|
|
|
require_once 'HTMLPurifier/HTMLModule/Edit.php';
|
2007-02-04 15:28:47 +00:00
|
|
|
require_once 'HTMLPurifier/HTMLModule/Bdo.php';
|
2007-02-04 16:23:26 +00:00
|
|
|
require_once 'HTMLPurifier/HTMLModule/Tables.php';
|
2007-02-04 16:35:40 +00:00
|
|
|
require_once 'HTMLPurifier/HTMLModule/Image.php';
|
2007-02-04 18:27:59 +00:00
|
|
|
require_once 'HTMLPurifier/HTMLModule/StyleAttribute.php';
|
2007-02-04 00:07:52 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Next-generation HTML definition that will supplant HTMLPurifier_HTMLDefinition
|
|
|
|
*/
|
|
|
|
class HTMLPurifier_XHTMLDefinition extends HTMLPurifier_HTMLDefinition
|
|
|
|
{
|
|
|
|
|
2007-02-04 20:09:35 +00:00
|
|
|
/**
|
|
|
|
* Array of HTMLPurifier_Module instances, indexed by module name
|
|
|
|
* @public
|
|
|
|
*/
|
2007-02-04 00:07:52 +00:00
|
|
|
var $modules = array();
|
2007-02-04 20:09:35 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Instance of HTMLPurifier_AttrTypes
|
|
|
|
* @public
|
|
|
|
*/
|
2007-02-04 00:07:52 +00:00
|
|
|
var $attr_types;
|
2007-02-04 20:09:35 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Instance of HTMLPurifier_AttrCollection
|
|
|
|
* @public
|
|
|
|
*/
|
2007-02-04 00:07:52 +00:00
|
|
|
var $attr_collection;
|
2007-02-04 20:09:35 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Nested lookup array of content set name (Block, Inline) to
|
|
|
|
* element name to whether or not it belongs in that content set.
|
|
|
|
* @public
|
|
|
|
*/
|
2007-02-04 03:53:57 +00:00
|
|
|
var $content_sets;
|
2007-02-04 00:07:52 +00:00
|
|
|
|
2007-02-04 20:09:35 +00:00
|
|
|
/**
|
|
|
|
* Performs low-cost, preliminary initialization.
|
|
|
|
* @param $config Instance of HTMLPurifier_Config
|
|
|
|
*/
|
2007-02-04 03:53:57 +00:00
|
|
|
function HTMLPurifier_XHTMLDefinition($config) {
|
2007-02-04 00:07:52 +00:00
|
|
|
|
2007-02-04 14:56:55 +00:00
|
|
|
$this->modules['Text'] = new HTMLPurifier_HTMLModule_Text();
|
|
|
|
$this->modules['Hypertext'] = new HTMLPurifier_HTMLModule_Hypertext();
|
|
|
|
$this->modules['List'] = new HTMLPurifier_HTMLModule_List();
|
|
|
|
$this->modules['Presentation'] = new HTMLPurifier_HTMLModule_Presentation();
|
|
|
|
$this->modules['Edit'] = new HTMLPurifier_HTMLModule_Edit();
|
2007-02-04 15:28:47 +00:00
|
|
|
$this->modules['Bdo'] = new HTMLPurifier_HTMLModule_Bdo();
|
2007-02-04 16:23:26 +00:00
|
|
|
$this->modules['Tables'] = new HTMLPurifier_HTMLModule_Tables();
|
2007-02-04 16:35:40 +00:00
|
|
|
$this->modules['Image'] = new HTMLPurifier_HTMLModule_Image();
|
2007-02-04 18:27:59 +00:00
|
|
|
$this->modules['StyleAttribute']= new HTMLPurifier_HTMLModule_StyleAttribute();
|
2007-02-04 00:07:52 +00:00
|
|
|
|
|
|
|
$this->attr_types = new HTMLPurifier_AttrTypes();
|
|
|
|
$this->attr_collection = new HTMLPurifier_AttrCollection();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2007-02-04 20:09:35 +00:00
|
|
|
/**
|
|
|
|
* Processes internals into form usable by HTMLPurifier internals.
|
|
|
|
* Modifying the definition after calling this function should not
|
|
|
|
* be done.
|
|
|
|
* @param $config Instance of HTMLPurifier_Config
|
|
|
|
*/
|
2007-02-04 00:07:52 +00:00
|
|
|
function setup($config) {
|
|
|
|
|
|
|
|
// perform attribute collection substitutions
|
|
|
|
$this->attr_collection->setup($this->attr_types, $this->modules);
|
|
|
|
|
|
|
|
// populate content_sets based on module hints
|
|
|
|
$content_sets = array();
|
|
|
|
foreach ($this->modules as $module_i => $module) {
|
|
|
|
foreach ($module->content_sets as $key => $value) {
|
|
|
|
if (isset($content_sets[$key])) {
|
|
|
|
// add it into the existing content set
|
|
|
|
$content_sets[$key] = $content_sets[$key] . ' | ' . $value;
|
|
|
|
} else {
|
|
|
|
$content_sets[$key] = $value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2007-02-04 03:53:57 +00:00
|
|
|
|
2007-02-04 00:07:52 +00:00
|
|
|
// perform content_set expansions
|
|
|
|
foreach ($content_sets as $i => $set) {
|
|
|
|
// only performed once, so infinite recursion is not
|
|
|
|
// a problem, you'll just have a stray $Set lying around
|
|
|
|
// at the end
|
|
|
|
$content_sets[$i] =
|
|
|
|
str_replace(
|
|
|
|
array_keys($content_sets),
|
|
|
|
array_values($content_sets),
|
|
|
|
$set);
|
|
|
|
}
|
2007-02-04 03:53:57 +00:00
|
|
|
// define convenient variables
|
2007-02-04 00:07:52 +00:00
|
|
|
$content_sets_keys = array_keys($content_sets);
|
|
|
|
$content_sets_values = array_values($content_sets);
|
2007-02-04 03:53:57 +00:00
|
|
|
foreach ($content_sets as $name => $set) {
|
|
|
|
$this->content_sets[$name] = $this->convertToLookup($set);
|
|
|
|
}
|
2007-02-04 00:07:52 +00:00
|
|
|
|
|
|
|
foreach ($this->modules as $module_i => $module) {
|
2007-02-04 03:53:57 +00:00
|
|
|
foreach ($module->info as $name => $def) {
|
|
|
|
$def =& $this->modules[$module_i]->info[$name];
|
2007-02-04 00:07:52 +00:00
|
|
|
|
|
|
|
// attribute value expansions
|
2007-02-04 03:53:57 +00:00
|
|
|
$this->attr_collection->performInclusions($def->attr);
|
2007-02-04 16:23:26 +00:00
|
|
|
$this->attr_collection->expandIdentifiers(
|
2007-02-04 03:53:57 +00:00
|
|
|
$def->attr, $this->attr_types);
|
2007-02-04 00:07:52 +00:00
|
|
|
|
|
|
|
// perform content model expansions
|
2007-02-04 03:53:57 +00:00
|
|
|
$content_model = $def->content_model;
|
2007-02-04 00:07:52 +00:00
|
|
|
if (is_string($content_model)) {
|
2007-02-04 03:53:57 +00:00
|
|
|
if (strpos($content_model, 'Inline') !== false) {
|
2007-02-04 20:09:35 +00:00
|
|
|
if ($name != 'del' && $name != 'ins') {
|
|
|
|
// this is for you, ins/del
|
|
|
|
$def->descendants_are_inline = true;
|
|
|
|
}
|
2007-02-04 03:53:57 +00:00
|
|
|
}
|
|
|
|
$def->content_model = str_replace(
|
2007-02-04 00:07:52 +00:00
|
|
|
$content_sets_keys, $content_sets_values, $content_model);
|
|
|
|
}
|
|
|
|
|
2007-02-04 01:01:27 +00:00
|
|
|
// get child def from content model
|
2007-02-04 03:53:57 +00:00
|
|
|
$def->child = $this->getChildDef($def);
|
2007-02-04 01:01:27 +00:00
|
|
|
|
2007-02-04 00:07:52 +00:00
|
|
|
// setup info
|
2007-02-04 03:53:57 +00:00
|
|
|
$this->info[$name] = $def;
|
|
|
|
if ($this->info_parent == $name) {
|
|
|
|
$this->info_parent_def = $this->info[$name];
|
2007-02-04 00:07:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-02-04 15:28:47 +00:00
|
|
|
$this->setupAttrTransform($config);
|
|
|
|
$this->setupBlockWrapper($config);
|
|
|
|
$this->setupParent($config);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2007-02-04 20:09:35 +00:00
|
|
|
/**
|
|
|
|
* Sets up attribute transformations
|
|
|
|
* @param $config Instance of HTMLPurifier_Config
|
|
|
|
*/
|
2007-02-04 15:28:47 +00:00
|
|
|
function setupAttrTransform($config) {
|
|
|
|
$this->info_attr_transform_post[] = new HTMLPurifier_AttrTransform_Lang();
|
|
|
|
}
|
|
|
|
|
2007-02-04 20:09:35 +00:00
|
|
|
/**
|
|
|
|
* Sets up block wrapper based on config
|
|
|
|
* @param $config Instance of HTMLPurifier_Config
|
|
|
|
*/
|
2007-02-04 15:28:47 +00:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-02-04 20:09:35 +00:00
|
|
|
/**
|
|
|
|
* Sets up parent of fragment based on config
|
|
|
|
* @param $config Instance of HTMLPurifier_Config
|
|
|
|
*/
|
2007-02-04 15:28:47 +00:00
|
|
|
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];
|
2007-02-04 00:07:52 +00:00
|
|
|
}
|
|
|
|
|
2007-02-04 20:09:35 +00:00
|
|
|
/**
|
|
|
|
* Instantiates a ChildDef based on content_model and content_model_type
|
|
|
|
* member variables in HTMLPurifier_ElementDef
|
|
|
|
* @note This will also defer to modules for custom HTMLPurifier_ChildDef
|
|
|
|
* subclasses that need content set expansion
|
|
|
|
* @param $def HTMLPurifier_ElementDef to have ChildDef extracted
|
|
|
|
* @return HTMLPurifier_ChildDef corresponding to ElementDef
|
|
|
|
*/
|
2007-02-04 03:53:57 +00:00
|
|
|
function getChildDef($def) {
|
|
|
|
$value = $def->content_model;
|
2007-02-04 20:09:35 +00:00
|
|
|
if (is_object($value)) return $value; // direct object, return
|
|
|
|
switch ($def->content_model_type) {
|
2007-02-04 00:07:52 +00:00
|
|
|
case 'required':
|
|
|
|
return new HTMLPurifier_ChildDef_Required($value);
|
|
|
|
case 'optional':
|
|
|
|
return new HTMLPurifier_ChildDef_Optional($value);
|
|
|
|
case 'empty':
|
|
|
|
return new HTMLPurifier_ChildDef_Empty();
|
|
|
|
case 'strictblockquote':
|
2007-02-04 03:53:57 +00:00
|
|
|
return new HTMLPurifier_ChildDef_StrictBlockquote($value);
|
2007-02-04 00:07:52 +00:00
|
|
|
case 'custom':
|
|
|
|
return new HTMLPurifier_ChildDef_Custom($value);
|
|
|
|
}
|
2007-02-04 20:09:35 +00:00
|
|
|
// defer to modules, see if they know what child_def to use
|
|
|
|
foreach ($this->modules as $module) {
|
|
|
|
if (!$module->defines_child_def) continue; // save a func call
|
|
|
|
$return = $module->getChildDef($def);
|
|
|
|
if ($return !== false) return $return;
|
|
|
|
}
|
|
|
|
// error-out
|
|
|
|
trigger_error(
|
|
|
|
'Could not determine which ChildDef class to instantiate',
|
|
|
|
E_USER_ERROR
|
|
|
|
);
|
|
|
|
return false;
|
2007-02-04 00:07:52 +00:00
|
|
|
}
|
|
|
|
|
2007-02-04 20:09:35 +00:00
|
|
|
/**
|
|
|
|
* Converts a string list of elements separated by pipes into
|
|
|
|
* a lookup array.
|
|
|
|
* @param $string List of elements
|
|
|
|
* @return Lookup array of elements
|
|
|
|
*/
|
2007-02-04 03:53:57 +00:00
|
|
|
function convertToLookup($string) {
|
|
|
|
$array = explode('|', str_replace(' ', '', $string));
|
2007-02-04 15:28:47 +00:00
|
|
|
$ret = array();
|
2007-02-04 03:53:57 +00:00
|
|
|
foreach ($array as $i => $k) {
|
2007-02-04 15:28:47 +00:00
|
|
|
$ret[$k] = true;
|
2007-02-04 03:53:57 +00:00
|
|
|
}
|
2007-02-04 15:28:47 +00:00
|
|
|
return $ret;
|
2007-02-04 03:53:57 +00:00
|
|
|
}
|
|
|
|
|
2007-02-04 00:07:52 +00:00
|
|
|
}
|
|
|
|
|
2007-02-04 03:53:57 +00:00
|
|
|
?>
|