summaryrefslogtreecommitdiffstats
path: root/library/vendor/HTMLPurifier/HTMLModule
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--library/vendor/HTMLPurifier/HTMLModule.php285
-rw-r--r--library/vendor/HTMLPurifier/HTMLModule/Bdo.php44
-rw-r--r--library/vendor/HTMLPurifier/HTMLModule/CommonAttributes.php32
-rw-r--r--library/vendor/HTMLPurifier/HTMLModule/Edit.php55
-rw-r--r--library/vendor/HTMLPurifier/HTMLModule/Forms.php194
-rw-r--r--library/vendor/HTMLPurifier/HTMLModule/Hypertext.php40
-rw-r--r--library/vendor/HTMLPurifier/HTMLModule/Iframe.php51
-rw-r--r--library/vendor/HTMLPurifier/HTMLModule/Image.php49
-rw-r--r--library/vendor/HTMLPurifier/HTMLModule/Legacy.php186
-rw-r--r--library/vendor/HTMLPurifier/HTMLModule/List.php51
-rw-r--r--library/vendor/HTMLPurifier/HTMLModule/Name.php26
-rw-r--r--library/vendor/HTMLPurifier/HTMLModule/Nofollow.php25
-rw-r--r--library/vendor/HTMLPurifier/HTMLModule/NonXMLCommonAttributes.php20
-rw-r--r--library/vendor/HTMLPurifier/HTMLModule/Object.php62
-rw-r--r--library/vendor/HTMLPurifier/HTMLModule/Presentation.php42
-rw-r--r--library/vendor/HTMLPurifier/HTMLModule/Proprietary.php40
-rw-r--r--library/vendor/HTMLPurifier/HTMLModule/Ruby.php36
-rw-r--r--library/vendor/HTMLPurifier/HTMLModule/SafeEmbed.php40
-rw-r--r--library/vendor/HTMLPurifier/HTMLModule/SafeObject.php62
-rw-r--r--library/vendor/HTMLPurifier/HTMLModule/SafeScripting.php40
-rw-r--r--library/vendor/HTMLPurifier/HTMLModule/Scripting.php73
-rw-r--r--library/vendor/HTMLPurifier/HTMLModule/StyleAttribute.php33
-rw-r--r--library/vendor/HTMLPurifier/HTMLModule/Tables.php75
-rw-r--r--library/vendor/HTMLPurifier/HTMLModule/Target.php28
-rw-r--r--library/vendor/HTMLPurifier/HTMLModule/TargetBlank.php24
-rw-r--r--library/vendor/HTMLPurifier/HTMLModule/TargetNoopener.php21
-rw-r--r--library/vendor/HTMLPurifier/HTMLModule/TargetNoreferrer.php21
-rw-r--r--library/vendor/HTMLPurifier/HTMLModule/Text.php87
-rw-r--r--library/vendor/HTMLPurifier/HTMLModule/Tidy.php227
-rw-r--r--library/vendor/HTMLPurifier/HTMLModule/Tidy/Name.php33
-rw-r--r--library/vendor/HTMLPurifier/HTMLModule/Tidy/Proprietary.php34
-rw-r--r--library/vendor/HTMLPurifier/HTMLModule/Tidy/Strict.php43
-rw-r--r--library/vendor/HTMLPurifier/HTMLModule/Tidy/Transitional.php16
-rw-r--r--library/vendor/HTMLPurifier/HTMLModule/Tidy/XHTML.php26
-rw-r--r--library/vendor/HTMLPurifier/HTMLModule/Tidy/XHTMLAndHTML4.php182
-rw-r--r--library/vendor/HTMLPurifier/HTMLModule/XMLCommonAttributes.php20
-rw-r--r--library/vendor/HTMLPurifier/HTMLModuleManager.php467
37 files changed, 2790 insertions, 0 deletions
diff --git a/library/vendor/HTMLPurifier/HTMLModule.php b/library/vendor/HTMLPurifier/HTMLModule.php
new file mode 100644
index 0000000..9dbb987
--- /dev/null
+++ b/library/vendor/HTMLPurifier/HTMLModule.php
@@ -0,0 +1,285 @@
+<?php
+
+/**
+ * Represents an XHTML 1.1 module, with information on elements, tags
+ * and attributes.
+ * @note Even though this is technically XHTML 1.1, it is also used for
+ * regular HTML parsing. We are using modulization as a convenient
+ * way to represent the internals of HTMLDefinition, and our
+ * implementation is by no means conforming and does not directly
+ * use the normative DTDs or XML schemas.
+ * @note The public variables in a module should almost directly
+ * correspond to the variables in HTMLPurifier_HTMLDefinition.
+ * However, the prefix info carries no special meaning in these
+ * objects (include it anyway if that's the correspondence though).
+ * @todo Consider making some member functions protected
+ */
+
+class HTMLPurifier_HTMLModule
+{
+
+ // -- Overloadable ----------------------------------------------------
+
+ /**
+ * Short unique string identifier of the module.
+ * @type string
+ */
+ public $name;
+
+ /**
+ * Informally, a list of elements this module changes.
+ * Not used in any significant way.
+ * @type array
+ */
+ public $elements = array();
+
+ /**
+ * Associative array of element names to element definitions.
+ * Some definitions may be incomplete, to be merged in later
+ * with the full definition.
+ * @type array
+ */
+ public $info = array();
+
+ /**
+ * Associative array of content set names to content set additions.
+ * This is commonly used to, say, add an A element to the Inline
+ * content set. This corresponds to an internal variable $content_sets
+ * and NOT info_content_sets member variable of HTMLDefinition.
+ * @type array
+ */
+ public $content_sets = array();
+
+ /**
+ * Associative array of attribute collection names to attribute
+ * collection additions. More rarely used for adding attributes to
+ * the global collections. Example is the StyleAttribute module adding
+ * the style attribute to the Core. Corresponds to HTMLDefinition's
+ * attr_collections->info, since the object's data is only info,
+ * with extra behavior associated with it.
+ * @type array
+ */
+ public $attr_collections = array();
+
+ /**
+ * Associative array of deprecated tag name to HTMLPurifier_TagTransform.
+ * @type array
+ */
+ public $info_tag_transform = array();
+
+ /**
+ * List of HTMLPurifier_AttrTransform to be performed before validation.
+ * @type array
+ */
+ public $info_attr_transform_pre = array();
+
+ /**
+ * List of HTMLPurifier_AttrTransform to be performed after validation.
+ * @type array
+ */
+ public $info_attr_transform_post = array();
+
+ /**
+ * List of HTMLPurifier_Injector to be performed during well-formedness fixing.
+ * An injector will only be invoked if all of it's pre-requisites are met;
+ * if an injector fails setup, there will be no error; it will simply be
+ * silently disabled.
+ * @type array
+ */
+ public $info_injector = array();
+
+ /**
+ * Boolean flag that indicates whether or not getChildDef is implemented.
+ * For optimization reasons: may save a call to a function. Be sure
+ * to set it if you do implement getChildDef(), otherwise it will have
+ * no effect!
+ * @type bool
+ */
+ public $defines_child_def = false;
+
+ /**
+ * Boolean flag whether or not this module is safe. If it is not safe, all
+ * of its members are unsafe. Modules are safe by default (this might be
+ * slightly dangerous, but it doesn't make much sense to force HTML Purifier,
+ * which is based off of safe HTML, to explicitly say, "This is safe," even
+ * though there are modules which are "unsafe")
+ *
+ * @type bool
+ * @note Previously, safety could be applied at an element level granularity.
+ * We've removed this ability, so in order to add "unsafe" elements
+ * or attributes, a dedicated module with this property set to false
+ * must be used.
+ */
+ public $safe = true;
+
+ /**
+ * Retrieves a proper HTMLPurifier_ChildDef subclass based on
+ * content_model and content_model_type member variables of
+ * the HTMLPurifier_ElementDef class. There is a similar function
+ * in HTMLPurifier_HTMLDefinition.
+ * @param HTMLPurifier_ElementDef $def
+ * @return HTMLPurifier_ChildDef subclass
+ */
+ public function getChildDef($def)
+ {
+ return false;
+ }
+
+ // -- Convenience -----------------------------------------------------
+
+ /**
+ * Convenience function that sets up a new element
+ * @param string $element Name of element to add
+ * @param string|bool $type What content set should element be registered to?
+ * Set as false to skip this step.
+ * @param string|HTMLPurifier_ChildDef $contents Allowed children in form of:
+ * "$content_model_type: $content_model"
+ * @param array|string $attr_includes What attribute collections to register to
+ * element?
+ * @param array $attr What unique attributes does the element define?
+ * @see HTMLPurifier_ElementDef:: for in-depth descriptions of these parameters.
+ * @return HTMLPurifier_ElementDef Created element definition object, so you
+ * can set advanced parameters
+ */
+ public function addElement($element, $type, $contents, $attr_includes = array(), $attr = array())
+ {
+ $this->elements[] = $element;
+ // parse content_model
+ list($content_model_type, $content_model) = $this->parseContents($contents);
+ // merge in attribute inclusions
+ $this->mergeInAttrIncludes($attr, $attr_includes);
+ // add element to content sets
+ if ($type) {
+ $this->addElementToContentSet($element, $type);
+ }
+ // create element
+ $this->info[$element] = HTMLPurifier_ElementDef::create(
+ $content_model,
+ $content_model_type,
+ $attr
+ );
+ // literal object $contents means direct child manipulation
+ if (!is_string($contents)) {
+ $this->info[$element]->child = $contents;
+ }
+ return $this->info[$element];
+ }
+
+ /**
+ * Convenience function that creates a totally blank, non-standalone
+ * element.
+ * @param string $element Name of element to create
+ * @return HTMLPurifier_ElementDef Created element
+ */
+ public function addBlankElement($element)
+ {
+ if (!isset($this->info[$element])) {
+ $this->elements[] = $element;
+ $this->info[$element] = new HTMLPurifier_ElementDef();
+ $this->info[$element]->standalone = false;
+ } else {
+ trigger_error("Definition for $element already exists in module, cannot redefine");
+ }
+ return $this->info[$element];
+ }
+
+ /**
+ * Convenience function that registers an element to a content set
+ * @param string $element Element to register
+ * @param string $type Name content set (warning: case sensitive, usually upper-case
+ * first letter)
+ */
+ public function addElementToContentSet($element, $type)
+ {
+ if (!isset($this->content_sets[$type])) {
+ $this->content_sets[$type] = '';
+ } else {
+ $this->content_sets[$type] .= ' | ';
+ }
+ $this->content_sets[$type] .= $element;
+ }
+
+ /**
+ * Convenience function that transforms single-string contents
+ * into separate content model and content model type
+ * @param string $contents Allowed children in form of:
+ * "$content_model_type: $content_model"
+ * @return array
+ * @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.
+ */
+ public function parseContents($contents)
+ {
+ if (!is_string($contents)) {
+ return array(null, null);
+ } // defer
+ switch ($contents) {
+ // check for shorthand content model forms
+ case 'Empty':
+ return array('empty', '');
+ case 'Inline':
+ return array('optional', 'Inline | #PCDATA');
+ case 'Flow':
+ return array('optional', 'Flow | #PCDATA');
+ }
+ 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 array $attr Reference to attr array to modify
+ * @param array $attr_includes Array of includes / string include to merge in
+ */
+ public 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;
+ }
+
+ /**
+ * Convenience function that generates a lookup table with boolean
+ * true as value.
+ * @param string $list List of values to turn into a lookup
+ * @note You can also pass an arbitrary number of arguments in
+ * place of the regular argument
+ * @return array array equivalent of list
+ */
+ public function makeLookup($list)
+ {
+ $args = func_get_args();
+ if (is_string($list)) {
+ $list = $args;
+ }
+ $ret = array();
+ foreach ($list as $value) {
+ if (is_null($value)) {
+ continue;
+ }
+ $ret[$value] = true;
+ }
+ return $ret;
+ }
+
+ /**
+ * Lazy load construction of the module after determining whether
+ * or not it's needed, and also when a finalized configuration object
+ * is available.
+ * @param HTMLPurifier_Config $config
+ */
+ public function setup($config)
+ {
+ }
+}
+
+// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLModule/Bdo.php b/library/vendor/HTMLPurifier/HTMLModule/Bdo.php
new file mode 100644
index 0000000..1e67c79
--- /dev/null
+++ b/library/vendor/HTMLPurifier/HTMLModule/Bdo.php
@@ -0,0 +1,44 @@
+<?php
+
+/**
+ * XHTML 1.1 Bi-directional Text Module, defines elements that
+ * declare directionality of content. Text Extension Module.
+ */
+class HTMLPurifier_HTMLModule_Bdo extends HTMLPurifier_HTMLModule
+{
+
+ /**
+ * @type string
+ */
+ public $name = 'Bdo';
+
+ /**
+ * @type array
+ */
+ public $attr_collections = array(
+ 'I18N' => array('dir' => false)
+ );
+
+ /**
+ * @param HTMLPurifier_Config $config
+ */
+ public function setup($config)
+ {
+ $bdo = $this->addElement(
+ 'bdo',
+ 'Inline',
+ 'Inline',
+ array('Core', 'Lang'),
+ array(
+ 'dir' => 'Enum#ltr,rtl', // required
+ // The Abstract Module specification has the attribute
+ // inclusions wrong for bdo: bdo allows Lang
+ )
+ );
+ $bdo->attr_transform_post[] = new HTMLPurifier_AttrTransform_BdoDir();
+
+ $this->attr_collections['I18N']['dir'] = 'Enum#ltr,rtl';
+ }
+}
+
+// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLModule/CommonAttributes.php b/library/vendor/HTMLPurifier/HTMLModule/CommonAttributes.php
new file mode 100644
index 0000000..7220c14
--- /dev/null
+++ b/library/vendor/HTMLPurifier/HTMLModule/CommonAttributes.php
@@ -0,0 +1,32 @@
+<?php
+
+class HTMLPurifier_HTMLModule_CommonAttributes extends HTMLPurifier_HTMLModule
+{
+ /**
+ * @type string
+ */
+ public $name = 'CommonAttributes';
+
+ /**
+ * @type array
+ */
+ public $attr_collections = array(
+ 'Core' => array(
+ 0 => array('Style'),
+ // 'xml:space' => false,
+ 'class' => 'Class',
+ 'id' => 'ID',
+ 'title' => 'CDATA',
+ 'contenteditable' => 'ContentEditable',
+ ),
+ 'Lang' => array(),
+ 'I18N' => array(
+ 0 => array('Lang'), // proprietary, for xml:lang/lang
+ ),
+ 'Common' => array(
+ 0 => array('Core', 'I18N')
+ )
+ );
+}
+
+// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLModule/Edit.php b/library/vendor/HTMLPurifier/HTMLModule/Edit.php
new file mode 100644
index 0000000..a9042a3
--- /dev/null
+++ b/library/vendor/HTMLPurifier/HTMLModule/Edit.php
@@ -0,0 +1,55 @@
+<?php
+
+/**
+ * XHTML 1.1 Edit Module, defines editing-related elements. Text Extension
+ * Module.
+ */
+class HTMLPurifier_HTMLModule_Edit extends HTMLPurifier_HTMLModule
+{
+
+ /**
+ * @type string
+ */
+ public $name = 'Edit';
+
+ /**
+ * @param HTMLPurifier_Config $config
+ */
+ public function setup($config)
+ {
+ $contents = 'Chameleon: #PCDATA | Inline ! #PCDATA | Flow';
+ $attr = array(
+ 'cite' => 'URI',
+ // 'datetime' => 'Datetime', // not implemented
+ );
+ $this->addElement('del', 'Inline', $contents, 'Common', $attr);
+ $this->addElement('ins', '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)
+
+ /**
+ * @type bool
+ */
+ public $defines_child_def = true;
+
+ /**
+ * @param HTMLPurifier_ElementDef $def
+ * @return HTMLPurifier_ChildDef_Chameleon
+ */
+ public function getChildDef($def)
+ {
+ if ($def->content_model_type != 'chameleon') {
+ return false;
+ }
+ $value = explode('!', $def->content_model);
+ return new HTMLPurifier_ChildDef_Chameleon($value[0], $value[1]);
+ }
+}
+
+// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLModule/Forms.php b/library/vendor/HTMLPurifier/HTMLModule/Forms.php
new file mode 100644
index 0000000..eb0edcf
--- /dev/null
+++ b/library/vendor/HTMLPurifier/HTMLModule/Forms.php
@@ -0,0 +1,194 @@
+<?php
+
+/**
+ * XHTML 1.1 Forms module, defines all form-related elements found in HTML 4.
+ */
+class HTMLPurifier_HTMLModule_Forms extends HTMLPurifier_HTMLModule
+{
+ /**
+ * @type string
+ */
+ public $name = 'Forms';
+
+ /**
+ * @type bool
+ */
+ public $safe = false;
+
+ /**
+ * @type array
+ */
+ public $content_sets = array(
+ 'Block' => 'Form',
+ 'Inline' => 'Formctrl',
+ );
+
+ /**
+ * @param HTMLPurifier_Config $config
+ */
+ public function setup($config)
+ {
+ if ($config->get('HTML.Forms')) {
+ $this->safe = true;
+ }
+
+ $form = $this->addElement(
+ 'form',
+ 'Form',
+ 'Required: Heading | List | Block | fieldset',
+ 'Common',
+ array(
+ 'accept' => 'ContentTypes',
+ 'accept-charset' => 'Charsets',
+ 'action*' => 'URI',
+ 'method' => 'Enum#get,post',
+ // really ContentType, but these two are the only ones used today
+ 'enctype' => 'Enum#application/x-www-form-urlencoded,multipart/form-data',
+ )
+ );
+ $form->excludes = array('form' => true);
+
+ $input = $this->addElement(
+ 'input',
+ 'Formctrl',
+ 'Empty',
+ 'Common',
+ array(
+ 'accept' => 'ContentTypes',
+ 'accesskey' => 'Character',
+ 'alt' => 'Text',
+ 'checked' => 'Bool#checked',
+ 'disabled' => 'Bool#disabled',
+ 'maxlength' => 'Number',
+ 'name' => 'CDATA',
+ 'readonly' => 'Bool#readonly',
+ 'size' => 'Number',
+ 'src' => 'URI#embedded',
+ 'tabindex' => 'Number',
+ 'type' => 'Enum#text,password,checkbox,button,radio,submit,reset,file,hidden,image',
+ 'value' => 'CDATA',
+ )
+ );
+ $input->attr_transform_post[] = new HTMLPurifier_AttrTransform_Input();
+
+ $this->addElement(
+ 'select',
+ 'Formctrl',
+ 'Required: optgroup | option',
+ 'Common',
+ array(
+ 'disabled' => 'Bool#disabled',
+ 'multiple' => 'Bool#multiple',
+ 'name' => 'CDATA',
+ 'size' => 'Number',
+ 'tabindex' => 'Number',
+ )
+ );
+
+ $this->addElement(
+ 'option',
+ false,
+ 'Optional: #PCDATA',
+ 'Common',
+ array(
+ 'disabled' => 'Bool#disabled',
+ 'label' => 'Text',
+ 'selected' => 'Bool#selected',
+ 'value' => 'CDATA',
+ )
+ );
+ // It's illegal for there to be more than one selected, but not
+ // be multiple. Also, no selected means undefined behavior. This might
+ // be difficult to implement; perhaps an injector, or a context variable.
+
+ $textarea = $this->addElement(
+ 'textarea',
+ 'Formctrl',
+ 'Optional: #PCDATA',
+ 'Common',
+ array(
+ 'accesskey' => 'Character',
+ 'cols*' => 'Number',
+ 'disabled' => 'Bool#disabled',
+ 'name' => 'CDATA',
+ 'readonly' => 'Bool#readonly',
+ 'rows*' => 'Number',
+ 'tabindex' => 'Number',
+ )
+ );
+ $textarea->attr_transform_pre[] = new HTMLPurifier_AttrTransform_Textarea();
+
+ $button = $this->addElement(
+ 'button',
+ 'Formctrl',
+ 'Optional: #PCDATA | Heading | List | Block | Inline',
+ 'Common',
+ array(
+ 'accesskey' => 'Character',
+ 'disabled' => 'Bool#disabled',
+ 'name' => 'CDATA',
+ 'tabindex' => 'Number',
+ 'type' => 'Enum#button,submit,reset',
+ 'value' => 'CDATA',
+ )
+ );
+
+ // For exclusions, ideally we'd specify content sets, not literal elements
+ $button->excludes = $this->makeLookup(
+ 'form',
+ 'fieldset', // Form
+ 'input',
+ 'select',
+ 'textarea',
+ 'label',
+ 'button', // Formctrl
+ 'a', // as per HTML 4.01 spec, this is omitted by modularization
+ 'isindex',
+ 'iframe' // legacy items
+ );
+
+ // Extra exclusion: img usemap="" is not permitted within this element.
+ // We'll omit this for now, since we don't have any good way of
+ // indicating it yet.
+
+ // This is HIGHLY user-unfriendly; we need a custom child-def for this
+ $this->addElement('fieldset', 'Form', 'Custom: (#WS?,legend,(Flow|#PCDATA)*)', 'Common');
+
+ $label = $this->addElement(
+ 'label',
+ 'Formctrl',
+ 'Optional: #PCDATA | Inline',
+ 'Common',
+ array(
+ 'accesskey' => 'Character',
+ // 'for' => 'IDREF', // IDREF not implemented, cannot allow
+ )
+ );
+ $label->excludes = array('label' => true);
+
+ $this->addElement(
+ 'legend',
+ false,
+ 'Optional: #PCDATA | Inline',
+ 'Common',
+ array(
+ 'accesskey' => 'Character',
+ )
+ );
+
+ $this->addElement(
+ 'optgroup',
+ false,
+ 'Required: option',
+ 'Common',
+ array(
+ 'disabled' => 'Bool#disabled',
+ 'label*' => 'Text',
+ )
+ );
+ // Don't forget an injector for <isindex>. This one's a little complex
+ // because it maps to multiple elements.
+ }
+}
+
+// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLModule/Hypertext.php b/library/vendor/HTMLPurifier/HTMLModule/Hypertext.php
new file mode 100644
index 0000000..72d7a31
--- /dev/null
+++ b/library/vendor/HTMLPurifier/HTMLModule/Hypertext.php
@@ -0,0 +1,40 @@
+<?php
+
+/**
+ * XHTML 1.1 Hypertext Module, defines hypertext links. Core Module.
+ */
+class HTMLPurifier_HTMLModule_Hypertext extends HTMLPurifier_HTMLModule
+{
+
+ /**
+ * @type string
+ */
+ public $name = 'Hypertext';
+
+ /**
+ * @param HTMLPurifier_Config $config
+ */
+ public function setup($config)
+ {
+ $a = $this->addElement(
+ 'a',
+ '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',
+ )
+ );
+ $a->formatting = true;
+ $a->excludes = array('a' => true);
+ }
+}
+
+// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLModule/Iframe.php b/library/vendor/HTMLPurifier/HTMLModule/Iframe.php
new file mode 100644
index 0000000..f7e7c91
--- /dev/null
+++ b/library/vendor/HTMLPurifier/HTMLModule/Iframe.php
@@ -0,0 +1,51 @@
+<?php
+
+/**
+ * XHTML 1.1 Iframe Module provides inline frames.
+ *
+ * @note This module is not considered safe unless an Iframe
+ * whitelisting mechanism is specified. Currently, the only
+ * such mechanism is %URL.SafeIframeRegexp
+ */
+class HTMLPurifier_HTMLModule_Iframe extends HTMLPurifier_HTMLModule
+{
+
+ /**
+ * @type string
+ */
+ public $name = 'Iframe';
+
+ /**
+ * @type bool
+ */
+ public $safe = false;
+
+ /**
+ * @param HTMLPurifier_Config $config
+ */
+ public function setup($config)
+ {
+ if ($config->get('HTML.SafeIframe')) {
+ $this->safe = true;
+ }
+ $this->addElement(
+ 'iframe',
+ 'Inline',
+ 'Flow',
+ 'Common',
+ array(
+ 'src' => 'URI#embedded',
+ 'width' => 'Length',
+ 'height' => 'Length',
+ 'name' => 'ID',
+ 'scrolling' => 'Enum#yes,no,auto',
+ 'frameborder' => 'Enum#0,1',
+ 'longdesc' => 'URI',
+ 'marginheight' => 'Pixels',
+ 'marginwidth' => 'Pixels',
+ )
+ );
+ }
+}
+
+// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLModule/Image.php b/library/vendor/HTMLPurifier/HTMLModule/Image.php
new file mode 100644
index 0000000..0f5fdb3
--- /dev/null
+++ b/library/vendor/HTMLPurifier/HTMLModule/Image.php
@@ -0,0 +1,49 @@
+<?php
+
+/**
+ * XHTML 1.1 Image Module provides basic image embedding.
+ * @note There is specialized code for removing empty images in
+ * HTMLPurifier_Strategy_RemoveForeignElements
+ */
+class HTMLPurifier_HTMLModule_Image extends HTMLPurifier_HTMLModule
+{
+
+ /**
+ * @type string
+ */
+ public $name = 'Image';
+
+ /**
+ * @param HTMLPurifier_Config $config
+ */
+ public function setup($config)
+ {
+ $max = $config->get('HTML.MaxImgLength');
+ $img = $this->addElement(
+ 'img',
+ 'Inline',
+ 'Empty',
+ 'Common',
+ array(
+ 'alt*' => 'Text',
+ // According to the spec, it's Length, but percents can
+ // be abused, so we allow only Pixels.
+ 'height' => 'Pixels#' . $max,
+ 'width' => 'Pixels#' . $max,
+ 'longdesc' => 'URI',
+ 'src*' => new HTMLPurifier_AttrDef_URI(true), // embedded
+ )
+ );
+ if ($max === null || $config->get('HTML.Trusted')) {
+ $img->attr['height'] =
+ $img->attr['width'] = 'Length';
+ }
+
+ // kind of strange, but splitting things up would be inefficient
+ $img->attr_transform_pre[] =
+ $img->attr_transform_post[] =
+ new HTMLPurifier_AttrTransform_ImgRequired();
+ }
+}
+
+// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLModule/Legacy.php b/library/vendor/HTMLPurifier/HTMLModule/Legacy.php
new file mode 100644
index 0000000..86b5299
--- /dev/null
+++ b/library/vendor/HTMLPurifier/HTMLModule/Legacy.php
@@ -0,0 +1,186 @@
+<?php
+
+/**
+ * XHTML 1.1 Legacy module defines elements that were previously
+ * deprecated.
+ *
+ * @note Not all legacy elements have been implemented yet, which
+ * is a bit of a reverse problem as compared to browsers! In
+ * addition, this legacy module may implement a bit more than
+ * mandated by XHTML 1.1.
+ *
+ * This module can be used in combination with TransformToStrict in order
+ * to transform as many deprecated elements as possible, but retain
+ * questionably deprecated elements that do not have good alternatives
+ * as well as transform elements that don't have an implementation.
+ * See docs/ref-strictness.txt for more details.
+ */
+
+class HTMLPurifier_HTMLModule_Legacy extends HTMLPurifier_HTMLModule
+{
+ /**
+ * @type string
+ */
+ public $name = 'Legacy';
+
+ /**
+ * @param HTMLPurifier_Config $config
+ */
+ public function setup($config)
+ {
+ $this->addElement(
+ 'basefont',
+ 'Inline',
+ 'Empty',
+ null,
+ array(
+ 'color' => 'Color',
+ 'face' => 'Text', // extremely broad, we should
+ 'size' => 'Text', // tighten it
+ 'id' => 'ID'
+ )
+ );
+ $this->addElement('center', 'Block', 'Flow', 'Common');
+ $this->addElement(
+ 'dir',
+ 'Block',
+ 'Required: li',
+ 'Common',
+ array(
+ 'compact' => 'Bool#compact'
+ )
+ );
+ $this->addElement(
+ 'font',
+ 'Inline',
+ 'Inline',
+ array('Core', 'I18N'),
+ array(
+ 'color' => 'Color',
+ 'face' => 'Text', // extremely broad, we should
+ 'size' => 'Text', // tighten it
+ )
+ );
+ $this->addElement(
+ 'menu',
+ 'Block',
+ 'Required: li',
+ 'Common',
+ array(
+ 'compact' => 'Bool#compact'
+ )
+ );
+
+ $s = $this->addElement('s', 'Inline', 'Inline', 'Common');
+ $s->formatting = true;
+
+ $strike = $this->addElement('strike', 'Inline', 'Inline', 'Common');
+ $strike->formatting = true;
+
+ $u = $this->addElement('u', 'Inline', 'Inline', 'Common');
+ $u->formatting = true;
+
+ // setup modifications to old elements
+
+ $align = 'Enum#left,right,center,justify';
+
+ $address = $this->addBlankElement('address');
+ $address->content_model = 'Inline | #PCDATA | p';
+ $address->content_model_type = 'optional';
+ $address->child = false;
+
+ $blockquote = $this->addBlankElement('blockquote');
+ $blockquote->content_model = 'Flow | #PCDATA';
+ $blockquote->content_model_type = 'optional';
+ $blockquote->child = false;
+
+ $br = $this->addBlankElement('br');
+ $br->attr['clear'] = 'Enum#left,all,right,none';
+
+ $caption = $this->addBlankElement('caption');
+ $caption->attr['align'] = 'Enum#top,bottom,left,right';
+
+ $div = $this->addBlankElement('div');
+ $div->attr['align'] = $align;
+
+ $dl = $this->addBlankElement('dl');
+ $dl->attr['compact'] = 'Bool#compact';
+
+ for ($i = 1; $i <= 6; $i++) {
+ $h = $this->addBlankElement("h$i");
+ $h->attr['align'] = $align;
+ }
+
+ $hr = $this->addBlankElement('hr');
+ $hr->attr['align'] = $align;
+ $hr->attr['noshade'] = 'Bool#noshade';
+ $hr->attr['size'] = 'Pixels';
+ $hr->attr['width'] = 'Length';
+
+ $img = $this->addBlankElement('img');
+ $img->attr['align'] = 'IAlign';
+ $img->attr['border'] = 'Pixels';
+ $img->attr['hspace'] = 'Pixels';
+ $img->attr['vspace'] = 'Pixels';
+
+ // figure out this integer business
+
+ $li = $this->addBlankElement('li');
+ $li->attr['value'] = new HTMLPurifier_AttrDef_Integer();
+ $li->attr['type'] = 'Enum#s:1,i,I,a,A,disc,square,circle';
+
+ $ol = $this->addBlankElement('ol');
+ $ol->attr['compact'] = 'Bool#compact';
+ $ol->attr['start'] = new HTMLPurifier_AttrDef_Integer();
+ $ol->attr['type'] = 'Enum#s:1,i,I,a,A';
+
+ $p = $this->addBlankElement('p');
+ $p->attr['align'] = $align;
+
+ $pre = $this->addBlankElement('pre');
+ $pre->attr['width'] = 'Number';
+
+ // script omitted
+
+ $table = $this->addBlankElement('table');
+ $table->attr['align'] = 'Enum#left,center,right';
+ $table->attr['bgcolor'] = 'Color';
+
+ $tr = $this->addBlankElement('tr');
+ $tr->attr['bgcolor'] = 'Color';
+
+ $th = $this->addBlankElement('th');
+ $th->attr['bgcolor'] = 'Color';
+ $th->attr['height'] = 'Length';
+ $th->attr['nowrap'] = 'Bool#nowrap';
+ $th->attr['width'] = 'Length';
+
+ $td = $this->addBlankElement('td');
+ $td->attr['bgcolor'] = 'Color';
+ $td->attr['height'] = 'Length';
+ $td->attr['nowrap'] = 'Bool#nowrap';
+ $td->attr['width'] = 'Length';
+
+ $ul = $this->addBlankElement('ul');
+ $ul->attr['compact'] = 'Bool#compact';
+ $ul->attr['type'] = 'Enum#square,disc,circle';
+
+ // "safe" modifications to "unsafe" elements
+ // WARNING: If you want to add support for an unsafe, legacy
+ // attribute, make a new TrustedLegacy module with the trusted
+ // bit set appropriately
+
+ $form = $this->addBlankElement('form');
+ $form->content_model = 'Flow | #PCDATA';
+ $form->content_model_type = 'optional';
+ $form->attr['target'] = 'FrameTarget';
+
+ $input = $this->addBlankElement('input');
+ $input->attr['align'] = 'IAlign';
+
+ $legend = $this->addBlankElement('legend');
+ $legend->attr['align'] = 'LAlign';
+ }
+}
+
+// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLModule/List.php b/library/vendor/HTMLPurifier/HTMLModule/List.php
new file mode 100644
index 0000000..7a20ff7
--- /dev/null
+++ b/library/vendor/HTMLPurifier/HTMLModule/List.php
@@ -0,0 +1,51 @@
+<?php
+
+/**
+ * XHTML 1.1 List Module, defines list-oriented elements. Core Module.
+ */
+class HTMLPurifier_HTMLModule_List extends HTMLPurifier_HTMLModule
+{
+ /**
+ * @type string
+ */
+ public $name = 'List';
+
+ // According to the abstract schema, the List content set is a fully formed
+ // one or more expr, but it invariably occurs in an optional declaration
+ // so we're not going to do that subtlety. It might cause trouble
+ // if a user defines "List" and expects that multiple lists are
+ // allowed to be specified, but then again, that's not very intuitive.
+ // Furthermore, the actual XML Schema may disagree. Regardless,
+ // we don't have support for such nested expressions without using
+ // the incredibly inefficient and draconic Custom ChildDef.
+
+ /**
+ * @type array
+ */
+ public $content_sets = array('Flow' => 'List');
+
+ /**
+ * @param HTMLPurifier_Config $config
+ */
+ public function setup($config)
+ {
+ $ol = $this->addElement('ol', 'List', new HTMLPurifier_ChildDef_List(), 'Common');
+ $ul = $this->addElement('ul', 'List', new HTMLPurifier_ChildDef_List(), 'Common');
+ // XXX The wrap attribute is handled by MakeWellFormed. This is all
+ // quite unsatisfactory, because we generated this
+ // *specifically* for lists, and now a big chunk of the handling
+ // is done properly by the List ChildDef. So actually, we just
+ // want enough information to make autoclosing work properly,
+ // and then hand off the tricky stuff to the ChildDef.
+ $ol->wrap = 'li';
+ $ul->wrap = 'li';
+ $this->addElement('dl', 'List', 'Required: dt | dd', 'Common');
+
+ $this->addElement('li', false, 'Flow', 'Common');
+
+ $this->addElement('dd', false, 'Flow', 'Common');
+ $this->addElement('dt', false, 'Inline', 'Common');
+ }
+}
+
+// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLModule/Name.php b/library/vendor/HTMLPurifier/HTMLModule/Name.php
new file mode 100644
index 0000000..60c0545
--- /dev/null
+++ b/library/vendor/HTMLPurifier/HTMLModule/Name.php
@@ -0,0 +1,26 @@
+<?php
+
+class HTMLPurifier_HTMLModule_Name extends HTMLPurifier_HTMLModule
+{
+ /**
+ * @type string
+ */
+ public $name = 'Name';
+
+ /**
+ * @param HTMLPurifier_Config $config
+ */
+ public function setup($config)
+ {
+ $elements = array('a', 'applet', 'form', 'frame', 'iframe', 'img', 'map');
+ foreach ($elements as $name) {
+ $element = $this->addBlankElement($name);
+ $element->attr['name'] = 'CDATA';
+ if (!$config->get('HTML.Attr.Name.UseCDATA')) {
+ $element->attr_transform_post[] = new HTMLPurifier_AttrTransform_NameSync();
+ }
+ }
+ }
+}
+
+// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLModule/Nofollow.php b/library/vendor/HTMLPurifier/HTMLModule/Nofollow.php
new file mode 100644
index 0000000..dc9410a
--- /dev/null
+++ b/library/vendor/HTMLPurifier/HTMLModule/Nofollow.php
@@ -0,0 +1,25 @@
+<?php
+
+/**
+ * Module adds the nofollow attribute transformation to a tags. It
+ * is enabled by HTML.Nofollow
+ */
+class HTMLPurifier_HTMLModule_Nofollow extends HTMLPurifier_HTMLModule
+{
+
+ /**
+ * @type string
+ */
+ public $name = 'Nofollow';
+
+ /**
+ * @param HTMLPurifier_Config $config
+ */
+ public function setup($config)
+ {
+ $a = $this->addBlankElement('a');
+ $a->attr_transform_post[] = new HTMLPurifier_AttrTransform_Nofollow();
+ }
+}
+
+// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLModule/NonXMLCommonAttributes.php b/library/vendor/HTMLPurifier/HTMLModule/NonXMLCommonAttributes.php
new file mode 100644
index 0000000..da72225
--- /dev/null
+++ b/library/vendor/HTMLPurifier/HTMLModule/NonXMLCommonAttributes.php
@@ -0,0 +1,20 @@
+<?php
+
+class HTMLPurifier_HTMLModule_NonXMLCommonAttributes extends HTMLPurifier_HTMLModule
+{
+ /**
+ * @type string
+ */
+ public $name = 'NonXMLCommonAttributes';
+
+ /**
+ * @type array
+ */
+ public $attr_collections = array(
+ 'Lang' => array(
+ 'lang' => 'LanguageCode',
+ )
+ );
+}
+
+// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLModule/Object.php b/library/vendor/HTMLPurifier/HTMLModule/Object.php
new file mode 100644
index 0000000..2f9efc5
--- /dev/null
+++ b/library/vendor/HTMLPurifier/HTMLModule/Object.php
@@ -0,0 +1,62 @@
+<?php
+
+/**
+ * XHTML 1.1 Object Module, defines elements for generic object inclusion
+ * @warning Users will commonly use <embed> to cater to legacy browsers: this
+ * module does not allow this sort of behavior
+ */
+class HTMLPurifier_HTMLModule_Object extends HTMLPurifier_HTMLModule
+{
+ /**
+ * @type string
+ */
+ public $name = 'Object';
+
+ /**
+ * @type bool
+ */
+ public $safe = false;
+
+ /**
+ * @param HTMLPurifier_Config $config
+ */
+ public function setup($config)
+ {
+ $this->addElement(
+ 'object',
+ 'Inline',
+ 'Optional: #PCDATA | Flow | param',
+ 'Common',
+ array(
+ 'archive' => 'URI',
+ 'classid' => 'URI',
+ 'codebase' => 'URI',
+ 'codetype' => 'Text',
+ 'data' => 'URI',
+ 'declare' => 'Bool#declare',
+ 'height' => 'Length',
+ 'name' => 'CDATA',
+ 'standby' => 'Text',
+ 'tabindex' => 'Number',
+ 'type' => 'ContentType',
+ 'width' => 'Length'
+ )
+ );
+
+ $this->addElement(
+ 'param',
+ false,
+ 'Empty',
+ null,
+ array(
+ 'id' => 'ID',
+ 'name*' => 'Text',
+ 'type' => 'Text',
+ 'value' => 'Text',
+ 'valuetype' => 'Enum#data,ref,object'
+ )
+ );
+ }
+}
+
+// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLModule/Presentation.php b/library/vendor/HTMLPurifier/HTMLModule/Presentation.php
new file mode 100644
index 0000000..6458ce9
--- /dev/null
+++ b/library/vendor/HTMLPurifier/HTMLModule/Presentation.php
@@ -0,0 +1,42 @@
+<?php
+
+/**
+ * XHTML 1.1 Presentation Module, defines simple presentation-related
+ * markup. Text Extension Module.
+ * @note The official XML Schema and DTD specs further divide this into
+ * two modules:
+ * - Block Presentation (hr)
+ * - Inline Presentation (b, big, i, small, sub, sup, tt)
+ * We have chosen not to heed this distinction, as content_sets
+ * provides satisfactory disambiguation.
+ */
+class HTMLPurifier_HTMLModule_Presentation extends HTMLPurifier_HTMLModule
+{
+
+ /**
+ * @type string
+ */
+ public $name = 'Presentation';
+
+ /**
+ * @param HTMLPurifier_Config $config
+ */
+ public function setup($config)
+ {
+ $this->addElement('hr', 'Block', 'Empty', 'Common');
+ $this->addElement('sub', 'Inline', 'Inline', 'Common');
+ $this->addElement('sup', 'Inline', 'Inline', 'Common');
+ $b = $this->addElement('b', 'Inline', 'Inline', 'Common');
+ $b->formatting = true;
+ $big = $this->addElement('big', 'Inline', 'Inline', 'Common');
+ $big->formatting = true;
+ $i = $this->addElement('i', 'Inline', 'Inline', 'Common');
+ $i->formatting = true;
+ $small = $this->addElement('small', 'Inline', 'Inline', 'Common');
+ $small->formatting = true;
+ $tt = $this->addElement('tt', 'Inline', 'Inline', 'Common');
+ $tt->formatting = true;
+ }
+}
+
+// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLModule/Proprietary.php b/library/vendor/HTMLPurifier/HTMLModule/Proprietary.php
new file mode 100644
index 0000000..5ee3c8e
--- /dev/null
+++ b/library/vendor/HTMLPurifier/HTMLModule/Proprietary.php
@@ -0,0 +1,40 @@
+<?php
+
+/**
+ * Module defines proprietary tags and attributes in HTML.
+ * @warning If this module is enabled, standards-compliance is off!
+ */
+class HTMLPurifier_HTMLModule_Proprietary extends HTMLPurifier_HTMLModule
+{
+ /**
+ * @type string
+ */
+ public $name = 'Proprietary';
+
+ /**
+ * @param HTMLPurifier_Config $config
+ */
+ public function setup($config)
+ {
+ $this->addElement(
+ 'marquee',
+ 'Inline',
+ 'Flow',
+ 'Common',
+ array(
+ 'direction' => 'Enum#left,right,up,down',
+ 'behavior' => 'Enum#alternate',
+ 'width' => 'Length',
+ 'height' => 'Length',
+ 'scrolldelay' => 'Number',
+ 'scrollamount' => 'Number',
+ 'loop' => 'Number',
+ 'bgcolor' => 'Color',
+ 'hspace' => 'Pixels',
+ 'vspace' => 'Pixels',
+ )
+ );
+ }
+}
+
+// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLModule/Ruby.php b/library/vendor/HTMLPurifier/HTMLModule/Ruby.php
new file mode 100644
index 0000000..a0d4892
--- /dev/null
+++ b/library/vendor/HTMLPurifier/HTMLModule/Ruby.php
@@ -0,0 +1,36 @@
+<?php
+
+/**
+ * XHTML 1.1 Ruby Annotation Module, defines elements that indicate
+ * short runs of text alongside base text for annotation or pronounciation.
+ */
+class HTMLPurifier_HTMLModule_Ruby extends HTMLPurifier_HTMLModule
+{
+
+ /**
+ * @type string
+ */
+ public $name = 'Ruby';
+
+ /**
+ * @param HTMLPurifier_Config $config
+ */
+ public function setup($config)
+ {
+ $this->addElement(
+ 'ruby',
+ 'Inline',
+ 'Custom: ((rb, (rt | (rp, rt, rp))) | (rbc, rtc, rtc?))',
+ 'Common'
+ );
+ $this->addElement('rbc', false, 'Required: rb', 'Common');
+ $this->addElement('rtc', false, 'Required: rt', 'Common');
+ $rb = $this->addElement('rb', false, 'Inline', 'Common');
+ $rb->excludes = array('ruby' => true);
+ $rt = $this->addElement('rt', false, 'Inline', 'Common', array('rbspan' => 'Number'));
+ $rt->excludes = array('ruby' => true);
+ $this->addElement('rp', false, 'Optional: #PCDATA', 'Common');
+ }
+}
+
+// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLModule/SafeEmbed.php b/library/vendor/HTMLPurifier/HTMLModule/SafeEmbed.php
new file mode 100644
index 0000000..04e6689
--- /dev/null
+++ b/library/vendor/HTMLPurifier/HTMLModule/SafeEmbed.php
@@ -0,0 +1,40 @@
+<?php
+
+/**
+ * A "safe" embed module. See SafeObject. This is a proprietary element.
+ */
+class HTMLPurifier_HTMLModule_SafeEmbed extends HTMLPurifier_HTMLModule
+{
+ /**
+ * @type string
+ */
+ public $name = 'SafeEmbed';
+
+ /**
+ * @param HTMLPurifier_Config $config
+ */
+ public function setup($config)
+ {
+ $max = $config->get('HTML.MaxImgLength');
+ $embed = $this->addElement(
+ 'embed',
+ 'Inline',
+ 'Empty',
+ 'Common',
+ array(
+ 'src*' => 'URI#embedded',
+ 'type' => 'Enum#application/x-shockwave-flash',
+ 'width' => 'Pixels#' . $max,
+ 'height' => 'Pixels#' . $max,
+ 'allowscriptaccess' => 'Enum#never',
+ 'allownetworking' => 'Enum#internal',
+ 'flashvars' => 'Text',
+ 'wmode' => 'Enum#window,transparent,opaque',
+ 'name' => 'ID',
+ )
+ );
+ $embed->attr_transform_post[] = new HTMLPurifier_AttrTransform_SafeEmbed();
+ }
+}
+
+// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLModule/SafeObject.php b/library/vendor/HTMLPurifier/HTMLModule/SafeObject.php
new file mode 100644
index 0000000..1297f80
--- /dev/null
+++ b/library/vendor/HTMLPurifier/HTMLModule/SafeObject.php
@@ -0,0 +1,62 @@
+<?php
+
+/**
+ * A "safe" object module. In theory, objects permitted by this module will
+ * be safe, and untrusted users can be allowed to embed arbitrary flash objects
+ * (maybe other types too, but only Flash is supported as of right now).
+ * Highly experimental.
+ */
+class HTMLPurifier_HTMLModule_SafeObject extends HTMLPurifier_HTMLModule
+{
+ /**
+ * @type string
+ */
+ public $name = 'SafeObject';
+
+ /**
+ * @param HTMLPurifier_Config $config
+ */
+ public function setup($config)
+ {
+ // These definitions are not intrinsically safe: the attribute transforms
+ // are a vital part of ensuring safety.
+
+ $max = $config->get('HTML.MaxImgLength');
+ $object = $this->addElement(
+ 'object',
+ 'Inline',
+ 'Optional: param | Flow | #PCDATA',
+ 'Common',
+ array(
+ // While technically not required by the spec, we're forcing
+ // it to this value.
+ 'type' => 'Enum#application/x-shockwave-flash',
+ 'width' => 'Pixels#' . $max,
+ 'height' => 'Pixels#' . $max,
+ 'data' => 'URI#embedded',
+ 'codebase' => new HTMLPurifier_AttrDef_Enum(
+ array(
+ 'http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0'
+ )
+ ),
+ )
+ );
+ $object->attr_transform_post[] = new HTMLPurifier_AttrTransform_SafeObject();
+
+ $param = $this->addElement(
+ 'param',
+ false,
+ 'Empty',
+ false,
+ array(
+ 'id' => 'ID',
+ 'name*' => 'Text',
+ 'value' => 'Text'
+ )
+ );
+ $param->attr_transform_post[] = new HTMLPurifier_AttrTransform_SafeParam();
+ $this->info_injector[] = 'SafeObject';
+ }
+}
+
+// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLModule/SafeScripting.php b/library/vendor/HTMLPurifier/HTMLModule/SafeScripting.php
new file mode 100644
index 0000000..aea7584
--- /dev/null
+++ b/library/vendor/HTMLPurifier/HTMLModule/SafeScripting.php
@@ -0,0 +1,40 @@
+<?php
+
+/**
+ * A "safe" script module. No inline JS is allowed, and pointed to JS
+ * files must match whitelist.
+ */
+class HTMLPurifier_HTMLModule_SafeScripting extends HTMLPurifier_HTMLModule
+{
+ /**
+ * @type string
+ */
+ public $name = 'SafeScripting';
+
+ /**
+ * @param HTMLPurifier_Config $config
+ */
+ public function setup($config)
+ {
+ // These definitions are not intrinsically safe: the attribute transforms
+ // are a vital part of ensuring safety.
+
+ $allowed = $config->get('HTML.SafeScripting');
+ $script = $this->addElement(
+ 'script',
+ 'Inline',
+ 'Optional:', // Not `Empty` to not allow to autoclose the <script /> tag @see https://www.w3.org/TR/html4/interact/scripts.html
+ null,
+ array(
+ // While technically not required by the spec, we're forcing
+ // it to this value.
+ 'type' => 'Enum#text/javascript',
+ 'src*' => new HTMLPurifier_AttrDef_Enum(array_keys($allowed), /*case sensitive*/ true)
+ )
+ );
+ $script->attr_transform_pre[] =
+ $script->attr_transform_post[] = new HTMLPurifier_AttrTransform_ScriptRequired();
+ }
+}
+
+// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLModule/Scripting.php b/library/vendor/HTMLPurifier/HTMLModule/Scripting.php
new file mode 100644
index 0000000..8b28a7b
--- /dev/null
+++ b/library/vendor/HTMLPurifier/HTMLModule/Scripting.php
@@ -0,0 +1,73 @@
+<?php
+
+/*
+
+WARNING: THIS MODULE IS EXTREMELY DANGEROUS AS IT ENABLES INLINE SCRIPTING
+INSIDE HTML PURIFIER DOCUMENTS. USE ONLY WITH TRUSTED USER INPUT!!!
+
+*/
+
+/**
+ * XHTML 1.1 Scripting module, defines elements that are used to contain
+ * information pertaining to executable scripts or the lack of support
+ * for executable scripts.
+ * @note This module does not contain inline scripting elements
+ */
+class HTMLPurifier_HTMLModule_Scripting extends HTMLPurifier_HTMLModule
+{
+ /**
+ * @type string
+ */
+ public $name = 'Scripting';
+
+ /**
+ * @type array
+ */
+ public $elements = array('script', 'noscript');
+
+ /**
+ * @type array
+ */
+ public $content_sets = array('Block' => 'script | noscript', 'Inline' => 'script | noscript');
+
+ /**
+ * @type bool
+ */
+ public $safe = false;
+
+ /**
+ * @param HTMLPurifier_Config $config
+ */
+ public function setup($config)
+ {
+ // TODO: create custom child-definition for noscript that
+ // auto-wraps stray #PCDATA in a similar manner to
+ // blockquote's custom definition (we would use it but
+ // blockquote's contents are optional while noscript's contents
+ // are required)
+
+ // TODO: convert this to new syntax, main problem is getting
+ // both content sets working
+
+ // In theory, this could be safe, but I don't see any reason to
+ // allow it.
+ $this->info['noscript'] = new HTMLPurifier_ElementDef();
+ $this->info['noscript']->attr = array(0 => array('Common'));
+ $this->info['noscript']->content_model = 'Heading | List | Block';
+ $this->info['noscript']->content_model_type = 'required';
+
+ $this->info['script'] = new HTMLPurifier_ElementDef();
+ $this->info['script']->attr = array(
+ 'defer' => new HTMLPurifier_AttrDef_Enum(array('defer')),
+ 'src' => new HTMLPurifier_AttrDef_URI(true),
+ 'type' => new HTMLPurifier_AttrDef_Enum(array('text/javascript'))
+ );
+ $this->info['script']->content_model = '#PCDATA';
+ $this->info['script']->content_model_type = 'optional';
+ $this->info['script']->attr_transform_pre[] =
+ $this->info['script']->attr_transform_post[] =
+ new HTMLPurifier_AttrTransform_ScriptRequired();
+ }
+}
+
+// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLModule/StyleAttribute.php b/library/vendor/HTMLPurifier/HTMLModule/StyleAttribute.php
new file mode 100644
index 0000000..497b832
--- /dev/null
+++ b/library/vendor/HTMLPurifier/HTMLModule/StyleAttribute.php
@@ -0,0 +1,33 @@
+<?php
+
+/**
+ * XHTML 1.1 Edit Module, defines editing-related elements. Text Extension
+ * Module.
+ */
+class HTMLPurifier_HTMLModule_StyleAttribute extends HTMLPurifier_HTMLModule
+{
+ /**
+ * @type string
+ */
+ public $name = 'StyleAttribute';
+
+ /**
+ * @type array
+ */
+ public $attr_collections = array(
+ // The inclusion routine differs from the Abstract Modules but
+ // is in line with the DTD and XML Schemas.
+ 'Style' => array('style' => false), // see constructor
+ 'Core' => array(0 => array('Style'))
+ );
+
+ /**
+ * @param HTMLPurifier_Config $config
+ */
+ public function setup($config)
+ {
+ $this->attr_collections['Style']['style'] = new HTMLPurifier_AttrDef_CSS();
+ }
+}
+
+// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLModule/Tables.php b/library/vendor/HTMLPurifier/HTMLModule/Tables.php
new file mode 100644
index 0000000..8a0b3b4
--- /dev/null
+++ b/library/vendor/HTMLPurifier/HTMLModule/Tables.php
@@ -0,0 +1,75 @@
+<?php
+
+/**
+ * XHTML 1.1 Tables Module, fully defines accessible table elements.
+ */
+class HTMLPurifier_HTMLModule_Tables extends HTMLPurifier_HTMLModule
+{
+ /**
+ * @type string
+ */
+ public $name = 'Tables';
+
+ /**
+ * @param HTMLPurifier_Config $config
+ */
+ public function setup($config)
+ {
+ $this->addElement('caption', false, 'Inline', 'Common');
+
+ $this->addElement(
+ 'table',
+ 'Block',
+ new HTMLPurifier_ChildDef_Table(),
+ 'Common',
+ array(
+ 'border' => 'Pixels',
+ 'cellpadding' => 'Length',
+ 'cellspacing' => 'Length',
+ 'frame' => 'Enum#void,above,below,hsides,lhs,rhs,vsides,box,border',
+ 'rules' => 'Enum#none,groups,rows,cols,all',
+ 'summary' => 'Text',
+ 'width' => 'Length'
+ )
+ );
+
+ // common attributes
+ $cell_align = array(
+ 'align' => 'Enum#left,center,right,justify,char',
+ 'charoff' => 'Length',
+ 'valign' => 'Enum#top,middle,bottom,baseline',
+ );
+
+ $cell_t = array_merge(
+ array(
+ 'abbr' => 'Text',
+ 'colspan' => 'Number',
+ 'rowspan' => 'Number',
+ // Apparently, as of HTML5 this attribute only applies
+ // to 'th' elements.
+ 'scope' => 'Enum#row,col,rowgroup,colgroup',
+ ),
+ $cell_align
+ );
+ $this->addElement('td', false, 'Flow', 'Common', $cell_t);
+ $this->addElement('th', false, 'Flow', 'Common', $cell_t);
+
+ $this->addElement('tr', false, 'Required: td | th', 'Common', $cell_align);
+
+ $cell_col = array_merge(
+ array(
+ 'span' => 'Number',
+ 'width' => 'MultiLength',
+ ),
+ $cell_align
+ );
+ $this->addElement('col', false, 'Empty', 'Common', $cell_col);
+ $this->addElement('colgroup', false, 'Optional: col', 'Common', $cell_col);
+
+ $this->addElement('tbody', false, 'Required: tr', 'Common', $cell_align);
+ $this->addElement('thead', false, 'Required: tr', 'Common', $cell_align);
+ $this->addElement('tfoot', false, 'Required: tr', 'Common', $cell_align);
+ }
+}
+
+// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLModule/Target.php b/library/vendor/HTMLPurifier/HTMLModule/Target.php
new file mode 100644
index 0000000..b188ac9
--- /dev/null
+++ b/library/vendor/HTMLPurifier/HTMLModule/Target.php
@@ -0,0 +1,28 @@
+<?php
+
+/**
+ * XHTML 1.1 Target Module, defines target attribute in link elements.
+ */
+class HTMLPurifier_HTMLModule_Target extends HTMLPurifier_HTMLModule
+{
+ /**
+ * @type string
+ */
+ public $name = 'Target';
+
+ /**
+ * @param HTMLPurifier_Config $config
+ */
+ public function setup($config)
+ {
+ $elements = array('a');
+ foreach ($elements as $name) {
+ $e = $this->addBlankElement($name);
+ $e->attr = array(
+ 'target' => new HTMLPurifier_AttrDef_HTML_FrameTarget()
+ );
+ }
+ }
+}
+
+// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLModule/TargetBlank.php b/library/vendor/HTMLPurifier/HTMLModule/TargetBlank.php
new file mode 100644
index 0000000..58ccc68
--- /dev/null
+++ b/library/vendor/HTMLPurifier/HTMLModule/TargetBlank.php
@@ -0,0 +1,24 @@
+<?php
+
+/**
+ * Module adds the target=blank attribute transformation to a tags. It
+ * is enabled by HTML.TargetBlank
+ */
+class HTMLPurifier_HTMLModule_TargetBlank extends HTMLPurifier_HTMLModule
+{
+ /**
+ * @type string
+ */
+ public $name = 'TargetBlank';
+
+ /**
+ * @param HTMLPurifier_Config $config
+ */
+ public function setup($config)
+ {
+ $a = $this->addBlankElement('a');
+ $a->attr_transform_post[] = new HTMLPurifier_AttrTransform_TargetBlank();
+ }
+}
+
+// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLModule/TargetNoopener.php b/library/vendor/HTMLPurifier/HTMLModule/TargetNoopener.php
new file mode 100644
index 0000000..b967ff5
--- /dev/null
+++ b/library/vendor/HTMLPurifier/HTMLModule/TargetNoopener.php
@@ -0,0 +1,21 @@
+<?php
+
+/**
+ * Module adds the target-based noopener attribute transformation to a tags. It
+ * is enabled by HTML.TargetNoopener
+ */
+class HTMLPurifier_HTMLModule_TargetNoopener extends HTMLPurifier_HTMLModule
+{
+ /**
+ * @type string
+ */
+ public $name = 'TargetNoopener';
+
+ /**
+ * @param HTMLPurifier_Config $config
+ */
+ public function setup($config) {
+ $a = $this->addBlankElement('a');
+ $a->attr_transform_post[] = new HTMLPurifier_AttrTransform_TargetNoopener();
+ }
+}
diff --git a/library/vendor/HTMLPurifier/HTMLModule/TargetNoreferrer.php b/library/vendor/HTMLPurifier/HTMLModule/TargetNoreferrer.php
new file mode 100644
index 0000000..32484d6
--- /dev/null
+++ b/library/vendor/HTMLPurifier/HTMLModule/TargetNoreferrer.php
@@ -0,0 +1,21 @@
+<?php
+
+/**
+ * Module adds the target-based noreferrer attribute transformation to a tags. It
+ * is enabled by HTML.TargetNoreferrer
+ */
+class HTMLPurifier_HTMLModule_TargetNoreferrer extends HTMLPurifier_HTMLModule
+{
+ /**
+ * @type string
+ */
+ public $name = 'TargetNoreferrer';
+
+ /**
+ * @param HTMLPurifier_Config $config
+ */
+ public function setup($config) {
+ $a = $this->addBlankElement('a');
+ $a->attr_transform_post[] = new HTMLPurifier_AttrTransform_TargetNoreferrer();
+ }
+}
diff --git a/library/vendor/HTMLPurifier/HTMLModule/Text.php b/library/vendor/HTMLPurifier/HTMLModule/Text.php
new file mode 100644
index 0000000..7a65e00
--- /dev/null
+++ b/library/vendor/HTMLPurifier/HTMLModule/Text.php
@@ -0,0 +1,87 @@
+<?php
+
+/**
+ * XHTML 1.1 Text Module, defines basic text containers. Core Module.
+ * @note In the normative XML Schema specification, this module
+ * is further abstracted into the following modules:
+ * - Block Phrasal (address, blockquote, pre, h1, h2, h3, h4, h5, h6)
+ * - Block Structural (div, p)
+ * - Inline Phrasal (abbr, acronym, cite, code, dfn, em, kbd, q, samp, strong, var)
+ * - Inline Structural (br, span)
+ * This module, functionally, does not distinguish between these
+ * sub-modules, but the code is internally structured to reflect
+ * these distinctions.
+ */
+class HTMLPurifier_HTMLModule_Text extends HTMLPurifier_HTMLModule
+{
+ /**
+ * @type string
+ */
+ public $name = 'Text';
+
+ /**
+ * @type array
+ */
+ public $content_sets = array(
+ 'Flow' => 'Heading | Block | Inline'
+ );
+
+ /**
+ * @param HTMLPurifier_Config $config
+ */
+ public function setup($config)
+ {
+ // Inline Phrasal -------------------------------------------------
+ $this->addElement('abbr', 'Inline', 'Inline', 'Common');
+ $this->addElement('acronym', 'Inline', 'Inline', 'Common');
+ $this->addElement('cite', 'Inline', 'Inline', 'Common');
+ $this->addElement('dfn', 'Inline', 'Inline', 'Common');
+ $this->addElement('kbd', 'Inline', 'Inline', 'Common');
+ $this->addElement('q', 'Inline', 'Inline', 'Common', array('cite' => 'URI'));
+ $this->addElement('samp', 'Inline', 'Inline', 'Common');
+ $this->addElement('var', 'Inline', 'Inline', 'Common');
+
+ $em = $this->addElement('em', 'Inline', 'Inline', 'Common');
+ $em->formatting = true;
+
+ $strong = $this->addElement('strong', 'Inline', 'Inline', 'Common');
+ $strong->formatting = true;
+
+ $code = $this->addElement('code', 'Inline', 'Inline', 'Common');
+ $code->formatting = true;
+
+ // Inline Structural ----------------------------------------------
+ $this->addElement('span', 'Inline', 'Inline', 'Common');
+ $this->addElement('br', 'Inline', 'Empty', 'Core');
+
+ // Block Phrasal --------------------------------------------------
+ $this->addElement('address', 'Block', 'Inline', 'Common');
+ $this->addElement('blockquote', 'Block', 'Optional: Heading | Block | List', 'Common', array('cite' => 'URI'));
+ $pre = $this->addElement('pre', 'Block', 'Inline', 'Common');
+ $pre->excludes = $this->makeLookup(
+ 'img',
+ 'big',
+ 'small',
+ 'object',
+ 'applet',
+ 'font',
+ 'basefont'
+ );
+ $this->addElement('h1', 'Heading', 'Inline', 'Common');
+ $this->addElement('h2', 'Heading', 'Inline', 'Common');
+ $this->addElement('h3', 'Heading', 'Inline', 'Common');
+ $this->addElement('h4', 'Heading', 'Inline', 'Common');
+ $this->addElement('h5', 'Heading', 'Inline', 'Common');
+ $this->addElement('h6', 'Heading', 'Inline', 'Common');
+
+ // Block Structural -----------------------------------------------
+ $p = $this->addElement('p', 'Block', 'Inline', 'Common');
+ $p->autoclose = array_flip(
+ array("address", "blockquote", "center", "dir", "div", "dl", "fieldset", "ol", "p", "ul")
+ );
+
+ $this->addElement('div', 'Block', 'Flow', 'Common');
+ }
+}
+
+// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLModule/Tidy.php b/library/vendor/HTMLPurifier/HTMLModule/Tidy.php
new file mode 100644
index 0000000..12173ba
--- /dev/null
+++ b/library/vendor/HTMLPurifier/HTMLModule/Tidy.php
@@ -0,0 +1,227 @@
+<?php
+
+/**
+ * Abstract class for a set of proprietary modules that clean up (tidy)
+ * poorly written HTML.
+ * @todo Figure out how to protect some of these methods/properties
+ */
+class HTMLPurifier_HTMLModule_Tidy extends HTMLPurifier_HTMLModule
+{
+ /**
+ * List of supported levels.
+ * Index zero is a special case "no fixes" level.
+ * @type array
+ */
+ public $levels = array(0 => 'none', 'light', 'medium', 'heavy');
+
+ /**
+ * Default level to place all fixes in.
+ * Disabled by default.
+ * @type string
+ */
+ public $defaultLevel = null;
+
+ /**
+ * Lists of fixes used by getFixesForLevel().
+ * Format is:
+ * HTMLModule_Tidy->fixesForLevel[$level] = array('fix-1', 'fix-2');
+ * @type array
+ */
+ public $fixesForLevel = array(
+ 'light' => array(),
+ 'medium' => array(),
+ 'heavy' => array()
+ );
+
+ /**
+ * Lazy load constructs the module by determining the necessary
+ * fixes to create and then delegating to the populate() function.
+ * @param HTMLPurifier_Config $config
+ * @todo Wildcard matching and error reporting when an added or
+ * subtracted fix has no effect.
+ */
+ public function setup($config)
+ {
+ // create fixes, initialize fixesForLevel
+ $fixes = $this->makeFixes();
+ $this->makeFixesForLevel($fixes);
+
+ // figure out which fixes to use
+ $level = $config->get('HTML.TidyLevel');
+ $fixes_lookup = $this->getFixesForLevel($level);
+
+ // get custom fix declarations: these need namespace processing
+ $add_fixes = $config->get('HTML.TidyAdd');
+ $remove_fixes = $config->get('HTML.TidyRemove');
+
+ foreach ($fixes as $name => $fix) {
+ // needs to be refactored a little to implement globbing
+ if (isset($remove_fixes[$name]) ||
+ (!isset($add_fixes[$name]) && !isset($fixes_lookup[$name]))) {
+ unset($fixes[$name]);
+ }
+ }
+
+ // populate this module with necessary fixes
+ $this->populate($fixes);
+ }
+
+ /**
+ * Retrieves all fixes per a level, returning fixes for that specific
+ * level as well as all levels below it.
+ * @param string $level level identifier, see $levels for valid values
+ * @return array Lookup up table of fixes
+ */
+ public function getFixesForLevel($level)
+ {
+ if ($level == $this->levels[0]) {
+ return array();
+ }
+ $activated_levels = array();
+ for ($i = 1, $c = count($this->levels); $i < $c; $i++) {
+ $activated_levels[] = $this->levels[$i];
+ if ($this->levels[$i] == $level) {
+ break;
+ }
+ }
+ if ($i == $c) {
+ trigger_error(
+ 'Tidy level ' . htmlspecialchars($level) . ' not recognized',
+ E_USER_WARNING
+ );
+ return array();
+ }
+ $ret = array();
+ foreach ($activated_levels as $level) {
+ foreach ($this->fixesForLevel[$level] as $fix) {
+ $ret[$fix] = true;
+ }
+ }
+ return $ret;
+ }
+
+ /**
+ * Dynamically populates the $fixesForLevel member variable using
+ * the fixes array. It may be custom overloaded, used in conjunction
+ * with $defaultLevel, or not used at all.
+ * @param array $fixes
+ */
+ public function makeFixesForLevel($fixes)
+ {
+ if (!isset($this->defaultLevel)) {
+ return;
+ }
+ if (!isset($this->fixesForLevel[$this->defaultLevel])) {
+ trigger_error(
+ 'Default level ' . $this->defaultLevel . ' does not exist',
+ E_USER_ERROR
+ );
+ return;
+ }
+ $this->fixesForLevel[$this->defaultLevel] = array_keys($fixes);
+ }
+
+ /**
+ * Populates the module with transforms and other special-case code
+ * based on a list of fixes passed to it
+ * @param array $fixes Lookup table of fixes to activate
+ */
+ public function populate($fixes)
+ {
+ foreach ($fixes as $name => $fix) {
+ // determine what the fix is for
+ list($type, $params) = $this->getFixType($name);
+ switch ($type) {
+ case 'attr_transform_pre':
+ case 'attr_transform_post':
+ $attr = $params['attr'];
+ if (isset($params['element'])) {
+ $element = $params['element'];
+ if (empty($this->info[$element])) {
+ $e = $this->addBlankElement($element);
+ } else {
+ $e = $this->info[$element];
+ }
+ } else {
+ $type = "info_$type";
+ $e = $this;
+ }
+ $e->{$type}[$attr] = $fix;
+ break;
+ case 'tag_transform':
+ $this->info_tag_transform[$params['element']] = $fix;
+ break;
+ case 'child':
+ case 'content_model_type':
+ $element = $params['element'];
+ if (empty($this->info[$element])) {
+ $e = $this->addBlankElement($element);
+ } else {
+ $e = $this->info[$element];
+ }
+ $e->$type = $fix;
+ break;
+ default:
+ trigger_error("Fix type $type not supported", E_USER_ERROR);
+ break;
+ }
+ }
+ }
+
+ /**
+ * Parses a fix name and determines what kind of fix it is, as well
+ * as other information defined by the fix
+ * @param $name String name of fix
+ * @return array(string $fix_type, array $fix_parameters)
+ * @note $fix_parameters is type dependant, see populate() for usage
+ * of these parameters
+ */
+ public function getFixType($name)
+ {
+ // parse it
+ $property = $attr = null;
+ if (strpos($name, '#') !== false) {
+ list($name, $property) = explode('#', $name);
+ }
+ if (strpos($name, '@') !== false) {
+ list($name, $attr) = explode('@', $name);
+ }
+
+ // figure out the parameters
+ $params = array();
+ if ($name !== '') {
+ $params['element'] = $name;
+ }
+ if (!is_null($attr)) {
+ $params['attr'] = $attr;
+ }
+
+ // special case: attribute transform
+ if (!is_null($attr)) {
+ if (is_null($property)) {
+ $property = 'pre';
+ }
+ $type = 'attr_transform_' . $property;
+ return array($type, $params);
+ }
+
+ // special case: tag transform
+ if (is_null($property)) {
+ return array('tag_transform', $params);
+ }
+
+ return array($property, $params);
+
+ }
+
+ /**
+ * Defines all fixes the module will perform in a compact
+ * associative array of fix name to fix implementation.
+ * @return array
+ */
+ public function makeFixes()
+ {
+ }
+}
+
+// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLModule/Tidy/Name.php b/library/vendor/HTMLPurifier/HTMLModule/Tidy/Name.php
new file mode 100644
index 0000000..a995161
--- /dev/null
+++ b/library/vendor/HTMLPurifier/HTMLModule/Tidy/Name.php
@@ -0,0 +1,33 @@
+<?php
+
+/**
+ * Name is deprecated, but allowed in strict doctypes, so onl
+ */
+class HTMLPurifier_HTMLModule_Tidy_Name extends HTMLPurifier_HTMLModule_Tidy
+{
+ /**
+ * @type string
+ */
+ public $name = 'Tidy_Name';
+
+ /**
+ * @type string
+ */
+ public $defaultLevel = 'heavy';
+
+ /**
+ * @return array
+ */
+ public function makeFixes()
+ {
+ $r = array();
+ // @name for img, a -----------------------------------------------
+ // Technically, it's allowed even on strict, so we allow authors to use
+ // it. However, it's deprecated in future versions of XHTML.
+ $r['img@name'] =
+ $r['a@name'] = new HTMLPurifier_AttrTransform_Name();
+ return $r;
+ }
+}
+
+// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLModule/Tidy/Proprietary.php b/library/vendor/HTMLPurifier/HTMLModule/Tidy/Proprietary.php
new file mode 100644
index 0000000..3326438
--- /dev/null
+++ b/library/vendor/HTMLPurifier/HTMLModule/Tidy/Proprietary.php
@@ -0,0 +1,34 @@
+<?php
+
+class HTMLPurifier_HTMLModule_Tidy_Proprietary extends HTMLPurifier_HTMLModule_Tidy
+{
+
+ /**
+ * @type string
+ */
+ public $name = 'Tidy_Proprietary';
+
+ /**
+ * @type string
+ */
+ public $defaultLevel = 'light';
+
+ /**
+ * @return array
+ */
+ public function makeFixes()
+ {
+ $r = array();
+ $r['table@background'] = new HTMLPurifier_AttrTransform_Background();
+ $r['td@background'] = new HTMLPurifier_AttrTransform_Background();
+ $r['th@background'] = new HTMLPurifier_AttrTransform_Background();
+ $r['tr@background'] = new HTMLPurifier_AttrTransform_Background();
+ $r['thead@background'] = new HTMLPurifier_AttrTransform_Background();
+ $r['tfoot@background'] = new HTMLPurifier_AttrTransform_Background();
+ $r['tbody@background'] = new HTMLPurifier_AttrTransform_Background();
+ $r['table@height'] = new HTMLPurifier_AttrTransform_Length('height');
+ return $r;
+ }
+}
+
+// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLModule/Tidy/Strict.php b/library/vendor/HTMLPurifier/HTMLModule/Tidy/Strict.php
new file mode 100644
index 0000000..803c44f
--- /dev/null
+++ b/library/vendor/HTMLPurifier/HTMLModule/Tidy/Strict.php
@@ -0,0 +1,43 @@
+<?php
+
+class HTMLPurifier_HTMLModule_Tidy_Strict extends HTMLPurifier_HTMLModule_Tidy_XHTMLAndHTML4
+{
+ /**
+ * @type string
+ */
+ public $name = 'Tidy_Strict';
+
+ /**
+ * @type string
+ */
+ public $defaultLevel = 'light';
+
+ /**
+ * @return array
+ */
+ public function makeFixes()
+ {
+ $r = parent::makeFixes();
+ $r['blockquote#content_model_type'] = 'strictblockquote';
+ return $r;
+ }
+
+ /**
+ * @type bool
+ */
+ public $defines_child_def = true;
+
+ /**
+ * @param HTMLPurifier_ElementDef $def
+ * @return HTMLPurifier_ChildDef_StrictBlockquote
+ */
+ public function getChildDef($def)
+ {
+ if ($def->content_model_type != 'strictblockquote') {
+ return parent::getChildDef($def);
+ }
+ return new HTMLPurifier_ChildDef_StrictBlockquote($def->content_model);
+ }
+}
+
+// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLModule/Tidy/Transitional.php b/library/vendor/HTMLPurifier/HTMLModule/Tidy/Transitional.php
new file mode 100644
index 0000000..c095ad9
--- /dev/null
+++ b/library/vendor/HTMLPurifier/HTMLModule/Tidy/Transitional.php
@@ -0,0 +1,16 @@
+<?php
+
+class HTMLPurifier_HTMLModule_Tidy_Transitional extends HTMLPurifier_HTMLModule_Tidy_XHTMLAndHTML4
+{
+ /**
+ * @type string
+ */
+ public $name = 'Tidy_Transitional';
+
+ /**
+ * @type string
+ */
+ public $defaultLevel = 'heavy';
+}
+
+// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLModule/Tidy/XHTML.php b/library/vendor/HTMLPurifier/HTMLModule/Tidy/XHTML.php
new file mode 100644
index 0000000..3ecddc4
--- /dev/null
+++ b/library/vendor/HTMLPurifier/HTMLModule/Tidy/XHTML.php
@@ -0,0 +1,26 @@
+<?php
+
+class HTMLPurifier_HTMLModule_Tidy_XHTML extends HTMLPurifier_HTMLModule_Tidy
+{
+ /**
+ * @type string
+ */
+ public $name = 'Tidy_XHTML';
+
+ /**
+ * @type string
+ */
+ public $defaultLevel = 'medium';
+
+ /**
+ * @return array
+ */
+ public function makeFixes()
+ {
+ $r = array();
+ $r['@lang'] = new HTMLPurifier_AttrTransform_Lang();
+ return $r;
+ }
+}
+
+// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLModule/Tidy/XHTMLAndHTML4.php b/library/vendor/HTMLPurifier/HTMLModule/Tidy/XHTMLAndHTML4.php
new file mode 100644
index 0000000..9ee3ffc
--- /dev/null
+++ b/library/vendor/HTMLPurifier/HTMLModule/Tidy/XHTMLAndHTML4.php
@@ -0,0 +1,182 @@
+<?php
+
+class HTMLPurifier_HTMLModule_Tidy_XHTMLAndHTML4 extends HTMLPurifier_HTMLModule_Tidy
+{
+
+ /**
+ * @return array
+ */
+ public function makeFixes()
+ {
+ $r = array();
+
+ // == deprecated tag transforms ===================================
+
+ $r['font'] = new HTMLPurifier_TagTransform_Font();
+ $r['menu'] = new HTMLPurifier_TagTransform_Simple('ul');
+ $r['dir'] = new HTMLPurifier_TagTransform_Simple('ul');
+ $r['center'] = new HTMLPurifier_TagTransform_Simple('div', 'text-align:center;');
+ $r['u'] = new HTMLPurifier_TagTransform_Simple('span', 'text-decoration:underline;');
+ $r['s'] = new HTMLPurifier_TagTransform_Simple('span', 'text-decoration:line-through;');
+ $r['strike'] = new HTMLPurifier_TagTransform_Simple('span', 'text-decoration:line-through;');
+
+ // == deprecated attribute transforms =============================
+
+ $r['caption@align'] =
+ new HTMLPurifier_AttrTransform_EnumToCSS(
+ 'align',
+ array(
+ // we're following IE's behavior, not Firefox's, due
+ // to the fact that no one supports caption-side:right,
+ // W3C included (with CSS 2.1). This is a slightly
+ // unreasonable attribute!
+ 'left' => 'text-align:left;',
+ 'right' => 'text-align:right;',
+ 'top' => 'caption-side:top;',
+ 'bottom' => 'caption-side:bottom;' // not supported by IE
+ )
+ );
+
+ // @align for img -------------------------------------------------
+ $r['img@align'] =
+ new HTMLPurifier_AttrTransform_EnumToCSS(
+ 'align',
+ array(
+ 'left' => 'float:left;',
+ 'right' => 'float:right;',
+ 'top' => 'vertical-align:top;',
+ 'middle' => 'vertical-align:middle;',
+ 'bottom' => 'vertical-align:baseline;',
+ )
+ );
+
+ // @align for table -----------------------------------------------
+ $r['table@align'] =
+ new HTMLPurifier_AttrTransform_EnumToCSS(
+ 'align',
+ array(
+ 'left' => 'float:left;',
+ 'center' => 'margin-left:auto;margin-right:auto;',
+ 'right' => 'float:right;'
+ )
+ );
+
+ // @align for hr -----------------------------------------------
+ $r['hr@align'] =
+ new HTMLPurifier_AttrTransform_EnumToCSS(
+ 'align',
+ array(
+ // we use both text-align and margin because these work
+ // for different browsers (IE and Firefox, respectively)
+ // and the melange makes for a pretty cross-compatible
+ // solution
+ 'left' => 'margin-left:0;margin-right:auto;text-align:left;',
+ 'center' => 'margin-left:auto;margin-right:auto;text-align:center;',
+ 'right' => 'margin-left:auto;margin-right:0;text-align:right;'
+ )
+ );
+
+ // @align for h1, h2, h3, h4, h5, h6, p, div ----------------------
+ // {{{
+ $align_lookup = array();
+ $align_values = array('left', 'right', 'center', 'justify');
+ foreach ($align_values as $v) {
+ $align_lookup[$v] = "text-align:$v;";
+ }
+ // }}}
+ $r['h1@align'] =
+ $r['h2@align'] =
+ $r['h3@align'] =
+ $r['h4@align'] =
+ $r['h5@align'] =
+ $r['h6@align'] =
+ $r['p@align'] =
+ $r['div@align'] =
+ new HTMLPurifier_AttrTransform_EnumToCSS('align', $align_lookup);
+
+ // @bgcolor for table, tr, td, th ---------------------------------
+ $r['table@bgcolor'] =
+ $r['tr@bgcolor'] =
+ $r['td@bgcolor'] =
+ $r['th@bgcolor'] =
+ new HTMLPurifier_AttrTransform_BgColor();
+
+ // @border for img ------------------------------------------------
+ $r['img@border'] = new HTMLPurifier_AttrTransform_Border();
+
+ // @clear for br --------------------------------------------------
+ $r['br@clear'] =
+ new HTMLPurifier_AttrTransform_EnumToCSS(
+ 'clear',
+ array(
+ 'left' => 'clear:left;',
+ 'right' => 'clear:right;',
+ 'all' => 'clear:both;',
+ 'none' => 'clear:none;',
+ )
+ );
+
+ // @height for td, th ---------------------------------------------
+ $r['td@height'] =
+ $r['th@height'] =
+ new HTMLPurifier_AttrTransform_Length('height');
+
+ // @hspace for img ------------------------------------------------
+ $r['img@hspace'] = new HTMLPurifier_AttrTransform_ImgSpace('hspace');
+
+ // @noshade for hr ------------------------------------------------
+ // this transformation is not precise but often good enough.
+ // different browsers use different styles to designate noshade
+ $r['hr@noshade'] =
+ new HTMLPurifier_AttrTransform_BoolToCSS(
+ 'noshade',
+ 'color:#808080;background-color:#808080;border:0;'
+ );
+
+ // @nowrap for td, th ---------------------------------------------
+ $r['td@nowrap'] =
+ $r['th@nowrap'] =
+ new HTMLPurifier_AttrTransform_BoolToCSS(
+ 'nowrap',
+ 'white-space:nowrap;'
+ );
+
+ // @size for hr --------------------------------------------------
+ $r['hr@size'] = new HTMLPurifier_AttrTransform_Length('size', 'height');
+
+ // @type for li, ol, ul -------------------------------------------
+ // {{{
+ $ul_types = array(
+ 'disc' => 'list-style-type:disc;',
+ 'square' => 'list-style-type:square;',
+ 'circle' => 'list-style-type:circle;'
+ );
+ $ol_types = array(
+ '1' => 'list-style-type:decimal;',
+ 'i' => 'list-style-type:lower-roman;',
+ 'I' => 'list-style-type:upper-roman;',
+ 'a' => 'list-style-type:lower-alpha;',
+ 'A' => 'list-style-type:upper-alpha;'
+ );
+ $li_types = $ul_types + $ol_types;
+ // }}}
+
+ $r['ul@type'] = new HTMLPurifier_AttrTransform_EnumToCSS('type', $ul_types);
+ $r['ol@type'] = new HTMLPurifier_AttrTransform_EnumToCSS('type', $ol_types, true);
+ $r['li@type'] = new HTMLPurifier_AttrTransform_EnumToCSS('type', $li_types, true);
+
+ // @vspace for img ------------------------------------------------
+ $r['img@vspace'] = new HTMLPurifier_AttrTransform_ImgSpace('vspace');
+
+ // @width for table, hr, td, th, col ------------------------------------------
+ $r['table@width'] =
+ $r['td@width'] =
+ $r['th@width'] =
+ $r['col@width'] =
+ $r['hr@width'] = new HTMLPurifier_AttrTransform_Length('width');
+
+ return $r;
+ }
+}
+
+// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLModule/XMLCommonAttributes.php b/library/vendor/HTMLPurifier/HTMLModule/XMLCommonAttributes.php
new file mode 100644
index 0000000..01dbe9d
--- /dev/null
+++ b/library/vendor/HTMLPurifier/HTMLModule/XMLCommonAttributes.php
@@ -0,0 +1,20 @@
+<?php
+
+class HTMLPurifier_HTMLModule_XMLCommonAttributes extends HTMLPurifier_HTMLModule
+{
+ /**
+ * @type string
+ */
+ public $name = 'XMLCommonAttributes';
+
+ /**
+ * @type array
+ */
+ public $attr_collections = array(
+ 'Lang' => array(
+ 'xml:lang' => 'LanguageCode',
+ )
+ );
+}
+
+// vim: et sw=4 sts=4
diff --git a/library/vendor/HTMLPurifier/HTMLModuleManager.php b/library/vendor/HTMLPurifier/HTMLModuleManager.php
new file mode 100644
index 0000000..38c058f
--- /dev/null
+++ b/library/vendor/HTMLPurifier/HTMLModuleManager.php
@@ -0,0 +1,467 @@
+<?php
+
+class HTMLPurifier_HTMLModuleManager
+{
+
+ /**
+ * @type HTMLPurifier_DoctypeRegistry
+ */
+ public $doctypes;
+
+ /**
+ * Instance of current doctype.
+ * @type string
+ */
+ public $doctype;
+
+ /**
+ * @type HTMLPurifier_AttrTypes
+ */
+ public $attrTypes;
+
+ /**
+ * Active instances of modules for the specified doctype are
+ * indexed, by name, in this array.
+ * @type HTMLPurifier_HTMLModule[]
+ */
+ public $modules = array();
+
+ /**
+ * Array of recognized HTMLPurifier_HTMLModule instances,
+ * indexed by module's class name. This array is usually lazy loaded, but a
+ * user can overload a module by pre-emptively registering it.
+ * @type HTMLPurifier_HTMLModule[]
+ */
+ public $registeredModules = array();
+
+ /**
+ * List of extra modules that were added by the user
+ * using addModule(). These get unconditionally merged into the current doctype, whatever
+ * it may be.
+ * @type HTMLPurifier_HTMLModule[]
+ */
+ public $userModules = array();
+
+ /**
+ * Associative array of element name to list of modules that have
+ * definitions for the element; this array is dynamically filled.
+ * @type array
+ */
+ public $elementLookup = array();
+
+ /**
+ * List of prefixes we should use for registering small names.
+ * @type array
+ */
+ public $prefixes = array('HTMLPurifier_HTMLModule_');
+
+ /**
+ * @type HTMLPurifier_ContentSets
+ */
+ public $contentSets;
+
+ /**
+ * @type HTMLPurifier_AttrCollections
+ */
+ public $attrCollections;
+
+ /**
+ * If set to true, unsafe elements and attributes will be allowed.
+ * @type bool
+ */
+ public $trusted = false;
+
+ public function __construct()
+ {
+ // editable internal objects
+ $this->attrTypes = new HTMLPurifier_AttrTypes();
+ $this->doctypes = new HTMLPurifier_DoctypeRegistry();
+
+ // setup basic modules
+ $common = array(
+ 'CommonAttributes', 'Text', 'Hypertext', 'List',
+ 'Presentation', 'Edit', 'Bdo', 'Tables', 'Image',
+ 'StyleAttribute',
+ // Unsafe:
+ 'Scripting', 'Object', 'Forms',
+ // Sorta legacy, but present in strict:
+ 'Name',
+ );
+ $transitional = array('Legacy', 'Target', 'Iframe');
+ $xml = array('XMLCommonAttributes');
+ $non_xml = array('NonXMLCommonAttributes');
+
+ // setup basic doctypes
+ $this->doctypes->register(
+ 'HTML 4.01 Transitional',
+ false,
+ array_merge($common, $transitional, $non_xml),
+ array('Tidy_Transitional', 'Tidy_Proprietary'),
+ array(),
+ '-//W3C//DTD HTML 4.01 Transitional//EN',
+ 'http://www.w3.org/TR/html4/loose.dtd'
+ );
+
+ $this->doctypes->register(
+ 'HTML 4.01 Strict',
+ false,
+ array_merge($common, $non_xml),
+ array('Tidy_Strict', 'Tidy_Proprietary', 'Tidy_Name'),
+ array(),
+ '-//W3C//DTD HTML 4.01//EN',
+ 'http://www.w3.org/TR/html4/strict.dtd'
+ );
+
+ $this->doctypes->register(
+ 'XHTML 1.0 Transitional',
+ true,
+ array_merge($common, $transitional, $xml, $non_xml),
+ array('Tidy_Transitional', 'Tidy_XHTML', 'Tidy_Proprietary', 'Tidy_Name'),
+ array(),
+ '-//W3C//DTD XHTML 1.0 Transitional//EN',
+ 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'
+ );
+
+ $this->doctypes->register(
+ 'XHTML 1.0 Strict',
+ true,
+ array_merge($common, $xml, $non_xml),
+ array('Tidy_Strict', 'Tidy_XHTML', 'Tidy_Strict', 'Tidy_Proprietary', 'Tidy_Name'),
+ array(),
+ '-//W3C//DTD XHTML 1.0 Strict//EN',
+ 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd'
+ );
+
+ $this->doctypes->register(
+ 'XHTML 1.1',
+ true,
+ // Iframe is a real XHTML 1.1 module, despite being
+ // "transitional"!
+ array_merge($common, $xml, array('Ruby', 'Iframe')),
+ array('Tidy_Strict', 'Tidy_XHTML', 'Tidy_Proprietary', 'Tidy_Strict', 'Tidy_Name'), // Tidy_XHTML1_1
+ array(),
+ '-//W3C//DTD XHTML 1.1//EN',
+ 'http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd'
+ );
+
+ }
+
+ /**
+ * Registers a module to the recognized module list, useful for
+ * overloading pre-existing modules.
+ * @param $module Mixed: string module name, with or without
+ * HTMLPurifier_HTMLModule prefix, or instance of
+ * subclass of HTMLPurifier_HTMLModule.
+ * @param $overload Boolean whether or not to overload previous modules.
+ * If this is not set, and you do overload a module,
+ * HTML Purifier will complain with a warning.
+ * @note This function will not call autoload, you must instantiate
+ * (and thus invoke) autoload outside the method.
+ * @note If a string is passed as a module name, different variants
+ * will be tested in this order:
+ * - Check for HTMLPurifier_HTMLModule_$name
+ * - Check all prefixes with $name in order they were added
+ * - Check for literal object name
+ * - Throw fatal error
+ * If your object name collides with an internal class, specify
+ * your module manually. All modules must have been included
+ * externally: registerModule will not perform inclusions for you!
+ */
+ public function registerModule($module, $overload = false)
+ {
+ if (is_string($module)) {
+ // attempt to load the module
+ $original_module = $module;
+ $ok = false;
+ foreach ($this->prefixes as $prefix) {
+ $module = $prefix . $original_module;
+ if (class_exists($module)) {
+ $ok = true;
+ break;
+ }
+ }
+ if (!$ok) {
+ $module = $original_module;
+ if (!class_exists($module)) {
+ trigger_error(
+ $original_module . ' module does not exist',
+ E_USER_ERROR
+ );
+ return;
+ }
+ }
+ $module = new $module();
+ }
+ if (empty($module->name)) {
+ trigger_error('Module instance of ' . get_class($module) . ' must have name');
+ return;
+ }
+ if (!$overload && isset($this->registeredModules[$module->name])) {
+ trigger_error('Overloading ' . $module->name . ' without explicit overload parameter', E_USER_WARNING);
+ }
+ $this->registeredModules[$module->name] = $module;
+ }
+
+ /**
+ * Adds a module to the current doctype by first registering it,
+ * and then tacking it on to the active doctype
+ */
+ public function addModule($module)
+ {
+ $this->registerModule($module);
+ if (is_object($module)) {
+ $module = $module->name;
+ }
+ $this->userModules[] = $module;
+ }
+
+ /**
+ * Adds a class prefix that registerModule() will use to resolve a
+ * string name to a concrete class
+ */
+ public function addPrefix($prefix)
+ {
+ $this->prefixes[] = $prefix;
+ }
+
+ /**
+ * Performs processing on modules, after being called you may
+ * use getElement() and getElements()
+ * @param HTMLPurifier_Config $config
+ */
+ public function setup($config)
+ {
+ $this->trusted = $config->get('HTML.Trusted');
+
+ // generate
+ $this->doctype = $this->doctypes->make($config);
+ $modules = $this->doctype->modules;
+
+ // take out the default modules that aren't allowed
+ $lookup = $config->get('HTML.AllowedModules');
+ $special_cases = $config->get('HTML.CoreModules');
+
+ if (is_array($lookup)) {
+ foreach ($modules as $k => $m) {
+ if (isset($special_cases[$m])) {
+ continue;
+ }
+ if (!isset($lookup[$m])) {
+ unset($modules[$k]);
+ }
+ }
+ }
+
+ // custom modules
+ if ($config->get('HTML.Proprietary')) {
+ $modules[] = 'Proprietary';
+ }
+ if ($config->get('HTML.SafeObject')) {
+ $modules[] = 'SafeObject';
+ }
+ if ($config->get('HTML.SafeEmbed')) {
+ $modules[] = 'SafeEmbed';
+ }
+ if ($config->get('HTML.SafeScripting') !== array()) {
+ $modules[] = 'SafeScripting';
+ }
+ if ($config->get('HTML.Nofollow')) {
+ $modules[] = 'Nofollow';
+ }
+ if ($config->get('HTML.TargetBlank')) {
+ $modules[] = 'TargetBlank';
+ }
+ // NB: HTML.TargetNoreferrer and HTML.TargetNoopener must be AFTER HTML.TargetBlank
+ // so that its post-attr-transform gets run afterwards.
+ if ($config->get('HTML.TargetNoreferrer')) {
+ $modules[] = 'TargetNoreferrer';
+ }
+ if ($config->get('HTML.TargetNoopener')) {
+ $modules[] = 'TargetNoopener';
+ }
+
+ // merge in custom modules
+ $modules = array_merge($modules, $this->userModules);
+
+ foreach ($modules as $module) {
+ $this->processModule($module);
+ $this->modules[$module]->setup($config);
+ }
+
+ foreach ($this->doctype->tidyModules as $module) {
+ $this->processModule($module);
+ $this->modules[$module]->setup($config);
+ }
+
+ // prepare any injectors
+ foreach ($this->modules as $module) {
+ $n = array();
+ foreach ($module->info_injector as $injector) {
+ if (!is_object($injector)) {
+ $class = "HTMLPurifier_Injector_$injector";
+ $injector = new $class;
+ }
+ $n[$injector->name] = $injector;
+ }
+ $module->info_injector = $n;
+ }
+
+ // setup lookup table based on all valid modules
+ foreach ($this->modules as $module) {
+ foreach ($module->info as $name => $def) {
+ if (!isset($this->elementLookup[$name])) {
+ $this->elementLookup[$name] = array();
+ }
+ $this->elementLookup[$name][] = $module->name;
+ }
+ }
+
+ // note the different choice
+ $this->contentSets = new HTMLPurifier_ContentSets(
+ // content set assembly deals with all possible modules,
+ // not just ones deemed to be "safe"
+ $this->modules
+ );
+ $this->attrCollections = new HTMLPurifier_AttrCollections(
+ $this->attrTypes,
+ // there is no way to directly disable a global attribute,
+ // but using AllowedAttributes or simply not including
+ // the module in your custom doctype should be sufficient
+ $this->modules
+ );
+ }
+
+ /**
+ * Takes a module and adds it to the active module collection,
+ * registering it if necessary.
+ */
+ public function processModule($module)
+ {
+ if (!isset($this->registeredModules[$module]) || is_object($module)) {
+ $this->registerModule($module);
+ }
+ $this->modules[$module] = $this->registeredModules[$module];
+ }
+
+ /**
+ * Retrieves merged element definitions.
+ * @return Array of HTMLPurifier_ElementDef
+ */
+ public function getElements()
+ {
+ $elements = array();
+ foreach ($this->modules as $module) {
+ if (!$this->trusted && !$module->safe) {
+ continue;
+ }
+ foreach ($module->info as $name => $v) {
+ if (isset($elements[$name])) {
+ continue;
+ }
+ $elements[$name] = $this->getElement($name);
+ }
+ }
+
+ // remove dud elements, this happens when an element that
+ // appeared to be safe actually wasn't
+ foreach ($elements as $n => $v) {
+ if ($v === false) {
+ unset($elements[$n]);
+ }
+ }
+
+ return $elements;
+
+ }
+
+ /**
+ * Retrieves a single merged element definition
+ * @param string $name Name of element
+ * @param bool $trusted Boolean trusted overriding parameter: set to true
+ * if you want the full version of an element
+ * @return HTMLPurifier_ElementDef Merged HTMLPurifier_ElementDef
+ * @note You may notice that modules are getting iterated over twice (once
+ * in getElements() and once here). This
+ * is because
+ */
+ public function getElement($name, $trusted = null)
+ {
+ if (!isset($this->elementLookup[$name])) {
+ return false;
+ }
+
+ // setup global state variables
+ $def = false;
+ if ($trusted === null) {
+ $trusted = $this->trusted;
+ }
+
+ // iterate through each module that has registered itself to this
+ // element
+ foreach ($this->elementLookup[$name] as $module_name) {
+ $module = $this->modules[$module_name];
+
+ // refuse to create/merge from a module that is deemed unsafe--
+ // pretend the module doesn't exist--when trusted mode is not on.
+ if (!$trusted && !$module->safe) {
+ continue;
+ }
+
+ // clone is used because, ideally speaking, the original
+ // definition should not be modified. Usually, this will
+ // make no difference, but for consistency's sake
+ $new_def = clone $module->info[$name];
+
+ if (!$def && $new_def->standalone) {
+ $def = $new_def;
+ } elseif ($def) {
+ // This will occur even if $new_def is standalone. In practice,
+ // this will usually result in a full replacement.
+ $def->mergeIn($new_def);
+ } else {
+ // :TODO:
+ // non-standalone definitions that don't have a standalone
+ // to merge into could be deferred to the end
+ // HOWEVER, it is perfectly valid for a non-standalone
+ // definition to lack a standalone definition, even
+ // after all processing: this allows us to safely
+ // specify extra attributes for elements that may not be
+ // enabled all in one place. In particular, this might
+ // be the case for trusted elements. WARNING: care must
+ // be taken that the /extra/ definitions are all safe.
+ continue;
+ }
+
+ // attribute value expansions
+ $this->attrCollections->performInclusions($def->attr);
+ $this->attrCollections->expandIdentifiers($def->attr, $this->attrTypes);
+
+ // descendants_are_inline, for ChildDef_Chameleon
+ if (is_string($def->content_model) &&
+ strpos($def->content_model, 'Inline') !== false) {
+ if ($name != 'del' && $name != 'ins') {
+ // this is for you, ins/del
+ $def->descendants_are_inline = true;
+ }
+ }
+
+ $this->contentSets->generateChildDef($def, $module);
+ }
+
+ // This can occur if there is a blank definition, but no base to
+ // mix it in with
+ if (!$def) {
+ return false;
+ }
+
+ // add information on required attributes
+ foreach ($def->attr as $attr_name => $attr_def) {
+ if ($attr_def->required) {
+ $def->required_attr[] = $attr_name;
+ }
+ }
+ return $def;
+ }
+}
+
+// vim: et sw=4 sts=4